Merge branch 'arm-next' of git://git.xilinx.com/linux-xlnx into next/cleanup
[deliverable/linux.git] / drivers / dma / imx-dma.c
index 7d9554cc4976313c90604eacecf4b78227a860f7..dbf0e6f8de8a8c64d4b29b33b9c834ae3ab904c7 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
 
 #include "dmaengine.h"
 #define IMXDMA_MAX_CHAN_DESCRIPTORS    16
@@ -167,6 +166,12 @@ struct imxdma_channel {
        int                             slot_2d;
 };
 
+enum imx_dma_type {
+       IMX1_DMA,
+       IMX21_DMA,
+       IMX27_DMA,
+};
+
 struct imxdma_engine {
        struct device                   *dev;
        struct device_dma_parameters    dma_parms;
@@ -177,7 +182,39 @@ struct imxdma_engine {
        spinlock_t                      lock;
        struct imx_dma_2d_config        slots_2d[IMX_DMA_2D_SLOTS];
        struct imxdma_channel           channel[IMX_DMA_CHANNELS];
+       enum imx_dma_type               devtype;
+};
+
+static struct platform_device_id imx_dma_devtype[] = {
+       {
+               .name = "imx1-dma",
+               .driver_data = IMX1_DMA,
+       }, {
+               .name = "imx21-dma",
+               .driver_data = IMX21_DMA,
+       }, {
+               .name = "imx27-dma",
+               .driver_data = IMX27_DMA,
+       }, {
+               /* sentinel */
+       }
 };
+MODULE_DEVICE_TABLE(platform, imx_dma_devtype);
+
+static inline int is_imx1_dma(struct imxdma_engine *imxdma)
+{
+       return imxdma->devtype == IMX1_DMA;
+}
+
+static inline int is_imx21_dma(struct imxdma_engine *imxdma)
+{
+       return imxdma->devtype == IMX21_DMA;
+}
+
+static inline int is_imx27_dma(struct imxdma_engine *imxdma)
+{
+       return imxdma->devtype == IMX27_DMA;
+}
 
 static struct imxdma_channel *to_imxdma_chan(struct dma_chan *chan)
 {
@@ -212,7 +249,9 @@ static unsigned imx_dmav1_readl(struct imxdma_engine *imxdma, unsigned offset)
 
 static int imxdma_hw_chain(struct imxdma_channel *imxdmac)
 {
-       if (cpu_is_mx27())
+       struct imxdma_engine *imxdma = imxdmac->imxdma;
+
+       if (is_imx27_dma(imxdma))
                return imxdmac->hw_chaining;
        else
                return 0;
@@ -267,7 +306,7 @@ static void imxdma_enable_hw(struct imxdma_desc *d)
        imx_dmav1_writel(imxdma, imx_dmav1_readl(imxdma, DMA_CCR(channel)) |
                         CCR_CEN | CCR_ACRPT, DMA_CCR(channel));
 
-       if ((cpu_is_mx21() || cpu_is_mx27()) &&
+       if (!is_imx1_dma(imxdma) &&
                        d->sg && imxdma_hw_chain(imxdmac)) {
                d->sg = sg_next(d->sg);
                if (d->sg) {
@@ -436,7 +475,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
        struct imxdma_engine *imxdma = dev_id;
        int i, disr;
 
-       if (cpu_is_mx21() || cpu_is_mx27())
+       if (!is_imx1_dma(imxdma))
                imxdma_err_handler(irq, dev_id);
 
        disr = imx_dmav1_readl(imxdma, DMA_DISR);
@@ -961,35 +1000,32 @@ static void imxdma_issue_pending(struct dma_chan *chan)
 static int __init imxdma_probe(struct platform_device *pdev)
        {
        struct imxdma_engine *imxdma;
+       struct resource *res;
        int ret, i;
+       int irq, irq_err;
 
-
-       imxdma = kzalloc(sizeof(*imxdma), GFP_KERNEL);
+       imxdma = devm_kzalloc(&pdev->dev, sizeof(*imxdma), GFP_KERNEL);
        if (!imxdma)
                return -ENOMEM;
 
-       if (cpu_is_mx1()) {
-               imxdma->base = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
-       } else if (cpu_is_mx21()) {
-               imxdma->base = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
-       } else if (cpu_is_mx27()) {
-               imxdma->base = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
-       } else {
-               kfree(imxdma);
-               return 0;
-       }
+       imxdma->devtype = pdev->id_entry->driver_data;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       imxdma->base = devm_request_and_ioremap(&pdev->dev, res);
+       if (!imxdma->base)
+               return -EADDRNOTAVAIL;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
 
        imxdma->dma_ipg = devm_clk_get(&pdev->dev, "ipg");
-       if (IS_ERR(imxdma->dma_ipg)) {
-               ret = PTR_ERR(imxdma->dma_ipg);
-               goto err_clk;
-       }
+       if (IS_ERR(imxdma->dma_ipg))
+               return PTR_ERR(imxdma->dma_ipg);
 
        imxdma->dma_ahb = devm_clk_get(&pdev->dev, "ahb");
-       if (IS_ERR(imxdma->dma_ahb)) {
-               ret = PTR_ERR(imxdma->dma_ahb);
-               goto err_clk;
-       }
+       if (IS_ERR(imxdma->dma_ahb))
+               return PTR_ERR(imxdma->dma_ahb);
 
        clk_prepare_enable(imxdma->dma_ipg);
        clk_prepare_enable(imxdma->dma_ahb);
@@ -997,18 +1033,25 @@ static int __init imxdma_probe(struct platform_device *pdev)
        /* reset DMA module */
        imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR);
 
-       if (cpu_is_mx1()) {
-               ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma);
+       if (is_imx1_dma(imxdma)) {
+               ret = devm_request_irq(&pdev->dev, irq,
+                                      dma_irq_handler, 0, "DMA", imxdma);
                if (ret) {
                        dev_warn(imxdma->dev, "Can't register IRQ for DMA\n");
-                       goto err_enable;
+                       goto err;
+               }
+
+               irq_err = platform_get_irq(pdev, 1);
+               if (irq_err < 0) {
+                       ret = irq_err;
+                       goto err;
                }
 
-               ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma);
+               ret = devm_request_irq(&pdev->dev, irq_err,
+                                      imxdma_err_handler, 0, "DMA", imxdma);
                if (ret) {
                        dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n");
-                       free_irq(MX1_DMA_INT, NULL);
-                       goto err_enable;
+                       goto err;
                }
        }
 
@@ -1038,14 +1081,14 @@ static int __init imxdma_probe(struct platform_device *pdev)
        for (i = 0; i < IMX_DMA_CHANNELS; i++) {
                struct imxdma_channel *imxdmac = &imxdma->channel[i];
 
-               if (cpu_is_mx21() || cpu_is_mx27()) {
-                       ret = request_irq(MX2x_INT_DMACH0 + i,
+               if (!is_imx1_dma(imxdma)) {
+                       ret = devm_request_irq(&pdev->dev, irq + i,
                                        dma_irq_handler, 0, "DMA", imxdma);
                        if (ret) {
                                dev_warn(imxdma->dev, "Can't register IRQ %d "
                                         "for DMA channel %d\n",
-                                        MX2x_INT_DMACH0 + i, i);
-                               goto err_init;
+                                        irq + i, i);
+                               goto err;
                        }
                        init_timer(&imxdmac->watchdog);
                        imxdmac->watchdog.function = &imxdma_watchdog;
@@ -1091,46 +1134,25 @@ static int __init imxdma_probe(struct platform_device *pdev)
        ret = dma_async_device_register(&imxdma->dma_device);
        if (ret) {
                dev_err(&pdev->dev, "unable to register\n");
-               goto err_init;
+               goto err;
        }
 
        return 0;
 
-err_init:
-
-       if (cpu_is_mx21() || cpu_is_mx27()) {
-               while (--i >= 0)
-                       free_irq(MX2x_INT_DMACH0 + i, NULL);
-       } else if cpu_is_mx1() {
-               free_irq(MX1_DMA_INT, NULL);
-               free_irq(MX1_DMA_ERR, NULL);
-       }
-err_enable:
+err:
        clk_disable_unprepare(imxdma->dma_ipg);
        clk_disable_unprepare(imxdma->dma_ahb);
-err_clk:
-       kfree(imxdma);
        return ret;
 }
 
 static int __exit imxdma_remove(struct platform_device *pdev)
 {
        struct imxdma_engine *imxdma = platform_get_drvdata(pdev);
-       int i;
 
         dma_async_device_unregister(&imxdma->dma_device);
 
-       if (cpu_is_mx21() || cpu_is_mx27()) {
-               for (i = 0; i < IMX_DMA_CHANNELS; i++)
-                       free_irq(MX2x_INT_DMACH0 + i, NULL);
-       } else if cpu_is_mx1() {
-               free_irq(MX1_DMA_INT, NULL);
-               free_irq(MX1_DMA_ERR, NULL);
-       }
-
        clk_disable_unprepare(imxdma->dma_ipg);
        clk_disable_unprepare(imxdma->dma_ahb);
-       kfree(imxdma);
 
         return 0;
 }
@@ -1139,6 +1161,7 @@ static struct platform_driver imxdma_driver = {
        .driver         = {
                .name   = "imx-dma",
        },
+       .id_table       = imx_dma_devtype,
        .remove         = __exit_p(imxdma_remove),
 };
 
This page took 0.03016 seconds and 5 git commands to generate.