Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 224340
b: refs/heads/master
c: 1d4b89f
h: refs/heads/master
v: v3
  • Loading branch information
Grazvydas Ignotas authored and John W. Linville committed Nov 15, 2010
1 parent 3ee2531 commit 6c16175
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cb7bbc7a5535ab2333915b83391e1d846a0914df
refs/heads/master: 1d4b89f2970f9ea0902d0a3bc1090f3c770b5080
64 changes: 61 additions & 3 deletions trunk/drivers/net/wireless/wl1251/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/platform_device.h>
#include <linux/wl12xx.h>
#include <linux/irq.h>
#include <linux/pm_runtime.h>

#include "wl1251.h"

Expand Down Expand Up @@ -173,10 +174,40 @@ static void wl1251_disable_line_irq(struct wl1251 *wl)

static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
{
if (wl->set_power)
wl->set_power(enable);
struct sdio_func *func = wl_to_func(wl);
int ret;

return 0;
if (enable) {
/*
* Power is controlled by runtime PM, but we still call board
* callback in case it wants to do any additional setup,
* for example enabling clock buffer for the module.
*/
if (wl->set_power)
wl->set_power(true);

ret = pm_runtime_get_sync(&func->dev);
if (ret < 0)
goto out;

sdio_claim_host(func);
sdio_enable_func(func);
sdio_release_host(func);
} else {
sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);

ret = pm_runtime_put_sync(&func->dev);
if (ret < 0)
goto out;

if (wl->set_power)
wl->set_power(false);
}

out:
return ret;
}

static struct wl1251_if_operations wl1251_sdio_ops = {
Expand Down Expand Up @@ -277,6 +308,10 @@ static int wl1251_sdio_probe(struct sdio_func *func,
goto out_free_irq;

sdio_set_drvdata(func, wl);

/* Tell PM core that we don't need the card to be powered now */
pm_runtime_put_noidle(&func->dev);

return ret;

out_free_irq:
Expand All @@ -298,6 +333,9 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
struct wl1251 *wl = sdio_get_drvdata(func);
struct wl1251_sdio *wl_sdio = wl->if_priv;

/* Undo decrement done above in wl1251_probe */
pm_runtime_get_noresume(&func->dev);

if (wl->irq)
free_irq(wl->irq, wl);
kfree(wl_sdio);
Expand All @@ -309,11 +347,31 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
sdio_release_host(func);
}

static int wl1251_suspend(struct device *dev)
{
/*
* Tell MMC/SDIO core it's OK to power down the card
* (if it isn't already), but not to remove it completely.
*/
return 0;
}

static int wl1251_resume(struct device *dev)
{
return 0;
}

static const struct dev_pm_ops wl1251_sdio_pm_ops = {
.suspend = wl1251_suspend,
.resume = wl1251_resume,
};

static struct sdio_driver wl1251_sdio_driver = {
.name = "wl1251_sdio",
.id_table = wl1251_devices,
.probe = wl1251_sdio_probe,
.remove = __devexit_p(wl1251_sdio_remove),
.drv.pm = &wl1251_sdio_pm_ops,
};

static int __init wl1251_sdio_init(void)
Expand Down

0 comments on commit 6c16175

Please sign in to comment.