mmc: core: Add a facility to "pause" re-tuning
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 16 May 2016 12:35:24 +0000 (15:35 +0300)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 17 May 2016 14:54:26 +0000 (16:54 +0200)
Re-tuning is not possible when switched to the RPMB
partition.  However re-tuning should not be needed
if re-tuning is done immediately before switching,
a small set of operations is done, and then we
immediately switch back to the main partition.

To ensure that re-tuning can't be done for a short
while, add a facility to "pause" re-tuning.

The existing facility to hold / release re-tuning
is used but it also flags re-tuning as needed to cause
re-tuning before the next command (which will be the
switch to RPMB).

We also need to "unpause" in the recovery path, which
is catered for by adding it to mmc_retune_disable().

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/host.c
include/linux/mmc/host.h

index e0a3ee1..1be42fa 100644 (file)
@@ -68,8 +68,32 @@ void mmc_retune_enable(struct mmc_host *host)
                          jiffies + host->retune_period * HZ);
 }
 
+/*
+ * Pause re-tuning for a small set of operations.  The pause begins after the
+ * next command and after first doing re-tuning.
+ */
+void mmc_retune_pause(struct mmc_host *host)
+{
+       if (!host->retune_paused) {
+               host->retune_paused = 1;
+               mmc_retune_needed(host);
+               mmc_retune_hold(host);
+       }
+}
+EXPORT_SYMBOL(mmc_retune_pause);
+
+void mmc_retune_unpause(struct mmc_host *host)
+{
+       if (host->retune_paused) {
+               host->retune_paused = 0;
+               mmc_retune_release(host);
+       }
+}
+EXPORT_SYMBOL(mmc_retune_unpause);
+
 void mmc_retune_disable(struct mmc_host *host)
 {
+       mmc_retune_unpause(host);
        host->can_retune = 0;
        del_timer_sync(&host->retune_timer);
        host->retune_now = 0;
index 85800b4..45cde8c 100644 (file)
@@ -329,6 +329,7 @@ struct mmc_host {
        unsigned int            can_retune:1;   /* re-tuning can be used */
        unsigned int            doing_retune:1; /* re-tuning in progress */
        unsigned int            retune_now:1;   /* do re-tuning at next req */
+       unsigned int            retune_paused:1; /* re-tuning is temporarily disabled */
 
        int                     rescan_disable; /* disable card detection */
        int                     rescan_entered; /* used with nonremovable devices */
@@ -526,4 +527,7 @@ static inline void mmc_retune_recheck(struct mmc_host *host)
                host->retune_now = 1;
 }
 
+void mmc_retune_pause(struct mmc_host *host);
+void mmc_retune_unpause(struct mmc_host *host);
+
 #endif /* LINUX_MMC_HOST_H */