diff options
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r-- | drivers/mmc/core/sdio.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c599a628a387..a86490dbca70 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -444,6 +444,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) | |||
444 | unsigned int bus_speed, timing; | 444 | unsigned int bus_speed, timing; |
445 | int err; | 445 | int err; |
446 | unsigned char speed; | 446 | unsigned char speed; |
447 | unsigned int max_rate; | ||
447 | 448 | ||
448 | /* | 449 | /* |
449 | * If the host doesn't support any of the UHS-I modes, fallback on | 450 | * If the host doesn't support any of the UHS-I modes, fallback on |
@@ -500,9 +501,12 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) | |||
500 | if (err) | 501 | if (err) |
501 | return err; | 502 | return err; |
502 | 503 | ||
504 | max_rate = min_not_zero(card->quirk_max_rate, | ||
505 | card->sw_caps.uhs_max_dtr); | ||
506 | |||
503 | if (bus_speed) { | 507 | if (bus_speed) { |
504 | mmc_set_timing(card->host, timing); | 508 | mmc_set_timing(card->host, timing); |
505 | mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); | 509 | mmc_set_clock(card->host, max_rate); |
506 | } | 510 | } |
507 | 511 | ||
508 | return 0; | 512 | return 0; |
@@ -788,6 +792,14 @@ try_again: | |||
788 | if (err) | 792 | if (err) |
789 | goto remove; | 793 | goto remove; |
790 | } | 794 | } |
795 | |||
796 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
797 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
798 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
799 | mmc_hostname(host)); | ||
800 | err = -EINVAL; | ||
801 | goto remove; | ||
802 | } | ||
791 | finish: | 803 | finish: |
792 | if (!oldcard) | 804 | if (!oldcard) |
793 | host->card = card; | 805 | host->card = card; |
@@ -801,6 +813,22 @@ err: | |||
801 | return err; | 813 | return err; |
802 | } | 814 | } |
803 | 815 | ||
816 | static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume) | ||
817 | { | ||
818 | int ret; | ||
819 | |||
820 | sdio_reset(host); | ||
821 | mmc_go_idle(host); | ||
822 | mmc_send_if_cond(host, host->card->ocr); | ||
823 | |||
824 | ret = mmc_send_io_op_cond(host, 0, NULL); | ||
825 | if (ret) | ||
826 | return ret; | ||
827 | |||
828 | return mmc_sdio_init_card(host, host->card->ocr, host->card, | ||
829 | powered_resume); | ||
830 | } | ||
831 | |||
804 | /* | 832 | /* |
805 | * Host is being removed. Free up the current card. | 833 | * Host is being removed. Free up the current card. |
806 | */ | 834 | */ |
@@ -948,14 +976,7 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
948 | 976 | ||
949 | /* No need to reinitialize powered-resumed nonremovable cards */ | 977 | /* No need to reinitialize powered-resumed nonremovable cards */ |
950 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { | 978 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { |
951 | sdio_reset(host); | 979 | err = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); |
952 | mmc_go_idle(host); | ||
953 | mmc_send_if_cond(host, host->card->ocr); | ||
954 | err = mmc_send_io_op_cond(host, 0, NULL); | ||
955 | if (!err) | ||
956 | err = mmc_sdio_init_card(host, host->card->ocr, | ||
957 | host->card, | ||
958 | mmc_card_keep_power(host)); | ||
959 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { | 980 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { |
960 | /* We may have switched to 1-bit mode during suspend */ | 981 | /* We may have switched to 1-bit mode during suspend */ |
961 | err = sdio_enable_4bit_bus(host->card); | 982 | err = sdio_enable_4bit_bus(host->card); |
@@ -978,8 +999,6 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
978 | { | 999 | { |
979 | int ret; | 1000 | int ret; |
980 | 1001 | ||
981 | mmc_claim_host(host); | ||
982 | |||
983 | /* | 1002 | /* |
984 | * Reset the card by performing the same steps that are taken by | 1003 | * Reset the card by performing the same steps that are taken by |
985 | * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. | 1004 | * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. |
@@ -997,20 +1016,12 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
997 | * | 1016 | * |
998 | */ | 1017 | */ |
999 | 1018 | ||
1000 | sdio_reset(host); | 1019 | mmc_claim_host(host); |
1001 | mmc_go_idle(host); | ||
1002 | mmc_send_if_cond(host, host->card->ocr); | ||
1003 | |||
1004 | ret = mmc_send_io_op_cond(host, 0, NULL); | ||
1005 | if (ret) | ||
1006 | goto out; | ||
1007 | 1020 | ||
1008 | ret = mmc_sdio_init_card(host, host->card->ocr, host->card, | 1021 | ret = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); |
1009 | mmc_card_keep_power(host)); | ||
1010 | if (!ret && host->sdio_irqs) | 1022 | if (!ret && host->sdio_irqs) |
1011 | mmc_signal_sdio_irq(host); | 1023 | mmc_signal_sdio_irq(host); |
1012 | 1024 | ||
1013 | out: | ||
1014 | mmc_release_host(host); | 1025 | mmc_release_host(host); |
1015 | 1026 | ||
1016 | return ret; | 1027 | return ret; |
@@ -1039,12 +1050,24 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) | |||
1039 | return ret; | 1050 | return ret; |
1040 | } | 1051 | } |
1041 | 1052 | ||
1042 | static int mmc_sdio_reset(struct mmc_host *host) | 1053 | static int mmc_sdio_hw_reset(struct mmc_host *host) |
1043 | { | 1054 | { |
1044 | mmc_power_cycle(host, host->card->ocr); | 1055 | mmc_power_cycle(host, host->card->ocr); |
1045 | return mmc_sdio_power_restore(host); | 1056 | return mmc_sdio_power_restore(host); |
1046 | } | 1057 | } |
1047 | 1058 | ||
1059 | static int mmc_sdio_sw_reset(struct mmc_host *host) | ||
1060 | { | ||
1061 | mmc_set_clock(host, host->f_init); | ||
1062 | sdio_reset(host); | ||
1063 | mmc_go_idle(host); | ||
1064 | |||
1065 | mmc_set_initial_state(host); | ||
1066 | mmc_set_initial_signal_voltage(host); | ||
1067 | |||
1068 | return mmc_sdio_reinit_card(host, 0); | ||
1069 | } | ||
1070 | |||
1048 | static const struct mmc_bus_ops mmc_sdio_ops = { | 1071 | static const struct mmc_bus_ops mmc_sdio_ops = { |
1049 | .remove = mmc_sdio_remove, | 1072 | .remove = mmc_sdio_remove, |
1050 | .detect = mmc_sdio_detect, | 1073 | .detect = mmc_sdio_detect, |
@@ -1055,7 +1078,8 @@ static const struct mmc_bus_ops mmc_sdio_ops = { | |||
1055 | .runtime_resume = mmc_sdio_runtime_resume, | 1078 | .runtime_resume = mmc_sdio_runtime_resume, |
1056 | .power_restore = mmc_sdio_power_restore, | 1079 | .power_restore = mmc_sdio_power_restore, |
1057 | .alive = mmc_sdio_alive, | 1080 | .alive = mmc_sdio_alive, |
1058 | .reset = mmc_sdio_reset, | 1081 | .hw_reset = mmc_sdio_hw_reset, |
1082 | .sw_reset = mmc_sdio_sw_reset, | ||
1059 | }; | 1083 | }; |
1060 | 1084 | ||
1061 | 1085 | ||