|
@@ -52,7 +52,6 @@ static void sdhci_finish_data(struct sdhci_host *);
|
|
|
|
|
|
static void sdhci_finish_command(struct sdhci_host *);
|
|
|
static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
|
|
|
-static void sdhci_tuning_timer(unsigned long data);
|
|
|
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
|
|
|
static int sdhci_pre_dma_transfer(struct sdhci_host *host,
|
|
|
struct mmc_data *data,
|
|
@@ -254,17 +253,6 @@ static void sdhci_init(struct sdhci_host *host, int soft)
|
|
|
static void sdhci_reinit(struct sdhci_host *host)
|
|
|
{
|
|
|
sdhci_init(host, 0);
|
|
|
- /*
|
|
|
- * Retuning stuffs are affected by different cards inserted and only
|
|
|
- * applicable to UHS-I cards. So reset these fields to their initial
|
|
|
- * value when card is removed.
|
|
|
- */
|
|
|
- if (host->flags & SDHCI_USING_RETUNING_TIMER) {
|
|
|
- host->flags &= ~SDHCI_USING_RETUNING_TIMER;
|
|
|
-
|
|
|
- del_timer_sync(&host->tuning_timer);
|
|
|
- host->flags &= ~SDHCI_NEEDS_RETUNING;
|
|
|
- }
|
|
|
sdhci_enable_card_detection(host);
|
|
|
}
|
|
|
|
|
@@ -1353,7 +1341,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
|
struct sdhci_host *host;
|
|
|
int present;
|
|
|
unsigned long flags;
|
|
|
- u32 tuning_opcode;
|
|
|
|
|
|
host = mmc_priv(mmc);
|
|
|
|
|
@@ -1387,39 +1374,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
|
host->mrq->cmd->error = -ENOMEDIUM;
|
|
|
tasklet_schedule(&host->finish_tasklet);
|
|
|
} else {
|
|
|
- u32 present_state;
|
|
|
-
|
|
|
- present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
|
|
|
- /*
|
|
|
- * Check if the re-tuning timer has already expired and there
|
|
|
- * is no on-going data transfer and DAT0 is not busy. If so,
|
|
|
- * we need to execute tuning procedure before sending command.
|
|
|
- */
|
|
|
- if ((host->flags & SDHCI_NEEDS_RETUNING) &&
|
|
|
- !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ)) &&
|
|
|
- (present_state & SDHCI_DATA_0_LVL_MASK)) {
|
|
|
- if (mmc->card) {
|
|
|
- /* eMMC uses cmd21 but sd and sdio use cmd19 */
|
|
|
- tuning_opcode =
|
|
|
- mmc->card->type == MMC_TYPE_MMC ?
|
|
|
- MMC_SEND_TUNING_BLOCK_HS200 :
|
|
|
- MMC_SEND_TUNING_BLOCK;
|
|
|
-
|
|
|
- /* Here we need to set the host->mrq to NULL,
|
|
|
- * in case the pending finish_tasklet
|
|
|
- * finishes it incorrectly.
|
|
|
- */
|
|
|
- host->mrq = NULL;
|
|
|
-
|
|
|
- spin_unlock_irqrestore(&host->lock, flags);
|
|
|
- sdhci_execute_tuning(mmc, tuning_opcode);
|
|
|
- spin_lock_irqsave(&host->lock, flags);
|
|
|
-
|
|
|
- /* Restore original mmc_request structure */
|
|
|
- host->mrq = mrq;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
|
|
|
sdhci_send_command(host, mrq->sbc);
|
|
|
else
|
|
@@ -2065,23 +2019,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
|
|
}
|
|
|
|
|
|
out:
|
|
|
- host->flags &= ~SDHCI_NEEDS_RETUNING;
|
|
|
-
|
|
|
if (tuning_count) {
|
|
|
- host->flags |= SDHCI_USING_RETUNING_TIMER;
|
|
|
- mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ);
|
|
|
+ /*
|
|
|
+ * In case tuning fails, host controllers which support
|
|
|
+ * re-tuning can try tuning again at a later time, when the
|
|
|
+ * re-tuning timer expires. So for these controllers, we
|
|
|
+ * return 0. Since there might be other controllers who do not
|
|
|
+ * have this capability, we return error for them.
|
|
|
+ */
|
|
|
+ err = 0;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * In case tuning fails, host controllers which support re-tuning can
|
|
|
- * try tuning again at a later time, when the re-tuning timer expires.
|
|
|
- * So for these controllers, we return 0. Since there might be other
|
|
|
- * controllers who do not have this capability, we return error for
|
|
|
- * them. SDHCI_USING_RETUNING_TIMER means the host is currently using
|
|
|
- * a retuning timer to do the retuning for the card.
|
|
|
- */
|
|
|
- if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
|
|
|
- err = 0;
|
|
|
+ host->mmc->retune_period = err ? 0 : tuning_count;
|
|
|
|
|
|
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
|
|
|
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
|
|
@@ -2337,20 +2286,6 @@ static void sdhci_timeout_timer(unsigned long data)
|
|
|
spin_unlock_irqrestore(&host->lock, flags);
|
|
|
}
|
|
|
|
|
|
-static void sdhci_tuning_timer(unsigned long data)
|
|
|
-{
|
|
|
- struct sdhci_host *host;
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- host = (struct sdhci_host *)data;
|
|
|
-
|
|
|
- spin_lock_irqsave(&host->lock, flags);
|
|
|
-
|
|
|
- host->flags |= SDHCI_NEEDS_RETUNING;
|
|
|
-
|
|
|
- spin_unlock_irqrestore(&host->lock, flags);
|
|
|
-}
|
|
|
-
|
|
|
/*****************************************************************************\
|
|
|
* *
|
|
|
* Interrupt handling *
|
|
@@ -2728,11 +2663,8 @@ int sdhci_suspend_host(struct sdhci_host *host)
|
|
|
{
|
|
|
sdhci_disable_card_detection(host);
|
|
|
|
|
|
- /* Disable tuning since we are suspending */
|
|
|
- if (host->flags & SDHCI_USING_RETUNING_TIMER) {
|
|
|
- del_timer_sync(&host->tuning_timer);
|
|
|
- host->flags &= ~SDHCI_NEEDS_RETUNING;
|
|
|
- }
|
|
|
+ mmc_retune_timer_stop(host->mmc);
|
|
|
+ mmc_retune_needed(host->mmc);
|
|
|
|
|
|
if (!device_may_wakeup(mmc_dev(host->mmc))) {
|
|
|
host->ier = 0;
|
|
@@ -2782,10 +2714,6 @@ int sdhci_resume_host(struct sdhci_host *host)
|
|
|
|
|
|
sdhci_enable_card_detection(host);
|
|
|
|
|
|
- /* Set the re-tuning expiration flag */
|
|
|
- if (host->flags & SDHCI_USING_RETUNING_TIMER)
|
|
|
- host->flags |= SDHCI_NEEDS_RETUNING;
|
|
|
-
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -2822,11 +2750,8 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
|
|
|
- /* Disable tuning since we are suspending */
|
|
|
- if (host->flags & SDHCI_USING_RETUNING_TIMER) {
|
|
|
- del_timer_sync(&host->tuning_timer);
|
|
|
- host->flags &= ~SDHCI_NEEDS_RETUNING;
|
|
|
- }
|
|
|
+ mmc_retune_timer_stop(host->mmc);
|
|
|
+ mmc_retune_needed(host->mmc);
|
|
|
|
|
|
spin_lock_irqsave(&host->lock, flags);
|
|
|
host->ier &= SDHCI_INT_CARD_INT;
|
|
@@ -2869,10 +2794,6 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
|
|
|
spin_unlock_irqrestore(&host->lock, flags);
|
|
|
}
|
|
|
|
|
|
- /* Set the re-tuning expiration flag */
|
|
|
- if (host->flags & SDHCI_USING_RETUNING_TIMER)
|
|
|
- host->flags |= SDHCI_NEEDS_RETUNING;
|
|
|
-
|
|
|
spin_lock_irqsave(&host->lock, flags);
|
|
|
|
|
|
host->runtime_suspended = false;
|
|
@@ -3408,13 +3329,6 @@ int sdhci_add_host(struct sdhci_host *host)
|
|
|
|
|
|
init_waitqueue_head(&host->buf_ready_int);
|
|
|
|
|
|
- if (host->version >= SDHCI_SPEC_300) {
|
|
|
- /* Initialize re-tuning timer */
|
|
|
- init_timer(&host->tuning_timer);
|
|
|
- host->tuning_timer.data = (unsigned long)host;
|
|
|
- host->tuning_timer.function = sdhci_tuning_timer;
|
|
|
- }
|
|
|
-
|
|
|
sdhci_init(host, 0);
|
|
|
|
|
|
ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
|