From f90a0612f0e110a8af976835273124dff4fa8b3d Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 17 Sep 2012 18:16:38 +0000 Subject: mmc: dw_mmc: lookup for optional biu and ciu clocks Some platforms allow for clock gating and control of bus interface unit clock and card interface unit clock. Add support for clock lookup of optional biu and ciu clocks for clock gating and clock speed determination. Signed-off-by: Abhilash Kesavan Signed-off-by: Thomas Abraham Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 227c42ef18c5..de45ad24becb 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1960,13 +1960,42 @@ int dw_mci_probe(struct dw_mci *host) return -ENODEV; } - if (!host->pdata->bus_hz) { + host->biu_clk = clk_get(host->dev, "biu"); + if (IS_ERR(host->biu_clk)) { + dev_dbg(host->dev, "biu clock not available\n"); + } else { + ret = clk_prepare_enable(host->biu_clk); + if (ret) { + dev_err(host->dev, "failed to enable biu clock\n"); + clk_put(host->biu_clk); + return ret; + } + } + + host->ciu_clk = clk_get(host->dev, "ciu"); + if (IS_ERR(host->ciu_clk)) { + dev_dbg(host->dev, "ciu clock not available\n"); + } else { + ret = clk_prepare_enable(host->ciu_clk); + if (ret) { + dev_err(host->dev, "failed to enable ciu clock\n"); + clk_put(host->ciu_clk); + goto err_clk_biu; + } + } + + if (IS_ERR(host->ciu_clk)) + host->bus_hz = host->pdata->bus_hz; + else + host->bus_hz = clk_get_rate(host->ciu_clk); + + if (!host->bus_hz) { dev_err(host->dev, "Platform data must supply bus speed\n"); - return -ENODEV; + ret = -ENODEV; + goto err_clk_ciu; } - host->bus_hz = host->pdata->bus_hz; host->quirks = host->pdata->quirks; spin_lock_init(&host->lock); @@ -2116,6 +2145,17 @@ err_dmaunmap: regulator_disable(host->vmmc); regulator_put(host->vmmc); } + +err_clk_ciu: + if (!IS_ERR(host->ciu_clk)) { + clk_disable_unprepare(host->ciu_clk); + clk_put(host->ciu_clk); + } +err_clk_biu: + if (!IS_ERR(host->biu_clk)) { + clk_disable_unprepare(host->biu_clk); + clk_put(host->biu_clk); + } return ret; } EXPORT_SYMBOL(dw_mci_probe); @@ -2149,6 +2189,12 @@ void dw_mci_remove(struct dw_mci *host) regulator_put(host->vmmc); } + if (!IS_ERR(host->ciu_clk)) + clk_disable_unprepare(host->ciu_clk); + if (!IS_ERR(host->biu_clk)) + clk_disable_unprepare(host->biu_clk); + clk_put(host->ciu_clk); + clk_put(host->biu_clk); } EXPORT_SYMBOL(dw_mci_remove); -- cgit v1.2.3