diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0415-bcm2835-sdhost-Improvements-to-error-recovery.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.4/0415-bcm2835-sdhost-Improvements-to-error-recovery.patch | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0415-bcm2835-sdhost-Improvements-to-error-recovery.patch b/target/linux/brcm2708/patches-4.4/0415-bcm2835-sdhost-Improvements-to-error-recovery.patch deleted file mode 100644 index 88d9d4db50..0000000000 --- a/target/linux/brcm2708/patches-4.4/0415-bcm2835-sdhost-Improvements-to-error-recovery.patch +++ /dev/null @@ -1,312 +0,0 @@ -From edeb743e7562d9fa4d5f19c557bf558036031973 Mon Sep 17 00:00:00 2001 -From: Phil Elwell <phil@raspberrypi.org> -Date: Wed, 15 Jun 2016 17:13:55 +0100 -Subject: [PATCH] bcm2835-sdhost: Improvements to error recovery - -1) Try to avoid reducing overclock when a card is removed. - -2) Reset overclock on card insertion. - -3) Reduce logging when errors occur, lowering the severity of - some messages and making others conditional on the debug - flag. - -4) Attempt to identify a disconnected SD bus earlier, treating a - zero returned OCR (voltage support) as an error condition. - -Signed-off-by: Phil Elwell <phil@raspberrypi.org> ---- - drivers/mmc/host/bcm2835-sdhost.c | 117 ++++++++++++++++++++++++-------------- - 1 file changed, 74 insertions(+), 43 deletions(-) - ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -38,6 +38,7 @@ - #include <linux/mmc/mmc.h> - #include <linux/mmc/host.h> - #include <linux/mmc/sd.h> -+#include <linux/mmc/sdio.h> - #include <linux/scatterlist.h> - #include <linux/of_address.h> - #include <linux/of_irq.h> -@@ -206,6 +207,7 @@ struct bcm2835_host { - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 delay_after_this_stop; /* minimum time between this stop and subsequent data transfer */ -+ u32 user_overclock_50; /* User's preferred frequency to use when 50MHz is requested (in MHz) */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - u32 overclock; /* Current frequency if overclocked, else zero */ - u32 pio_limit; /* Maximum block count for PIO (0 = always DMA) */ -@@ -282,7 +284,7 @@ static void log_dump(void) - do { - entry = sdhost_log_buf + idx; - if (entry->event[0] != '\0') -- pr_err("[%08x] %.4s %x %x\n", -+ pr_info("[%08x] %.4s %x %x\n", - entry->timestamp, - entry->event, - entry->param1, -@@ -324,7 +326,7 @@ static void bcm2835_sdhost_dumpcmd(struc - const char *label) - { - if (cmd) -- pr_err("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", -+ pr_info("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n", - mmc_hostname(host->mmc), - (cmd == host->cmd) ? '>' : ' ', - label, cmd->opcode, cmd->arg, cmd->flags, -@@ -339,7 +341,7 @@ static void bcm2835_sdhost_dumpregs(stru - bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc"); - bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd"); - if (host->mrq->data) -- pr_err("%s: data blocks %x blksz %x - err %d\n", -+ pr_info("%s: data blocks %x blksz %x - err %d\n", - mmc_hostname(host->mmc), - host->mrq->data->blocks, - host->mrq->data->blksz, -@@ -347,53 +349,53 @@ static void bcm2835_sdhost_dumpregs(stru - bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop"); - } - -- pr_err("%s: =========== REGISTER DUMP ===========\n", -+ pr_info("%s: =========== REGISTER DUMP ===========\n", - mmc_hostname(host->mmc)); - -- pr_err("%s: SDCMD 0x%08x\n", -+ pr_info("%s: SDCMD 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCMD)); -- pr_err("%s: SDARG 0x%08x\n", -+ pr_info("%s: SDARG 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDARG)); -- pr_err("%s: SDTOUT 0x%08x\n", -+ pr_info("%s: SDTOUT 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDTOUT)); -- pr_err("%s: SDCDIV 0x%08x\n", -+ pr_info("%s: SDCDIV 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDCDIV)); -- pr_err("%s: SDRSP0 0x%08x\n", -+ pr_info("%s: SDRSP0 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP0)); -- pr_err("%s: SDRSP1 0x%08x\n", -+ pr_info("%s: SDRSP1 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP1)); -- pr_err("%s: SDRSP2 0x%08x\n", -+ pr_info("%s: SDRSP2 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP2)); - pr_err("%s: SDRSP3 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDRSP3)); -- pr_err("%s: SDHSTS 0x%08x\n", -+ pr_info("%s: SDHSTS 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHSTS)); -- pr_err("%s: SDVDD 0x%08x\n", -+ pr_info("%s: SDVDD 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDVDD)); -- pr_err("%s: SDEDM 0x%08x\n", -+ pr_info("%s: SDEDM 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDEDM)); -- pr_err("%s: SDHCFG 0x%08x\n", -+ pr_info("%s: SDHCFG 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHCFG)); -- pr_err("%s: SDHBCT 0x%08x\n", -+ pr_info("%s: SDHBCT 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBCT)); -- pr_err("%s: SDHBLC 0x%08x\n", -+ pr_info("%s: SDHBLC 0x%08x\n", - mmc_hostname(host->mmc), - bcm2835_sdhost_read(host, SDHBLC)); - -- pr_err("%s: ===========================================\n", -+ pr_info("%s: ===========================================\n", - mmc_hostname(host->mmc)); - } - -@@ -608,7 +610,7 @@ static void bcm2835_sdhost_read_block_pi - (fsm_state != SDEDM_FSM_READCRC)) { - hsts = bcm2835_sdhost_read(host, - SDHSTS); -- pr_err("%s: fsm %x, hsts %x\n", -+ pr_info("%s: fsm %x, hsts %x\n", - mmc_hostname(host->mmc), - fsm_state, hsts); - if (hsts & SDHSTS_ERROR_MASK) -@@ -698,7 +700,7 @@ static void bcm2835_sdhost_write_block_p - (fsm_state != SDEDM_FSM_WRITESTART2)) { - hsts = bcm2835_sdhost_read(host, - SDHSTS); -- pr_err("%s: fsm %x, hsts %x\n", -+ pr_info("%s: fsm %x, hsts %x\n", - mmc_hostname(host->mmc), - fsm_state, hsts); - if (hsts & SDHSTS_ERROR_MASK) -@@ -953,9 +955,10 @@ bool bcm2835_sdhost_send_command(struct - - while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { - if (timeout == 0) { -- pr_err("%s: previous command never completed.\n", -+ pr_warn("%s: previous command never completed.\n", - mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -+ if (host->debug) -+ bcm2835_sdhost_dumpregs(host); - cmd->error = -EILSEQ; - tasklet_schedule(&host->finish_tasklet); - return false; -@@ -1213,10 +1216,12 @@ static void bcm2835_sdhost_finish_comman - - /* Check for errors */ - if (sdcmd & SDCMD_NEW_FLAG) { -- pr_err("%s: command never completed.\n", -- mmc_hostname(host->mmc)); -- bcm2835_sdhost_dumpregs(host); -- host->cmd->error = -EIO; -+ if (host->debug) { -+ pr_err("%s: command %d never completed.\n", -+ mmc_hostname(host->mmc), host->cmd->opcode); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ host->cmd->error = -EILSEQ; - tasklet_schedule(&host->finish_tasklet); - return; - } else if (sdcmd & SDCMD_FAIL_FLAG) { -@@ -1238,15 +1243,14 @@ static void bcm2835_sdhost_finish_comman - } else { - if (sdhsts & SDHSTS_CMD_TIME_OUT) { - if (host->debug) -- pr_err("%s: command %d timeout\n", -+ pr_warn("%s: command %d timeout\n", - mmc_hostname(host->mmc), - host->cmd->opcode); - host->cmd->error = -ETIMEDOUT; - } else { -- pr_err("%s: unexpected command %d error\n", -+ pr_warn("%s: unexpected command %d error\n", - mmc_hostname(host->mmc), - host->cmd->opcode); -- bcm2835_sdhost_dumpregs(host); - host->cmd->error = -EILSEQ; - } - tasklet_schedule(&host->finish_tasklet); -@@ -1370,8 +1374,10 @@ static void bcm2835_sdhost_busy_irq(stru - } else if (intmask & SDHSTS_CMD_TIME_OUT) - host->cmd->error = -ETIMEDOUT; - -- log_dump(); -- bcm2835_sdhost_dumpregs(host); -+ if (host->debug) { -+ log_dump(); -+ bcm2835_sdhost_dumpregs(host); -+ } - } - else - bcm2835_sdhost_finish_command(host, NULL); -@@ -1595,7 +1601,7 @@ void bcm2835_sdhost_set_clock(struct bcm - host->overclock_50 = (clock/MHZ); - - if (clock != host->overclock) { -- pr_warn("%s: overclocking to %dHz\n", -+ pr_info("%s: overclocking to %dHz\n", - mmc_hostname(host->mmc), clock); - host->overclock = clock; - } -@@ -1605,6 +1611,11 @@ void bcm2835_sdhost_set_clock(struct bcm - pr_warn("%s: cancelling overclock\n", - mmc_hostname(host->mmc)); - } -+ } else if (input_clock == 0) { -+ /* Reset the preferred overclock when the clock is stopped. -+ * This always happens during initialisation. */ -+ host->overclock_50 = host->user_overclock_50; -+ host->overclock = 0; - } - - /* Set the timeout to 500ms */ -@@ -1678,13 +1689,15 @@ static void bcm2835_sdhost_request(struc - log_event("REQ<", (u32)mrq, edm); - if ((fsm != SDEDM_FSM_IDENTMODE) && - (fsm != SDEDM_FSM_DATAMODE)) { -- pr_err("%s: previous command (%d) not complete (EDM %x)\n", -- mmc_hostname(host->mmc), -- bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK, -- edm); - log_event("REQ!", (u32)mrq, edm); -- log_dump(); -- bcm2835_sdhost_dumpregs(host); -+ if (host->debug) { -+ pr_warn("%s: previous command (%d) not complete (EDM %x)\n", -+ mmc_hostname(host->mmc), -+ bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK, -+ edm); -+ log_dump(); -+ bcm2835_sdhost_dumpregs(host); -+ } - mrq->cmd->error = -EILSEQ; - tasklet_schedule(&host->finish_tasklet); - mmiowb(); -@@ -1814,16 +1827,19 @@ static void bcm2835_sdhost_tasklet_finis - mrq = host->mrq; - - /* Drop the overclock after any data corruption, or after any -- error overclocked */ -+ * error while overclocked. Ignore errors for status commands, -+ * as they are likely when a card is ejected. */ - if (host->overclock) { -- if ((mrq->cmd && mrq->cmd->error) || -+ if ((mrq->cmd && mrq->cmd->error && -+ (mrq->cmd->opcode != MMC_SEND_STATUS)) || - (mrq->data && mrq->data->error) || -- (mrq->stop && mrq->stop->error)) { -+ (mrq->stop && mrq->stop->error) || -+ (mrq->sbc && mrq->sbc->error)) { - host->overclock_50--; - pr_warn("%s: reducing overclock due to errors\n", - mmc_hostname(host->mmc)); - host->reset_clock = 1; -- mrq->cmd->error = -EILSEQ; -+ mrq->cmd->error = -ETIMEDOUT; - mrq->cmd->retries = 1; - } - } -@@ -1848,6 +1864,21 @@ static void bcm2835_sdhost_tasklet_finis - mmc_hostname(host->mmc), err); - } - -+ /* The SDHOST block doesn't report any errors for a disconnected -+ interface. All cards and SDIO devices should report some supported -+ voltage range, so a zero response to SEND_OP_COND, IO_SEND_OP_COND -+ or APP_SEND_OP_COND can be treated as an error. */ -+ if (((mrq->cmd->opcode == MMC_SEND_OP_COND) || -+ (mrq->cmd->opcode == SD_IO_SEND_OP_COND) || -+ (mrq->cmd->opcode == SD_APP_OP_COND)) && -+ (mrq->cmd->error == 0) && -+ (mrq->cmd->resp[0] == 0)) { -+ mrq->cmd->error = -ETIMEDOUT; -+ if (host->debug) -+ pr_info("%s: faking timeout due to zero OCR\n", -+ mmc_hostname(host->mmc)); -+ } -+ - mmc_request_done(host->mmc, mrq); - log_event("TSK>", (u32)mrq, 0); - } -@@ -2023,7 +2054,7 @@ static int bcm2835_sdhost_probe(struct p - &host->delay_after_stop); - of_property_read_u32(node, - "brcm,overclock-50", -- &host->overclock_50); -+ &host->user_overclock_50); - of_property_read_u32(node, - "brcm,pio-limit", - &host->pio_limit); |