diff options
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r-- | drivers/mmc/core/mmc.c | 287 |
1 files changed, 264 insertions, 23 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 5700b1cbdfec..36270449dd9d 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -101,7 +101,7 @@ static int mmc_decode_cid(struct mmc_card *card) | |||
101 | break; | 101 | break; |
102 | 102 | ||
103 | default: | 103 | default: |
104 | printk(KERN_ERR "%s: card has unknown MMCA version %d\n", | 104 | pr_err("%s: card has unknown MMCA version %d\n", |
105 | mmc_hostname(card->host), card->csd.mmca_vsn); | 105 | mmc_hostname(card->host), card->csd.mmca_vsn); |
106 | return -EINVAL; | 106 | return -EINVAL; |
107 | } | 107 | } |
@@ -135,7 +135,7 @@ static int mmc_decode_csd(struct mmc_card *card) | |||
135 | */ | 135 | */ |
136 | csd->structure = UNSTUFF_BITS(resp, 126, 2); | 136 | csd->structure = UNSTUFF_BITS(resp, 126, 2); |
137 | if (csd->structure == 0) { | 137 | if (csd->structure == 0) { |
138 | printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", | 138 | pr_err("%s: unrecognised CSD structure version %d\n", |
139 | mmc_hostname(card->host), csd->structure); | 139 | mmc_hostname(card->host), csd->structure); |
140 | return -EINVAL; | 140 | return -EINVAL; |
141 | } | 141 | } |
@@ -195,7 +195,7 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) | |||
195 | */ | 195 | */ |
196 | ext_csd = kmalloc(512, GFP_KERNEL); | 196 | ext_csd = kmalloc(512, GFP_KERNEL); |
197 | if (!ext_csd) { | 197 | if (!ext_csd) { |
198 | printk(KERN_ERR "%s: could not allocate a buffer to " | 198 | pr_err("%s: could not allocate a buffer to " |
199 | "receive the ext_csd.\n", mmc_hostname(card->host)); | 199 | "receive the ext_csd.\n", mmc_hostname(card->host)); |
200 | return -ENOMEM; | 200 | return -ENOMEM; |
201 | } | 201 | } |
@@ -217,12 +217,12 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) | |||
217 | * stored in their CSD. | 217 | * stored in their CSD. |
218 | */ | 218 | */ |
219 | if (card->csd.capacity == (4096 * 512)) { | 219 | if (card->csd.capacity == (4096 * 512)) { |
220 | printk(KERN_ERR "%s: unable to read EXT_CSD " | 220 | pr_err("%s: unable to read EXT_CSD " |
221 | "on a possible high capacity card. " | 221 | "on a possible high capacity card. " |
222 | "Card will be ignored.\n", | 222 | "Card will be ignored.\n", |
223 | mmc_hostname(card->host)); | 223 | mmc_hostname(card->host)); |
224 | } else { | 224 | } else { |
225 | printk(KERN_WARNING "%s: unable to read " | 225 | pr_warning("%s: unable to read " |
226 | "EXT_CSD, performance might " | 226 | "EXT_CSD, performance might " |
227 | "suffer.\n", | 227 | "suffer.\n", |
228 | mmc_hostname(card->host)); | 228 | mmc_hostname(card->host)); |
@@ -239,7 +239,9 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) | |||
239 | */ | 239 | */ |
240 | static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | 240 | static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) |
241 | { | 241 | { |
242 | int err = 0; | 242 | int err = 0, idx; |
243 | unsigned int part_size; | ||
244 | u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0; | ||
243 | 245 | ||
244 | BUG_ON(!card); | 246 | BUG_ON(!card); |
245 | 247 | ||
@@ -250,7 +252,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
250 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; | 252 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; |
251 | if (card->csd.structure == 3) { | 253 | if (card->csd.structure == 3) { |
252 | if (card->ext_csd.raw_ext_csd_structure > 2) { | 254 | if (card->ext_csd.raw_ext_csd_structure > 2) { |
253 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | 255 | pr_err("%s: unrecognised EXT_CSD structure " |
254 | "version %d\n", mmc_hostname(card->host), | 256 | "version %d\n", mmc_hostname(card->host), |
255 | card->ext_csd.raw_ext_csd_structure); | 257 | card->ext_csd.raw_ext_csd_structure); |
256 | err = -EINVAL; | 258 | err = -EINVAL; |
@@ -260,7 +262,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
260 | 262 | ||
261 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; | 263 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; |
262 | if (card->ext_csd.rev > 6) { | 264 | if (card->ext_csd.rev > 6) { |
263 | printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n", | 265 | pr_err("%s: unrecognised EXT_CSD revision %d\n", |
264 | mmc_hostname(card->host), card->ext_csd.rev); | 266 | mmc_hostname(card->host), card->ext_csd.rev); |
265 | err = -EINVAL; | 267 | err = -EINVAL; |
266 | goto out; | 268 | goto out; |
@@ -306,7 +308,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
306 | break; | 308 | break; |
307 | default: | 309 | default: |
308 | /* MMC v4 spec says this cannot happen */ | 310 | /* MMC v4 spec says this cannot happen */ |
309 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " | 311 | pr_warning("%s: card is mmc v4 but doesn't " |
310 | "support any high-speed modes.\n", | 312 | "support any high-speed modes.\n", |
311 | mmc_hostname(card->host)); | 313 | mmc_hostname(card->host)); |
312 | } | 314 | } |
@@ -340,7 +342,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
340 | * There are two boot regions of equal size, defined in | 342 | * There are two boot regions of equal size, defined in |
341 | * multiples of 128K. | 343 | * multiples of 128K. |
342 | */ | 344 | */ |
343 | card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; | 345 | if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) { |
346 | for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) { | ||
347 | part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; | ||
348 | mmc_part_add(card, part_size, | ||
349 | EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, | ||
350 | "boot%d", idx, true); | ||
351 | } | ||
352 | } | ||
344 | } | 353 | } |
345 | 354 | ||
346 | card->ext_csd.raw_hc_erase_gap_size = | 355 | card->ext_csd.raw_hc_erase_gap_size = |
@@ -359,11 +368,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
359 | * card has the Enhanced area enabled. If so, export enhanced | 368 | * card has the Enhanced area enabled. If so, export enhanced |
360 | * area offset and size to user by adding sysfs interface. | 369 | * area offset and size to user by adding sysfs interface. |
361 | */ | 370 | */ |
371 | card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; | ||
362 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && | 372 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && |
363 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { | 373 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { |
364 | u8 hc_erase_grp_sz = | 374 | hc_erase_grp_sz = |
365 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | 375 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; |
366 | u8 hc_wp_grp_sz = | 376 | hc_wp_grp_sz = |
367 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; | 377 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; |
368 | 378 | ||
369 | card->ext_csd.enhanced_area_en = 1; | 379 | card->ext_csd.enhanced_area_en = 1; |
@@ -392,6 +402,41 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
392 | card->ext_csd.enhanced_area_offset = -EINVAL; | 402 | card->ext_csd.enhanced_area_offset = -EINVAL; |
393 | card->ext_csd.enhanced_area_size = -EINVAL; | 403 | card->ext_csd.enhanced_area_size = -EINVAL; |
394 | } | 404 | } |
405 | |||
406 | /* | ||
407 | * General purpose partition feature support -- | ||
408 | * If ext_csd has the size of general purpose partitions, | ||
409 | * set size, part_cfg, partition name in mmc_part. | ||
410 | */ | ||
411 | if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & | ||
412 | EXT_CSD_PART_SUPPORT_PART_EN) { | ||
413 | if (card->ext_csd.enhanced_area_en != 1) { | ||
414 | hc_erase_grp_sz = | ||
415 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | ||
416 | hc_wp_grp_sz = | ||
417 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; | ||
418 | |||
419 | card->ext_csd.enhanced_area_en = 1; | ||
420 | } | ||
421 | |||
422 | for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { | ||
423 | if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && | ||
424 | !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && | ||
425 | !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) | ||
426 | continue; | ||
427 | part_size = | ||
428 | (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] | ||
429 | << 16) + | ||
430 | (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] | ||
431 | << 8) + | ||
432 | ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; | ||
433 | part_size *= (size_t)(hc_erase_grp_sz * | ||
434 | hc_wp_grp_sz); | ||
435 | mmc_part_add(card, part_size << 19, | ||
436 | EXT_CSD_PART_CONFIG_ACC_GP0 + idx, | ||
437 | "gp%d", idx, false); | ||
438 | } | ||
439 | } | ||
395 | card->ext_csd.sec_trim_mult = | 440 | card->ext_csd.sec_trim_mult = |
396 | ext_csd[EXT_CSD_SEC_TRIM_MULT]; | 441 | ext_csd[EXT_CSD_SEC_TRIM_MULT]; |
397 | card->ext_csd.sec_erase_mult = | 442 | card->ext_csd.sec_erase_mult = |
@@ -402,14 +447,48 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
402 | ext_csd[EXT_CSD_TRIM_MULT]; | 447 | ext_csd[EXT_CSD_TRIM_MULT]; |
403 | } | 448 | } |
404 | 449 | ||
405 | if (card->ext_csd.rev >= 5) | 450 | if (card->ext_csd.rev >= 5) { |
451 | /* check whether the eMMC card supports HPI */ | ||
452 | if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { | ||
453 | card->ext_csd.hpi = 1; | ||
454 | if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x2) | ||
455 | card->ext_csd.hpi_cmd = MMC_STOP_TRANSMISSION; | ||
456 | else | ||
457 | card->ext_csd.hpi_cmd = MMC_SEND_STATUS; | ||
458 | /* | ||
459 | * Indicate the maximum timeout to close | ||
460 | * a command interrupted by HPI | ||
461 | */ | ||
462 | card->ext_csd.out_of_int_time = | ||
463 | ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] * 10; | ||
464 | } | ||
465 | |||
406 | card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; | 466 | card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM]; |
467 | card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; | ||
468 | } | ||
407 | 469 | ||
470 | card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; | ||
408 | if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) | 471 | if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) |
409 | card->erased_byte = 0xFF; | 472 | card->erased_byte = 0xFF; |
410 | else | 473 | else |
411 | card->erased_byte = 0x0; | 474 | card->erased_byte = 0x0; |
412 | 475 | ||
476 | /* eMMC v4.5 or later */ | ||
477 | if (card->ext_csd.rev >= 6) { | ||
478 | card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; | ||
479 | |||
480 | card->ext_csd.generic_cmd6_time = 10 * | ||
481 | ext_csd[EXT_CSD_GENERIC_CMD6_TIME]; | ||
482 | card->ext_csd.power_off_longtime = 10 * | ||
483 | ext_csd[EXT_CSD_POWER_OFF_LONG_TIME]; | ||
484 | |||
485 | card->ext_csd.cache_size = | ||
486 | ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 | | ||
487 | ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | | ||
488 | ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | | ||
489 | ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; | ||
490 | } | ||
491 | |||
413 | out: | 492 | out: |
414 | return err; | 493 | return err; |
415 | } | 494 | } |
@@ -530,6 +609,86 @@ static struct device_type mmc_type = { | |||
530 | }; | 609 | }; |
531 | 610 | ||
532 | /* | 611 | /* |
612 | * Select the PowerClass for the current bus width | ||
613 | * If power class is defined for 4/8 bit bus in the | ||
614 | * extended CSD register, select it by executing the | ||
615 | * mmc_switch command. | ||
616 | */ | ||
617 | static int mmc_select_powerclass(struct mmc_card *card, | ||
618 | unsigned int bus_width, u8 *ext_csd) | ||
619 | { | ||
620 | int err = 0; | ||
621 | unsigned int pwrclass_val; | ||
622 | unsigned int index = 0; | ||
623 | struct mmc_host *host; | ||
624 | |||
625 | BUG_ON(!card); | ||
626 | |||
627 | host = card->host; | ||
628 | BUG_ON(!host); | ||
629 | |||
630 | if (ext_csd == NULL) | ||
631 | return 0; | ||
632 | |||
633 | /* Power class selection is supported for versions >= 4.0 */ | ||
634 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
635 | return 0; | ||
636 | |||
637 | /* Power class values are defined only for 4/8 bit bus */ | ||
638 | if (bus_width == EXT_CSD_BUS_WIDTH_1) | ||
639 | return 0; | ||
640 | |||
641 | switch (1 << host->ios.vdd) { | ||
642 | case MMC_VDD_165_195: | ||
643 | if (host->ios.clock <= 26000000) | ||
644 | index = EXT_CSD_PWR_CL_26_195; | ||
645 | else if (host->ios.clock <= 52000000) | ||
646 | index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? | ||
647 | EXT_CSD_PWR_CL_52_195 : | ||
648 | EXT_CSD_PWR_CL_DDR_52_195; | ||
649 | else if (host->ios.clock <= 200000000) | ||
650 | index = EXT_CSD_PWR_CL_200_195; | ||
651 | break; | ||
652 | case MMC_VDD_32_33: | ||
653 | case MMC_VDD_33_34: | ||
654 | case MMC_VDD_34_35: | ||
655 | case MMC_VDD_35_36: | ||
656 | if (host->ios.clock <= 26000000) | ||
657 | index = EXT_CSD_PWR_CL_26_360; | ||
658 | else if (host->ios.clock <= 52000000) | ||
659 | index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? | ||
660 | EXT_CSD_PWR_CL_52_360 : | ||
661 | EXT_CSD_PWR_CL_DDR_52_360; | ||
662 | else if (host->ios.clock <= 200000000) | ||
663 | index = EXT_CSD_PWR_CL_200_360; | ||
664 | break; | ||
665 | default: | ||
666 | pr_warning("%s: Voltage range not supported " | ||
667 | "for power class.\n", mmc_hostname(host)); | ||
668 | return -EINVAL; | ||
669 | } | ||
670 | |||
671 | pwrclass_val = ext_csd[index]; | ||
672 | |||
673 | if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) | ||
674 | pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> | ||
675 | EXT_CSD_PWR_CL_8BIT_SHIFT; | ||
676 | else | ||
677 | pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_4BIT_MASK) >> | ||
678 | EXT_CSD_PWR_CL_4BIT_SHIFT; | ||
679 | |||
680 | /* If the power class is different from the default value */ | ||
681 | if (pwrclass_val > 0) { | ||
682 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
683 | EXT_CSD_POWER_CLASS, | ||
684 | pwrclass_val, | ||
685 | card->ext_csd.generic_cmd6_time); | ||
686 | } | ||
687 | |||
688 | return err; | ||
689 | } | ||
690 | |||
691 | /* | ||
533 | * Handle the detection and initialisation of a card. | 692 | * Handle the detection and initialisation of a card. |
534 | * | 693 | * |
535 | * In the case of a resume, "oldcard" will contain the card | 694 | * In the case of a resume, "oldcard" will contain the card |
@@ -548,11 +707,16 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
548 | BUG_ON(!host); | 707 | BUG_ON(!host); |
549 | WARN_ON(!host->claimed); | 708 | WARN_ON(!host->claimed); |
550 | 709 | ||
710 | /* Set correct bus mode for MMC before attempting init */ | ||
711 | if (!mmc_host_is_spi(host)) | ||
712 | mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); | ||
713 | |||
551 | /* | 714 | /* |
552 | * Since we're changing the OCR value, we seem to | 715 | * Since we're changing the OCR value, we seem to |
553 | * need to tell some cards to go back to the idle | 716 | * need to tell some cards to go back to the idle |
554 | * state. We wait 1ms to give cards time to | 717 | * state. We wait 1ms to give cards time to |
555 | * respond. | 718 | * respond. |
719 | * mmc_go_idle is needed for eMMC that are asleep | ||
556 | */ | 720 | */ |
557 | mmc_go_idle(host); | 721 | mmc_go_idle(host); |
558 | 722 | ||
@@ -668,7 +832,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
668 | */ | 832 | */ |
669 | if (card->ext_csd.enhanced_area_en) { | 833 | if (card->ext_csd.enhanced_area_en) { |
670 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 834 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
671 | EXT_CSD_ERASE_GROUP_DEF, 1, 0); | 835 | EXT_CSD_ERASE_GROUP_DEF, 1, |
836 | card->ext_csd.generic_cmd6_time); | ||
672 | 837 | ||
673 | if (err && err != -EBADMSG) | 838 | if (err && err != -EBADMSG) |
674 | goto free_card; | 839 | goto free_card; |
@@ -706,17 +871,35 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
706 | } | 871 | } |
707 | 872 | ||
708 | /* | 873 | /* |
874 | * If the host supports the power_off_notify capability then | ||
875 | * set the notification byte in the ext_csd register of device | ||
876 | */ | ||
877 | if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && | ||
878 | (card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) { | ||
879 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
880 | EXT_CSD_POWER_OFF_NOTIFICATION, | ||
881 | EXT_CSD_POWER_ON, | ||
882 | card->ext_csd.generic_cmd6_time); | ||
883 | if (err && err != -EBADMSG) | ||
884 | goto free_card; | ||
885 | } | ||
886 | |||
887 | if (!err) | ||
888 | card->poweroff_notify_state = MMC_POWERED_ON; | ||
889 | |||
890 | /* | ||
709 | * Activate high speed (if supported) | 891 | * Activate high speed (if supported) |
710 | */ | 892 | */ |
711 | if ((card->ext_csd.hs_max_dtr != 0) && | 893 | if ((card->ext_csd.hs_max_dtr != 0) && |
712 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | 894 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { |
713 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 895 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
714 | EXT_CSD_HS_TIMING, 1, 0); | 896 | EXT_CSD_HS_TIMING, 1, |
897 | card->ext_csd.generic_cmd6_time); | ||
715 | if (err && err != -EBADMSG) | 898 | if (err && err != -EBADMSG) |
716 | goto free_card; | 899 | goto free_card; |
717 | 900 | ||
718 | if (err) { | 901 | if (err) { |
719 | printk(KERN_WARNING "%s: switch to highspeed failed\n", | 902 | pr_warning("%s: switch to highspeed failed\n", |
720 | mmc_hostname(card->host)); | 903 | mmc_hostname(card->host)); |
721 | err = 0; | 904 | err = 0; |
722 | } else { | 905 | } else { |
@@ -726,6 +909,22 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
726 | } | 909 | } |
727 | 910 | ||
728 | /* | 911 | /* |
912 | * Enable HPI feature (if supported) | ||
913 | */ | ||
914 | if (card->ext_csd.hpi) { | ||
915 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
916 | EXT_CSD_HPI_MGMT, 1, 0); | ||
917 | if (err && err != -EBADMSG) | ||
918 | goto free_card; | ||
919 | if (err) { | ||
920 | pr_warning("%s: Enabling HPI failed\n", | ||
921 | mmc_hostname(card->host)); | ||
922 | err = 0; | ||
923 | } else | ||
924 | card->ext_csd.hpi_en = 1; | ||
925 | } | ||
926 | |||
927 | /* | ||
729 | * Compute bus speed. | 928 | * Compute bus speed. |
730 | */ | 929 | */ |
731 | max_dtr = (unsigned int)-1; | 930 | max_dtr = (unsigned int)-1; |
@@ -780,10 +979,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
780 | bus_width = bus_widths[idx]; | 979 | bus_width = bus_widths[idx]; |
781 | if (bus_width == MMC_BUS_WIDTH_1) | 980 | if (bus_width == MMC_BUS_WIDTH_1) |
782 | ddr = 0; /* no DDR for 1-bit width */ | 981 | ddr = 0; /* no DDR for 1-bit width */ |
982 | err = mmc_select_powerclass(card, ext_csd_bits[idx][0], | ||
983 | ext_csd); | ||
984 | if (err) | ||
985 | pr_err("%s: power class selection to " | ||
986 | "bus width %d failed\n", | ||
987 | mmc_hostname(card->host), | ||
988 | 1 << bus_width); | ||
989 | |||
783 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 990 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
784 | EXT_CSD_BUS_WIDTH, | 991 | EXT_CSD_BUS_WIDTH, |
785 | ext_csd_bits[idx][0], | 992 | ext_csd_bits[idx][0], |
786 | 0); | 993 | card->ext_csd.generic_cmd6_time); |
787 | if (!err) { | 994 | if (!err) { |
788 | mmc_set_bus_width(card->host, bus_width); | 995 | mmc_set_bus_width(card->host, bus_width); |
789 | 996 | ||
@@ -803,13 +1010,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
803 | } | 1010 | } |
804 | 1011 | ||
805 | if (!err && ddr) { | 1012 | if (!err && ddr) { |
1013 | err = mmc_select_powerclass(card, ext_csd_bits[idx][1], | ||
1014 | ext_csd); | ||
1015 | if (err) | ||
1016 | pr_err("%s: power class selection to " | ||
1017 | "bus width %d ddr %d failed\n", | ||
1018 | mmc_hostname(card->host), | ||
1019 | 1 << bus_width, ddr); | ||
1020 | |||
806 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1021 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
807 | EXT_CSD_BUS_WIDTH, | 1022 | EXT_CSD_BUS_WIDTH, |
808 | ext_csd_bits[idx][1], | 1023 | ext_csd_bits[idx][1], |
809 | 0); | 1024 | card->ext_csd.generic_cmd6_time); |
810 | } | 1025 | } |
811 | if (err) { | 1026 | if (err) { |
812 | printk(KERN_WARNING "%s: switch to bus width %d ddr %d " | 1027 | pr_warning("%s: switch to bus width %d ddr %d " |
813 | "failed\n", mmc_hostname(card->host), | 1028 | "failed\n", mmc_hostname(card->host), |
814 | 1 << bus_width, ddr); | 1029 | 1 << bus_width, ddr); |
815 | goto free_card; | 1030 | goto free_card; |
@@ -840,6 +1055,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
840 | } | 1055 | } |
841 | } | 1056 | } |
842 | 1057 | ||
1058 | /* | ||
1059 | * If cache size is higher than 0, this indicates | ||
1060 | * the existence of cache and it can be turned on. | ||
1061 | */ | ||
1062 | if ((host->caps2 & MMC_CAP2_CACHE_CTRL) && | ||
1063 | card->ext_csd.cache_size > 0) { | ||
1064 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
1065 | EXT_CSD_CACHE_CTRL, 1, 0); | ||
1066 | if (err && err != -EBADMSG) | ||
1067 | goto free_card; | ||
1068 | |||
1069 | /* | ||
1070 | * Only if no error, cache is turned on successfully. | ||
1071 | */ | ||
1072 | card->ext_csd.cache_ctrl = err ? 0 : 1; | ||
1073 | } | ||
1074 | |||
843 | if (!oldcard) | 1075 | if (!oldcard) |
844 | host->card = card; | 1076 | host->card = card; |
845 | 1077 | ||
@@ -891,6 +1123,7 @@ static void mmc_detect(struct mmc_host *host) | |||
891 | 1123 | ||
892 | mmc_claim_host(host); | 1124 | mmc_claim_host(host); |
893 | mmc_detach_bus(host); | 1125 | mmc_detach_bus(host); |
1126 | mmc_power_off(host); | ||
894 | mmc_release_host(host); | 1127 | mmc_release_host(host); |
895 | } | 1128 | } |
896 | } | 1129 | } |
@@ -900,16 +1133,20 @@ static void mmc_detect(struct mmc_host *host) | |||
900 | */ | 1133 | */ |
901 | static int mmc_suspend(struct mmc_host *host) | 1134 | static int mmc_suspend(struct mmc_host *host) |
902 | { | 1135 | { |
1136 | int err = 0; | ||
1137 | |||
903 | BUG_ON(!host); | 1138 | BUG_ON(!host); |
904 | BUG_ON(!host->card); | 1139 | BUG_ON(!host->card); |
905 | 1140 | ||
906 | mmc_claim_host(host); | 1141 | mmc_claim_host(host); |
907 | if (!mmc_host_is_spi(host)) | 1142 | if (mmc_card_can_sleep(host)) |
1143 | err = mmc_card_sleep(host); | ||
1144 | else if (!mmc_host_is_spi(host)) | ||
908 | mmc_deselect_cards(host); | 1145 | mmc_deselect_cards(host); |
909 | host->card->state &= ~MMC_STATE_HIGHSPEED; | 1146 | host->card->state &= ~MMC_STATE_HIGHSPEED; |
910 | mmc_release_host(host); | 1147 | mmc_release_host(host); |
911 | 1148 | ||
912 | return 0; | 1149 | return err; |
913 | } | 1150 | } |
914 | 1151 | ||
915 | /* | 1152 | /* |
@@ -1016,6 +1253,10 @@ int mmc_attach_mmc(struct mmc_host *host) | |||
1016 | BUG_ON(!host); | 1253 | BUG_ON(!host); |
1017 | WARN_ON(!host->claimed); | 1254 | WARN_ON(!host->claimed); |
1018 | 1255 | ||
1256 | /* Set correct bus mode for MMC before attempting attach */ | ||
1257 | if (!mmc_host_is_spi(host)) | ||
1258 | mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); | ||
1259 | |||
1019 | err = mmc_send_op_cond(host, 0, &ocr); | 1260 | err = mmc_send_op_cond(host, 0, &ocr); |
1020 | if (err) | 1261 | if (err) |
1021 | return err; | 1262 | return err; |
@@ -1038,7 +1279,7 @@ int mmc_attach_mmc(struct mmc_host *host) | |||
1038 | * support. | 1279 | * support. |
1039 | */ | 1280 | */ |
1040 | if (ocr & 0x7F) { | 1281 | if (ocr & 0x7F) { |
1041 | printk(KERN_WARNING "%s: card claims to support voltages " | 1282 | pr_warning("%s: card claims to support voltages " |
1042 | "below the defined range. These will be ignored.\n", | 1283 | "below the defined range. These will be ignored.\n", |
1043 | mmc_hostname(host)); | 1284 | mmc_hostname(host)); |
1044 | ocr &= ~0x7F; | 1285 | ocr &= ~0x7F; |
@@ -1077,7 +1318,7 @@ remove_card: | |||
1077 | err: | 1318 | err: |
1078 | mmc_detach_bus(host); | 1319 | mmc_detach_bus(host); |
1079 | 1320 | ||
1080 | printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", | 1321 | pr_err("%s: error %d whilst initialising MMC card\n", |
1081 | mmc_hostname(host), err); | 1322 | mmc_hostname(host), err); |
1082 | 1323 | ||
1083 | return err; | 1324 | return err; |