Skip to content

Commit 3c83dd5

Browse files
tmlindKalle Valo
authored and
Kalle Valo
committed
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 <[email protected]> Signed-off-by: Tony Lindgren <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 4e651ba commit 3c83dd5

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

drivers/net/wireless/ti/wlcore/main.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <linux/interrupt.h>
2828
#include <linux/irq.h>
2929
#include <linux/pm_runtime.h>
30+
#include <linux/pm_wakeirq.h>
3031

3132
#include "wlcore.h"
3233
#include "debug.h"
@@ -6627,13 +6628,25 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
66276628
}
66286629

66296630
#ifdef CONFIG_PM
6631+
device_init_wakeup(wl->dev, true);
6632+
66306633
ret = enable_irq_wake(wl->irq);
66316634
if (!ret) {
66326635
wl->irq_wake_enabled = true;
6633-
device_init_wakeup(wl->dev, 1);
66346636
if (pdev_data->pwr_in_suspend)
66356637
wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
66366638
}
6639+
6640+
res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
6641+
if (res) {
6642+
wl->wakeirq = res->start;
6643+
wl->wakeirq_flags = res->flags & IRQF_TRIGGER_MASK;
6644+
ret = dev_pm_set_dedicated_wake_irq(wl->dev, wl->wakeirq);
6645+
if (ret)
6646+
wl->wakeirq = -ENODEV;
6647+
} else {
6648+
wl->wakeirq = -ENODEV;
6649+
}
66376650
#endif
66386651
disable_irq(wl->irq);
66396652
wl1271_power_off(wl);
@@ -6661,6 +6674,9 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
66616674
wl1271_unregister_hw(wl);
66626675

66636676
out_irq:
6677+
if (wl->wakeirq >= 0)
6678+
dev_pm_clear_wake_irq(wl->dev);
6679+
device_init_wakeup(wl->dev, false);
66646680
free_irq(wl->irq, wl);
66656681

66666682
out_free_nvs:
@@ -6825,10 +6841,16 @@ int wlcore_remove(struct platform_device *pdev)
68256841
if (!wl->initialized)
68266842
return 0;
68276843

6828-
if (wl->irq_wake_enabled) {
6829-
device_init_wakeup(wl->dev, 0);
6830-
disable_irq_wake(wl->irq);
6844+
if (wl->wakeirq >= 0) {
6845+
dev_pm_clear_wake_irq(wl->dev);
6846+
wl->wakeirq = -ENODEV;
68316847
}
6848+
6849+
device_init_wakeup(wl->dev, false);
6850+
6851+
if (wl->irq_wake_enabled)
6852+
disable_irq_wake(wl->irq);
6853+
68326854
wl1271_unregister_hw(wl);
68336855

68346856
pm_runtime_put_sync(wl->dev);

drivers/net/wireless/ti/wlcore/sdio.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static const struct of_device_id wlcore_sdio_of_match_table[] = {
241241
{ }
242242
};
243243

244-
static int wlcore_probe_of(struct device *dev, int *irq,
244+
static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq,
245245
struct wlcore_platdev_data *pdev_data)
246246
{
247247
struct device_node *np = dev->of_node;
@@ -259,6 +259,8 @@ static int wlcore_probe_of(struct device *dev, int *irq,
259259
return -EINVAL;
260260
}
261261

262+
*wakeirq = irq_of_parse_and_map(np, 1);
263+
262264
/* optional clock frequency params */
263265
of_property_read_u32(np, "ref-clock-frequency",
264266
&pdev_data->ref_clock_freq);
@@ -268,7 +270,7 @@ static int wlcore_probe_of(struct device *dev, int *irq,
268270
return 0;
269271
}
270272
#else
271-
static int wlcore_probe_of(struct device *dev, int *irq,
273+
static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq,
272274
struct wlcore_platdev_data *pdev_data)
273275
{
274276
return -ENODATA;
@@ -280,10 +282,10 @@ static int wl1271_probe(struct sdio_func *func,
280282
{
281283
struct wlcore_platdev_data *pdev_data;
282284
struct wl12xx_sdio_glue *glue;
283-
struct resource res[1];
285+
struct resource res[2];
284286
mmc_pm_flag_t mmcflags;
285287
int ret = -ENOMEM;
286-
int irq;
288+
int irq, wakeirq;
287289
const char *chip_family;
288290

289291
/* We are only able to handle the wlan function */
@@ -308,7 +310,7 @@ static int wl1271_probe(struct sdio_func *func,
308310
/* Use block mode for transferring over one block size of data */
309311
func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
310312

311-
ret = wlcore_probe_of(&func->dev, &irq, pdev_data);
313+
ret = wlcore_probe_of(&func->dev, &irq, &wakeirq, pdev_data);
312314
if (ret)
313315
goto out;
314316

@@ -351,6 +353,11 @@ static int wl1271_probe(struct sdio_func *func,
351353
irqd_get_trigger_type(irq_get_irq_data(irq));
352354
res[0].name = "irq";
353355

356+
res[1].start = wakeirq;
357+
res[1].flags = IORESOURCE_IRQ |
358+
irqd_get_trigger_type(irq_get_irq_data(wakeirq));
359+
res[1].name = "wakeirq";
360+
354361
ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
355362
if (ret) {
356363
dev_err(glue->dev, "can't add resources\n");

drivers/net/wireless/ti/wlcore/wlcore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,10 @@ struct wl1271 {
199199
struct wl1271_if_operations *if_ops;
200200

201201
int irq;
202+
int wakeirq;
202203

203204
int irq_flags;
205+
int wakeirq_flags;
204206

205207
spinlock_t wl_lock;
206208

0 commit comments

Comments
 (0)