diff options
author | Sebastian Hesselbarth <sebastian.hesselbarth@googlemail.com> | 2012-07-05 12:14:01 +0200 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-07-22 16:42:48 -0400 |
commit | 30b87c60e9cbfcdfce22aa652fc1e5d061fcb733 (patch) | |
tree | cfecead12bf49e8db4718a969a143320d773ee4d /drivers/mmc | |
parent | a9ca1d5477a89c1833214a01463190f7bd77d8a9 (diff) |
mmc: sdhci-dove: Prepare for common clock framework
As mach-dove is moving towards common clock framework prepare
the sdhci driver to grab its clock.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@googlemail.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci-dove.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index 9c853688179..a6e53a1ebb0 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c @@ -20,11 +20,17 @@ */ #include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> #include <linux/module.h> #include <linux/mmc/host.h> #include "sdhci-pltfm.h" +struct sdhci_dove_priv { + struct clk *clk; +}; + static u16 sdhci_dove_readw(struct sdhci_host *host, int reg) { u16 ret; @@ -72,11 +78,51 @@ static struct sdhci_pltfm_data sdhci_dove_pdata = { static int __devinit sdhci_dove_probe(struct platform_device *pdev) { - return sdhci_pltfm_register(pdev, &sdhci_dove_pdata); + struct sdhci_host *host; + struct sdhci_pltfm_host *pltfm_host; + struct sdhci_dove_priv *priv; + int ret; + + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); + if (ret) + goto sdhci_dove_register_fail; + + priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), + GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "unable to allocate private data"); + ret = -ENOMEM; + goto sdhci_dove_allocate_fail; + } + + host = platform_get_drvdata(pdev); + pltfm_host = sdhci_priv(host); + pltfm_host->priv = priv; + + priv->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(priv->clk)) + clk_prepare_enable(priv->clk); + return 0; + +sdhci_dove_allocate_fail: + sdhci_pltfm_unregister(pdev); +sdhci_dove_register_fail: + return ret; } static int __devexit sdhci_dove_remove(struct platform_device *pdev) { + struct sdhci_host *host = platform_get_drvdata(pdev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_dove_priv *priv = pltfm_host->priv; + + if (priv->clk) { + if (!IS_ERR(priv->clk)) { + clk_disable_unprepare(priv->clk); + clk_put(priv->clk); + } + devm_kfree(&pdev->dev, priv->clk); + } return sdhci_pltfm_unregister(pdev); } |