diff options
author | ludovic.desroches@atmel.com <ludovic.desroches@atmel.com> | 2014-12-01 09:35:09 -0500 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-12-02 05:08:33 -0500 |
commit | 467e081d23e67f6216cbe0df911bd5017f1f0b55 (patch) | |
tree | 04b9800f838654d65d58a9a9f819f34f1a6a7233 /drivers/mmc | |
parent | 5e0fe89740657116cacf9c40c93a3676536d31fb (diff) |
mmc: atmel-mci: use probe deferring if dma controller is not ready yet
Return probe defer if requesting a dma channel without a dma controller
probed.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 00f60886c1e5..62aba9af19f4 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -2272,29 +2272,25 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot, | |||
2272 | mmc_free_host(slot->mmc); | 2272 | mmc_free_host(slot->mmc); |
2273 | } | 2273 | } |
2274 | 2274 | ||
2275 | static bool atmci_configure_dma(struct atmel_mci *host) | 2275 | static int atmci_configure_dma(struct atmel_mci *host) |
2276 | { | 2276 | { |
2277 | if (host == NULL) | 2277 | host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev, |
2278 | return false; | 2278 | "rxtx"); |
2279 | if (IS_ERR(host->dma.chan)) | ||
2280 | return PTR_ERR(host->dma.chan); | ||
2281 | |||
2282 | dev_info(&host->pdev->dev, "using %s for DMA transfers\n", | ||
2283 | dma_chan_name(host->dma.chan)); | ||
2284 | |||
2285 | host->dma_conf.src_addr = host->mapbase + ATMCI_RDR; | ||
2286 | host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2287 | host->dma_conf.src_maxburst = 1; | ||
2288 | host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR; | ||
2289 | host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2290 | host->dma_conf.dst_maxburst = 1; | ||
2291 | host->dma_conf.device_fc = false; | ||
2279 | 2292 | ||
2280 | host->dma.chan = dma_request_slave_channel(&host->pdev->dev, "rxtx"); | 2293 | return 0; |
2281 | if (!host->dma.chan) { | ||
2282 | dev_warn(&host->pdev->dev, "no DMA channel available\n"); | ||
2283 | return false; | ||
2284 | } else { | ||
2285 | dev_info(&host->pdev->dev, | ||
2286 | "using %s for DMA transfers\n", | ||
2287 | dma_chan_name(host->dma.chan)); | ||
2288 | |||
2289 | host->dma_conf.src_addr = host->mapbase + ATMCI_RDR; | ||
2290 | host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2291 | host->dma_conf.src_maxburst = 1; | ||
2292 | host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR; | ||
2293 | host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
2294 | host->dma_conf.dst_maxburst = 1; | ||
2295 | host->dma_conf.device_fc = false; | ||
2296 | return true; | ||
2297 | } | ||
2298 | } | 2294 | } |
2299 | 2295 | ||
2300 | /* | 2296 | /* |
@@ -2411,7 +2407,10 @@ static int atmci_probe(struct platform_device *pdev) | |||
2411 | 2407 | ||
2412 | /* Get MCI capabilities and set operations according to it */ | 2408 | /* Get MCI capabilities and set operations according to it */ |
2413 | atmci_get_cap(host); | 2409 | atmci_get_cap(host); |
2414 | if (atmci_configure_dma(host)) { | 2410 | ret = atmci_configure_dma(host); |
2411 | if (ret == -EPROBE_DEFER) | ||
2412 | goto err_dma_probe_defer; | ||
2413 | if (ret == 0) { | ||
2415 | host->prepare_data = &atmci_prepare_data_dma; | 2414 | host->prepare_data = &atmci_prepare_data_dma; |
2416 | host->submit_data = &atmci_submit_data_dma; | 2415 | host->submit_data = &atmci_submit_data_dma; |
2417 | host->stop_transfer = &atmci_stop_transfer_dma; | 2416 | host->stop_transfer = &atmci_stop_transfer_dma; |
@@ -2496,8 +2495,9 @@ err_init_slot: | |||
2496 | pm_runtime_put_noidle(&pdev->dev); | 2495 | pm_runtime_put_noidle(&pdev->dev); |
2497 | 2496 | ||
2498 | del_timer_sync(&host->timer); | 2497 | del_timer_sync(&host->timer); |
2499 | if (host->dma.chan) | 2498 | if (!IS_ERR(host->dma.chan)) |
2500 | dma_release_channel(host->dma.chan); | 2499 | dma_release_channel(host->dma.chan); |
2500 | err_dma_probe_defer: | ||
2501 | free_irq(irq, host); | 2501 | free_irq(irq, host); |
2502 | return ret; | 2502 | return ret; |
2503 | } | 2503 | } |
@@ -2523,7 +2523,7 @@ static int atmci_remove(struct platform_device *pdev) | |||
2523 | atmci_readl(host, ATMCI_SR); | 2523 | atmci_readl(host, ATMCI_SR); |
2524 | 2524 | ||
2525 | del_timer_sync(&host->timer); | 2525 | del_timer_sync(&host->timer); |
2526 | if (host->dma.chan) | 2526 | if (!IS_ERR(host->dma.chan)) |
2527 | dma_release_channel(host->dma.chan); | 2527 | dma_release_channel(host->dma.chan); |
2528 | 2528 | ||
2529 | free_irq(platform_get_irq(pdev, 0), host); | 2529 | free_irq(platform_get_irq(pdev, 0), host); |