aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/mmp_tdma.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 22:10:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-09 22:10:41 -0400
commitb7e97d22113bcaafff93774e3085f5b567eaba9c (patch)
tree1d3a13574310bde064fceb4408cf91a44c59c078 /drivers/dma/mmp_tdma.c
parent943c2acea53784c45fb291498d04d5188fdea891 (diff)
parentd0fc905429f7f5f3ad365466669c55b04b92c1e5 (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.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index 6d9c82e891d7..f3e8d71bcbc7 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <mach/regs-icu.h> 21#include <mach/regs-icu.h>
22#include <linux/platform_data/dma-mmp_tdma.h> 22#include <linux/platform_data/dma-mmp_tdma.h>
23#include <linux/of_device.h>
23 24
24#include "dmaengine.h" 25#include "dmaengine.h"
25 26
@@ -127,7 +128,6 @@ struct mmp_tdma_device {
127 void __iomem *base; 128 void __iomem *base;
128 struct dma_device device; 129 struct dma_device device;
129 struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM]; 130 struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM];
130 int irq;
131}; 131};
132 132
133#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan) 133#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,
492 return -ENOMEM; 492 return -ENOMEM;
493 } 493 }
494 if (irq) 494 if (irq)
495 tdmac->irq = irq + idx; 495 tdmac->irq = irq;
496 tdmac->dev = tdev->dev; 496 tdmac->dev = tdev->dev;
497 tdmac->chan.device = &tdev->device; 497 tdmac->chan.device = &tdev->device;
498 tdmac->idx = idx; 498 tdmac->idx = idx;
@@ -505,34 +505,43 @@ static int __devinit mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
505 /* add the channel to tdma_chan list */ 505 /* add the channel to tdma_chan list */
506 list_add_tail(&tdmac->chan.device_node, 506 list_add_tail(&tdmac->chan.device_node,
507 &tdev->device.channels); 507 &tdev->device.channels);
508
509 return 0; 508 return 0;
510} 509}
511 510
511static struct of_device_id mmp_tdma_dt_ids[] = {
512 { .compatible = "marvell,adma-1.0", .data = (void *)MMP_AUD_TDMA},
513 { .compatible = "marvell,pxa910-squ", .data = (void *)PXA910_SQU},
514 {}
515};
516MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids);
517
512static int __devinit mmp_tdma_probe(struct platform_device *pdev) 518static int __devinit mmp_tdma_probe(struct platform_device *pdev)
513{ 519{
514 const struct platform_device_id *id = platform_get_device_id(pdev); 520 enum mmp_tdma_type type;
515 enum mmp_tdma_type type = id->driver_data; 521 const struct of_device_id *of_id;
516 struct mmp_tdma_device *tdev; 522 struct mmp_tdma_device *tdev;
517 struct resource *iores; 523 struct resource *iores;
518 int i, ret; 524 int i, ret;
519 int irq = 0; 525 int irq = 0, irq_num = 0;
520 int chan_num = TDMA_CHANNEL_NUM; 526 int chan_num = TDMA_CHANNEL_NUM;
521 527
528 of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
529 if (of_id)
530 type = (enum mmp_tdma_type) of_id->data;
531 else
532 type = platform_get_device_id(pdev)->driver_data;
533
522 /* always have couple channels */ 534 /* always have couple channels */
523 tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL); 535 tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
524 if (!tdev) 536 if (!tdev)
525 return -ENOMEM; 537 return -ENOMEM;
526 538
527 tdev->dev = &pdev->dev; 539 tdev->dev = &pdev->dev;
528 iores = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
529 if (!iores)
530 return -EINVAL;
531 540
532 if (resource_size(iores) != chan_num) 541 for (i = 0; i < chan_num; i++) {
533 tdev->irq = iores->start; 542 if (platform_get_irq(pdev, i) > 0)
534 else 543 irq_num++;
535 irq = iores->start; 544 }
536 545
537 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 546 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
538 if (!iores) 547 if (!iores)
@@ -542,25 +551,26 @@ static int __devinit mmp_tdma_probe(struct platform_device *pdev)
542 if (!tdev->base) 551 if (!tdev->base)
543 return -EADDRNOTAVAIL; 552 return -EADDRNOTAVAIL;
544 553
545 if (tdev->irq) { 554 INIT_LIST_HEAD(&tdev->device.channels);
546 ret = devm_request_irq(&pdev->dev, tdev->irq, 555
556 if (irq_num != chan_num) {
557 irq = platform_get_irq(pdev, 0);
558 ret = devm_request_irq(&pdev->dev, irq,
547 mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev); 559 mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev);
548 if (ret) 560 if (ret)
549 return ret; 561 return ret;
550 } 562 }
551 563
552 dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
553 dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
554
555 INIT_LIST_HEAD(&tdev->device.channels);
556
557 /* initialize channel parameters */ 564 /* initialize channel parameters */
558 for (i = 0; i < chan_num; i++) { 565 for (i = 0; i < chan_num; i++) {
566 irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
559 ret = mmp_tdma_chan_init(tdev, i, irq, type); 567 ret = mmp_tdma_chan_init(tdev, i, irq, type);
560 if (ret) 568 if (ret)
561 return ret; 569 return ret;
562 } 570 }
563 571
572 dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
573 dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
564 tdev->device.dev = &pdev->dev; 574 tdev->device.dev = &pdev->dev;
565 tdev->device.device_alloc_chan_resources = 575 tdev->device.device_alloc_chan_resources =
566 mmp_tdma_alloc_chan_resources; 576 mmp_tdma_alloc_chan_resources;
@@ -595,6 +605,7 @@ static struct platform_driver mmp_tdma_driver = {
595 .driver = { 605 .driver = {
596 .name = "mmp-tdma", 606 .name = "mmp-tdma",
597 .owner = THIS_MODULE, 607 .owner = THIS_MODULE,
608 .of_match_table = mmp_tdma_dt_ids,
598 }, 609 },
599 .id_table = mmp_tdma_id_table, 610 .id_table = mmp_tdma_id_table,
600 .probe = mmp_tdma_probe, 611 .probe = mmp_tdma_probe,