mmc: host: Add facility to support re-tuning
[deliverable/linux.git] / drivers / mmc / core / host.c
index 8be0df758e68270e94f9dacef3fe8572dc45701e..e90e02fc596a351bdea8508af49fd69481fff5fd 100644 (file)
@@ -301,6 +301,73 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
 
 #endif
 
+void mmc_retune_enable(struct mmc_host *host)
+{
+       host->can_retune = 1;
+       if (host->retune_period)
+               mod_timer(&host->retune_timer,
+                         jiffies + host->retune_period * HZ);
+}
+
+void mmc_retune_disable(struct mmc_host *host)
+{
+       host->can_retune = 0;
+       del_timer_sync(&host->retune_timer);
+       host->retune_now = 0;
+       host->need_retune = 0;
+}
+
+void mmc_retune_timer_stop(struct mmc_host *host)
+{
+       del_timer_sync(&host->retune_timer);
+}
+EXPORT_SYMBOL(mmc_retune_timer_stop);
+
+void mmc_retune_hold(struct mmc_host *host)
+{
+       if (!host->hold_retune)
+               host->retune_now = 1;
+       host->hold_retune += 1;
+}
+
+void mmc_retune_release(struct mmc_host *host)
+{
+       if (host->hold_retune)
+               host->hold_retune -= 1;
+       else
+               WARN_ON(1);
+}
+
+int mmc_retune(struct mmc_host *host)
+{
+       int err;
+
+       if (host->retune_now)
+               host->retune_now = 0;
+       else
+               return 0;
+
+       if (!host->need_retune || host->doing_retune || !host->card)
+               return 0;
+
+       host->need_retune = 0;
+
+       host->doing_retune = 1;
+
+       err = mmc_execute_tuning(host->card);
+
+       host->doing_retune = 0;
+
+       return err;
+}
+
+static void mmc_retune_timer(unsigned long data)
+{
+       struct mmc_host *host = (struct mmc_host *)data;
+
+       mmc_retune_needed(host);
+}
+
 /**
  *     mmc_of_parse() - parse host's device-tree node
  *     @host: host whose node should be parsed.
@@ -504,6 +571,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 #ifdef CONFIG_PM
        host->pm_notify.notifier_call = mmc_pm_notify;
 #endif
+       setup_timer(&host->retune_timer, mmc_retune_timer, (unsigned long)host);
 
        /*
         * By default, hosts do not support SGIO or large requests.
This page took 0.037036 seconds and 5 git commands to generate.