aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2013-10-30 07:34:51 -0400
committerChris Ball <chris@printf.net>2014-01-13 12:48:25 -0500
commite5a233cb647d749de2f188477c9a54b94d90477f (patch)
tree77c100b8c11c31e95e69a56aea6be92bbfeed255
parente3c418f1b26b59841bd074baa740a43afc15199b (diff)
mmc: sh_mmcif: Factorize DMA channel request and configuration code
The channel request and configuration code is duplicated for the rx and tx channels. Create a function that requests a single channel and call it twice instead. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/sh_mmcif.c100
1 files changed, 51 insertions, 49 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index d032b080ac4d..bebf2fe38ea0 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -381,73 +381,75 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
381 desc, cookie); 381 desc, cookie);
382} 382}
383 383
384static void sh_mmcif_request_dma(struct sh_mmcif_host *host, 384static struct dma_chan *
385 struct sh_mmcif_plat_data *pdata) 385sh_mmcif_request_dma_one(struct sh_mmcif_host *host,
386 struct sh_mmcif_plat_data *pdata,
387 enum dma_transfer_direction direction)
386{ 388{
387 struct resource *res = platform_get_resource(host->pd, IORESOURCE_MEM, 0);
388 struct dma_slave_config cfg; 389 struct dma_slave_config cfg;
390 struct dma_chan *chan;
391 unsigned int slave_id;
392 struct resource *res;
389 dma_cap_mask_t mask; 393 dma_cap_mask_t mask;
390 int ret; 394 int ret;
391 395
392 host->dma_active = false;
393
394 if (pdata) {
395 if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
396 return;
397 } else if (!host->pd->dev.of_node) {
398 return;
399 }
400
401 /* We can only either use DMA for both Tx and Rx or not use it at all */
402 dma_cap_zero(mask); 396 dma_cap_zero(mask);
403 dma_cap_set(DMA_SLAVE, mask); 397 dma_cap_set(DMA_SLAVE, mask);
404 398
405 host->chan_tx = dma_request_slave_channel_compat(mask, shdma_chan_filter, 399 if (pdata)
406 pdata ? (void *)pdata->slave_id_tx : NULL, 400 slave_id = direction == DMA_MEM_TO_DEV
407 &host->pd->dev, "tx"); 401 ? pdata->slave_id_tx : pdata->slave_id_rx;
408 dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__, 402 else
409 host->chan_tx); 403 slave_id = 0;
410 404
411 if (!host->chan_tx) 405 chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
412 return; 406 (void *)slave_id, &host->pd->dev,
407 direction == DMA_MEM_TO_DEV ? "tx" : "rx");
408
409 dev_dbg(&host->pd->dev, "%s: %s: got channel %p\n", __func__,
410 direction == DMA_MEM_TO_DEV ? "TX" : "RX", chan);
411
412 if (!chan)
413 return NULL;
414
415 res = platform_get_resource(host->pd, IORESOURCE_MEM, 0);
413 416
414 /* In the OF case the driver will get the slave ID from the DT */ 417 /* In the OF case the driver will get the slave ID from the DT */
415 if (pdata) 418 cfg.slave_id = slave_id;
416 cfg.slave_id = pdata->slave_id_tx; 419 cfg.direction = direction;
417 cfg.direction = DMA_MEM_TO_DEV;
418 cfg.dst_addr = res->start + MMCIF_CE_DATA; 420 cfg.dst_addr = res->start + MMCIF_CE_DATA;
419 cfg.src_addr = 0; 421 cfg.src_addr = 0;
420 ret = dmaengine_slave_config(host->chan_tx, &cfg); 422 ret = dmaengine_slave_config(chan, &cfg);
421 if (ret < 0) 423 if (ret < 0) {
422 goto ecfgtx; 424 dma_release_channel(chan);
425 return NULL;
426 }
423 427
424 host->chan_rx = dma_request_slave_channel_compat(mask, shdma_chan_filter, 428 return chan;
425 pdata ? (void *)pdata->slave_id_rx : NULL, 429}
426 &host->pd->dev, "rx");
427 dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
428 host->chan_rx);
429 430
430 if (!host->chan_rx) 431static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
431 goto erqrx; 432 struct sh_mmcif_plat_data *pdata)
433{
434 host->dma_active = false;
432 435
433 if (pdata) 436 if (pdata) {
434 cfg.slave_id = pdata->slave_id_rx; 437 if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
435 cfg.direction = DMA_DEV_TO_MEM; 438 return;
436 cfg.dst_addr = 0; 439 } else if (!host->pd->dev.of_node) {
437 cfg.src_addr = res->start + MMCIF_CE_DATA; 440 return;
438 ret = dmaengine_slave_config(host->chan_rx, &cfg); 441 }
439 if (ret < 0)
440 goto ecfgrx;
441 442
442 return; 443 /* We can only either use DMA for both Tx and Rx or not use it at all */
444 host->chan_tx = sh_mmcif_request_dma_one(host, pdata, DMA_MEM_TO_DEV);
445 if (!host->chan_tx)
446 return;
443 447
444ecfgrx: 448 host->chan_rx = sh_mmcif_request_dma_one(host, pdata, DMA_DEV_TO_MEM);
445 dma_release_channel(host->chan_rx); 449 if (!host->chan_rx) {
446 host->chan_rx = NULL; 450 dma_release_channel(host->chan_tx);
447erqrx: 451 host->chan_tx = NULL;
448ecfgtx: 452 }
449 dma_release_channel(host->chan_tx);
450 host->chan_tx = NULL;
451} 453}
452 454
453static void sh_mmcif_release_dma(struct sh_mmcif_host *host) 455static void sh_mmcif_release_dma(struct sh_mmcif_host *host)