aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/pl330.c
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2011-10-24 05:43:31 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-12-22 20:07:04 -0500
commit93ed55441245a39e3935f5cf1af3e22febcce905 (patch)
tree5e238c5e269274fd47c1d03cb0a1c6172feef8fc /drivers/dma/pl330.c
parente1cd8454dac99473c2349efce1346264c494f28d (diff)
DMA: PL330: Add device tree support
For PL330 dma controllers instantiated from device tree, the channel lookup is based on phandle of the dma controller and dma request id specified by the client node. During probe, the private data of each channel of the controller is set to point to the device node of the dma controller. The 'chan_id' of the each channel is used as the dma request id. Client driver requesting dma channels specify the phandle of the dma controller and the request id. The pl330 filter function converts the phandle to the device node pointer and matches that with channel's private data. If a match is found, the request id from the client node and the 'chan_id' of the channel is matched. A channel is found if both the values match. Acked-by: Jassi Brar <jassisinghbrar@gmail.com> Acked-by: Boojin Kim <boojin.kim@samsung.com> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Reviewed-by: Rob Herring <rob.herring@calxeda.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'drivers/dma/pl330.c')
-rw-r--r--drivers/dma/pl330.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 317aaeaa6f66..a626e15799a5 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
19#include <linux/amba/pl330.h> 19#include <linux/amba/pl330.h>
20#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
21#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
22#include <linux/of.h>
22 23
23#define NR_DEFAULT_DESC 16 24#define NR_DEFAULT_DESC 16
24 25
@@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param)
277 if (chan->device->dev->driver != &pl330_driver.drv) 278 if (chan->device->dev->driver != &pl330_driver.drv)
278 return false; 279 return false;
279 280
281#ifdef CONFIG_OF
282 if (chan->device->dev->of_node) {
283 const __be32 *prop_value;
284 phandle phandle;
285 struct device_node *node;
286
287 prop_value = ((struct property *)param)->value;
288 phandle = be32_to_cpup(prop_value++);
289 node = of_find_node_by_phandle(phandle);
290 return ((chan->private == node) &&
291 (chan->chan_id == be32_to_cpup(prop_value)));
292 }
293#endif
294
280 peri_id = chan->private; 295 peri_id = chan->private;
281 return *peri_id == (unsigned)param; 296 return *peri_id == (unsigned)param;
282} 297}
@@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
855 INIT_LIST_HEAD(&pd->channels); 870 INIT_LIST_HEAD(&pd->channels);
856 871
857 /* Initialize channel parameters */ 872 /* Initialize channel parameters */
858 num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan); 873 num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
874 (u8)pi->pcfg.num_chan);
859 pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); 875 pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
860 876
861 for (i = 0; i < num_chan; i++) { 877 for (i = 0; i < num_chan; i++) {
862 pch = &pdmac->peripherals[i]; 878 pch = &pdmac->peripherals[i];
863 pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; 879 if (!adev->dev.of_node)
880 pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
881 else
882 pch->chan.private = adev->dev.of_node;
883
864 INIT_LIST_HEAD(&pch->work_list); 884 INIT_LIST_HEAD(&pch->work_list);
865 spin_lock_init(&pch->lock); 885 spin_lock_init(&pch->lock);
866 pch->pl330_chid = NULL; 886 pch->pl330_chid = NULL;
@@ -872,10 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
872 } 892 }
873 893
874 pd->dev = &adev->dev; 894 pd->dev = &adev->dev;
875 if (pdat) 895 if (pdat) {
876 pd->cap_mask = pdat->cap_mask; 896 pd->cap_mask = pdat->cap_mask;
877 else 897 } else {
878 dma_cap_set(DMA_MEMCPY, pd->cap_mask); 898 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
899 if (pi->pcfg.num_peri) {
900 dma_cap_set(DMA_SLAVE, pd->cap_mask);
901 dma_cap_set(DMA_CYCLIC, pd->cap_mask);
902 }
903 }
879 904
880 pd->device_alloc_chan_resources = pl330_alloc_chan_resources; 905 pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
881 pd->device_free_chan_resources = pl330_free_chan_resources; 906 pd->device_free_chan_resources = pl330_free_chan_resources;