Merge "mmc: sdhci: Dump registers in case of DATA CRC/timeout errors"

This commit is contained in:
qctecmdr 2022-01-02 20:11:32 -08:00 • committed by Gerrit - the friendly Code Review server
commit 6c2909cd85
2 changed files with 57 additions and 3 deletions

View file

@ -43,6 +43,11 @@
#define MAX_TUNING_LOOP 40
#if defined(CONFIG_SDC_QTI)
#define SDHCI_DBG_DUMP_RS_INTERVAL (10 * HZ)
#define SDHCI_DBG_DUMP_RS_BURST 2
#endif
static unsigned int debug_quirks = 0;
static unsigned int debug_quirks2;
@ -1486,6 +1491,10 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
timeout += 10 * HZ;
sdhci_mod_timer(host, cmd->mrq, timeout);
#if defined(CONFIG_SDC_QTI)
if (cmd->data)
host->data_start_time = ktime_get();
#endif
sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
mmc_log_string(host->mmc,
"updated ARGUMENT=0x%08x ARGUMENT_MODE=0x%08x COMMAND=0x%08x\n",
@ -3127,6 +3136,10 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
{
u32 command;
#if defined(CONFIG_SDC_QTI)
bool pr_msg = false;
#endif
/* CMD19 generates _only_ Buffer Read Ready interrupt */
if (intmask & SDHCI_INT_DATA_AVAIL) {
command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
@ -3217,9 +3230,41 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
host->ops->adma_workaround(host, intmask);
}
if (host->data->error)
if (host->data->error) {
#if defined(CONFIG_SDC_QTI)
if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT
| SDHCI_INT_DATA_END_BIT)) {
command = SDHCI_GET_CMD(sdhci_readw(host,
SDHCI_COMMAND));
if ((command != MMC_SEND_TUNING_BLOCK_HS200) &&
(command != MMC_SEND_TUNING_BLOCK))
pr_msg = true;
} else {
pr_msg = true;
}
if (host->mmc->ops->get_cd &&
!host->mmc->ops->get_cd(host->mmc)) {
pr_msg = false;
pr_err("%s: Got data error(%d) during card removal\n",
mmc_hostname(host->mmc), host->data->error);
}
if (pr_msg && __ratelimit(&host->dbg_dump_rs)) {
pr_err("%s: data txfr (0x%08x) error: %d after %lld ms\n",
mmc_hostname(host->mmc), intmask,
host->data->error, ktime_to_ms(ktime_sub(
ktime_get(), host->data_start_time)));
mmc_log_string(host->mmc,
"data txfr (0x%08x) error: %d after %lld ms\n",
intmask, host->data->error,
ktime_to_ms(ktime_sub(ktime_get(),
host->data_start_time)));
sdhci_dumpregs(host);
}
#endif
sdhci_finish_data(host);
else {
} else {
if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
sdhci_transfer_pio(host);
@ -3830,6 +3875,11 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
*/
host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1;
#if defined(CONFIG_SDC_QTI)
ratelimit_state_init(&host->dbg_dump_rs, SDHCI_DBG_DUMP_RS_INTERVAL,
SDHCI_DBG_DUMP_RS_BURST);
#endif
return host;
}

View file

@ -15,7 +15,7 @@
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/interrupt.h>
#include <linux/ratelimit.h>
#include <linux/mmc/host.h>
/*
@ -616,6 +616,10 @@ struct sdhci_host {
u64 data_timeout;
#if defined(CONFIG_SDC_QTI)
ktime_t data_start_time;
struct ratelimit_state dbg_dump_rs;
#endif
unsigned long private[0] ____cacheline_aligned;
};