diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-09 18:50:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-09 18:50:25 -0400 |
| commit | a6a5ed0dd36b4977789e888170f96840cc8b4501 (patch) | |
| tree | d003cfb810c7fc78cb6fad97a41927dbcdc4b364 | |
| parent | 0d20fbbe82dadc43f50a4ca5346e962de23cf950 (diff) | |
| parent | 49bb1e619568ec84785ceb366f07db2a6f0b64cc (diff) | |
Merge branch 'for-linus' of git://dev.laptop.org/users/cjb/mmc
* 'for-linus' of git://dev.laptop.org/users/cjb/mmc:
mmc: sdhci-s3c: Fix mmc card I/O problem
mmc: sd: UHS-I bus speed should be set last in UHS initialization
mmc: sdhi: initialise mmc_data->flags before use
mmc: core: use non-reentrant workqueue for clock gating
mmc: core: prevent aggressive clock gating racing with ios updates
mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release}
mmc: sdhci-esdhc-imx: add missing inclusion of linux/module.h
| -rw-r--r-- | drivers/mmc/core/core.c | 35 | ||||
| -rw-r--r-- | drivers/mmc/core/host.c | 12 | ||||
| -rw-r--r-- | drivers/mmc/core/host.h | 8 | ||||
| -rw-r--r-- | drivers/mmc/core/sd.c | 81 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-s3c.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/sh_mobile_sdhi.c | 4 |
7 files changed, 99 insertions, 44 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 91a0a7460ebb..b27b94078c21 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -133,7 +133,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
| 133 | if (mrq->done) | 133 | if (mrq->done) |
| 134 | mrq->done(mrq); | 134 | mrq->done(mrq); |
| 135 | 135 | ||
| 136 | mmc_host_clk_gate(host); | 136 | mmc_host_clk_release(host); |
| 137 | } | 137 | } |
| 138 | } | 138 | } |
| 139 | 139 | ||
| @@ -192,7 +192,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
| 192 | mrq->stop->mrq = mrq; | 192 | mrq->stop->mrq = mrq; |
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | mmc_host_clk_ungate(host); | 195 | mmc_host_clk_hold(host); |
| 196 | led_trigger_event(host->led, LED_FULL); | 196 | led_trigger_event(host->led, LED_FULL); |
| 197 | host->ops->request(host, mrq); | 197 | host->ops->request(host, mrq); |
| 198 | } | 198 | } |
| @@ -728,15 +728,17 @@ static inline void mmc_set_ios(struct mmc_host *host) | |||
| 728 | */ | 728 | */ |
| 729 | void mmc_set_chip_select(struct mmc_host *host, int mode) | 729 | void mmc_set_chip_select(struct mmc_host *host, int mode) |
| 730 | { | 730 | { |
| 731 | mmc_host_clk_hold(host); | ||
| 731 | host->ios.chip_select = mode; | 732 | host->ios.chip_select = mode; |
| 732 | mmc_set_ios(host); | 733 | mmc_set_ios(host); |
| 734 | mmc_host_clk_release(host); | ||
| 733 | } | 735 | } |
| 734 | 736 | ||
| 735 | /* | 737 | /* |
| 736 | * Sets the host clock to the highest possible frequency that | 738 | * Sets the host clock to the highest possible frequency that |
| 737 | * is below "hz". | 739 | * is below "hz". |
| 738 | */ | 740 | */ |
| 739 | void mmc_set_clock(struct mmc_host *host, unsigned int hz) | 741 | static void __mmc_set_clock(struct mmc_host *host, unsigned int hz) |
| 740 | { | 742 | { |
| 741 | WARN_ON(hz < host->f_min); | 743 | WARN_ON(hz < host->f_min); |
| 742 | 744 | ||
| @@ -747,6 +749,13 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz) | |||
| 747 | mmc_set_ios(host); | 749 | mmc_set_ios(host); |
| 748 | } | 750 | } |
| 749 | 751 | ||
| 752 | void mmc_set_clock(struct mmc_host *host, unsigned int hz) | ||
| 753 | { | ||
| 754 | mmc_host_clk_hold(host); | ||
| 755 | __mmc_set_clock(host, hz); | ||
| 756 | mmc_host_clk_release(host); | ||
| 757 | } | ||
| 758 | |||
| 750 | #ifdef CONFIG_MMC_CLKGATE | 759 | #ifdef CONFIG_MMC_CLKGATE |
| 751 | /* | 760 | /* |
| 752 | * This gates the clock by setting it to 0 Hz. | 761 | * This gates the clock by setting it to 0 Hz. |
| @@ -779,7 +788,7 @@ void mmc_ungate_clock(struct mmc_host *host) | |||
| 779 | if (host->clk_old) { | 788 | if (host->clk_old) { |
| 780 | BUG_ON(host->ios.clock); | 789 | BUG_ON(host->ios.clock); |
| 781 | /* This call will also set host->clk_gated to false */ | 790 | /* This call will also set host->clk_gated to false */ |
| 782 | mmc_set_clock(host, host->clk_old); | 791 | __mmc_set_clock(host, host->clk_old); |
| 783 | } | 792 | } |
| 784 | } | 793 | } |
| 785 | 794 | ||
| @@ -807,8 +816,10 @@ void mmc_set_ungated(struct mmc_host *host) | |||
| 807 | */ | 816 | */ |
| 808 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) | 817 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) |
| 809 | { | 818 | { |
| 819 | mmc_host_clk_hold(host); | ||
| 810 | host->ios.bus_mode = mode; | 820 | host->ios.bus_mode = mode; |
| 811 | mmc_set_ios(host); | 821 | mmc_set_ios(host); |
| 822 | mmc_host_clk_release(host); | ||
| 812 | } | 823 | } |
| 813 | 824 | ||
| 814 | /* | 825 | /* |
| @@ -816,8 +827,10 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) | |||
| 816 | */ | 827 | */ |
| 817 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width) | 828 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width) |
| 818 | { | 829 | { |
| 830 | mmc_host_clk_hold(host); | ||
| 819 | host->ios.bus_width = width; | 831 | host->ios.bus_width = width; |
| 820 | mmc_set_ios(host); | 832 | mmc_set_ios(host); |
| 833 | mmc_host_clk_release(host); | ||
| 821 | } | 834 | } |
| 822 | 835 | ||
| 823 | /** | 836 | /** |
| @@ -1015,8 +1028,10 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | |||
| 1015 | 1028 | ||
| 1016 | ocr &= 3 << bit; | 1029 | ocr &= 3 << bit; |
| 1017 | 1030 | ||
| 1031 | mmc_host_clk_hold(host); | ||
| 1018 | host->ios.vdd = bit; | 1032 | host->ios.vdd = bit; |
| 1019 | mmc_set_ios(host); | 1033 | mmc_set_ios(host); |
| 1034 | mmc_host_clk_release(host); | ||
| 1020 | } else { | 1035 | } else { |
| 1021 | pr_warning("%s: host doesn't support card's voltages\n", | 1036 | pr_warning("%s: host doesn't support card's voltages\n", |
| 1022 | mmc_hostname(host)); | 1037 | mmc_hostname(host)); |
| @@ -1063,8 +1078,10 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 | |||
| 1063 | */ | 1078 | */ |
| 1064 | void mmc_set_timing(struct mmc_host *host, unsigned int timing) | 1079 | void mmc_set_timing(struct mmc_host *host, unsigned int timing) |
| 1065 | { | 1080 | { |
| 1081 | mmc_host_clk_hold(host); | ||
| 1066 | host->ios.timing = timing; | 1082 | host->ios.timing = timing; |
| 1067 | mmc_set_ios(host); | 1083 | mmc_set_ios(host); |
| 1084 | mmc_host_clk_release(host); | ||
| 1068 | } | 1085 | } |
| 1069 | 1086 | ||
| 1070 | /* | 1087 | /* |
| @@ -1072,8 +1089,10 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing) | |||
| 1072 | */ | 1089 | */ |
| 1073 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) | 1090 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) |
| 1074 | { | 1091 | { |
| 1092 | mmc_host_clk_hold(host); | ||
| 1075 | host->ios.drv_type = drv_type; | 1093 | host->ios.drv_type = drv_type; |
| 1076 | mmc_set_ios(host); | 1094 | mmc_set_ios(host); |
| 1095 | mmc_host_clk_release(host); | ||
| 1077 | } | 1096 | } |
| 1078 | 1097 | ||
| 1079 | /* | 1098 | /* |
| @@ -1091,6 +1110,8 @@ static void mmc_power_up(struct mmc_host *host) | |||
| 1091 | { | 1110 | { |
| 1092 | int bit; | 1111 | int bit; |
| 1093 | 1112 | ||
| 1113 | mmc_host_clk_hold(host); | ||
| 1114 | |||
| 1094 | /* If ocr is set, we use it */ | 1115 | /* If ocr is set, we use it */ |
| 1095 | if (host->ocr) | 1116 | if (host->ocr) |
| 1096 | bit = ffs(host->ocr) - 1; | 1117 | bit = ffs(host->ocr) - 1; |
| @@ -1126,10 +1147,14 @@ static void mmc_power_up(struct mmc_host *host) | |||
| 1126 | * time required to reach a stable voltage. | 1147 | * time required to reach a stable voltage. |
| 1127 | */ | 1148 | */ |
| 1128 | mmc_delay(10); | 1149 | mmc_delay(10); |
| 1150 | |||
| 1151 | mmc_host_clk_release(host); | ||
| 1129 | } | 1152 | } |
| 1130 | 1153 | ||
| 1131 | static void mmc_power_off(struct mmc_host *host) | 1154 | static void mmc_power_off(struct mmc_host *host) |
| 1132 | { | 1155 | { |
| 1156 | mmc_host_clk_hold(host); | ||
| 1157 | |||
| 1133 | host->ios.clock = 0; | 1158 | host->ios.clock = 0; |
| 1134 | host->ios.vdd = 0; | 1159 | host->ios.vdd = 0; |
| 1135 | 1160 | ||
| @@ -1147,6 +1172,8 @@ static void mmc_power_off(struct mmc_host *host) | |||
| 1147 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 1172 | host->ios.bus_width = MMC_BUS_WIDTH_1; |
| 1148 | host->ios.timing = MMC_TIMING_LEGACY; | 1173 | host->ios.timing = MMC_TIMING_LEGACY; |
| 1149 | mmc_set_ios(host); | 1174 | mmc_set_ios(host); |
| 1175 | |||
| 1176 | mmc_host_clk_release(host); | ||
| 1150 | } | 1177 | } |
| 1151 | 1178 | ||
| 1152 | /* | 1179 | /* |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index b29d3e8fd3a2..793d0a0dad8d 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
| @@ -119,14 +119,14 @@ static void mmc_host_clk_gate_work(struct work_struct *work) | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /** | 121 | /** |
| 122 | * mmc_host_clk_ungate - ungate hardware MCI clocks | 122 | * mmc_host_clk_hold - ungate hardware MCI clocks |
| 123 | * @host: host to ungate. | 123 | * @host: host to ungate. |
| 124 | * | 124 | * |
| 125 | * Makes sure the host ios.clock is restored to a non-zero value | 125 | * Makes sure the host ios.clock is restored to a non-zero value |
| 126 | * past this call. Increase clock reference count and ungate clock | 126 | * past this call. Increase clock reference count and ungate clock |
| 127 | * if we're the first user. | 127 | * if we're the first user. |
| 128 | */ | 128 | */ |
| 129 | void mmc_host_clk_ungate(struct mmc_host *host) | 129 | void mmc_host_clk_hold(struct mmc_host *host) |
| 130 | { | 130 | { |
| 131 | unsigned long flags; | 131 | unsigned long flags; |
| 132 | 132 | ||
| @@ -164,14 +164,14 @@ static bool mmc_host_may_gate_card(struct mmc_card *card) | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /** | 166 | /** |
| 167 | * mmc_host_clk_gate - gate off hardware MCI clocks | 167 | * mmc_host_clk_release - gate off hardware MCI clocks |
| 168 | * @host: host to gate. | 168 | * @host: host to gate. |
| 169 | * | 169 | * |
| 170 | * Calls the host driver with ios.clock set to zero as often as possible | 170 | * Calls the host driver with ios.clock set to zero as often as possible |
| 171 | * in order to gate off hardware MCI clocks. Decrease clock reference | 171 | * in order to gate off hardware MCI clocks. Decrease clock reference |
| 172 | * count and schedule disabling of clock. | 172 | * count and schedule disabling of clock. |
| 173 | */ | 173 | */ |
| 174 | void mmc_host_clk_gate(struct mmc_host *host) | 174 | void mmc_host_clk_release(struct mmc_host *host) |
| 175 | { | 175 | { |
| 176 | unsigned long flags; | 176 | unsigned long flags; |
| 177 | 177 | ||
| @@ -179,7 +179,7 @@ void mmc_host_clk_gate(struct mmc_host *host) | |||
| 179 | host->clk_requests--; | 179 | host->clk_requests--; |
| 180 | if (mmc_host_may_gate_card(host->card) && | 180 | if (mmc_host_may_gate_card(host->card) && |
| 181 | !host->clk_requests) | 181 | !host->clk_requests) |
| 182 | schedule_work(&host->clk_gate_work); | 182 | queue_work(system_nrt_wq, &host->clk_gate_work); |
| 183 | spin_unlock_irqrestore(&host->clk_lock, flags); | 183 | spin_unlock_irqrestore(&host->clk_lock, flags); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| @@ -231,7 +231,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
| 231 | if (cancel_work_sync(&host->clk_gate_work)) | 231 | if (cancel_work_sync(&host->clk_gate_work)) |
| 232 | mmc_host_clk_gate_delayed(host); | 232 | mmc_host_clk_gate_delayed(host); |
| 233 | if (host->clk_gated) | 233 | if (host->clk_gated) |
| 234 | mmc_host_clk_ungate(host); | 234 | mmc_host_clk_hold(host); |
| 235 | /* There should be only one user now */ | 235 | /* There should be only one user now */ |
| 236 | WARN_ON(host->clk_requests > 1); | 236 | WARN_ON(host->clk_requests > 1); |
| 237 | } | 237 | } |
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index de199f911928..fb8a5cd2e4a1 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h | |||
| @@ -16,16 +16,16 @@ int mmc_register_host_class(void); | |||
| 16 | void mmc_unregister_host_class(void); | 16 | void mmc_unregister_host_class(void); |
| 17 | 17 | ||
| 18 | #ifdef CONFIG_MMC_CLKGATE | 18 | #ifdef CONFIG_MMC_CLKGATE |
| 19 | void mmc_host_clk_ungate(struct mmc_host *host); | 19 | void mmc_host_clk_hold(struct mmc_host *host); |
| 20 | void mmc_host_clk_gate(struct mmc_host *host); | 20 | void mmc_host_clk_release(struct mmc_host *host); |
| 21 | unsigned int mmc_host_clk_rate(struct mmc_host *host); | 21 | unsigned int mmc_host_clk_rate(struct mmc_host *host); |
| 22 | 22 | ||
| 23 | #else | 23 | #else |
| 24 | static inline void mmc_host_clk_ungate(struct mmc_host *host) | 24 | static inline void mmc_host_clk_hold(struct mmc_host *host) |
| 25 | { | 25 | { |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | static inline void mmc_host_clk_gate(struct mmc_host *host) | 28 | static inline void mmc_host_clk_release(struct mmc_host *host) |
| 29 | { | 29 | { |
| 30 | } | 30 | } |
| 31 | 31 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 633975ff2bb3..0370e03e3142 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -469,56 +469,75 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status) | |||
| 469 | return 0; | 469 | return 0; |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) | 472 | static void sd_update_bus_speed_mode(struct mmc_card *card) |
| 473 | { | 473 | { |
| 474 | unsigned int bus_speed = 0, timing = 0; | ||
| 475 | int err; | ||
| 476 | |||
| 477 | /* | 474 | /* |
| 478 | * If the host doesn't support any of the UHS-I modes, fallback on | 475 | * If the host doesn't support any of the UHS-I modes, fallback on |
| 479 | * default speed. | 476 | * default speed. |
| 480 | */ | 477 | */ |
| 481 | if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | 478 | if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | |
| 482 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) | 479 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) { |
| 483 | return 0; | 480 | card->sd_bus_speed = 0; |
| 481 | return; | ||
| 482 | } | ||
| 484 | 483 | ||
| 485 | if ((card->host->caps & MMC_CAP_UHS_SDR104) && | 484 | if ((card->host->caps & MMC_CAP_UHS_SDR104) && |
| 486 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { | 485 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { |
| 487 | bus_speed = UHS_SDR104_BUS_SPEED; | 486 | card->sd_bus_speed = UHS_SDR104_BUS_SPEED; |
| 488 | timing = MMC_TIMING_UHS_SDR104; | ||
| 489 | card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; | ||
| 490 | } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && | 487 | } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && |
| 491 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { | 488 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { |
| 492 | bus_speed = UHS_DDR50_BUS_SPEED; | 489 | card->sd_bus_speed = UHS_DDR50_BUS_SPEED; |
| 493 | timing = MMC_TIMING_UHS_DDR50; | ||
| 494 | card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; | ||
| 495 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | 490 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | |
| 496 | MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & | 491 | MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & |
| 497 | SD_MODE_UHS_SDR50)) { | 492 | SD_MODE_UHS_SDR50)) { |
| 498 | bus_speed = UHS_SDR50_BUS_SPEED; | 493 | card->sd_bus_speed = UHS_SDR50_BUS_SPEED; |
| 499 | timing = MMC_TIMING_UHS_SDR50; | ||
| 500 | card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; | ||
| 501 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | 494 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | |
| 502 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && | 495 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && |
| 503 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { | 496 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { |
| 504 | bus_speed = UHS_SDR25_BUS_SPEED; | 497 | card->sd_bus_speed = UHS_SDR25_BUS_SPEED; |
| 505 | timing = MMC_TIMING_UHS_SDR25; | ||
| 506 | card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; | ||
| 507 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | 498 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | |
| 508 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | | 499 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | |
| 509 | MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & | 500 | MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & |
| 510 | SD_MODE_UHS_SDR12)) { | 501 | SD_MODE_UHS_SDR12)) { |
| 511 | bus_speed = UHS_SDR12_BUS_SPEED; | 502 | card->sd_bus_speed = UHS_SDR12_BUS_SPEED; |
| 512 | timing = MMC_TIMING_UHS_SDR12; | 503 | } |
| 513 | card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; | 504 | } |
| 505 | |||
| 506 | static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) | ||
| 507 | { | ||
| 508 | int err; | ||
| 509 | unsigned int timing = 0; | ||
| 510 | |||
| 511 | switch (card->sd_bus_speed) { | ||
| 512 | case UHS_SDR104_BUS_SPEED: | ||
| 513 | timing = MMC_TIMING_UHS_SDR104; | ||
| 514 | card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; | ||
| 515 | break; | ||
| 516 | case UHS_DDR50_BUS_SPEED: | ||
| 517 | timing = MMC_TIMING_UHS_DDR50; | ||
| 518 | card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; | ||
| 519 | break; | ||
| 520 | case UHS_SDR50_BUS_SPEED: | ||
| 521 | timing = MMC_TIMING_UHS_SDR50; | ||
| 522 | card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; | ||
| 523 | break; | ||
| 524 | case UHS_SDR25_BUS_SPEED: | ||
| 525 | timing = MMC_TIMING_UHS_SDR25; | ||
| 526 | card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; | ||
| 527 | break; | ||
| 528 | case UHS_SDR12_BUS_SPEED: | ||
| 529 | timing = MMC_TIMING_UHS_SDR12; | ||
| 530 | card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; | ||
| 531 | break; | ||
| 532 | default: | ||
| 533 | return 0; | ||
| 514 | } | 534 | } |
| 515 | 535 | ||
| 516 | card->sd_bus_speed = bus_speed; | 536 | err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status); |
| 517 | err = mmc_sd_switch(card, 1, 0, bus_speed, status); | ||
| 518 | if (err) | 537 | if (err) |
| 519 | return err; | 538 | return err; |
| 520 | 539 | ||
| 521 | if ((status[16] & 0xF) != bus_speed) | 540 | if ((status[16] & 0xF) != card->sd_bus_speed) |
| 522 | printk(KERN_WARNING "%s: Problem setting bus speed mode!\n", | 541 | printk(KERN_WARNING "%s: Problem setting bus speed mode!\n", |
| 523 | mmc_hostname(card->host)); | 542 | mmc_hostname(card->host)); |
| 524 | else { | 543 | else { |
| @@ -618,18 +637,24 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) | |||
| 618 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | 637 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); |
| 619 | } | 638 | } |
| 620 | 639 | ||
| 640 | /* | ||
| 641 | * Select the bus speed mode depending on host | ||
| 642 | * and card capability. | ||
| 643 | */ | ||
| 644 | sd_update_bus_speed_mode(card); | ||
| 645 | |||
| 621 | /* Set the driver strength for the card */ | 646 | /* Set the driver strength for the card */ |
| 622 | err = sd_select_driver_type(card, status); | 647 | err = sd_select_driver_type(card, status); |
| 623 | if (err) | 648 | if (err) |
| 624 | goto out; | 649 | goto out; |
| 625 | 650 | ||
| 626 | /* Set bus speed mode of the card */ | 651 | /* Set current limit for the card */ |
| 627 | err = sd_set_bus_speed_mode(card, status); | 652 | err = sd_set_current_limit(card, status); |
| 628 | if (err) | 653 | if (err) |
| 629 | goto out; | 654 | goto out; |
| 630 | 655 | ||
| 631 | /* Set current limit for the card */ | 656 | /* Set bus speed mode of the card */ |
| 632 | err = sd_set_current_limit(card, status); | 657 | err = sd_set_bus_speed_mode(card, status); |
| 633 | if (err) | 658 | if (err) |
| 634 | goto out; | 659 | goto out; |
| 635 | 660 | ||
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 0e9780f5a4a9..4dc0028086a3 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
| 19 | #include <linux/module.h> | ||
| 19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 20 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
| 21 | #include <linux/mmc/mmc.h> | 22 | #include <linux/mmc/mmc.h> |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 2bd7bf4fece7..fe886d6c474a 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -302,6 +302,8 @@ static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width) | |||
| 302 | ctrl &= ~SDHCI_CTRL_8BITBUS; | 302 | ctrl &= ~SDHCI_CTRL_8BITBUS; |
| 303 | break; | 303 | break; |
| 304 | default: | 304 | default: |
| 305 | ctrl &= ~SDHCI_CTRL_4BITBUS; | ||
| 306 | ctrl &= ~SDHCI_CTRL_8BITBUS; | ||
| 305 | break; | 307 | break; |
| 306 | } | 308 | } |
| 307 | 309 | ||
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 774f6439d7ce..0c4a672f5db6 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c | |||
| @@ -120,11 +120,11 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
| 120 | mmc_data->hclk = clk_get_rate(priv->clk); | 120 | mmc_data->hclk = clk_get_rate(priv->clk); |
| 121 | mmc_data->set_pwr = sh_mobile_sdhi_set_pwr; | 121 | mmc_data->set_pwr = sh_mobile_sdhi_set_pwr; |
| 122 | mmc_data->get_cd = sh_mobile_sdhi_get_cd; | 122 | mmc_data->get_cd = sh_mobile_sdhi_get_cd; |
| 123 | if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT) | ||
| 124 | mmc_data->write16_hook = sh_mobile_sdhi_write16_hook; | ||
| 125 | mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; | 123 | mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; |
| 126 | if (p) { | 124 | if (p) { |
| 127 | mmc_data->flags = p->tmio_flags; | 125 | mmc_data->flags = p->tmio_flags; |
| 126 | if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT) | ||
| 127 | mmc_data->write16_hook = sh_mobile_sdhi_write16_hook; | ||
| 128 | mmc_data->ocr_mask = p->tmio_ocr_mask; | 128 | mmc_data->ocr_mask = p->tmio_ocr_mask; |
| 129 | mmc_data->capabilities |= p->tmio_caps; | 129 | mmc_data->capabilities |= p->tmio_caps; |
| 130 | 130 | ||
