diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/core/core.c | 12 | ||||
| -rw-r--r-- | drivers/mmc/core/sdio_io.c | 49 |
2 files changed, 58 insertions, 3 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 30acd5265821..f4b97d3c3d0f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -1151,6 +1151,9 @@ void mmc_stop_host(struct mmc_host *host) | |||
| 1151 | cancel_delayed_work(&host->detect); | 1151 | cancel_delayed_work(&host->detect); |
| 1152 | mmc_flush_scheduled_work(); | 1152 | mmc_flush_scheduled_work(); |
| 1153 | 1153 | ||
| 1154 | /* clear pm flags now and let card drivers set them as needed */ | ||
| 1155 | host->pm_flags = 0; | ||
| 1156 | |||
| 1154 | mmc_bus_get(host); | 1157 | mmc_bus_get(host); |
| 1155 | if (host->bus_ops && !host->bus_dead) { | 1158 | if (host->bus_ops && !host->bus_dead) { |
| 1156 | if (host->bus_ops->remove) | 1159 | if (host->bus_ops->remove) |
| @@ -1273,12 +1276,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | |||
| 1273 | mmc_claim_host(host); | 1276 | mmc_claim_host(host); |
| 1274 | mmc_detach_bus(host); | 1277 | mmc_detach_bus(host); |
| 1275 | mmc_release_host(host); | 1278 | mmc_release_host(host); |
| 1279 | host->pm_flags = 0; | ||
| 1276 | err = 0; | 1280 | err = 0; |
| 1277 | } | 1281 | } |
| 1278 | } | 1282 | } |
| 1279 | mmc_bus_put(host); | 1283 | mmc_bus_put(host); |
| 1280 | 1284 | ||
| 1281 | if (!err) | 1285 | if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER)) |
| 1282 | mmc_power_off(host); | 1286 | mmc_power_off(host); |
| 1283 | 1287 | ||
| 1284 | return err; | 1288 | return err; |
| @@ -1296,8 +1300,10 @@ int mmc_resume_host(struct mmc_host *host) | |||
| 1296 | 1300 | ||
| 1297 | mmc_bus_get(host); | 1301 | mmc_bus_get(host); |
| 1298 | if (host->bus_ops && !host->bus_dead) { | 1302 | if (host->bus_ops && !host->bus_dead) { |
| 1299 | mmc_power_up(host); | 1303 | if (!(host->pm_flags & MMC_PM_KEEP_POWER)) { |
| 1300 | mmc_select_voltage(host, host->ocr); | 1304 | mmc_power_up(host); |
| 1305 | mmc_select_voltage(host, host->ocr); | ||
| 1306 | } | ||
| 1301 | BUG_ON(!host->bus_ops->resume); | 1307 | BUG_ON(!host->bus_ops->resume); |
| 1302 | err = host->bus_ops->resume(host); | 1308 | err = host->bus_ops->resume(host); |
| 1303 | if (err) { | 1309 | if (err) { |
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 87c618904ee2..ff27c8c71355 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c | |||
| @@ -640,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, | |||
| 640 | *err_ret = ret; | 640 | *err_ret = ret; |
| 641 | } | 641 | } |
| 642 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); | 642 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); |
| 643 | |||
| 644 | /** | ||
| 645 | * sdio_get_host_pm_caps - get host power management capabilities | ||
| 646 | * @func: SDIO function attached to host | ||
| 647 | * | ||
| 648 | * Returns a capability bitmask corresponding to power management | ||
| 649 | * features supported by the host controller that the card function | ||
| 650 | * might rely upon during a system suspend. The host doesn't need | ||
| 651 | * to be claimed, nor the function active, for this information to be | ||
| 652 | * obtained. | ||
| 653 | */ | ||
| 654 | mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func) | ||
| 655 | { | ||
| 656 | BUG_ON(!func); | ||
| 657 | BUG_ON(!func->card); | ||
| 658 | |||
| 659 | return func->card->host->pm_caps; | ||
| 660 | } | ||
| 661 | EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps); | ||
| 662 | |||
| 663 | /** | ||
| 664 | * sdio_set_host_pm_flags - set wanted host power management capabilities | ||
| 665 | * @func: SDIO function attached to host | ||
| 666 | * | ||
| 667 | * Set a capability bitmask corresponding to wanted host controller | ||
| 668 | * power management features for the upcoming suspend state. | ||
| 669 | * This must be called, if needed, each time the suspend method of | ||
| 670 | * the function driver is called, and must contain only bits that | ||
| 671 | * were returned by sdio_get_host_pm_caps(). | ||
| 672 | * The host doesn't need to be claimed, nor the function active, | ||
| 673 | * for this information to be set. | ||
| 674 | */ | ||
| 675 | int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags) | ||
| 676 | { | ||
| 677 | struct mmc_host *host; | ||
| 678 | |||
| 679 | BUG_ON(!func); | ||
| 680 | BUG_ON(!func->card); | ||
| 681 | |||
| 682 | host = func->card->host; | ||
| 683 | |||
| 684 | if (flags & ~host->pm_caps) | ||
| 685 | return -EINVAL; | ||
| 686 | |||
| 687 | /* function suspend methods are serialized, hence no lock needed */ | ||
| 688 | host->pm_flags |= flags; | ||
| 689 | return 0; | ||
| 690 | } | ||
| 691 | EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags); | ||
