Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ohad Ben-Cohen and committed by
Chris Ball
4d0812c3 b432b4b3

+13 -3
+13 -3
drivers/mmc/core/sdio.c
··· 560 560 561 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 + 563 576 out: 564 577 if (err) { 565 578 mmc_sdio_remove(host); ··· 581 568 mmc_detach_bus(host); 582 569 mmc_release_host(host); 583 570 } 584 - 585 - /* Tell PM core that we're done */ 586 - pm_runtime_put(&host->card->dev); 587 571 } 588 572 589 573 /*