mmp_tdma.c (f1a7757008b810217b2380d01b740244f21c09bd) mmp_tdma.c (293b2da1b61136813fc2764f43304c66ff8040e9)
1/*
2 * Driver For Marvell Two-channel DMA Engine
3 *
4 * Copyright: Marvell International Ltd.
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:

--- 5 unchanged lines hidden (view full) ---

14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/dma-mapping.h>
17#include <linux/slab.h>
18#include <linux/dmaengine.h>
19#include <linux/platform_device.h>
20#include <linux/device.h>
21#include <mach/regs-icu.h>
1/*
2 * Driver For Marvell Two-channel DMA Engine
3 *
4 * Copyright: Marvell International Ltd.
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:

--- 5 unchanged lines hidden (view full) ---

14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/dma-mapping.h>
17#include <linux/slab.h>
18#include <linux/dmaengine.h>
19#include <linux/platform_device.h>
20#include <linux/device.h>
21#include <mach/regs-icu.h>
22#include <mach/sram.h>
23#include <linux/of_device.h>
22#include <linux/platform_data/dma-mmp_tdma.h>
24
25#include "dmaengine.h"
26
27/*
28 * Two-Channel DMA registers
29 */
30#define TDBCR 0x00 /* Byte Count */
31#define TDSAR 0x10 /* Src Addr */

--- 91 unchanged lines hidden (view full) ---

123};
124
125#define TDMA_CHANNEL_NUM 2
126struct mmp_tdma_device {
127 struct device *dev;
128 void __iomem *base;
129 struct dma_device device;
130 struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM];
23
24#include "dmaengine.h"
25
26/*
27 * Two-Channel DMA registers
28 */
29#define TDBCR 0x00 /* Byte Count */
30#define TDSAR 0x10 /* Src Addr */

--- 91 unchanged lines hidden (view full) ---

