diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/host.c | 68 | ||||
-rw-r--r-- | drivers/mmc/core/host.h | 6 |
2 files changed, 74 insertions, 0 deletions
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 8be0df758e68..e90e02fc596a 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -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. diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index f2ab9e578126..992bf5397633 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -15,5 +15,11 @@ int mmc_register_host_class(void); void mmc_unregister_host_class(void); +void mmc_retune_enable(struct mmc_host *host); +void mmc_retune_disable(struct mmc_host *host); +void mmc_retune_hold(struct mmc_host *host); +void mmc_retune_release(struct mmc_host *host); +int mmc_retune(struct mmc_host *host); + #endif |