Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[linux-drm-fsl-dcu.git] / drivers / dma / omap-dma.c
index 7624a0873412ef7778879d3ec8e8faf836c9340b..249445c8a4c6fa8a1001088b0678ff7e1c48e06a 100644 (file)
@@ -22,6 +22,9 @@
 
 #include "virt-dma.h"
 
+#define OMAP_SDMA_REQUESTS     127
+#define OMAP_SDMA_CHANNELS     32
+
 struct omap_dmadev {
        struct dma_device ddev;
        spinlock_t lock;
@@ -31,9 +34,10 @@ struct omap_dmadev {
        const struct omap_dma_reg *reg_map;
        struct omap_system_dma_plat_info *plat;
        bool legacy;
+       unsigned dma_requests;
        spinlock_t irq_lock;
        uint32_t irq_enable_mask;
-       struct omap_chan *lch_map[32];
+       struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
 };
 
 struct omap_chan {
@@ -589,6 +593,7 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
        omap_free_dma(c->dma_ch);
 
        dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
+       c->dma_sig = 0;
 }
 
 static size_t omap_dma_sg_size(struct omap_sg *sg)
@@ -1082,7 +1087,7 @@ static int omap_dma_resume(struct dma_chan *chan)
        return 0;
 }
 
-static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
+static int omap_dma_chan_init(struct omap_dmadev *od)
 {
        struct omap_chan *c;
 
@@ -1091,7 +1096,6 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
                return -ENOMEM;
 
        c->reg_map = od->reg_map;
-       c->dma_sig = dma_sig;
        c->vc.desc_free = omap_dma_desc_free;
        vchan_init(&c->vc, &od->ddev);
        INIT_LIST_HEAD(&c->node);
@@ -1163,8 +1167,17 @@ static int omap_dma_probe(struct platform_device *pdev)
 
        tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-       for (i = 0; i < 127; i++) {
-               rc = omap_dma_chan_init(od, i);
+       od->dma_requests = OMAP_SDMA_REQUESTS;
+       if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
+                                                     "dma-requests",
+                                                     &od->dma_requests)) {
+               dev_info(&pdev->dev,
+                        "Missing dma-requests property, using %u.\n",
+                        OMAP_SDMA_REQUESTS);
+       }
+
+       for (i = 0; i < OMAP_SDMA_CHANNELS; i++) {
+               rc = omap_dma_chan_init(od);
                if (rc) {
                        omap_dma_free(od);
                        return rc;
@@ -1255,10 +1268,14 @@ static struct platform_driver omap_dma_driver = {
 bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
 {
        if (chan->device->dev->driver == &omap_dma_driver.driver) {
+               struct omap_dmadev *od = to_omap_dma_dev(chan->device);
                struct omap_chan *c = to_omap_dma_chan(chan);
                unsigned req = *(unsigned *)param;
 
-               return req == c->dma_sig;
+               if (req <= od->dma_requests) {
+                       c->dma_sig = req;
+                       return true;
+               }
        }
        return false;
 }