mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
Merge "mmc: sdhci: Dump registers in case of DATA CRC/timeout errors"
This commit is contained in:
commit
6c2909cd85
2 changed files with 57 additions and 3 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue