diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-10-11 14:43:46 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-11 14:43:46 -0400 |
commit | d86a4f2dd4ec554cf3346f4cab763925761c4095 (patch) | |
tree | b101bd903187c5dbf3201986c2e9f7bcaf20b402 /drivers/net | |
parent | bf53f939e02c0e818df93ab130fedc0e4ba95796 (diff) | |
parent | 674f3058c806ae2591b98f59194fa85b650aa667 (diff) |
Merge branch 'wireless-next' of git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_sdio.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 4c250d7dc3fa..784ef3432641 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mmc/card.h> | 30 | #include <linux/mmc/card.h> |
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/wl12xx.h> | 32 | #include <linux/wl12xx.h> |
33 | #include <linux/pm_runtime.h> | ||
33 | 34 | ||
34 | #include "wl1271.h" | 35 | #include "wl1271.h" |
35 | #include "wl12xx_80211.h" | 36 | #include "wl12xx_80211.h" |
@@ -160,12 +161,19 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
160 | static int wl1271_sdio_power_on(struct wl1271 *wl) | 161 | static int wl1271_sdio_power_on(struct wl1271 *wl) |
161 | { | 162 | { |
162 | struct sdio_func *func = wl_to_func(wl); | 163 | struct sdio_func *func = wl_to_func(wl); |
164 | int ret; | ||
165 | |||
166 | /* Power up the card */ | ||
167 | ret = pm_runtime_get_sync(&func->dev); | ||
168 | if (ret < 0) | ||
169 | goto out; | ||
163 | 170 | ||
164 | sdio_claim_host(func); | 171 | sdio_claim_host(func); |
165 | sdio_enable_func(func); | 172 | sdio_enable_func(func); |
166 | sdio_release_host(func); | 173 | sdio_release_host(func); |
167 | 174 | ||
168 | return 0; | 175 | out: |
176 | return ret; | ||
169 | } | 177 | } |
170 | 178 | ||
171 | static int wl1271_sdio_power_off(struct wl1271 *wl) | 179 | static int wl1271_sdio_power_off(struct wl1271 *wl) |
@@ -176,15 +184,12 @@ static int wl1271_sdio_power_off(struct wl1271 *wl) | |||
176 | sdio_disable_func(func); | 184 | sdio_disable_func(func); |
177 | sdio_release_host(func); | 185 | sdio_release_host(func); |
178 | 186 | ||
179 | return 0; | 187 | /* Power down the card */ |
188 | return pm_runtime_put_sync(&func->dev); | ||
180 | } | 189 | } |
181 | 190 | ||
182 | static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) | 191 | static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) |
183 | { | 192 | { |
184 | /* Let the SDIO stack handle wlan_enable control, so we | ||
185 | * keep host claimed while wlan is in use to keep wl1271 | ||
186 | * alive. | ||
187 | */ | ||
188 | if (enable) | 193 | if (enable) |
189 | return wl1271_sdio_power_on(wl); | 194 | return wl1271_sdio_power_on(wl); |
190 | else | 195 | else |
@@ -256,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
256 | 261 | ||
257 | sdio_set_drvdata(func, wl); | 262 | sdio_set_drvdata(func, wl); |
258 | 263 | ||
264 | /* Tell PM core that we don't need the card to be powered now */ | ||
265 | pm_runtime_put_noidle(&func->dev); | ||
266 | |||
259 | wl1271_notice("initialized"); | 267 | wl1271_notice("initialized"); |
260 | 268 | ||
261 | return 0; | 269 | return 0; |
@@ -274,16 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func) | |||
274 | { | 282 | { |
275 | struct wl1271 *wl = sdio_get_drvdata(func); | 283 | struct wl1271 *wl = sdio_get_drvdata(func); |
276 | 284 | ||
285 | /* Undo decrement done above in wl1271_probe */ | ||
286 | pm_runtime_get_noresume(&func->dev); | ||
287 | |||
277 | wl1271_unregister_hw(wl); | 288 | wl1271_unregister_hw(wl); |
278 | free_irq(wl->irq, wl); | 289 | free_irq(wl->irq, wl); |
279 | wl1271_free_hw(wl); | 290 | wl1271_free_hw(wl); |
280 | } | 291 | } |
281 | 292 | ||
293 | static int wl1271_suspend(struct device *dev) | ||
294 | { | ||
295 | /* Tell MMC/SDIO core it's OK to power down the card | ||
296 | * (if it isn't already), but not to remove it completely */ | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static int wl1271_resume(struct device *dev) | ||
301 | { | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static const struct dev_pm_ops wl1271_sdio_pm_ops = { | ||
306 | .suspend = wl1271_suspend, | ||
307 | .resume = wl1271_resume, | ||
308 | }; | ||
309 | |||
282 | static struct sdio_driver wl1271_sdio_driver = { | 310 | static struct sdio_driver wl1271_sdio_driver = { |
283 | .name = "wl1271_sdio", | 311 | .name = "wl1271_sdio", |
284 | .id_table = wl1271_devices, | 312 | .id_table = wl1271_devices, |
285 | .probe = wl1271_probe, | 313 | .probe = wl1271_probe, |
286 | .remove = __devexit_p(wl1271_remove), | 314 | .remove = __devexit_p(wl1271_remove), |
315 | .drv = { | ||
316 | .pm = &wl1271_sdio_pm_ops, | ||
317 | }, | ||
287 | }; | 318 | }; |
288 | 319 | ||
289 | static int __init wl1271_init(void) | 320 | static int __init wl1271_init(void) |