Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Niklas Söderlund and committed by
Vinod Koul
20ea6be6 d57d3a48

+10 -2
+10 -2
drivers/dma/of-dma.c
··· 240 240 struct of_phandle_args dma_spec; 241 241 struct of_dma *ofdma; 242 242 struct dma_chan *chan; 243 - int count, i; 243 + int count, i, start; 244 244 int ret_no_channel = -ENODEV; 245 + static atomic_t last_index; 245 246 246 247 if (!np || !name) { 247 248 pr_err("%s: not enough information provided\n", __func__); ··· 260 259 return ERR_PTR(-ENODEV); 261 260 } 262 261 262 + /* 263 + * approximate an average distribution across multiple 264 + * entries with the same name 265 + */ 266 + start = atomic_inc_return(&last_index); 263 267 for (i = 0; i < count; i++) { 264 - if (of_dma_match_channel(np, name, i, &dma_spec)) 268 + if (of_dma_match_channel(np, name, 269 + (i + start) % count, 270 + &dma_spec)) 265 271 continue; 266 272 267 273 mutex_lock(&of_dma_lock);