]> git.karo-electronics.de Git - linux-beck.git/commitdiff
dmaengine: of_dma: approximate an average distribution
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Wed, 11 May 2016 13:15:11 +0000 (15:15 +0200)
committerVinod Koul <vinod.koul@intel.com>
Sat, 14 May 2016 08:04:10 +0000 (13:34 +0530)
Currently the following DT description would result in dmac0 always
being tried first and dmac1 second if dmac0 was unavailable. This
results in heavier use of dmac0 then of dmac1. This patch adds an
approximate average distribution over the two nodes lessening the load
of anyone of them.

   i2c6: i2c@e60b0000 {
           ...
           dmas = <&dmac0 0x77>, <&dmac0 0x78>,
                  <&dmac1 0x77>, <&dmac1 0x78>;
           dma-names = "tx", "rx", "tx", "rx";
           ...
   };

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
drivers/dma/of-dma.c

index 1e1f2986eba8f194767362bd96d8a866dba1097a..faae0bfe1109ed1e7d2f0e25269b28b3269b15ff 100644 (file)
@@ -240,8 +240,9 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
        struct of_phandle_args  dma_spec;
        struct of_dma           *ofdma;
        struct dma_chan         *chan;
-       int                     count, i;
+       int                     count, i, start;
        int                     ret_no_channel = -ENODEV;
+       static atomic_t         last_index;
 
        if (!np || !name) {
                pr_err("%s: not enough information provided\n", __func__);
@@ -259,8 +260,15 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
                return ERR_PTR(-ENODEV);
        }
 
+       /*
+        * approximate an average distribution across multiple
+        * entries with the same name
+        */
+       start = atomic_inc_return(&last_index);
        for (i = 0; i < count; i++) {
-               if (of_dma_match_channel(np, name, i, &dma_spec))
+               if (of_dma_match_channel(np, name,
+                                        (i + start) % count,
+                                        &dma_spec))
                        continue;
 
                mutex_lock(&of_dma_lock);