diff mbox

[v1,1/1] mmc: mxcmmc: setup mpc512x related clocks

Message ID 1368543609-11372-2-git-send-email-gsi@denx.de (mailing list archive)
State New, archived
Headers show

Commit Message

Gerhard Sittig May 14, 2013, 3 p.m. UTC
the mxcmmc(4) driver is shared across the i.MX and MPC512x platforms,
setup the 'sdhc_clk' instead of 'ipg' and 'per' in the mpc512x case

this change re-uses the i.MX 'per' clock related variable for everything
SDHC/MMC related, and makes the 'ipg' clock related variable access
conditional -- this approach is less intrusive than adding an #ifdef and
two sets of variables everywhere

viewing the change with 'git diff -w' better reflects its nature

Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
 drivers/mmc/host/mxcmmc.c |   41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)

Comments

Sascha Hauer May 15, 2013, 8:04 a.m. UTC | #1
On Tue, May 14, 2013 at 05:00:09PM +0200, Gerhard Sittig wrote:
> the mxcmmc(4) driver is shared across the i.MX and MPC512x platforms,
> setup the 'sdhc_clk' instead of 'ipg' and 'per' in the mpc512x case
> 
> this change re-uses the i.MX 'per' clock related variable for everything
> SDHC/MMC related, and makes the 'ipg' clock related variable access
> conditional -- this approach is less intrusive than adding an #ifdef and
> two sets of variables everywhere
> 
> viewing the change with 'git diff -w' better reflects its nature
> 
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
>  drivers/mmc/host/mxcmmc.c |   41 +++++++++++++++++++++++++++--------------
>  1 file changed, 27 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
> index d503635..b9d21cc 100644
> --- a/drivers/mmc/host/mxcmmc.c
> +++ b/drivers/mmc/host/mxcmmc.c
> @@ -1121,20 +1121,29 @@ static int mxcmci_probe(struct platform_device *pdev)
>  	host->res = r;
>  	host->irq = irq;
>  
> -	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
> -	if (IS_ERR(host->clk_ipg)) {
> -		ret = PTR_ERR(host->clk_ipg);
> -		goto out_iounmap;
> -	}
> +	if (!is_mpc512x_mmc(host)) {
> +		host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
> +		if (IS_ERR(host->clk_ipg)) {
> +			ret = PTR_ERR(host->clk_ipg);
> +			goto out_iounmap;
> +		}
>  
> -	host->clk_per = devm_clk_get(&pdev->dev, "per");
> -	if (IS_ERR(host->clk_per)) {
> -		ret = PTR_ERR(host->clk_per);
> -		goto out_iounmap;
> +		host->clk_per = devm_clk_get(&pdev->dev, "per");
> +		if (IS_ERR(host->clk_per)) {
> +			ret = PTR_ERR(host->clk_per);
> +			goto out_iounmap;
> +		}
> +	} else {
> +		host->clk_per = devm_clk_get(&pdev->dev, "sdhc_clk");
> +		if (IS_ERR(host->clk_per)) {
> +			ret = PTR_ERR(host->clk_per);
> +			goto out_iounmap;
> +		}
>  	}

No! The clocks we need are SDHC core specific, not powerPC/ARM
specific.

The clocks are modelled after the input clocks of the device, *not*
after what the SoC offers control over.

See "Figure 34-22. Clock Used in SDHC" in the MPC5121 Programming guide.
This shows that the SDHC core has a SDHC_CLK, IPG_CLK and IPG_CLK_S.
These are the 3 clocks the SDHC core needs and the driver has to request
them. If you do not have software control over all clocks, you still
have to provide dummy clocks.

That said, this is currently hard to implement as the clock support for
the MPC5121 is utterly broken. The MPC5121 clk_get implementation
currently ignores the device argument and relies only on the "sdhc_clk"
string.

Fix your platform code, then you don't have to mess with the driver.

Sascha
diff mbox

Patch

diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index d503635..b9d21cc 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1121,20 +1121,29 @@  static int mxcmci_probe(struct platform_device *pdev)
 	host->res = r;
 	host->irq = irq;
 
-	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
-	if (IS_ERR(host->clk_ipg)) {
-		ret = PTR_ERR(host->clk_ipg);
-		goto out_iounmap;
-	}
+	if (!is_mpc512x_mmc(host)) {
+		host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+		if (IS_ERR(host->clk_ipg)) {
+			ret = PTR_ERR(host->clk_ipg);
+			goto out_iounmap;
+		}
 
-	host->clk_per = devm_clk_get(&pdev->dev, "per");
-	if (IS_ERR(host->clk_per)) {
-		ret = PTR_ERR(host->clk_per);
-		goto out_iounmap;
+		host->clk_per = devm_clk_get(&pdev->dev, "per");
+		if (IS_ERR(host->clk_per)) {
+			ret = PTR_ERR(host->clk_per);
+			goto out_iounmap;
+		}
+	} else {
+		host->clk_per = devm_clk_get(&pdev->dev, "sdhc_clk");
+		if (IS_ERR(host->clk_per)) {
+			ret = PTR_ERR(host->clk_per);
+			goto out_iounmap;
+		}
 	}
 
 	clk_prepare_enable(host->clk_per);
-	clk_prepare_enable(host->clk_ipg);
+	if (host->clk_ipg)
+		clk_prepare_enable(host->clk_ipg);
 
 	mxcmci_softreset(host);
 
@@ -1204,7 +1213,8 @@  out_free_dma:
 		dma_release_channel(host->dma);
 out_clk_put:
 	clk_disable_unprepare(host->clk_per);
-	clk_disable_unprepare(host->clk_ipg);
+	if (host->clk_ipg)
+		clk_disable_unprepare(host->clk_ipg);
 out_iounmap:
 	iounmap(host->base);
 out_free:
@@ -1236,7 +1246,8 @@  static int mxcmci_remove(struct platform_device *pdev)
 		dma_release_channel(host->dma);
 
 	clk_disable_unprepare(host->clk_per);
-	clk_disable_unprepare(host->clk_ipg);
+	if (host->clk_ipg)
+		clk_disable_unprepare(host->clk_ipg);
 
 	release_mem_region(host->res->start, resource_size(host->res));
 
@@ -1255,7 +1266,8 @@  static int mxcmci_suspend(struct device *dev)
 	if (mmc)
 		ret = mmc_suspend_host(mmc);
 	clk_disable_unprepare(host->clk_per);
-	clk_disable_unprepare(host->clk_ipg);
+	if (host->clk_ipg)
+		clk_disable_unprepare(host->clk_ipg);
 
 	return ret;
 }
@@ -1267,7 +1279,8 @@  static int mxcmci_resume(struct device *dev)
 	int ret = 0;
 
 	clk_prepare_enable(host->clk_per);
-	clk_prepare_enable(host->clk_ipg);
+	if (host->clk_ipg)
+		clk_prepare_enable(host->clk_ipg);
 	if (mmc)
 		ret = mmc_resume_host(mmc);