21 #include <linux/module.h>
23 #include <linux/slab.h>
26 #include "../dmaengine.h"
37 #define NR_DESCS_PER_CHANNEL 32
39 #define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
40 #define to_shdma_dev(d) container_of(d, struct shdma_dev, dma_dev)
48 static unsigned int slave_num = 256;
52 static unsigned long *shdma_slave_used;
55 static void shdma_chan_xfer_ld_queue(
struct shdma_chan *schan)
85 power_up = list_empty(&schan->
ld_queue);
87 cookie = dma_cookie_assign(tx);
118 ret = pm_runtime_get(schan->
dev);
122 dev_err(schan->
dev,
"%s(): GET = %d\n", __func__, ret);
143 shdma_chan_xfer_ld_queue(schan);
174 static int shdma_setup_slave(
struct shdma_chan *schan,
int slave_id)
180 if (slave_id < 0 || slave_id >= slave_num)
186 ret = ops->
set_slave(schan, slave_id,
false);
215 int slave_id = (
int)arg;
222 if (slave_id >= slave_num)
225 ret = ops->
set_slave(schan, slave_id,
true);
233 static int shdma_alloc_chan_resources(
struct dma_chan *
chan)
248 ret = shdma_setup_slave(schan, slave->
slave_id);
267 desc->
async_tx.tx_submit = shdma_tx_submit;
287 bool head_acked =
false;
317 "Completing cookie %d, expected %d\n",
319 schan->
dma_chan.completed_cookie + 1);
328 dev_dbg(schan->
dev,
"descriptor #%d@%p on %d callback\n",
339 head_acked = async_tx_test_ack(tx);
341 switch (desc->
mark) {
351 dev_dbg(schan->
dev,
"descriptor %p #%d completed.\n",
356 async_tx_test_ack(&desc->
async_tx)) || all) {
363 dev_dbg(schan->
dev,
"Bring down channel %d\n", schan->
id);
364 pm_runtime_put(schan->
dev);
370 if (all && !callback)
377 spin_unlock_irqrestore(&schan->
chan_lock, flags);
390 static void shdma_chan_ld_cleanup(
struct shdma_chan *schan,
bool all)
392 while (__ld_cleanup(schan, all))
399 static void shdma_free_chan_resources(
struct dma_chan *chan)
415 shdma_chan_ld_cleanup(schan,
true);
455 size_t copy_size = *len;
461 new = shdma_get_desc(schan);
463 dev_err(schan->
dev,
"No free link descriptor available\n");
467 ops->
desc_setup(schan,
new, *src, *dst, ©_size);
471 new->async_tx.cookie = -
EBUSY;
479 "chaining (%u/%u)@%x -> %x with %p, cookie %d\n",
480 copy_size, *len, *src, *dst, &new->async_tx,
481 new->async_tx.cookie);
484 new->async_tx.flags =
flags;
515 unsigned long irq_flags;
543 dev_dbg(schan->
dev,
"Add SG #%d@%p[%d], dma %llx\n",
544 i, sg, len, (
unsigned long long)sg_addr);
547 new = shdma_add_desc(schan, flags,
548 &sg_addr, addr, &len, &first,
551 new = shdma_add_desc(schan, flags,
552 addr, &sg_addr, &len, &first,
557 new->chunks = chunks--;
563 new->async_tx.cookie = -
ENOSPC;
568 spin_unlock_irqrestore(&schan->
chan_lock, irq_flags);
575 list_splice(&
tx_list, &schan->ld_free);
577 spin_unlock_irqrestore(&schan->chan_lock, irq_flags);
584 size_t len,
unsigned long flags)
600 return shdma_prep_sg(schan, &sg, 1, &dma_dest,
DMA_MEM_TO_MEM, flags);
619 if (slave_id < 0 || !sg_len) {
620 dev_warn(schan->
dev,
"%s: bad parameter: len=%d, id=%d\n",
621 __func__, sg_len, slave_id);
627 return shdma_prep_sg(schan, sgl, sg_len, &slave_addr,
656 spin_unlock_irqrestore(&schan->
chan_lock, flags);
658 shdma_chan_ld_cleanup(schan,
true);
672 ret = shdma_setup_slave(schan, config->
slave_id);
683 static void shdma_issue_pending(
struct dma_chan *chan)
689 shdma_chan_xfer_ld_queue(schan);
703 shdma_chan_ld_cleanup(schan,
false);
707 status = dma_cookie_status(chan, cookie, txstate);
717 if (sdesc->cookie == cookie) {
723 spin_unlock_irqrestore(&schan->
chan_lock, flags);
733 unsigned int handled = 0;
751 if (!list_empty(&
dl)) {
752 dev_dbg(schan->
dev,
"Bring down channel %d\n", schan->
id);
753 pm_runtime_put(schan->
dev);
812 shdma_chan_xfer_ld_queue(schan);
815 shdma_chan_ld_cleanup(schan,
false);
821 unsigned long flags,
const char *
name)
826 schan->
irq = ret < 0 ? ret : irq;
858 INIT_LIST_HEAD(&schan->
ld_free);
884 !sdev->
ops->embedded_desc ||
885 !sdev->
ops->start_xfer ||
886 !sdev->
ops->setup_xfer ||
887 !sdev->
ops->set_slave ||
888 !sdev->
ops->desc_setup ||
889 !sdev->
ops->slave_addr ||
890 !sdev->
ops->channel_busy ||
891 !sdev->
ops->halt_channel ||
892 !sdev->
ops->desc_completed)
903 = shdma_alloc_chan_resources;
925 static int __init shdma_enter(
void)
929 if (!shdma_slave_used)
935 static void __exit shdma_exit(
void)
937 kfree(shdma_slave_used);