Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 281593
b: refs/heads/master
c: 93ed554
h: refs/heads/master
i:
  281591: 67ec87b
v: v3
  • Loading branch information
Thomas Abraham authored and Kukjin Kim committed Dec 23, 2011
1 parent cc87373 commit e96b08d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e1cd8454dac99473c2349efce1346264c494f28d
refs/heads/master: 93ed55441245a39e3935f5cf1af3e22febcce905
30 changes: 30 additions & 0 deletions trunk/Documentation/devicetree/bindings/dma/arm-pl330.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
* ARM PrimeCell PL330 DMA Controller

The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
between memory and peripherals or memory to memory.

Required properties:
- compatible: should include both "arm,pl330" and "arm,primecell".
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.

Example:

pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <99>;
};

Client drivers (device nodes requiring dma transfers from dev-to-mem or
mem-to-dev) should specify the DMA channel numbers using a two-value pair
as shown below.

[property name] = <[phandle of the dma controller] [dma request id]>;

where 'dma request id' is the dma request number which is connected
to the client controller. The 'property name' is recommended to be
of the form <name>-dma-channel.

Example: tx-dma-channel = <&pdma0 12>;
33 changes: 29 additions & 4 deletions trunk/drivers/dma/pl330.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/amba/pl330.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
#include <linux/of.h>

#define NR_DEFAULT_DESC 16

Expand Down Expand Up @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
if (chan->device->dev->driver != &pl330_driver.drv)
return false;

#ifdef CONFIG_OF
if (chan->device->dev->of_node) {
const __be32 *prop_value;
phandle phandle;
struct device_node *node;

prop_value = ((struct property *)param)->value;
phandle = be32_to_cpup(prop_value++);
node = of_find_node_by_phandle(phandle);
return ((chan->private == node) &&
(chan->chan_id == be32_to_cpup(prop_value)));
}
#endif

peri_id = chan->private;
return *peri_id == (unsigned)param;
}
Expand Down Expand Up @@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
INIT_LIST_HEAD(&pd->channels);

/* Initialize channel parameters */
num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan);
num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
(u8)pi->pcfg.num_chan);
pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);

for (i = 0; i < num_chan; i++) {
pch = &pdmac->peripherals[i];
pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
if (!adev->dev.of_node)
pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
else
pch->chan.private = adev->dev.of_node;

INIT_LIST_HEAD(&pch->work_list);
spin_lock_init(&pch->lock);
pch->pl330_chid = NULL;
Expand All @@ -872,10 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
}

pd->dev = &adev->dev;
if (pdat)
if (pdat) {
pd->cap_mask = pdat->cap_mask;
else
} else {
dma_cap_set(DMA_MEMCPY, pd->cap_mask);
if (pi->pcfg.num_peri) {
dma_cap_set(DMA_SLAVE, pd->cap_mask);
dma_cap_set(DMA_CYCLIC, pd->cap_mask);
}
}

pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
pd->device_free_chan_resources = pl330_free_chan_resources;
Expand Down

0 comments on commit e96b08d

Please sign in to comment.