diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 11:10:41 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 11:10:41 +0900 |
commit | b7e97d22113bcaafff93774e3085f5b567eaba9c (patch) | |
tree | 1d3a13574310bde064fceb4408cf91a44c59c078 /drivers/dma/mmp_tdma.c | |
parent | 943c2acea53784c45fb291498d04d5188fdea891 (diff) | |
parent | d0fc905429f7f5f3ad365466669c55b04b92c1e5 (diff) |
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
Pull slave-dmaengine updates from Vinod Koul:
"This time we have Andy updates on dw_dmac which is attempting to make
this IP block available as PCI and platform device though not fully
complete this time.
We also have TI EDMA moving the dma driver to use dmaengine APIs, also
have a new driver for mmp-tdma, along with bunch of small updates.
Now for your excitement the merge is little unusual here, while
merging the auto merge on linux-next picks wrong choice for pl330
(drivers/dma/pl330.c) and this causes build failure. The correct
resolution is in linux-next. (DMA: PL330: Fix build error) I didn't
back merge your tree this time as you are better than me so no point
in doing that for me :)"
Fixed the pl330 conflict as in linux-next, along with trivial header
file conflicts due to changed includes.
* 'next' of git://git.infradead.org/users/vkoul/slave-dma: (29 commits)
dma: tegra: fix interrupt name issue with apb dma.
dw_dmac: fix a regression in dwc_prep_dma_memcpy
dw_dmac: introduce software emulation of LLP transfers
dw_dmac: autoconfigure data_width or get it via platform data
dw_dmac: autoconfigure block_size or use platform data
dw_dmac: get number of channels from hardware if possible
dw_dmac: fill optional encoded parameters in register structure
dw_dmac: mark dwc_dump_chan_regs as inline
DMA: PL330: return ENOMEM instead of 0 from pl330_alloc_chan_resources
DMA: PL330: Remove redundant runtime_suspend/resume functions
DMA: PL330: Remove controller clock enable/disable
dmaengine: use kmem_cache_zalloc instead of kmem_cache_alloc/memset
DMA: PL330: Set the capability of pdm0 and pdm1 as DMA_PRIVATE
ARM: EXYNOS: Set the capability of pdm0 and pdm1 as DMA_PRIVATE
dma: tegra: use list_move_tail instead of list_del/list_add_tail
mxs/dma: Enlarge the CCW descriptor area to 4 pages
dw_dmac: utilize slave_id to pass request line
dmaengine: mmp_tdma: add dt support
dmaengine: mmp-pdma support
spi: davici - make davinci select edma
...
Diffstat (limited to 'drivers/dma/mmp_tdma.c')
-rw-r--r-- | drivers/dma/mmp_tdma.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 6d9c82e891d..f3e8d71bcbc 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -20,6 +20,7 @@ #include <linux/device.h> #include <mach/regs-icu.h> #include <linux/platform_data/dma-mmp_tdma.h> +#include <linux/of_device.h> #include "dmaengine.h" @@ -127,7 +128,6 @@ struct mmp_tdma_device { void __iomem *base; struct dma_device device; struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM]; - int irq; }; #define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan) @@ -492,7 +492,7 @@ static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev, return -ENOMEM; } if (irq) - tdmac->irq = irq + idx; + tdmac->irq = irq; tdmac->dev = tdev->dev; tdmac->chan.device = &tdev->device; tdmac->idx = idx; @@ -505,34 +505,43 @@ static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev, /* add the channel to tdma_chan list */ list_add_tail(&tdmac->chan.device_node, &tdev->device.channels); - return 0; } +static struct of_device_id mmp_tdma_dt_ids[] = { + { .compatible = "marvell,adma-1.0", .data = (void *)MMP_AUD_TDMA}, + { .compatible = "marvell,pxa910-squ", .data = (void *)PXA910_SQU}, + {} +}; +MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids); + static int __devinit mmp_tdma_probe(struct platform_device *pdev) { - const struct platform_device_id *id = platform_get_device_id(pdev); - enum mmp_tdma_type type = id->driver_data; + enum mmp_tdma_type type; + const struct of_device_id *of_id; struct mmp_tdma_device *tdev; struct resource *iores; int i, ret; - int irq = 0; + int irq = 0, irq_num = 0; int chan_num = TDMA_CHANNEL_NUM; + of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev); + if (of_id) + type = (enum mmp_tdma_type) of_id->data; + else + type = platform_get_device_id(pdev)->driver_data; + /* always have couple channels */ tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL); if (!tdev) return -ENOMEM; tdev->dev = &pdev->dev; - iores = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!iores) - return -EINVAL; - if (resource_size(iores) != chan_num) - tdev->irq = iores->start; - else - irq = iores->start; + for (i = 0; i < chan_num; i++) { + if (platform_get_irq(pdev, i) > 0) + irq_num++; + } iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iores) @@ -542,25 +551,26 @@ static int __devinit mmp_tdma_probe(struct platform_device *pdev) if (!tdev->base) return -EADDRNOTAVAIL; - if (tdev->irq) { - ret = devm_request_irq(&pdev->dev, tdev->irq, + INIT_LIST_HEAD(&tdev->device.channels); + + if (irq_num != chan_num) { + irq = platform_get_irq(pdev, 0); + ret = devm_request_irq(&pdev->dev, irq, mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev); if (ret) return ret; } - dma_cap_set(DMA_SLAVE, tdev->device.cap_mask); - dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask); - - INIT_LIST_HEAD(&tdev->device.channels); - /* initialize channel parameters */ for (i = 0; i < chan_num; i++) { + irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i); ret = mmp_tdma_chan_init(tdev, i, irq, type); if (ret) return ret; } + dma_cap_set(DMA_SLAVE, tdev->device.cap_mask); + dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask); tdev->device.dev = &pdev->dev; tdev->device.device_alloc_chan_resources = mmp_tdma_alloc_chan_resources; @@ -595,6 +605,7 @@ static struct platform_driver mmp_tdma_driver = { .driver = { .name = "mmp-tdma", .owner = THIS_MODULE, + .of_match_table = mmp_tdma_dt_ids, }, .id_table = mmp_tdma_id_table, .probe = mmp_tdma_probe, |