summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ti/wlcore/main.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2018-10-01 14:41:10 -0700
committerKalle Valo <kvalo@codeaurora.org>2018-10-05 11:33:31 +0300
commit3c83dd577c7f3f49420c661e693be7049bf0ca02 (patch)
tree01b44ef02898b35ea1d8ab07cf87f7e3958d2be6 /drivers/net/wireless/ti/wlcore/main.c
parent4e651bad848955d88b29a568bfbfb4b831270e16 (diff)
wlcore: Add support for optional wakeirq
Now with wlcore using PM runtime, we can also add support for Linux generic wakeirq handling for it if configured in the dts file. The wakeirq can be configured as the second interrupt in the dts file with interrupts-extended property where it is the padconf irq of the OOB GPIO pin used for wlcore interrupt. Note that eventually we should also allow configuring wlcore to use the SDIO dat1 IRQ for wake-up, and in that case the the wakeirq should be configured to be the padconf interrupt of the dat1 pin and not the padconf interrupt of the OOB GPIO pin. Cc: Eyal Reizer <eyalr@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/main.c')
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 19e3c5a0b715..26b187336875 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_wakeirq.h>
#include "wlcore.h"
#include "debug.h"
@@ -6627,13 +6628,25 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
}
#ifdef CONFIG_PM
+ device_init_wakeup(wl->dev, true);
+
ret = enable_irq_wake(wl->irq);
if (!ret) {
wl->irq_wake_enabled = true;
- device_init_wakeup(wl->dev, 1);
if (pdev_data->pwr_in_suspend)
wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
}
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ if (res) {
+ wl->wakeirq = res->start;
+ wl->wakeirq_flags = res->flags & IRQF_TRIGGER_MASK;
+ ret = dev_pm_set_dedicated_wake_irq(wl->dev, wl->wakeirq);
+ if (ret)
+ wl->wakeirq = -ENODEV;
+ } else {
+ wl->wakeirq = -ENODEV;
+ }
#endif
disable_irq(wl->irq);
wl1271_power_off(wl);
@@ -6661,6 +6674,9 @@ out_unreg:
wl1271_unregister_hw(wl);
out_irq:
+ if (wl->wakeirq >= 0)
+ dev_pm_clear_wake_irq(wl->dev);
+ device_init_wakeup(wl->dev, false);
free_irq(wl->irq, wl);
out_free_nvs:
@@ -6825,10 +6841,16 @@ int wlcore_remove(struct platform_device *pdev)
if (!wl->initialized)
return 0;
- if (wl->irq_wake_enabled) {
- device_init_wakeup(wl->dev, 0);
- disable_irq_wake(wl->irq);
+ if (wl->wakeirq >= 0) {
+ dev_pm_clear_wake_irq(wl->dev);
+ wl->wakeirq = -ENODEV;
}
+
+ device_init_wakeup(wl->dev, false);
+
+ if (wl->irq_wake_enabled)
+ disable_irq_wake(wl->irq);
+
wl1271_unregister_hw(wl);
pm_runtime_put_sync(wl->dev);