summaryrefslogtreecommitdiff
path: root/drivers/dma
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2015-10-14 11:42:49 (GMT)
committerVinod Koul <vinod.koul@intel.com>2015-10-14 14:27:11 (GMT)
commitca304fa9bb762f091e851d48de43f623c975d47a (patch)
treec772e271becb06e49be494e8701fe2d6c8a7d9fd /drivers/dma
parent700c371913072fc891650a6dafacfd147ce805a7 (diff)
downloadlinux-ca304fa9bb762f091e851d48de43f623c975d47a.tar.xz
ARM/dmaengine: edma: Public API to use private struct pointer
Instead of relying on indexes pointing to edma private date in the global pointer array, pass the private data pointer via the public API. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/edma.c79
1 files changed, 43 insertions, 36 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index fcb4680..53d48b2 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -119,6 +119,7 @@ struct edma_chan {
};
struct edma_cc {
+ struct edma *cc;
int ctlr;
struct dma_device dma_slave;
struct edma_chan slave_chans[EDMA_CHANS];
@@ -150,6 +151,7 @@ static void edma_desc_free(struct virt_dma_desc *vdesc)
/* Dispatch a queued descriptor to the controller (caller holds lock) */
static void edma_execute(struct edma_chan *echan)
{
+ struct edma *cc = echan->ecc->cc;
struct virt_dma_desc *vdesc;
struct edma_desc *edesc;
struct device *dev = echan->vchan.chan.device->dev;
@@ -174,7 +176,7 @@ static void edma_execute(struct edma_chan *echan)
/* Write descriptor PaRAM set(s) */
for (i = 0; i < nslots; i++) {
j = i + edesc->processed;
- edma_write_slot(echan->slot[i], &edesc->pset[j].param);
+ edma_write_slot(cc, echan->slot[i], &edesc->pset[j].param);
edesc->sg_len += edesc->pset[j].len;
dev_vdbg(echan->vchan.chan.device->dev,
"\n pset[%d]:\n"
@@ -199,7 +201,7 @@ static void edma_execute(struct edma_chan *echan)
edesc->pset[j].param.link_bcntrld);
/* Link to the previous slot if not the last set */
if (i != (nslots - 1))
- edma_link(echan->slot[i], echan->slot[i+1]);
+ edma_link(cc, echan->slot[i], echan->slot[i+1]);
}
edesc->processed += nslots;
@@ -211,9 +213,9 @@ static void edma_execute(struct edma_chan *echan)
*/
if (edesc->processed == edesc->pset_nr) {
if (edesc->cyclic)
- edma_link(echan->slot[nslots-1], echan->slot[1]);
+ edma_link(cc, echan->slot[nslots-1], echan->slot[1]);
else
- edma_link(echan->slot[nslots-1],
+ edma_link(cc, echan->slot[nslots-1],
echan->ecc->dummy_slot);
}
@@ -224,19 +226,19 @@ static void edma_execute(struct edma_chan *echan)
* transfers of MAX_NR_SG
*/
dev_dbg(dev, "missed event on channel %d\n", echan->ch_num);
- edma_clean_channel(echan->ch_num);
- edma_stop(echan->ch_num);
- edma_start(echan->ch_num);
- edma_trigger_channel(echan->ch_num);
+ edma_clean_channel(cc, echan->ch_num);
+ edma_stop(cc, echan->ch_num);
+ edma_start(cc, echan->ch_num);
+ edma_trigger_channel(cc, echan->ch_num);
echan->missed = 0;
} else if (edesc->processed <= MAX_NR_SG) {
dev_dbg(dev, "first transfer starting on channel %d\n",
echan->ch_num);
- edma_start(echan->ch_num);
+ edma_start(cc, echan->ch_num);
} else {
dev_dbg(dev, "chan: %d: completed %d elements, resuming\n",
echan->ch_num, edesc->processed);
- edma_resume(echan->ch_num);
+ edma_resume(cc, echan->ch_num);
}
}
@@ -254,10 +256,11 @@ static int edma_terminate_all(struct dma_chan *chan)
* echan->edesc is NULL and exit.)
*/
if (echan->edesc) {
- edma_stop(echan->ch_num);
+ edma_stop(echan->ecc->cc, echan->ch_num);
/* Move the cyclic channel back to default queue */
if (echan->edesc->cyclic)
- edma_assign_channel_eventq(echan->ch_num,
+ edma_assign_channel_eventq(echan->ecc->cc,
+ echan->ch_num,
EVENTQ_DEFAULT);
/*
* free the running request descriptor
@@ -295,7 +298,7 @@ static int edma_dma_pause(struct dma_chan *chan)
if (!echan->edesc)
return -EINVAL;
- edma_pause(echan->ch_num);
+ edma_pause(echan->ecc->cc, echan->ch_num);
return 0;
}
@@ -303,7 +306,7 @@ static int edma_dma_resume(struct dma_chan *chan)
{
struct edma_chan *echan = to_edma_chan(chan);
- edma_resume(echan->ch_num);
+ edma_resume(echan->ecc->cc, echan->ch_num);
return 0;
}
@@ -485,8 +488,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
for (i = 0; i < nslots; i++) {
if (echan->slot[i] < 0) {
echan->slot[i] =
- edma_alloc_slot(EDMA_CTLR(echan->ch_num),
- EDMA_SLOT_ANY);
+ edma_alloc_slot(echan->ecc->cc, EDMA_SLOT_ANY);
if (echan->slot[i] < 0) {
kfree(edesc);
dev_err(dev, "%s: Failed to allocate slot\n",
@@ -641,8 +643,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
/* Allocate a PaRAM slot, if needed */
if (echan->slot[i] < 0) {
echan->slot[i] =
- edma_alloc_slot(EDMA_CTLR(echan->ch_num),
- EDMA_SLOT_ANY);
+ edma_alloc_slot(echan->ecc->cc, EDMA_SLOT_ANY);
if (echan->slot[i] < 0) {
kfree(edesc);
dev_err(dev, "%s: Failed to allocate slot\n",
@@ -703,7 +704,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
}
/* Place the cyclic channel to highest priority queue */
- edma_assign_channel_eventq(echan->ch_num, EVENTQ_0);
+ edma_assign_channel_eventq(echan->ecc->cc, echan->ch_num, EVENTQ_0);
return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
}
@@ -711,6 +712,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
{
struct edma_chan *echan = data;
+ struct edma *cc = echan->ecc->cc;
struct device *dev = echan->vchan.chan.device->dev;
struct edma_desc *edesc;
struct edmacc_param p;
@@ -727,13 +729,13 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
} else if (edesc->processed == edesc->pset_nr) {
dev_dbg(dev, "Transfer complete, stopping channel %d\n", ch_num);
edesc->residue = 0;
- edma_stop(echan->ch_num);
+ edma_stop(cc, echan->ch_num);
vchan_cookie_complete(&edesc->vdesc);
echan->edesc = NULL;
} else {
dev_dbg(dev, "Intermediate transfer complete on channel %d\n", ch_num);
- edma_pause(echan->ch_num);
+ edma_pause(cc, echan->ch_num);
/* Update statistics for tx_status */
edesc->residue -= edesc->sg_len;
@@ -744,7 +746,7 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
}
break;
case EDMA_DMA_CC_ERROR:
- edma_read_slot(EDMA_CHAN_SLOT(echan->slot[0]), &p);
+ edma_read_slot(cc, echan->slot[0], &p);
/*
* Issue later based on missed flag which will be sure
@@ -767,10 +769,10 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
* missed, so its safe to issue it here.
*/
dev_dbg(dev, "Error occurred but slot is non-null, TRIGGERING\n");
- edma_clean_channel(echan->ch_num);
- edma_stop(echan->ch_num);
- edma_start(echan->ch_num);
- edma_trigger_channel(echan->ch_num);
+ edma_clean_channel(cc, echan->ch_num);
+ edma_stop(cc, echan->ch_num);
+ edma_start(cc, echan->ch_num);
+ edma_trigger_channel(cc, echan->ch_num);
}
break;
default:
@@ -789,8 +791,8 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
int a_ch_num;
LIST_HEAD(descs);
- a_ch_num = edma_alloc_channel(echan->ch_num, edma_callback,
- echan, EVENTQ_DEFAULT);
+ a_ch_num = edma_alloc_channel(echan->ecc->cc, echan->ch_num,
+ edma_callback, echan, EVENTQ_DEFAULT);
if (a_ch_num < 0) {
ret = -ENODEV;
@@ -814,7 +816,7 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
return 0;
err_wrong_chan:
- edma_free_channel(a_ch_num);
+ edma_free_channel(echan->ecc->cc, a_ch_num);
err_no_chan:
return ret;
}
@@ -827,21 +829,21 @@ static void edma_free_chan_resources(struct dma_chan *chan)
int i;
/* Terminate transfers */
- edma_stop(echan->ch_num);
+ edma_stop(echan->ecc->cc, echan->ch_num);
vchan_free_chan_resources(&echan->vchan);
/* Free EDMA PaRAM slots */
for (i = 1; i < EDMA_MAX_SLOTS; i++) {
if (echan->slot[i] >= 0) {
- edma_free_slot(echan->slot[i]);
+ edma_free_slot(echan->ecc->cc, echan->slot[i]);
echan->slot[i] = -1;
}
}
/* Free EDMA channel */
if (echan->alloced) {
- edma_free_channel(echan->ch_num);
+ edma_free_channel(echan->ecc->cc, echan->ch_num);
echan->alloced = false;
}
@@ -871,7 +873,8 @@ static u32 edma_residue(struct edma_desc *edesc)
* We always read the dst/src position from the first RamPar
* pset. That's the one which is active now.
*/
- pos = edma_get_position(edesc->echan->slot[0], dst);
+ pos = edma_get_position(edesc->echan->ecc->cc, edesc->echan->slot[0],
+ dst);
/*
* Cyclic is simple. Just subtract pset[0].addr from pos.
@@ -1008,8 +1011,12 @@ static int edma_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ ecc->cc = edma_get_data(pdev->dev.parent);
+ if (!ecc->cc)
+ return -ENODEV;
+
ecc->ctlr = pdev->id;
- ecc->dummy_slot = edma_alloc_slot(ecc->ctlr, EDMA_SLOT_ANY);
+ ecc->dummy_slot = edma_alloc_slot(ecc->cc, EDMA_SLOT_ANY);
if (ecc->dummy_slot < 0) {
dev_err(&pdev->dev, "Can't allocate PaRAM dummy slot\n");
return ecc->dummy_slot;
@@ -1042,7 +1049,7 @@ static int edma_probe(struct platform_device *pdev)
return 0;
err_reg1:
- edma_free_slot(ecc->dummy_slot);
+ edma_free_slot(ecc->cc, ecc->dummy_slot);
return ret;
}
@@ -1055,7 +1062,7 @@ static int edma_remove(struct platform_device *pdev)
if (parent_node)
of_dma_controller_free(parent_node);
dma_async_device_unregister(&ecc->dma_slave);
- edma_free_slot(ecc->dummy_slot);
+ edma_free_slot(ecc->cc, ecc->dummy_slot);
return 0;
}