#include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_wakeirq.h>
 
 #include "wlcore.h"
 #include "debug.h"
        }
 
 #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);
        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:
        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);
 
        { }
 };
 
-static int wlcore_probe_of(struct device *dev, int *irq,
+static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq,
                           struct wlcore_platdev_data *pdev_data)
 {
        struct device_node *np = dev->of_node;
                return -EINVAL;
        }
 
+       *wakeirq = irq_of_parse_and_map(np, 1);
+
        /* optional clock frequency params */
        of_property_read_u32(np, "ref-clock-frequency",
                             &pdev_data->ref_clock_freq);
        return 0;
 }
 #else
-static int wlcore_probe_of(struct device *dev, int *irq,
+static int wlcore_probe_of(struct device *dev, int *irq, int *wakeirq,
                           struct wlcore_platdev_data *pdev_data)
 {
        return -ENODATA;
 {
        struct wlcore_platdev_data *pdev_data;
        struct wl12xx_sdio_glue *glue;
-       struct resource res[1];
+       struct resource res[2];
        mmc_pm_flag_t mmcflags;
        int ret = -ENOMEM;
-       int irq;
+       int irq, wakeirq;
        const char *chip_family;
 
        /* We are only able to handle the wlan function */
        /* Use block mode for transferring over one block size of data */
        func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
 
-       ret = wlcore_probe_of(&func->dev, &irq, pdev_data);
+       ret = wlcore_probe_of(&func->dev, &irq, &wakeirq, pdev_data);
        if (ret)
                goto out;
 
                       irqd_get_trigger_type(irq_get_irq_data(irq));
        res[0].name = "irq";
 
+       res[1].start = wakeirq;
+       res[1].flags = IORESOURCE_IRQ |
+                      irqd_get_trigger_type(irq_get_irq_data(wakeirq));
+       res[1].name = "wakeirq";
+
        ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
        if (ret) {
                dev_err(glue->dev, "can't add resources\n");