@@ -1161,6 +1161,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sdhci_host *host;
unsigned long flags;
+ unsigned int lastclock;
u8 ctrl;
host = mmc_priv(mmc);
@@ -1171,6 +1172,24 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
goto out;
/*
+ * get/put runtime_pm usage counter at ios->clock transitions
+ * We need to do it before any other chip access, as sdhci could
+ * be power gated
+ */
+ lastclock = host->iosclock;
+ host->iosclock = ios->clock;
+ if (lastclock == 0 && ios->clock != 0) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ pm_runtime_get_sync(&host->parent.dev);
+ spin_lock_irqsave(&host->lock, flags);
+ } else if (lastclock != 0 && ios->clock == 0) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ pm_runtime_put_autosuspend(&host->parent.dev);
+ spin_lock_irqsave(&host->lock, flags);
+ /* no need to configure the rest.. */
+ goto out;
+ }
+ /*
* Reset the chip on each power off.
* Should clear out any weird states.
*/
@@ -1779,6 +1798,7 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
host = mmc_priv(mmc);
host->mmc = mmc;
+ host->iosclock = 0;
return host;
}
@@ -114,6 +114,7 @@ struct sdhci_host {
unsigned int timeout_clk; /* Timeout freq (KHz) */
unsigned int clock; /* Current clock (MHz) */
+ unsigned int iosclock; /* Last clock asked via set_ios */
u8 pwr; /* Current voltage */
struct mmc_request *mrq; /* Current request */