Commit d617c426a6ef8d731da1936bca7649a1574d5420

Authored by Jan Kloetzke
Committed by Andy Fleming
1 parent 93ad0d18c0

mmc: make mmc_send_status() more reliable

Align the card status polling with the Linux kernel and retry the
command at least five times. Also some cards apparently mishandle the
status bits, so make sure to check the card state too.

Signed-off-by: Jan Kloetzke <jan.kloetzke@dspg.com>
Cc: Andy Fleming <afleming@gmail.com>

Showing 2 changed files with 14 additions and 8 deletions Side-by-side Diff

... ... @@ -108,7 +108,7 @@
108 108 int mmc_send_status(struct mmc *mmc, int timeout)
109 109 {
110 110 struct mmc_cmd cmd;
111   - int err;
  111 + int err, retries = 5;
112 112 #ifdef CONFIG_MMC_TRACE
113 113 int status;
114 114 #endif
115 115  
116 116  
... ... @@ -121,17 +121,21 @@
121 121  
122 122 do {
123 123 err = mmc_send_cmd(mmc, &cmd, NULL);
124   - if (err)
  124 + if (!err) {
  125 + if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
  126 + (cmd.response[0] & MMC_STATUS_CURR_STATE) !=
  127 + MMC_STATE_PRG)
  128 + break;
  129 + else if (cmd.response[0] & MMC_STATUS_MASK) {
  130 + printf("Status Error: 0x%08X\n",
  131 + cmd.response[0]);
  132 + return COMM_ERR;
  133 + }
  134 + } else if (--retries < 0)
125 135 return err;
126   - else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
127   - break;
128 136  
129 137 udelay(1000);
130 138  
131   - if (cmd.response[0] & MMC_STATUS_MASK) {
132   - printf("Status Error: 0x%08X\n", cmd.response[0]);
133   - return COMM_ERR;
134   - }
135 139 } while (timeout--);
136 140  
137 141 #ifdef CONFIG_MMC_TRACE
... ... @@ -112,6 +112,8 @@
112 112 #define MMC_STATUS_CURR_STATE (0xf << 9)
113 113 #define MMC_STATUS_ERROR (1 << 19)
114 114  
  115 +#define MMC_STATE_PRG (7 << 9)
  116 +
115 117 #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
116 118 #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
117 119 #define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */