aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/shdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/shdma.c')
-rw-r--r--drivers/dma/shdma.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 544340d7a464..a1727522343e 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -26,8 +26,7 @@
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29 29#include <linux/sh_dma.h>
30#include <asm/dmaengine.h>
31 30
32#include "shdma.h" 31#include "shdma.h"
33 32
@@ -45,7 +44,7 @@ enum sh_dmae_desc_status {
45#define LOG2_DEFAULT_XFER_SIZE 2 44#define LOG2_DEFAULT_XFER_SIZE 2
46 45
47/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ 46/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
48static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; 47static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SH_DMA_SLAVE_NUMBER)];
49 48
50static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); 49static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
51 50
@@ -190,7 +189,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
190 struct sh_dmae_device *shdev = container_of(sh_chan->common.device, 189 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
191 struct sh_dmae_device, common); 190 struct sh_dmae_device, common);
192 struct sh_dmae_pdata *pdata = shdev->pdata; 191 struct sh_dmae_pdata *pdata = shdev->pdata;
193 struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; 192 const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
194 u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16); 193 u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
195 int shift = chan_pdata->dmars_bit; 194 int shift = chan_pdata->dmars_bit;
196 195
@@ -266,8 +265,8 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan)
266 return NULL; 265 return NULL;
267} 266}
268 267
269static struct sh_dmae_slave_config *sh_dmae_find_slave( 268static const struct sh_dmae_slave_config *sh_dmae_find_slave(
270 struct sh_dmae_chan *sh_chan, enum sh_dmae_slave_chan_id slave_id) 269 struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param)
271{ 270{
272 struct dma_device *dma_dev = sh_chan->common.device; 271 struct dma_device *dma_dev = sh_chan->common.device;
273 struct sh_dmae_device *shdev = container_of(dma_dev, 272 struct sh_dmae_device *shdev = container_of(dma_dev,
@@ -275,11 +274,11 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave(
275 struct sh_dmae_pdata *pdata = shdev->pdata; 274 struct sh_dmae_pdata *pdata = shdev->pdata;
276 int i; 275 int i;
277 276
278 if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER) 277 if (param->slave_id >= SH_DMA_SLAVE_NUMBER)
279 return NULL; 278 return NULL;
280 279
281 for (i = 0; i < pdata->slave_num; i++) 280 for (i = 0; i < pdata->slave_num; i++)
282 if (pdata->slave[i].slave_id == slave_id) 281 if (pdata->slave[i].slave_id == param->slave_id)
283 return pdata->slave + i; 282 return pdata->slave + i;
284 283
285 return NULL; 284 return NULL;
@@ -290,6 +289,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
290 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 289 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
291 struct sh_desc *desc; 290 struct sh_desc *desc;
292 struct sh_dmae_slave *param = chan->private; 291 struct sh_dmae_slave *param = chan->private;
292 int ret;
293 293
294 pm_runtime_get_sync(sh_chan->dev); 294 pm_runtime_get_sync(sh_chan->dev);
295 295
@@ -298,14 +298,18 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
298 * never runs concurrently with itself or free_chan_resources. 298 * never runs concurrently with itself or free_chan_resources.
299 */ 299 */
300 if (param) { 300 if (param) {
301 struct sh_dmae_slave_config *cfg; 301 const struct sh_dmae_slave_config *cfg;
302 302
303 cfg = sh_dmae_find_slave(sh_chan, param->slave_id); 303 cfg = sh_dmae_find_slave(sh_chan, param);
304 if (!cfg) 304 if (!cfg) {
305 return -EINVAL; 305 ret = -EINVAL;
306 goto efindslave;
307 }
306 308
307 if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) 309 if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) {
308 return -EBUSY; 310 ret = -EBUSY;
311 goto etestused;
312 }
309 313
310 param->config = cfg; 314 param->config = cfg;
311 315
@@ -334,10 +338,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
334 } 338 }
335 spin_unlock_bh(&sh_chan->desc_lock); 339 spin_unlock_bh(&sh_chan->desc_lock);
336 340
337 if (!sh_chan->descs_allocated) 341 if (!sh_chan->descs_allocated) {
338 pm_runtime_put(sh_chan->dev); 342 ret = -ENOMEM;
343 goto edescalloc;
344 }
339 345
340 return sh_chan->descs_allocated; 346 return sh_chan->descs_allocated;
347
348edescalloc:
349 if (param)
350 clear_bit(param->slave_id, sh_dmae_slave_used);
351etestused:
352efindslave:
353 pm_runtime_put(sh_chan->dev);
354 return ret;
341} 355}
342 356
343/* 357/*
@@ -559,12 +573,14 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
559{ 573{
560 struct sh_dmae_slave *param; 574 struct sh_dmae_slave *param;
561 struct sh_dmae_chan *sh_chan; 575 struct sh_dmae_chan *sh_chan;
576 dma_addr_t slave_addr;
562 577
563 if (!chan) 578 if (!chan)
564 return NULL; 579 return NULL;
565 580
566 sh_chan = to_sh_chan(chan); 581 sh_chan = to_sh_chan(chan);
567 param = chan->private; 582 param = chan->private;
583 slave_addr = param->config->addr;
568 584
569 /* Someone calling slave DMA on a public channel? */ 585 /* Someone calling slave DMA on a public channel? */
570 if (!param || !sg_len) { 586 if (!param || !sg_len) {
@@ -577,7 +593,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
577 * if (param != NULL), this is a successfully requested slave channel, 593 * if (param != NULL), this is a successfully requested slave channel,
578 * therefore param->config != NULL too. 594 * therefore param->config != NULL too.
579 */ 595 */
580 return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &param->config->addr, 596 return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &slave_addr,
581 direction, flags); 597 direction, flags);
582} 598}
583 599
@@ -859,7 +875,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
859 int irq, unsigned long flags) 875 int irq, unsigned long flags)
860{ 876{
861 int err; 877 int err;
862 struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id]; 878 const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
863 struct platform_device *pdev = to_platform_device(shdev->common.dev); 879 struct platform_device *pdev = to_platform_device(shdev->common.dev);
864 struct sh_dmae_chan *new_sh_chan; 880 struct sh_dmae_chan *new_sh_chan;
865 881