summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Green <andy.green@linaro.org>2011-05-02 12:53:55 +0800
committerAndy Green <andy.green@linaro.org>2011-05-02 12:53:55 +0800
commit7482b9bc86482f490d812f5c507767cd60bef6a7 (patch)
tree53cdd9a06dfc1c32e63780d0b18a043b077981e1
parent950903b0cbcab05a0ce83afa40fa21ca2e6b6087 (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.c17
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 = {