|
@@ -301,6 +301,73 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
|
|
|
|
|
|
#endif
|
|
#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
|
|
* mmc_of_parse() - parse host's device-tree node
|
|
* @host: host whose node should be parsed.
|
|
* @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
|
|
#ifdef CONFIG_PM
|
|
host->pm_notify.notifier_call = mmc_pm_notify;
|
|
host->pm_notify.notifier_call = mmc_pm_notify;
|
|
#endif
|
|
#endif
|
|
|
|
+ setup_timer(&host->retune_timer, mmc_retune_timer, (unsigned long)host);
|
|
|
|
|
|
/*
|
|
/*
|
|
* By default, hosts do not support SGIO or large requests.
|
|
* By default, hosts do not support SGIO or large requests.
|