diff options
Diffstat (limited to 'drivers/mmc/host/sh_mmcif.c')
-rw-r--r-- | drivers/mmc/host/sh_mmcif.c | 74 |
1 files changed, 27 insertions, 47 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index d9a655f47d41..dd64b8663984 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -248,7 +248,6 @@ struct sh_mmcif_host { int sg_idx; int sg_blkidx; bool power; - bool card_present; bool ccs_enable; /* Command Completion Signal support */ bool clk_ctrl2_enable; struct mutex thread_lock; @@ -1064,16 +1063,6 @@ static void sh_mmcif_clk_setup(struct sh_mmcif_host *host) host->mmc->f_max, host->mmc->f_min); } -static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios) -{ - struct mmc_host *mmc = host->mmc; - - if (!IS_ERR(mmc->supply.vmmc)) - /* Errors ignored... */ - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, - ios->power_mode ? ios->vdd : 0); -} - static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct sh_mmcif_host *host = mmc_priv(mmc); @@ -1091,42 +1080,32 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->state = STATE_IOS; spin_unlock_irqrestore(&host->lock, flags); - if (ios->power_mode == MMC_POWER_UP) { - if (!host->card_present) { - /* See if we also get DMA */ + switch (ios->power_mode) { + case MMC_POWER_UP: + if (!IS_ERR(mmc->supply.vmmc)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); + if (!host->power) { + clk_prepare_enable(host->clk); + pm_runtime_get_sync(dev); + sh_mmcif_sync_reset(host); sh_mmcif_request_dma(host); - host->card_present = true; - } - sh_mmcif_set_power(host, ios); - } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { - /* clock stop */ - sh_mmcif_clock_control(host, 0); - if (ios->power_mode == MMC_POWER_OFF) { - if (host->card_present) { - sh_mmcif_release_dma(host); - host->card_present = false; - } + host->power = true; } + break; + case MMC_POWER_OFF: + if (!IS_ERR(mmc->supply.vmmc)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); if (host->power) { - pm_runtime_put_sync(dev); + sh_mmcif_clock_control(host, 0); + sh_mmcif_release_dma(host); + pm_runtime_put(dev); clk_disable_unprepare(host->clk); host->power = false; - if (ios->power_mode == MMC_POWER_OFF) - sh_mmcif_set_power(host, ios); - } - host->state = STATE_IDLE; - return; - } - - if (ios->clock) { - if (!host->power) { - clk_prepare_enable(host->clk); - - pm_runtime_get_sync(dev); - host->power = true; - sh_mmcif_sync_reset(host); } + break; + case MMC_POWER_ON: sh_mmcif_clock_control(host, ios->clock); + break; } host->timing = ios->timing; @@ -1519,23 +1498,23 @@ static int sh_mmcif_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); - pm_runtime_enable(dev); - host->power = false; - host->clk = devm_clk_get(dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); dev_err(dev, "cannot get clock: %d\n", ret); - goto err_pm; + goto err_host; } ret = clk_prepare_enable(host->clk); if (ret < 0) - goto err_pm; + goto err_host; sh_mmcif_clk_setup(host); - ret = pm_runtime_resume(dev); + pm_runtime_enable(dev); + host->power = false; + + ret = pm_runtime_get_sync(dev); if (ret < 0) goto err_clk; @@ -1579,12 +1558,13 @@ static int sh_mmcif_probe(struct platform_device *pdev) sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0xffff, clk_get_rate(host->clk) / 1000000UL); + pm_runtime_put(dev); clk_disable_unprepare(host->clk); return ret; err_clk: clk_disable_unprepare(host->clk); -err_pm: + pm_runtime_put_sync(dev); pm_runtime_disable(dev); err_host: mmc_free_host(mmc); |