diff options
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r-- | drivers/mmc/core/core.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f545a3e6eb80..690255c7d4dc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -290,8 +290,11 @@ static void mmc_wait_for_req_done(struct mmc_host *host, | |||
290 | static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, | 290 | static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, |
291 | bool is_first_req) | 291 | bool is_first_req) |
292 | { | 292 | { |
293 | if (host->ops->pre_req) | 293 | if (host->ops->pre_req) { |
294 | mmc_host_clk_hold(host); | ||
294 | host->ops->pre_req(host, mrq, is_first_req); | 295 | host->ops->pre_req(host, mrq, is_first_req); |
296 | mmc_host_clk_release(host); | ||
297 | } | ||
295 | } | 298 | } |
296 | 299 | ||
297 | /** | 300 | /** |
@@ -306,8 +309,11 @@ static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, | |||
306 | static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, | 309 | static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, |
307 | int err) | 310 | int err) |
308 | { | 311 | { |
309 | if (host->ops->post_req) | 312 | if (host->ops->post_req) { |
313 | mmc_host_clk_hold(host); | ||
310 | host->ops->post_req(host, mrq, err); | 314 | host->ops->post_req(host, mrq, err); |
315 | mmc_host_clk_release(host); | ||
316 | } | ||
311 | } | 317 | } |
312 | 318 | ||
313 | /** | 319 | /** |
@@ -620,7 +626,9 @@ int mmc_host_enable(struct mmc_host *host) | |||
620 | int err; | 626 | int err; |
621 | 627 | ||
622 | host->en_dis_recurs = 1; | 628 | host->en_dis_recurs = 1; |
629 | mmc_host_clk_hold(host); | ||
623 | err = host->ops->enable(host); | 630 | err = host->ops->enable(host); |
631 | mmc_host_clk_release(host); | ||
624 | host->en_dis_recurs = 0; | 632 | host->en_dis_recurs = 0; |
625 | 633 | ||
626 | if (err) { | 634 | if (err) { |
@@ -640,7 +648,9 @@ static int mmc_host_do_disable(struct mmc_host *host, int lazy) | |||
640 | int err; | 648 | int err; |
641 | 649 | ||
642 | host->en_dis_recurs = 1; | 650 | host->en_dis_recurs = 1; |
651 | mmc_host_clk_hold(host); | ||
643 | err = host->ops->disable(host, lazy); | 652 | err = host->ops->disable(host, lazy); |
653 | mmc_host_clk_release(host); | ||
644 | host->en_dis_recurs = 0; | 654 | host->en_dis_recurs = 0; |
645 | 655 | ||
646 | if (err < 0) { | 656 | if (err < 0) { |
@@ -1121,6 +1131,10 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc, | |||
1121 | * might not allow this operation | 1131 | * might not allow this operation |
1122 | */ | 1132 | */ |
1123 | voltage = regulator_get_voltage(supply); | 1133 | voltage = regulator_get_voltage(supply); |
1134 | |||
1135 | if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE) | ||
1136 | min_uV = max_uV = voltage; | ||
1137 | |||
1124 | if (voltage < 0) | 1138 | if (voltage < 0) |
1125 | result = voltage; | 1139 | result = voltage; |
1126 | else if (voltage < min_uV || voltage > max_uV) | 1140 | else if (voltage < min_uV || voltage > max_uV) |
@@ -1203,8 +1217,11 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 | |||
1203 | 1217 | ||
1204 | host->ios.signal_voltage = signal_voltage; | 1218 | host->ios.signal_voltage = signal_voltage; |
1205 | 1219 | ||
1206 | if (host->ops->start_signal_voltage_switch) | 1220 | if (host->ops->start_signal_voltage_switch) { |
1221 | mmc_host_clk_hold(host); | ||
1207 | err = host->ops->start_signal_voltage_switch(host, &host->ios); | 1222 | err = host->ops->start_signal_voltage_switch(host, &host->ios); |
1223 | mmc_host_clk_release(host); | ||
1224 | } | ||
1208 | 1225 | ||
1209 | return err; | 1226 | return err; |
1210 | } | 1227 | } |
@@ -1239,6 +1256,7 @@ static void mmc_poweroff_notify(struct mmc_host *host) | |||
1239 | int err = 0; | 1256 | int err = 0; |
1240 | 1257 | ||
1241 | card = host->card; | 1258 | card = host->card; |
1259 | mmc_claim_host(host); | ||
1242 | 1260 | ||
1243 | /* | 1261 | /* |
1244 | * Send power notify command only if card | 1262 | * Send power notify command only if card |
@@ -1269,6 +1287,7 @@ static void mmc_poweroff_notify(struct mmc_host *host) | |||
1269 | /* Set the card state to no notification after the poweroff */ | 1287 | /* Set the card state to no notification after the poweroff */ |
1270 | card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; | 1288 | card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; |
1271 | } | 1289 | } |
1290 | mmc_release_host(host); | ||
1272 | } | 1291 | } |
1273 | 1292 | ||
1274 | /* | 1293 | /* |
@@ -1327,12 +1346,28 @@ static void mmc_power_up(struct mmc_host *host) | |||
1327 | 1346 | ||
1328 | void mmc_power_off(struct mmc_host *host) | 1347 | void mmc_power_off(struct mmc_host *host) |
1329 | { | 1348 | { |
1349 | int err = 0; | ||
1330 | mmc_host_clk_hold(host); | 1350 | mmc_host_clk_hold(host); |
1331 | 1351 | ||
1332 | host->ios.clock = 0; | 1352 | host->ios.clock = 0; |
1333 | host->ios.vdd = 0; | 1353 | host->ios.vdd = 0; |
1334 | 1354 | ||
1335 | mmc_poweroff_notify(host); | 1355 | /* |
1356 | * For eMMC 4.5 device send AWAKE command before | ||
1357 | * POWER_OFF_NOTIFY command, because in sleep state | ||
1358 | * eMMC 4.5 devices respond to only RESET and AWAKE cmd | ||
1359 | */ | ||
1360 | if (host->card && mmc_card_is_sleep(host->card) && | ||
1361 | host->bus_ops->resume) { | ||
1362 | err = host->bus_ops->resume(host); | ||
1363 | |||
1364 | if (!err) | ||
1365 | mmc_poweroff_notify(host); | ||
1366 | else | ||
1367 | pr_warning("%s: error %d during resume " | ||
1368 | "(continue with poweroff sequence)\n", | ||
1369 | mmc_hostname(host), err); | ||
1370 | } | ||
1336 | 1371 | ||
1337 | /* | 1372 | /* |
1338 | * Reset ocr mask to be the highest possible voltage supported for | 1373 | * Reset ocr mask to be the highest possible voltage supported for |
@@ -2386,12 +2421,6 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2386 | */ | 2421 | */ |
2387 | if (mmc_try_claim_host(host)) { | 2422 | if (mmc_try_claim_host(host)) { |
2388 | if (host->bus_ops->suspend) { | 2423 | if (host->bus_ops->suspend) { |
2389 | /* | ||
2390 | * For eMMC 4.5 device send notify command | ||
2391 | * before sleep, because in sleep state eMMC 4.5 | ||
2392 | * devices respond to only RESET and AWAKE cmd | ||
2393 | */ | ||
2394 | mmc_poweroff_notify(host); | ||
2395 | err = host->bus_ops->suspend(host); | 2424 | err = host->bus_ops->suspend(host); |
2396 | } | 2425 | } |
2397 | mmc_do_release_host(host); | 2426 | mmc_do_release_host(host); |