122};
123
124#define TDMA_CHANNEL_NUM 2
125struct mmp_tdma_device {
126 struct device *dev;
127 void __iomem *base;
128 struct dma_device device;
129 struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM];
130 int irq;
131};
132
133#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)
134
135static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys)
136{
137 writel(phys, tdmac->reg_base + TDNDPR);
138 writel(readl(tdmac->reg_base + TDCR) | TDCR_FETCHND,

--- 348 unchanged lines hidden (view full) ---

487
488 /* alloc channel */
489 tdmac = devm_kzalloc(tdev->dev, sizeof(*tdmac), GFP_KERNEL);
490 if (!tdmac) {
491 dev_err(tdev->dev, "no free memory for DMA channels!\n");
492 return -ENOMEM;
493 }
494 if (irq)
131};
132
133#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)
134
135static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys)
136{
137 writel(phys, tdmac->reg_base + TDNDPR);
138 writel(readl(tdmac->reg_base + TDCR) | TDCR_FETCHND,

--- 348 unchanged lines hidden (view full) ---

487
488 /* alloc channel */
489 tdmac = devm_kzalloc(tdev->dev, sizeof(*tdmac), GFP_KERNEL);
490 if (!tdmac) {
491 dev_err(tdev->dev, "no free memory for DMA channels!\n");
492 return -ENOMEM;
493 }
494 if (irq)
495 tdmac->irq = irq;
495 tdmac->irq = irq + idx;
496 tdmac->dev = tdev->dev;
497 tdmac->chan.device = &tdev->device;
498 tdmac->idx = idx;
499 tdmac->type = type;
500 tdmac->reg_base = (unsigned long)tdev->base + idx * 4;
501 tdmac->status = DMA_SUCCESS;
502 tdev->tdmac[tdmac->idx] = tdmac;
503 tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac);
504
505 /* add the channel to tdma_chan list */
506 list_add_tail(&tdmac->chan.device_node,
507 &tdev->device.channels);
496 tdmac->dev = tdev->dev;
497 tdmac->chan.device = &tdev->device;
498 tdmac->idx = idx;
499 tdmac->type = type;
500 tdmac->reg_base = (unsigned long)tdev->base + idx * 4;
501 tdmac->status = DMA_SUCCESS;
502 tdev->tdmac[tdmac->idx] = tdmac;
503 tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac);
504
505 /* add the channel to tdma_chan list */
506 list_add_tail(&tdmac->chan.device_node,
507 &tdev->device.channels);
508
508 return 0;
509}
510
509 return 0;
510}
511
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
518static int __devinit mmp_tdma_probe(struct platform_device *pdev)
519{
512static int __devinit mmp_tdma_probe(struct platform_device *pdev)
513{
520 enum mmp_tdma_type type;
521 const struct of_device_id *of_id;
514 const struct platform_device_id *id = platform_get_device_id(pdev);
515 enum mmp_tdma_type type = id->driver_data;
522 struct mmp_tdma_device *tdev;
523 struct resource *iores;
524 int i, ret;
516 struct mmp_tdma_device *tdev;
517 struct resource *iores;
518 int i, ret;
525 int irq = 0, irq_num = 0;
519 int irq = 0;
526 int chan_num = TDMA_CHANNEL_NUM;
527
520 int chan_num = TDMA_CHANNEL_NUM;
521
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
534 /* always have couple channels */
535 tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
536 if (!tdev)
537 return -ENOMEM;
538
539 tdev->dev = &pdev->dev;
522 /* always have couple channels */
523 tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
524 if (!tdev)
525 return -ENOMEM;
526
527 tdev->dev = &pdev->dev;
528 iores = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
529 if (!iores)
530 return -EINVAL;
540
531
541 for (i = 0; i < chan_num; i++) {
542 if (platform_get_irq(pdev, i) > 0)
543 irq_num++;
544 }
532 if (resource_size(iores) != chan_num)
533 tdev->irq = iores->start;
534 else
535 irq = iores->start;
545
546 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
547 if (!iores)
548 return -EINVAL;
549
550 tdev->base = devm_request_and_ioremap(&pdev->dev, iores);
551 if (!tdev->base)
552 return -EADDRNOTAVAIL;
553
536
537 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
538 if (!iores)
539 return -EINVAL;
540
541 tdev->base = devm_request_and_ioremap(&pdev->dev, iores);
542 if (!tdev->base)
543 return -EADDRNOTAVAIL;
544
554 INIT_LIST_HEAD(&tdev->device.channels);
555
556 if (irq_num != chan_num) {
557 irq = platform_get_irq(pdev, 0);
558 ret = devm_request_irq(&pdev->dev, irq,
545 if (tdev->irq) {
546 ret = devm_request_irq(&pdev->dev, tdev->irq,
559 mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev);
560 if (ret)
561 return ret;
562 }
563
547 mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev);
548 if (ret)
549 return ret;
550 }
551
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
564 /* initialize channel parameters */
565 for (i = 0; i < chan_num; i++) {
557 /* initialize channel parameters */
558 for (i = 0; i < chan_num; i++) {
566 irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
567 ret = mmp_tdma_chan_init(tdev, i, irq, type);
568 if (ret)
569 return ret;
570 }
571
559 ret = mmp_tdma_chan_init(tdev, i, irq, type);
560 if (ret)
561 return ret;
562 }
563
572 dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
573 dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
574 tdev->device.dev = &pdev->dev;
575 tdev->device.device_alloc_chan_resources =
576 mmp_tdma_alloc_chan_resources;
577 tdev->device.device_free_chan_resources =
578 mmp_tdma_free_chan_resources;
579 tdev->device.device_prep_dma_cyclic = mmp_tdma_prep_dma_cyclic;
580 tdev->device.device_tx_status = mmp_tdma_tx_status;
581 tdev->device.device_issue_pending = mmp_tdma_issue_pending;

--- 18 unchanged lines hidden (view full) ---

600 { "pxa910-squ", PXA910_SQU },
601 { },
602};
603
604static struct platform_driver mmp_tdma_driver = {
605 .driver = {
606 .name = "mmp-tdma",
607 .owner = THIS_MODULE,
564 tdev->device.dev = &pdev->dev;
565 tdev->device.device_alloc_chan_resources =
566 mmp_tdma_alloc_chan_resources;
567 tdev->device.device_free_chan_resources =
568 mmp_tdma_free_chan_resources;
569 tdev->device.device_prep_dma_cyclic = mmp_tdma_prep_dma_cyclic;
570 tdev->device.device_tx_status = mmp_tdma_tx_status;
571 tdev->device.device_issue_pending = mmp_tdma_issue_pending;

--- 18 unchanged lines hidden (view full) ---

590 { "pxa910-squ", PXA910_SQU },
591 { },
592};
593
594static struct platform_driver mmp_tdma_driver = {
595 .driver = {
596 .name = "mmp-tdma",
597 .owner = THIS_MODULE,
608 .of_match_table = mmp_tdma_dt_ids,
609 },
610 .id_table = mmp_tdma_id_table,
611 .probe = mmp_tdma_probe,
612 .remove = __devexit_p(mmp_tdma_remove),
613};
614
615module_platform_driver(mmp_tdma_driver);
616
617MODULE_LICENSE("GPL");
618MODULE_DESCRIPTION("MMP Two-Channel DMA Driver");
619MODULE_ALIAS("platform:mmp-tdma");
620MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
621MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");
598 },
599 .id_table = mmp_tdma_id_table,
600 .probe = mmp_tdma_probe,
601 .remove = __devexit_p(mmp_tdma_remove),
602};
603
604module_platform_driver(mmp_tdma_driver);
605
606MODULE_LICENSE("GPL");
607MODULE_DESCRIPTION("MMP Two-Channel DMA Driver");
608MODULE_ALIAS("platform:mmp-tdma");
609MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
610MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");