diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/host/mvsdio.c | 14 | ||||
| -rw-r--r-- | drivers/mmc/host/mxcmmc.c | 39 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 42 | 
3 files changed, 70 insertions, 25 deletions
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index eeb8cd125b0..3b9136c1a47 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -19,6 +19,7 @@  #include <linux/dma-mapping.h>  #include <linux/scatterlist.h>  #include <linux/irq.h> +#include <linux/clk.h>  #include <linux/gpio.h>  #include <linux/mmc/host.h> @@ -51,6 +52,7 @@ struct mvsd_host {  	struct device *dev;  	struct resource *res;  	int irq; +	struct clk *clk;  	int gpio_card_detect;  	int gpio_write_protect;  }; @@ -770,6 +772,13 @@ static int __init mvsd_probe(struct platform_device *pdev)  	} else  		host->irq = irq; +	/* Not all platforms can gate the clock, so it is not +	   an error if the clock does not exists. */ +	host->clk = clk_get(&pdev->dev, NULL); +	if (!IS_ERR(host->clk)) { +		clk_prepare_enable(host->clk); +	} +  	if (mvsd_data->gpio_card_detect) {  		ret = gpio_request(mvsd_data->gpio_card_detect,  				   DRIVER_NAME " cd"); @@ -854,6 +863,11 @@ static int __exit mvsd_remove(struct platform_device *pdev)  		mvsd_power_down(host);  		iounmap(host->base);  		release_resource(host->res); + +		if (!IS_ERR(host->clk)) { +			clk_disable_unprepare(host->clk); +			clk_put(host->clk); +		}  		mmc_free_host(mmc);  	}  	platform_set_drvdata(pdev, NULL); diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index b2058b43232..28ed52d58f7 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -136,7 +136,8 @@ struct mxcmci_host {  	u16			rev_no;  	unsigned int		cmdat; -	struct clk		*clk; +	struct clk		*clk_ipg; +	struct clk		*clk_per;  	int			clock; @@ -672,7 +673,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)  {  	unsigned int divider;  	int prescaler = 0; -	unsigned int clk_in = clk_get_rate(host->clk); +	unsigned int clk_in = clk_get_rate(host->clk_per);  	while (prescaler <= 0x800) {  		for (divider = 1; divider <= 0xF; divider++) { @@ -900,12 +901,20 @@ static int mxcmci_probe(struct platform_device *pdev)  	host->res = r;  	host->irq = irq; -	host->clk = clk_get(&pdev->dev, NULL); -	if (IS_ERR(host->clk)) { -		ret = PTR_ERR(host->clk); +	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); +	if (IS_ERR(host->clk_ipg)) { +		ret = PTR_ERR(host->clk_ipg);  		goto out_iounmap;  	} -	clk_enable(host->clk); + +	host->clk_per = devm_clk_get(&pdev->dev, "per"); +	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);  	mxcmci_softreset(host); @@ -917,8 +926,8 @@ static int mxcmci_probe(struct platform_device *pdev)  		goto out_clk_put;  	} -	mmc->f_min = clk_get_rate(host->clk) >> 16; -	mmc->f_max = clk_get_rate(host->clk) >> 1; +	mmc->f_min = clk_get_rate(host->clk_per) >> 16; +	mmc->f_max = clk_get_rate(host->clk_per) >> 1;  	/* recommended in data sheet */  	writew(0x2db4, host->base + MMC_REG_READ_TO); @@ -967,8 +976,8 @@ out_free_dma:  	if (host->dma)  		dma_release_channel(host->dma);  out_clk_put: -	clk_disable(host->clk); -	clk_put(host->clk); +	clk_disable_unprepare(host->clk_per); +	clk_disable_unprepare(host->clk_ipg);  out_iounmap:  	iounmap(host->base);  out_free: @@ -999,8 +1008,8 @@ static int mxcmci_remove(struct platform_device *pdev)  	if (host->dma)  		dma_release_channel(host->dma); -	clk_disable(host->clk); -	clk_put(host->clk); +	clk_disable_unprepare(host->clk_per); +	clk_disable_unprepare(host->clk_ipg);  	release_mem_region(host->res->start, resource_size(host->res)); @@ -1018,7 +1027,8 @@ static int mxcmci_suspend(struct device *dev)  	if (mmc)  		ret = mmc_suspend_host(mmc); -	clk_disable(host->clk); +	clk_disable_unprepare(host->clk_per); +	clk_disable_unprepare(host->clk_ipg);  	return ret;  } @@ -1029,7 +1039,8 @@ static int mxcmci_resume(struct device *dev)  	struct mxcmci_host *host = mmc_priv(mmc);  	int ret = 0; -	clk_enable(host->clk); +	clk_prepare_enable(host->clk_per); +	clk_prepare_enable(host->clk_ipg);  	if (mmc)  		ret = mmc_resume_host(mmc); diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 365b16c230f..ebbe984e5d0 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -71,6 +71,9 @@ struct pltfm_imx_data {  	enum imx_esdhc_type devtype;  	struct pinctrl *pinctrl;  	struct esdhc_platform_data boarddata; +	struct clk *clk_ipg; +	struct clk *clk_ahb; +	struct clk *clk_per;  };  static struct platform_device_id imx_esdhc_devtype[] = { @@ -439,7 +442,6 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)  	struct sdhci_pltfm_host *pltfm_host;  	struct sdhci_host *host;  	struct esdhc_platform_data *boarddata; -	struct clk *clk;  	int err;  	struct pltfm_imx_data *imx_data; @@ -460,14 +462,29 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)  	imx_data->devtype = pdev->id_entry->driver_data;  	pltfm_host->priv = imx_data; -	clk = clk_get(mmc_dev(host->mmc), NULL); -	if (IS_ERR(clk)) { -		dev_err(mmc_dev(host->mmc), "clk err\n"); -		err = PTR_ERR(clk); +	imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); +	if (IS_ERR(imx_data->clk_ipg)) { +		err = PTR_ERR(imx_data->clk_ipg);  		goto err_clk_get;  	} -	clk_prepare_enable(clk); -	pltfm_host->clk = clk; + +	imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); +	if (IS_ERR(imx_data->clk_ahb)) { +		err = PTR_ERR(imx_data->clk_ahb); +		goto err_clk_get; +	} + +	imx_data->clk_per = devm_clk_get(&pdev->dev, "per"); +	if (IS_ERR(imx_data->clk_per)) { +		err = PTR_ERR(imx_data->clk_per); +		goto err_clk_get; +	} + +	pltfm_host->clk = imx_data->clk_per; + +	clk_prepare_enable(imx_data->clk_per); +	clk_prepare_enable(imx_data->clk_ipg); +	clk_prepare_enable(imx_data->clk_ahb);  	imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);  	if (IS_ERR(imx_data->pinctrl)) { @@ -567,8 +584,9 @@ no_card_detect_irq:  no_card_detect_pin:  no_board_data:  pin_err: -	clk_disable_unprepare(pltfm_host->clk); -	clk_put(pltfm_host->clk); +	clk_disable_unprepare(imx_data->clk_per); +	clk_disable_unprepare(imx_data->clk_ipg); +	clk_disable_unprepare(imx_data->clk_ahb);  err_clk_get:  	kfree(imx_data);  err_imx_data: @@ -594,8 +612,10 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)  		gpio_free(boarddata->cd_gpio);  	} -	clk_disable_unprepare(pltfm_host->clk); -	clk_put(pltfm_host->clk); +	clk_disable_unprepare(imx_data->clk_per); +	clk_disable_unprepare(imx_data->clk_ipg); +	clk_disable_unprepare(imx_data->clk_ahb); +  	kfree(imx_data);  	sdhci_pltfm_free(pdev);  |