linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] mmc: atmel-mci: use probe deferring if dma controller is not ready yet
@ 2014-11-19 14:51 Ludovic Desroches
  2014-11-19 14:57 ` Arnd Bergmann
  0 siblings, 1 reply; 3+ messages in thread
From: Ludovic Desroches @ 2014-11-19 14:51 UTC (permalink / raw)
  To: linux-arm-kernel

Return probe defer if requesting a dma channel without a dma controller
probed. Using late_initcall is no more needing.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---

patch based on
mmc: atmel-mci: remove compat for non DT board when requesting dma chan

v2 changes:
- use module_platform_driver
- remove warning message when asking for probe deferring

 drivers/mmc/host/atmel-mci.c | 61 ++++++++++++++++++++------------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index ba38f94..72f6501 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -2265,37 +2265,39 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
 	mmc_free_host(slot->mmc);
 }
 
-static bool atmci_configure_dma(struct atmel_mci *host)
+static int atmci_configure_dma(struct atmel_mci *host)
 {
 	struct mci_platform_data	*pdata;
 	dma_cap_mask_t mask;
+	int ret = 0;
 
 	if (host == NULL)
-		return false;
+		return -EINVAL;
 
 	pdata = host->pdev->dev.platform_data;
 
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	host->dma.chan = dma_request_slave_channel(&host->pdev->dev, "rxtx");
-	if (!host->dma.chan) {
-		dev_warn(&host->pdev->dev, "no DMA channel available\n");
-		return false;
-	} else {
-		dev_info(&host->pdev->dev,
-					"using %s for DMA transfers\n",
-					dma_chan_name(host->dma.chan));
-
-		host->dma_conf.src_addr = host->mapbase + ATMCI_RDR;
-		host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-		host->dma_conf.src_maxburst = 1;
-		host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR;
-		host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-		host->dma_conf.dst_maxburst = 1;
-		host->dma_conf.device_fc = false;
-		return true;
+	host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev, "rxtx");
+	if (IS_ERR(host->dma.chan)) {
+		ret = PTR_ERR(host->dma.chan);
+		host->dma.chan = NULL;
+		return ret;
 	}
+
+	dev_info(&host->pdev->dev,
+			"using %s for DMA transfers\n",
+			dma_chan_name(host->dma.chan));
+
+	host->dma_conf.src_addr = host->mapbase + ATMCI_RDR;
+	host->dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	host->dma_conf.src_maxburst = 1;
+	host->dma_conf.dst_addr = host->mapbase + ATMCI_TDR;
+	host->dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	host->dma_conf.dst_maxburst = 1;
+	host->dma_conf.device_fc = false;
+	return ret;
 }
 
 /*
@@ -2411,7 +2413,10 @@ static int __init atmci_probe(struct platform_device *pdev)
 
 	/* Get MCI capabilities and set operations according to it */
 	atmci_get_cap(host);
-	if (atmci_configure_dma(host)) {
+	ret = atmci_configure_dma(host);
+	if (ret == -EPROBE_DEFER)
+		goto err_dma_probe_defer;
+	if (ret == 0) {
 		host->prepare_data = &atmci_prepare_data_dma;
 		host->submit_data = &atmci_submit_data_dma;
 		host->stop_transfer = &atmci_stop_transfer_dma;
@@ -2484,6 +2489,7 @@ err_init_slot:
 	del_timer_sync(&host->timer);
 	if (host->dma.chan)
 		dma_release_channel(host->dma.chan);
+err_dma_probe_defer:
 	free_irq(irq, host);
 	return ret;
 }
@@ -2518,25 +2524,14 @@ static int __exit atmci_remove(struct platform_device *pdev)
 }
 
 static struct platform_driver atmci_driver = {
+	.probe		= atmci_probe,
 	.remove		= __exit_p(atmci_remove),
 	.driver		= {
 		.name		= "atmel_mci",
 		.of_match_table	= of_match_ptr(atmci_dt_ids),
 	},
 };
-
-static int __init atmci_init(void)
-{
-	return platform_driver_probe(&atmci_driver, atmci_probe);
-}
-
-static void __exit atmci_exit(void)
-{
-	platform_driver_unregister(&atmci_driver);
-}
-
-late_initcall(atmci_init); /* try to load after dma driver when built-in */
-module_exit(atmci_exit);
+module_platform_driver(atmci_driver);
 
 MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver");
 MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
-- 
2.0.3

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2] mmc: atmel-mci: use probe deferring if dma controller is not ready yet
  2014-11-19 14:51 [PATCH v2] mmc: atmel-mci: use probe deferring if dma controller is not ready yet Ludovic Desroches
@ 2014-11-19 14:57 ` Arnd Bergmann
  2014-11-19 15:15   ` Ludovic Desroches
  0 siblings, 1 reply; 3+ messages in thread
From: Arnd Bergmann @ 2014-11-19 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 19 November 2014 15:51:07 Ludovic Desroches wrote:
> @@ -2265,37 +2265,39 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
>         mmc_free_host(slot->mmc);
>  }
>  
> -static bool atmci_configure_dma(struct atmel_mci *host)
> +static int atmci_configure_dma(struct atmel_mci *host)
>  {
>         struct mci_platform_data        *pdata;
>         dma_cap_mask_t mask;
> +       int ret = 0;
>  
>         if (host == NULL)
> -               return false;
> +               return -EINVAL;
>  
>         pdata = host->pdev->dev.platform_data;
>  
>         dma_cap_zero(mask);
>         dma_cap_set(DMA_SLAVE, mask);
>  
> 

Host can't be NULL here, the only caller has already checked and dereferenced
the pointer before calling atmci_configure_dma.

The mask variable is now completely unused and can be removed.

	Arnd

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2] mmc: atmel-mci: use probe deferring if dma controller is not ready yet
  2014-11-19 14:57 ` Arnd Bergmann
@ 2014-11-19 15:15   ` Ludovic Desroches
  0 siblings, 0 replies; 3+ messages in thread
From: Ludovic Desroches @ 2014-11-19 15:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 19, 2014 at 03:57:56PM +0100, Arnd Bergmann wrote:
> On Wednesday 19 November 2014 15:51:07 Ludovic Desroches wrote:
> > @@ -2265,37 +2265,39 @@ static void atmci_cleanup_slot(struct atmel_mci_slot *slot,
> >         mmc_free_host(slot->mmc);
> >  }
> >  
> > -static bool atmci_configure_dma(struct atmel_mci *host)
> > +static int atmci_configure_dma(struct atmel_mci *host)
> >  {
> >         struct mci_platform_data        *pdata;
> >         dma_cap_mask_t mask;
> > +       int ret = 0;
> >  
> >         if (host == NULL)
> > -               return false;
> > +               return -EINVAL;
> >  
> >         pdata = host->pdev->dev.platform_data;
> >  
> >         dma_cap_zero(mask);
> >         dma_cap_set(DMA_SLAVE, mask);
> >  
> > 
> 
> Host can't be NULL here, the only caller has already checked and dereferenced
> the pointer before calling atmci_configure_dma.
> 
> The mask variable is now completely unused and can be removed.

Thanks, there is some extra stuff that can be removed too. I'll split
those changes in two patches, one to remove all non DT DMA stuff and one
for probe deferring.

Ludovic

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-11-19 15:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-19 14:51 [PATCH v2] mmc: atmel-mci: use probe deferring if dma controller is not ready yet Ludovic Desroches
2014-11-19 14:57 ` Arnd Bergmann
2014-11-19 15:15   ` Ludovic Desroches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).