brcm2708: update linux 4.4 patches to latest version
[openwrt/staging/yousong.git] / target / linux / brcm2708 / patches-4.4 / 0416-bcm2835-sdhost-Improvements-to-error-recovery.patch
diff --git a/target/linux/brcm2708/patches-4.4/0416-bcm2835-sdhost-Improvements-to-error-recovery.patch b/target/linux/brcm2708/patches-4.4/0416-bcm2835-sdhost-Improvements-to-error-recovery.patch
deleted file mode 100644 (file)
index 0437931..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-From d90c379ffd993c72371252fe7840c14e4428410b 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);