From 297c7f2f158f7dfa9ab5813260ff954f9c2f83d2 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 9 Jun 2011 23:40:27 +0000 Subject: mmc: sdio: fix runtime PM path during driver removal After commit e1866b3 "PM / Runtime: Rework runtime PM handling during driver removal" was introduced, the driver core stopped incrementing the runtime PM usage counter of the device during the invocation of the ->remove() callback. This indirectly broke SDIO's runtime PM path during driver removal, because no one calls _put_sync() anymore after ->remove() completes. This means that the power of runtime-PM-managed SDIO cards is kept high after their driver is removed (even if it was powered down beforehand). Fix that by directly calling _put_sync() when the last usage counter is downref'ed by the SDIO bus. Reported-and-tested-by: Daniel Drake Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/core/sdio_bus.c') diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index d29b9c36919a..d2565df8a7fb 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -189,7 +189,7 @@ static int sdio_bus_remove(struct device *dev) /* Then undo the runtime PM settings in sdio_bus_probe() */ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) - pm_runtime_put_noidle(dev); + pm_runtime_put_sync(dev); out: return ret; -- cgit From ecc024419a13da1e589aebc422d9d1e3c0124ba4 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Sun, 17 Jul 2011 16:38:21 +0100 Subject: mmc: fix runtime PM with -ENOSYS suspend case In the case where a driver returns -ENOSYS from its suspend handler to indicate that the device should be powered down over suspend, the remove routine of the driver was not being called, leading to lots of confusion during resume. The problem is that runtime PM is disabled during this process, and when we reach mmc_sdio_remove, calling the runtime PM functions here (validly) return errors, and this was causing us to skip the remove function. Fix this by ignoring the error value of pm_runtime_get_sync(), which can return valid errors. This also matches the behaviour of pci_device_remove(). Signed-off-by: Daniel Drake Signed-off-by: Chris Ball --- drivers/mmc/core/sdio_bus.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/mmc/core/sdio_bus.c') diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index d2565df8a7fb..e4e6822d09e3 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -167,11 +167,8 @@ static int sdio_bus_remove(struct device *dev) int ret = 0; /* Make sure card is powered before invoking ->remove() */ - if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) { - ret = pm_runtime_get_sync(dev); - if (ret < 0) - goto out; - } + if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) + pm_runtime_get_sync(dev); drv->remove(func); @@ -191,7 +188,6 @@ static int sdio_bus_remove(struct device *dev) if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) pm_runtime_put_sync(dev); -out: return ret; } -- cgit