diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/sd.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index fb18b301502e..ae54e8eb7fea 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -183,16 +183,13 @@ static void mmc_decode_scr(struct mmc_card *card) | |||
183 | } | 183 | } |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * Test if the card supports high-speed mode and, if so, switch to it. | 186 | * Fetches and decodes switch information |
187 | */ | 187 | */ |
188 | static int mmc_switch_hs(struct mmc_card *card) | 188 | static int mmc_read_switch(struct mmc_card *card) |
189 | { | 189 | { |
190 | int err; | 190 | int err; |
191 | u8 *status; | 191 | u8 *status; |
192 | 192 | ||
193 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
194 | return MMC_ERR_NONE; | ||
195 | |||
196 | err = MMC_ERR_FAILED; | 193 | err = MMC_ERR_FAILED; |
197 | 194 | ||
198 | status = kmalloc(64, GFP_KERNEL); | 195 | status = kmalloc(64, GFP_KERNEL); |
@@ -209,14 +206,43 @@ static int mmc_switch_hs(struct mmc_card *card) | |||
209 | * Card not supporting high-speed will ignore the | 206 | * Card not supporting high-speed will ignore the |
210 | * command. | 207 | * command. |
211 | */ | 208 | */ |
212 | if (err == MMC_ERR_TIMEOUT) | 209 | err = MMC_ERR_NONE; |
213 | err = MMC_ERR_NONE; | ||
214 | goto out; | 210 | goto out; |
215 | } | 211 | } |
216 | 212 | ||
217 | if (status[13] & 0x02) | 213 | if (status[13] & 0x02) |
218 | card->sw_caps.hs_max_dtr = 50000000; | 214 | card->sw_caps.hs_max_dtr = 50000000; |
219 | 215 | ||
216 | out: | ||
217 | kfree(status); | ||
218 | |||
219 | return err; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Test if the card supports high-speed mode and, if so, switch to it. | ||
224 | */ | ||
225 | static int mmc_switch_hs(struct mmc_card *card) | ||
226 | { | ||
227 | int err; | ||
228 | u8 *status; | ||
229 | |||
230 | if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) | ||
231 | return MMC_ERR_NONE; | ||
232 | |||
233 | if (card->sw_caps.hs_max_dtr == 0) | ||
234 | return MMC_ERR_NONE; | ||
235 | |||
236 | err = MMC_ERR_FAILED; | ||
237 | |||
238 | status = kmalloc(64, GFP_KERNEL); | ||
239 | if (!status) { | ||
240 | printk("%s: could not allocate a buffer for switch " | ||
241 | "capabilities.\n", | ||
242 | mmc_hostname(card->host)); | ||
243 | return err; | ||
244 | } | ||
245 | |||
220 | err = mmc_sd_switch(card, 1, 0, 1, status); | 246 | err = mmc_sd_switch(card, 1, 0, 1, status); |
221 | if (err != MMC_ERR_NONE) | 247 | if (err != MMC_ERR_NONE) |
222 | goto out; | 248 | goto out; |
@@ -393,7 +419,14 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
393 | mmc_decode_scr(card); | 419 | mmc_decode_scr(card); |
394 | 420 | ||
395 | /* | 421 | /* |
396 | * Check if card can be switched into high-speed mode. | 422 | * Fetch switch information from card. |
423 | */ | ||
424 | err = mmc_read_switch(card); | ||
425 | if (err != MMC_ERR_NONE) | ||
426 | goto free_card; | ||
427 | |||
428 | /* | ||
429 | * Attempt to change to high-speed (if supported) | ||
397 | */ | 430 | */ |
398 | err = mmc_switch_hs(card); | 431 | err = mmc_switch_hs(card); |
399 | if (err != MMC_ERR_NONE) | 432 | if (err != MMC_ERR_NONE) |