aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2010-11-14 05:40:33 -0500
committerChris Ball <cjb@laptop.org>2010-11-19 17:06:52 -0500
commit4d0812c37f2f6cf6fc7ca086b5a5e572cbbe7f6d (patch)
treed9952cc0c7e88030db701434dd056fa99aa96150 /drivers/mmc
parentb432b4b3440a34c1430fcd66bab783640724bd28 (diff)
mmc: sdio: fix nasty oops in mmc_sdio_detect
Power off the card in mmc_sdio_detect __before__ a potential error handler, which completely removes the card, executes, and only if the card was successfully powered on beforehand. While we're at it, use the _sync variant of the runtime PM put API, in order to ensure that the card is left powered off in case an error occurred, and the card is going to be removed. Reproduced and tested on the OLPC XO-1.5. Reported-by: Daniel Drake <dsd@laptop.org> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sdio.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index c3ad1058cd31..42a949b723b8 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -560,6 +560,19 @@ static void mmc_sdio_detect(struct mmc_host *host)
560 560
561 mmc_release_host(host); 561 mmc_release_host(host);
562 562
563 /*
564 * Tell PM core it's OK to power off the card now.
565 *
566 * The _sync variant is used in order to ensure that the card
567 * is left powered off in case an error occurred, and the card
568 * is going to be removed.
569 *
570 * Since there is no specific reason to believe a new user
571 * is about to show up at this point, the _sync variant is
572 * desirable anyway.
573 */
574 pm_runtime_put_sync(&host->card->dev);
575
563out: 576out:
564 if (err) { 577 if (err) {
565 mmc_sdio_remove(host); 578 mmc_sdio_remove(host);
@@ -568,9 +581,6 @@ out:
568 mmc_detach_bus(host); 581 mmc_detach_bus(host);
569 mmc_release_host(host); 582 mmc_release_host(host);
570 } 583 }
571
572 /* Tell PM core that we're done */
573 pm_runtime_put(&host->card->dev);
574} 584}
575 585
576/* 586/*