diff options
Diffstat (limited to 'drivers/base/power/wakeup.c')
-rw-r--r-- | drivers/base/power/wakeup.c | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index cdd6f256da59..ea01621ed769 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -19,6 +19,11 @@ #include "power.h" +#ifndef CONFIG_SUSPEND +suspend_state_t pm_suspend_target_state; +#define pm_suspend_target_state (PM_SUSPEND_ON) +#endif + /* * If set, the suspend/hibernate code will abort transitions to a sleep state * if wakeup events are registered during or immediately before the transition. @@ -54,7 +59,7 @@ static unsigned int saved_count; static DEFINE_SPINLOCK(events_lock); -static void pm_wakeup_timer_fn(unsigned long data); +static void pm_wakeup_timer_fn(struct timer_list *t); static LIST_HEAD(wakeup_sources); @@ -176,7 +181,7 @@ void wakeup_source_add(struct wakeup_source *ws) return; spin_lock_init(&ws->lock); - setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws); + timer_setup(&ws->timer, pm_wakeup_timer_fn, 0); ws->active = false; ws->last_time = ktime_get(); @@ -268,6 +273,9 @@ int device_wakeup_enable(struct device *dev) if (!dev || !dev->power.can_wakeup) return -EINVAL; + if (pm_suspend_target_state != PM_SUSPEND_ON) + dev_dbg(dev, "Suspicious %s() during system transition!\n", __func__); + ws = wakeup_source_register(dev_name(dev)); if (!ws) return -ENOMEM; @@ -291,22 +299,19 @@ EXPORT_SYMBOL_GPL(device_wakeup_enable); * * Call under the device's power.lock lock. */ -int device_wakeup_attach_irq(struct device *dev, +void device_wakeup_attach_irq(struct device *dev, struct wake_irq *wakeirq) { struct wakeup_source *ws; ws = dev->power.wakeup; - if (!ws) { - dev_err(dev, "forgot to call call device_init_wakeup?\n"); - return -EINVAL; - } + if (!ws) + return; if (ws->wakeirq) - return -EEXIST; + dev_err(dev, "Leftover wakeup IRQ found, overriding\n"); ws->wakeirq = wakeirq; - return 0; } /** @@ -448,9 +453,7 @@ int device_init_wakeup(struct device *dev, bool enable) device_set_wakeup_capable(dev, true); ret = device_wakeup_enable(dev); } else { - if (dev->power.can_wakeup) - device_wakeup_disable(dev); - + device_wakeup_disable(dev); device_set_wakeup_capable(dev, false); } @@ -464,9 +467,6 @@ EXPORT_SYMBOL_GPL(device_init_wakeup); */ int device_set_wakeup_enable(struct device *dev, bool enable) { - if (!dev || !dev->power.can_wakeup) - return -EINVAL; - return enable ? device_wakeup_enable(dev) : device_wakeup_disable(dev); } EXPORT_SYMBOL_GPL(device_set_wakeup_enable); @@ -481,8 +481,7 @@ static bool wakeup_source_not_registered(struct wakeup_source *ws) * Use timer struct to check if the given source is initialized * by wakeup_source_add. */ - return ws->timer.function != pm_wakeup_timer_fn || - ws->timer.data != (unsigned long)ws; + return ws->timer.function != pm_wakeup_timer_fn; } /* @@ -724,9 +723,9 @@ EXPORT_SYMBOL_GPL(pm_relax); * in @data if it is currently active and its timer has not been canceled and * the expiration time of the timer is not in future. */ -static void pm_wakeup_timer_fn(unsigned long data) +static void pm_wakeup_timer_fn(struct timer_list *t) { - struct wakeup_source *ws = (struct wakeup_source *)data; + struct wakeup_source *ws = from_timer(ws, t, timer); unsigned long flags; spin_lock_irqsave(&ws->lock, flags); |