summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Yariv <ido@wizery.com>2011-02-28 00:13:58 +0200
committerLuciano Coelho <coelho@ti.com>2011-03-03 16:10:45 +0200
commit11251e7e5c7c5411d1f77dbc7f9bfa2c23626749 (patch)
tree95def2eccf41fbe98b8a4141127b179a466c0d76
parentf62c317c1f7f67c249ee9254e55a02fad0d0f86b (diff)
downloadlinux-11251e7e5c7c5411d1f77dbc7f9bfa2c23626749.tar.bz2
wl12xx: Don't rely on runtime PM for toggling power
Runtime PM might not always be enabled. Even if it is enabled in the running kernel, it can still be temporarily disabled, for instance during suspend. Runtime PM is opportunistic in nature, and should not be relied on for toggling power. In case the interface is removed and re-added while runtime PM is disabled, the FW will fail to boot, as it is mandatory to toggle power between boots. For instance, this can happen during suspend in case one of the devices fails to suspend before the MMC host suspends, but after mac80211 was suspended. The interface will be removed and reactivated without toggling the power. Fix this by calling mmc_power_save_host/mmc_power_restore_host in wl1271_sdio_power_on/off functions. It will toggle the power to the chip even if runtime PM is disabled. The runtime PM functions should still be called to make sure runtime PM does not opportunistically power the chip off (e.g. after resuming from system suspend). Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index d5e874825069..f27e91502631 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -28,6 +28,7 @@
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
#include <linux/gpio.h>
#include <linux/wl12xx.h>
#include <linux/pm_runtime.h>
@@ -163,11 +164,16 @@ static int wl1271_sdio_power_on(struct wl1271 *wl)
struct sdio_func *func = wl_to_func(wl);
int ret;
- /* Power up the card */
+ /* Make sure the card will not be powered off by runtime PM */
ret = pm_runtime_get_sync(&func->dev);
if (ret < 0)
goto out;
+ /* Runtime PM might be disabled, so power up the card manually */
+ ret = mmc_power_restore_host(func->card->host);
+ if (ret < 0)
+ goto out;
+
sdio_claim_host(func);
sdio_enable_func(func);
sdio_release_host(func);
@@ -179,12 +185,18 @@ out:
static int wl1271_sdio_power_off(struct wl1271 *wl)
{
struct sdio_func *func = wl_to_func(wl);
+ int ret;
sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);
- /* Power down the card */
+ /* Runtime PM might be disabled, so power off the card manually */
+ ret = mmc_power_save_host(func->card->host);
+ if (ret < 0)
+ return ret;
+
+ /* Let runtime PM know the card is powered off */
return pm_runtime_put_sync(&func->dev);
}