Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac9fd305 authored by Sahitya Tummala's avatar Sahitya Tummala
Browse files

mmc: sdhci: Fix issue with SDHCI_NEEDS_RETUNING



The following two issues are addressed with this change -

1. The current code sets SDHCI_NEEDS_RETUNING flag even for tuning
commands and it will unecessarily cause tuning to be done again
for the next read/write command. Hence, we must not set this flag
for any CRC failures to tuning commands.

2. If SDHCI_NEEDS_RETUNING flag is set and if all tuning phases
pass, then the driver attempts to change the driver type by sending
CMD6 which is a not a tuning command. The driver will thus attempt
to do re-tuning again before sending CMD6 and goes forever in a
recursive loop. Hence, clear SDHCI_NEEDS_RETUNING flag before
executing tuning.

Change-Id: Iaf3b24b93fdf655392fe02c973799e465960a495
Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
parent cd738d78
Loading
Loading
Loading
Loading
+9 −2
Original line number Original line Diff line number Diff line
@@ -1735,6 +1735,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
					MMC_SEND_TUNING_BLOCK_HS200 :
					MMC_SEND_TUNING_BLOCK_HS200 :
					MMC_SEND_TUNING_BLOCK;
					MMC_SEND_TUNING_BLOCK;
				host->mrq = NULL;
				host->mrq = NULL;
				host->flags &= ~SDHCI_NEEDS_RETUNING;
				spin_unlock_irqrestore(&host->lock, flags);
				spin_unlock_irqrestore(&host->lock, flags);
				sdhci_execute_tuning(mmc, tuning_opcode);
				sdhci_execute_tuning(mmc, tuning_opcode);
				spin_lock_irqsave(&host->lock, flags);
				spin_lock_irqsave(&host->lock, flags);
@@ -2774,6 +2775,7 @@ static void sdhci_tuning_timer(unsigned long data)
static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
{
{
	u16 auto_cmd_status;
	u16 auto_cmd_status;
	u32 command;
	BUG_ON(intmask == 0);
	BUG_ON(intmask == 0);


	if (!host->cmd) {
	if (!host->cmd) {
@@ -2805,7 +2807,12 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
	}
	}


	if (host->cmd->error) {
	if (host->cmd->error) {
		if (host->cmd->error == -EILSEQ)
		command = SDHCI_GET_CMD(sdhci_readw(host,
						    SDHCI_COMMAND));
		if (host->cmd->error == -EILSEQ &&
		    (command != MMC_SEND_TUNING_BLOCK_HS400) &&
		    (command != MMC_SEND_TUNING_BLOCK_HS200) &&
		    (command != MMC_SEND_TUNING_BLOCK))
				host->flags |= SDHCI_NEEDS_RETUNING;
				host->flags |= SDHCI_NEEDS_RETUNING;
		tasklet_schedule(&host->finish_tasklet);
		tasklet_schedule(&host->finish_tasklet);
		return;
		return;