]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/dma/at_hdmac.c
dmaengine: at_hdmac: simplify device selection from platform data or DT
[karo-tx-linux.git] / drivers / dma / at_hdmac.c
index 30ec030456cf7e75c86c63946720544b3983d80e..97f87b29b9f3db5ea0068e076e145a0a81d5ad08 100644 (file)
@@ -1177,14 +1177,22 @@ static void atc_free_chan_resources(struct dma_chan *chan)
 
 /*--  Module Management  -----------------------------------------------*/
 
+/* cap_mask is a multi-u32 bitfield, fill it with proper C code. */
+static struct at_dma_platform_data at91sam9rl_config = {
+       .nr_channels = 2,
+};
+static struct at_dma_platform_data at91sam9g45_config = {
+       .nr_channels = 8,
+};
+
 #if defined(CONFIG_OF)
 static const struct of_device_id atmel_dma_dt_ids[] = {
        {
                .compatible = "atmel,at91sam9rl-dma",
-               .data = (void *)ATDMA_DEVTYPE_SAM9RL
+               .data = &at91sam9rl_config,
        }, {
                .compatible = "atmel,at91sam9g45-dma",
-               .data = (void *)ATDMA_DEVTYPE_SAM9G45
+               .data = &at91sam9g45_config,
        }, {
                /* sentinel */
        }
@@ -1196,26 +1204,27 @@ MODULE_DEVICE_TABLE(of, atmel_dma_dt_ids);
 static const struct platform_device_id atdma_devtypes[] = {
        {
                .name = "at91sam9rl_dma",
-               .driver_data = ATDMA_DEVTYPE_SAM9RL,
+               .driver_data = (unsigned long) &at91sam9rl_config,
        }, {
                .name = "at91sam9g45_dma",
-               .driver_data = ATDMA_DEVTYPE_SAM9G45,
+               .driver_data = (unsigned long) &at91sam9g45_config,
        }, {
                /* sentinel */
        }
 };
 
-static inline enum atdma_devtype __init at_dma_get_driver_data(
-                                       struct platform_device *pdev)
+static inline struct at_dma_platform_data * __init at_dma_get_driver_data(
+                                               struct platform_device *pdev)
 {
        if (pdev->dev.of_node) {
                const struct of_device_id *match;
                match = of_match_node(atmel_dma_dt_ids, pdev->dev.of_node);
                if (match == NULL)
-                       return ATDMA_DEVTYPE_UNDEFINED;
-               return (enum atdma_devtype)match->data;
+                       return NULL;
+               return match->data;
        }
-       return platform_get_device_id(pdev)->driver_data;
+       return (struct at_dma_platform_data *)
+                       platform_get_device_id(pdev)->driver_data;
 }
 
 /**
@@ -1242,26 +1251,17 @@ static int __init at_dma_probe(struct platform_device *pdev)
        int                     irq;
        int                     err;
        int                     i;
-       u32                     nr_channels;
-       dma_cap_mask_t          cap_mask = {};
-       enum atdma_devtype      atdmatype;
+       struct at_dma_platform_data *plat_dat;
 
-       dma_cap_set(DMA_MEMCPY, cap_mask);
+       /* setup platform data for each SoC */
+       dma_cap_set(DMA_MEMCPY, at91sam9rl_config.cap_mask);
+       dma_cap_set(DMA_MEMCPY, at91sam9g45_config.cap_mask);
+       dma_cap_set(DMA_SLAVE, at91sam9g45_config.cap_mask);
 
        /* get DMA parameters from controller type */
-       atdmatype = at_dma_get_driver_data(pdev);
-
-       switch (atdmatype) {
-       case ATDMA_DEVTYPE_SAM9RL:
-               nr_channels = 2;
-               break;
-       case ATDMA_DEVTYPE_SAM9G45:
-               nr_channels = 8;
-               dma_cap_set(DMA_SLAVE, cap_mask);
-               break;
-       default:
-               return -EINVAL;
-       }
+       plat_dat = at_dma_get_driver_data(pdev);
+       if (!plat_dat)
+               return -ENODEV;
 
        io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!io)
@@ -1272,15 +1272,14 @@ static int __init at_dma_probe(struct platform_device *pdev)
                return irq;
 
        size = sizeof(struct at_dma);
-       size += nr_channels * sizeof(struct at_dma_chan);
+       size += plat_dat->nr_channels * sizeof(struct at_dma_chan);
        atdma = kzalloc(size, GFP_KERNEL);
        if (!atdma)
                return -ENOMEM;
 
        /* discover transaction capabilities */
-       atdma->dma_common.cap_mask = cap_mask;
-       atdma->all_chan_mask = (1 << nr_channels) - 1;
-       atdma->devtype = atdmatype;
+       atdma->dma_common.cap_mask = plat_dat->cap_mask;
+       atdma->all_chan_mask = (1 << plat_dat->nr_channels) - 1;
 
        size = resource_size(io);
        if (!request_mem_region(io->start, size, pdev->dev.driver->name)) {
@@ -1326,7 +1325,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
 
        /* initialize channels related values */
        INIT_LIST_HEAD(&atdma->dma_common.channels);
-       for (i = 0; i < nr_channels; i++) {
+       for (i = 0; i < plat_dat->nr_channels; i++) {
                struct at_dma_chan      *atchan = &atdma->chan[i];
 
                atchan->chan_common.device = &atdma->dma_common;
@@ -1371,7 +1370,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
        dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
          dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
          dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)  ? "slave " : "",
-         nr_channels);
+         plat_dat->nr_channels);
 
        dma_async_device_register(&atdma->dma_common);