summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Green <andy.green@linaro.org>2011-03-25 14:23:51 +0000
committerSebastien Jan <s-jan@ti.com>2011-03-30 19:20:48 +0200
commit555c787abb033df7a678b3c4fdb2e51c4cf44d32 (patch)
treec5ed8ba060ba315b8b60ec8a48e93c462e4e4d21
parent1aa523c2d964de4872b31caddf0a9f1ac4eb2e96 (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.c20
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 = {