diff options
author | Andy Green <andy.green@linaro.org> | 2011-03-25 14:23:51 +0000 |
---|---|---|
committer | Sebastien Jan <s-jan@ti.com> | 2011-03-30 19:20:48 +0200 |
commit | 555c787abb033df7a678b3c4fdb2e51c4cf44d32 (patch) | |
tree | c5ed8ba060ba315b8b60ec8a48e93c462e4e4d21 | |
parent | 1aa523c2d964de4872b31caddf0a9f1ac4eb2e96 (diff) |
DRIVERS: WLAN: WL12XX provide driver runtime pm idleint-2.6.38-iv11
WL12XX fails to do power management in MMC layer when the last runtime_pm put
is done and it calls runtime_pm_idle to indicate the device is not in use.
The real reason seems to be to do with the .1 device, SDIO bluetooth,
holding open the connection.
This works around the problem by forcing power down in a local
runtime_idle.
Signed-off-by: Andy Green <andy.green@linaro.org>
-rw-r--r-- | drivers/net/wireless/wl12xx/sdio.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 93cbb8d5aba..8c0eb433a35 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,6 +164,11 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) struct sdio_func *func = wl_to_func(wl); int ret; + /* + * defeat the runtime_idle OFF state + */ + mmc_power_restore_host(func->card->host); + /* Power up the card */ ret = pm_runtime_get_sync(&func->dev); if (ret < 0) @@ -302,9 +308,23 @@ static int wl1271_resume(struct device *dev) return 0; } +/* + * SDIO bus runtime idle gets precedence over this, but that just calls + * the generic version. The generic version will call our version if + * it exists, so we still get called. We need to allow it to power us + * off. + */ +static int wl1271_runtime_idle(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + + return mmc_power_save_host(func->card->host); +} + static const struct dev_pm_ops wl1271_sdio_pm_ops = { .suspend = wl1271_suspend, .resume = wl1271_resume, + .runtime_idle = wl1271_runtime_idle, }; static struct sdio_driver wl1271_sdio_driver = { |