Skip to content

Commit

Permalink
dmaengine: pl330: make platform data optional
Browse files Browse the repository at this point in the history
The pl330 needs platform data for describing peripheral connections, but
some platforms may only support memory to memory dma channels. In this
case, we can probe for how many channels there are and don't need the
platform data.

As memcpy requests don't need channel private data to hold peripheral
info, allow private data to be NULL in this case.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Vinod Koul <vkoul@infradead.org>
Cc: Dan Williams <dan.j.williams@intel.com>
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
  • Loading branch information
Rob Herring authored and Vinod Koul committed Jul 26, 2011
1 parent 1c1d954 commit 4e0e610
Showing 1 changed file with 36 additions and 28 deletions.
64 changes: 36 additions & 28 deletions drivers/dma/pl330.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct dma_pl330_dmac {
spinlock_t pool_lock;

/* Peripheral channels connected to this DMAC */
struct dma_pl330_chan peripherals[0]; /* keep at end */
struct dma_pl330_chan *peripherals; /* keep at end */
};

struct dma_pl330_desc {
Expand Down Expand Up @@ -451,8 +451,13 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
desc->txd.cookie = 0;
async_tx_ack(&desc->txd);

desc->req.rqtype = peri->rqtype;
desc->req.peri = peri->peri_id;
if (peri) {
desc->req.rqtype = peri->rqtype;
desc->req.peri = peri->peri_id;
} else {
desc->req.rqtype = MEMTOMEM;
desc->req.peri = 0;
}

dma_async_tx_descriptor_init(&desc->txd, &pch->chan);

Expand Down Expand Up @@ -529,10 +534,10 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
struct pl330_info *pi;
int burst;

if (unlikely(!pch || !len || !peri))
if (unlikely(!pch || !len))
return NULL;

if (peri->rqtype != MEMTOMEM)
if (peri && peri->rqtype != MEMTOMEM)
return NULL;

pi = &pch->dmac->pif;
Expand Down Expand Up @@ -577,7 +582,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
int i, burst_size;
dma_addr_t addr;

if (unlikely(!pch || !sgl || !sg_len))
if (unlikely(!pch || !sgl || !sg_len || !peri))
return NULL;

/* Make sure the direction is consistent */
Expand Down Expand Up @@ -666,17 +671,12 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
struct dma_device *pd;
struct resource *res;
int i, ret, irq;
int num_chan;

pdat = adev->dev.platform_data;

if (!pdat || !pdat->nr_valid_peri) {
dev_err(&adev->dev, "platform data missing\n");
return -ENODEV;
}

/* Allocate a new DMAC and its Channels */
pdmac = kzalloc(pdat->nr_valid_peri * sizeof(*pch)
+ sizeof(*pdmac), GFP_KERNEL);
pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
if (!pdmac) {
dev_err(&adev->dev, "unable to allocate mem\n");
return -ENOMEM;
Expand All @@ -685,7 +685,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
pi = &pdmac->pif;
pi->dev = &adev->dev;
pi->pl330_data = NULL;
pi->mcbufsz = pdat->mcbuf_sz;
pi->mcbufsz = pdat ? pdat->mcbuf_sz : 0;

res = &adev->res;
request_mem_region(res->start, resource_size(res), "dma-pl330");
Expand Down Expand Up @@ -717,27 +717,35 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
INIT_LIST_HEAD(&pd->channels);

/* Initialize channel parameters */
for (i = 0; i < pdat->nr_valid_peri; i++) {
struct dma_pl330_peri *peri = &pdat->peri[i];
pch = &pdmac->peripherals[i];
num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);

switch (peri->rqtype) {
case MEMTOMEM:
for (i = 0; i < num_chan; i++) {
pch = &pdmac->peripherals[i];
if (pdat) {
struct dma_pl330_peri *peri = &pdat->peri[i];

switch (peri->rqtype) {
case MEMTOMEM:
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
break;
case MEMTODEV:
case DEVTOMEM:
dma_cap_set(DMA_SLAVE, pd->cap_mask);
break;
default:
dev_err(&adev->dev, "DEVTODEV Not Supported\n");
continue;
}
pch->chan.private = peri;
} else {
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
break;
case MEMTODEV:
case DEVTOMEM:
dma_cap_set(DMA_SLAVE, pd->cap_mask);
break;
default:
dev_err(&adev->dev, "DEVTODEV Not Supported\n");
continue;
pch->chan.private = NULL;
}

INIT_LIST_HEAD(&pch->work_list);
spin_lock_init(&pch->lock);
pch->pl330_chid = NULL;
pch->chan.private = peri;
pch->chan.device = pd;
pch->chan.chan_id = i;
pch->dmac = pdmac;
Expand Down

0 comments on commit 4e0e610

Please sign in to comment.