diff options
author | Andy Green <andy.green@linaro.org> | 2011-05-02 12:53:55 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2011-05-02 12:53:55 +0800 |
commit | 7482b9bc86482f490d812f5c507767cd60bef6a7 (patch) | |
tree | 53cdd9a06dfc1c32e63780d0b18a043b077981e1 | |
parent | 950903b0cbcab05a0ce83afa40fa21ca2e6b6087 (diff) |
DRIVERS: WLAN: WL12XX provide driver runtime pm idle
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 | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 41beaba49a4..003ab03842b 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> @@ -159,7 +160,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) struct sdio_func *func = wl_to_func(wl); int ret; - /* Make sure the card will not be powered off by runtime PM */ + /* Power up the card */ ret = pm_runtime_get_sync(&func->dev); if (ret < 0) goto out; @@ -318,9 +319,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 = { |