aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorAaron Lu <aaron.lu@amd.com>2012-07-04 01:29:09 -0400
committerChris Ball <cjb@laptop.org>2012-07-22 15:25:49 -0400
commit973905feab85416784f36cc94b868392fd465ef4 (patch)
treea44c153c77eae6c52d4bafb5f0a8da745cba7b35 /drivers/mmc/host/sdhci.c
parentaa6439daddf579b93ace8b45956a416234c3854c (diff)
mmc: sdhci: Introduce new flag SDHCI_USING_RETUNING_TIMER
Add a new flag of SDHCI_USING_RETUNING_TIMER to represent if the host is using a retuning timer for the card inserted. This flag is set when the host does tuning the first time for the card and the host's retuning mode is 1. This flag is used afterwards whenever needs to decide if the host is currently using a retuning timer. This flag is cleared when the card is removed in sdhci_reinit. The set/clear of the flag and the start/stop of the retuning timer is associated with the card's init/remove time, so there is no need to touch it when the host is to be removed as at that time the card should have already been removed. Signed-off-by: Aaron Lu <aaron.lu@amd.com> Reviewed-by: Girish K S <girish.shivananjappa@linaro.org> Reviewed-by: Philip Rakity <prakity@marvell.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b0a5629dea3e..3ec418212894 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -250,8 +250,9 @@ static void sdhci_reinit(struct sdhci_host *host)
250 * applicable to UHS-I cards. So reset these fields to their initial 250 * applicable to UHS-I cards. So reset these fields to their initial
251 * value when card is removed. 251 * value when card is removed.
252 */ 252 */
253 if (host->version >= SDHCI_SPEC_300 && host->tuning_count && 253 if (host->flags & SDHCI_USING_RETUNING_TIMER) {
254 host->tuning_mode == SDHCI_TUNING_MODE_1) { 254 host->flags &= ~SDHCI_USING_RETUNING_TIMER;
255
255 del_timer_sync(&host->tuning_timer); 256 del_timer_sync(&host->tuning_timer);
256 host->flags &= ~SDHCI_NEEDS_RETUNING; 257 host->flags &= ~SDHCI_NEEDS_RETUNING;
257 host->mmc->max_blk_count = 258 host->mmc->max_blk_count =
@@ -1873,6 +1874,7 @@ out:
1873 */ 1874 */
1874 if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && 1875 if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count &&
1875 (host->tuning_mode == SDHCI_TUNING_MODE_1)) { 1876 (host->tuning_mode == SDHCI_TUNING_MODE_1)) {
1877 host->flags |= SDHCI_USING_RETUNING_TIMER;
1876 mod_timer(&host->tuning_timer, jiffies + 1878 mod_timer(&host->tuning_timer, jiffies +
1877 host->tuning_count * HZ); 1879 host->tuning_count * HZ);
1878 /* Tuning mode 1 limits the maximum data length to 4MB */ 1880 /* Tuning mode 1 limits the maximum data length to 4MB */
@@ -1890,10 +1892,10 @@ out:
1890 * try tuning again at a later time, when the re-tuning timer expires. 1892 * try tuning again at a later time, when the re-tuning timer expires.
1891 * So for these controllers, we return 0. Since there might be other 1893 * So for these controllers, we return 0. Since there might be other
1892 * controllers who do not have this capability, we return error for 1894 * controllers who do not have this capability, we return error for
1893 * them. 1895 * them. SDHCI_USING_RETUNING_TIMER means the host is currently using
1896 * a retuning timer to do the retuning for the card.
1894 */ 1897 */
1895 if (err && host->tuning_count && 1898 if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
1896 host->tuning_mode == SDHCI_TUNING_MODE_1)
1897 err = 0; 1899 err = 0;
1898 1900
1899 sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier); 1901 sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
@@ -2400,7 +2402,6 @@ out:
2400int sdhci_suspend_host(struct sdhci_host *host) 2402int sdhci_suspend_host(struct sdhci_host *host)
2401{ 2403{
2402 int ret; 2404 int ret;
2403 bool has_tuning_timer;
2404 2405
2405 if (host->ops->platform_suspend) 2406 if (host->ops->platform_suspend)
2406 host->ops->platform_suspend(host); 2407 host->ops->platform_suspend(host);
@@ -2408,16 +2409,14 @@ int sdhci_suspend_host(struct sdhci_host *host)
2408 sdhci_disable_card_detection(host); 2409 sdhci_disable_card_detection(host);
2409 2410
2410 /* Disable tuning since we are suspending */ 2411 /* Disable tuning since we are suspending */
2411 has_tuning_timer = host->version >= SDHCI_SPEC_300 && 2412 if (host->flags & SDHCI_USING_RETUNING_TIMER) {
2412 host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1;
2413 if (has_tuning_timer) {
2414 del_timer_sync(&host->tuning_timer); 2413 del_timer_sync(&host->tuning_timer);
2415 host->flags &= ~SDHCI_NEEDS_RETUNING; 2414 host->flags &= ~SDHCI_NEEDS_RETUNING;
2416 } 2415 }
2417 2416
2418 ret = mmc_suspend_host(host->mmc); 2417 ret = mmc_suspend_host(host->mmc);
2419 if (ret) { 2418 if (ret) {
2420 if (has_tuning_timer) { 2419 if (host->flags & SDHCI_USING_RETUNING_TIMER) {
2421 host->flags |= SDHCI_NEEDS_RETUNING; 2420 host->flags |= SDHCI_NEEDS_RETUNING;
2422 mod_timer(&host->tuning_timer, jiffies + 2421 mod_timer(&host->tuning_timer, jiffies +
2423 host->tuning_count * HZ); 2422 host->tuning_count * HZ);
@@ -2468,8 +2467,7 @@ int sdhci_resume_host(struct sdhci_host *host)
2468 host->ops->platform_resume(host); 2467 host->ops->platform_resume(host);
2469 2468
2470 /* Set the re-tuning expiration flag */ 2469 /* Set the re-tuning expiration flag */
2471 if ((host->version >= SDHCI_SPEC_300) && host->tuning_count && 2470 if (host->flags & SDHCI_USING_RETUNING_TIMER)
2472 (host->tuning_mode == SDHCI_TUNING_MODE_1))
2473 host->flags |= SDHCI_NEEDS_RETUNING; 2471 host->flags |= SDHCI_NEEDS_RETUNING;
2474 2472
2475 return ret; 2473 return ret;
@@ -2508,8 +2506,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
2508 int ret = 0; 2506 int ret = 0;
2509 2507
2510 /* Disable tuning since we are suspending */ 2508 /* Disable tuning since we are suspending */
2511 if (host->version >= SDHCI_SPEC_300 && 2509 if (host->flags & SDHCI_USING_RETUNING_TIMER) {
2512 host->tuning_mode == SDHCI_TUNING_MODE_1) {
2513 del_timer_sync(&host->tuning_timer); 2510 del_timer_sync(&host->tuning_timer);
2514 host->flags &= ~SDHCI_NEEDS_RETUNING; 2511 host->flags &= ~SDHCI_NEEDS_RETUNING;
2515 } 2512 }
@@ -2550,8 +2547,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
2550 sdhci_do_enable_preset_value(host, true); 2547 sdhci_do_enable_preset_value(host, true);
2551 2548
2552 /* Set the re-tuning expiration flag */ 2549 /* Set the re-tuning expiration flag */
2553 if ((host->version >= SDHCI_SPEC_300) && host->tuning_count && 2550 if (host->flags & SDHCI_USING_RETUNING_TIMER)
2554 (host->tuning_mode == SDHCI_TUNING_MODE_1))
2555 host->flags |= SDHCI_NEEDS_RETUNING; 2551 host->flags |= SDHCI_NEEDS_RETUNING;
2556 2552
2557 spin_lock_irqsave(&host->lock, flags); 2553 spin_lock_irqsave(&host->lock, flags);
@@ -3140,8 +3136,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
3140 free_irq(host->irq, host); 3136 free_irq(host->irq, host);
3141 3137
3142 del_timer_sync(&host->timer); 3138 del_timer_sync(&host->timer);
3143 if (host->version >= SDHCI_SPEC_300)
3144 del_timer_sync(&host->tuning_timer);
3145 3139
3146 tasklet_kill(&host->card_tasklet); 3140 tasklet_kill(&host->card_tasklet);
3147 tasklet_kill(&host->finish_tasklet); 3141 tasklet_kill(&host->finish_tasklet);