aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/of-dma.c
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>2016-05-11 15:15:11 +0200
committerVinod Koul <vinod.koul@intel.com>2016-05-14 13:34:10 +0530
commit20ea6be6bffd4da8cfe3aeea9e6a090f346a54da (patch)
treecaa4b02597ed8bc935cae7489b0eeacaa3b0506c /drivers/dma/of-dma.c
parentdmaengine: core: Use IS_ENABLED() instead of checking for built-in or module (diff)
downloadlinux-dev-20ea6be6bffd4da8cfe3aeea9e6a090f346a54da.tar.xz
linux-dev-20ea6be6bffd4da8cfe3aeea9e6a090f346a54da.zip
dmaengine: of_dma: approximate an average distribution
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>
Diffstat (limited to 'drivers/dma/of-dma.c')
-rw-r--r--drivers/dma/of-dma.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index 1e1f2986eba8..faae0bfe1109 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -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);