@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
#include <linux/leds.h>
@@ -1221,6 +1222,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);
@@ -1231,6 +1233,27 @@ 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->mmc->parent);
+ spin_lock_irqsave(&host->lock, flags);
+ } else if (lastclock != 0 && ios->clock == 0) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ pm_runtime_mark_last_busy(host->mmc->parent);
+ pm_runtime_put_autosuspend(host->mmc->parent);
+ spin_lock_irqsave(&host->lock, flags);
+ }
+ /* no need to configure the rest.. */
+ if (host->iosclock == 0)
+ goto out;
+
+ /*
* Reset the chip on each power off.
* Should clear out any weird states.
*/
@@ -1303,6 +1326,8 @@ static int sdhci_get_ro(struct mmc_host *mmc)
I'm wondering if this code could be generic to all drivers, and if clock gating could not be taking/releasing reference counter on the mmc_bus whenever there is a clock gating transition?
We could condition that on some MMC_CAP_POWERGATE_WILL_CLKGATE capability flag.
Regards,
Pierre
---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)