Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update error handling for SDHCI tuning #181

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 12 additions & 25 deletions drivers/mmc/host/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <linux/mmc/sdio.h>
#include <linux/mmc/slot-gpio.h>

#include "../core/host.h"
#include "sdhci.h"

#define DRIVER_NAME "sdhci"
Expand Down Expand Up @@ -305,7 +304,7 @@ static void sdhci_set_default_irqs(struct sdhci_host *host)

if (host->tuning_mode == SDHCI_TUNING_MODE_2 ||
host->tuning_mode == SDHCI_TUNING_MODE_3)
host->ier |= SDHCI_INT_RETUNE | SDHCI_INT_TUNING_ERR;
host->ier |= SDHCI_INT_RETUNE;

sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
Expand Down Expand Up @@ -2974,7 +2973,8 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)

sdhci_start_tuning(host);

host->tuning_err = __sdhci_execute_tuning(host, opcode);
err = __sdhci_execute_tuning(host, opcode);
host->tuning_err = err;

sdhci_end_tuning(host);
out:
Expand Down Expand Up @@ -3473,12 +3473,18 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
host->data->error = -EILSEQ;
if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
sdhci_err_stats_inc(host, DAT_CRC);
} else if ((intmask & SDHCI_INT_DATA_CRC) &&
} else if ((intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) &&
SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
!= MMC_BUS_TEST_R) {
host->data->error = -EILSEQ;
if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
sdhci_err_stats_inc(host, DAT_CRC);
if (intmask & SDHCI_INT_TUNING_ERROR) {
u16 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);

ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
}
} else if (intmask & SDHCI_INT_ADMA_ERROR) {
pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc),
intmask);
Expand Down Expand Up @@ -3625,24 +3631,6 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if (intmask & SDHCI_INT_RETUNE)
mmc_retune_needed(host->mmc);

if (intmask & SDHCI_INT_TUNING_ERR) {
u16 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
/*
* Only complain and retune if we're actually using the
* host's tuning circuits.
*/
if (ctrl2 & SDHCI_CTRL_TUNED_CLK) {
sdhci_writew(host,
ctrl2 & ~SDHCI_CTRL_TUNED_CLK,
SDHCI_HOST_CONTROL2);
mmc_retune_recheck(host->mmc);
pr_err("%s: Unrecoverable error in tuning circuit\n",
mmc_hostname(host->mmc));
}
sdhci_writel(host, SDHCI_INT_TUNING_ERR,
SDHCI_INT_STATUS);
}

if ((intmask & SDHCI_INT_CARD_INT) &&
(host->ier & SDHCI_INT_CARD_INT)) {
sdhci_enable_sdio_irq_nolock(host, false);
Expand All @@ -3652,8 +3640,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
SDHCI_INT_RETUNE | SDHCI_INT_TUNING_ERR |
SDHCI_INT_CARD_INT);
SDHCI_INT_RETUNE | SDHCI_INT_CARD_INT);

if (intmask) {
unexpected |= intmask;
Expand Down Expand Up @@ -4032,7 +4019,7 @@ bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
} else
*cmd_error = 0;

if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) {
if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) {
*data_error = -EILSEQ;
if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
sdhci_err_stats_inc(host, DAT_CRC);
Expand Down
4 changes: 2 additions & 2 deletions drivers/mmc/host/sdhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
#define SDHCI_INT_BUS_POWER 0x00800000
#define SDHCI_INT_AUTO_CMD_ERR 0x01000000
#define SDHCI_INT_ADMA_ERROR 0x02000000
#define SDHCI_INT_TUNING_ERR 0x04000000
#define SDHCI_INT_TUNING_ERROR 0x04000000

#define SDHCI_INT_NORMAL_MASK 0x00007FFF
#define SDHCI_INT_ERROR_MASK 0xFFFF8000
Expand All @@ -163,7 +163,7 @@
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \
SDHCI_INT_BLK_GAP)
SDHCI_INT_BLK_GAP | SDHCI_INT_TUNING_ERROR)
#define SDHCI_INT_ALL_MASK ((unsigned int)-1)

#define SDHCI_CQE_INT_ERR_MASK ( \
Expand Down