xref: /OK3568_Linux_fs/kernel/drivers/base/power/wakeup.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * drivers/base/power/wakeup.c - System wakeup events framework
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun #define pr_fmt(fmt) "PM: " fmt
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/device.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/sched/signal.h>
12*4882a593Smuzhiyun #include <linux/capability.h>
13*4882a593Smuzhiyun #include <linux/export.h>
14*4882a593Smuzhiyun #include <linux/suspend.h>
15*4882a593Smuzhiyun #include <linux/seq_file.h>
16*4882a593Smuzhiyun #include <linux/debugfs.h>
17*4882a593Smuzhiyun #include <linux/pm_wakeirq.h>
18*4882a593Smuzhiyun #include <linux/irq.h>
19*4882a593Smuzhiyun #include <linux/irqdesc.h>
20*4882a593Smuzhiyun #include <linux/wakeup_reason.h>
21*4882a593Smuzhiyun #include <trace/events/power.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "power.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #ifndef CONFIG_SUSPEND
26*4882a593Smuzhiyun suspend_state_t pm_suspend_target_state;
27*4882a593Smuzhiyun #define pm_suspend_target_state	(PM_SUSPEND_ON)
28*4882a593Smuzhiyun #endif
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define list_for_each_entry_rcu_locked(pos, head, member) \
31*4882a593Smuzhiyun 	list_for_each_entry_rcu(pos, head, member, \
32*4882a593Smuzhiyun 		srcu_read_lock_held(&wakeup_srcu))
33*4882a593Smuzhiyun /*
34*4882a593Smuzhiyun  * If set, the suspend/hibernate code will abort transitions to a sleep state
35*4882a593Smuzhiyun  * if wakeup events are registered during or immediately before the transition.
36*4882a593Smuzhiyun  */
37*4882a593Smuzhiyun bool events_check_enabled __read_mostly;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* First wakeup IRQ seen by the kernel in the last cycle. */
40*4882a593Smuzhiyun static unsigned int wakeup_irq[2] __read_mostly;
41*4882a593Smuzhiyun static DEFINE_RAW_SPINLOCK(wakeup_irq_lock);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /* If greater than 0 and the system is suspending, terminate the suspend. */
44*4882a593Smuzhiyun static atomic_t pm_abort_suspend __read_mostly;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun  * Combined counters of registered wakeup events and wakeup events in progress.
48*4882a593Smuzhiyun  * They need to be modified together atomically, so it's better to use one
49*4882a593Smuzhiyun  * atomic variable to hold them both.
50*4882a593Smuzhiyun  */
51*4882a593Smuzhiyun static atomic_t combined_event_count = ATOMIC_INIT(0);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define IN_PROGRESS_BITS	(sizeof(int) * 4)
54*4882a593Smuzhiyun #define MAX_IN_PROGRESS		((1 << IN_PROGRESS_BITS) - 1)
55*4882a593Smuzhiyun 
split_counters(unsigned int * cnt,unsigned int * inpr)56*4882a593Smuzhiyun static void split_counters(unsigned int *cnt, unsigned int *inpr)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun 	unsigned int comb = atomic_read(&combined_event_count);
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	*cnt = (comb >> IN_PROGRESS_BITS);
61*4882a593Smuzhiyun 	*inpr = comb & MAX_IN_PROGRESS;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /* A preserved old value of the events counter. */
65*4882a593Smuzhiyun static unsigned int saved_count;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun static DEFINE_RAW_SPINLOCK(events_lock);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun static void pm_wakeup_timer_fn(struct timer_list *t);
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun static LIST_HEAD(wakeup_sources);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun DEFINE_STATIC_SRCU(wakeup_srcu);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun static struct wakeup_source deleted_ws = {
78*4882a593Smuzhiyun 	.name = "deleted",
79*4882a593Smuzhiyun 	.lock =  __SPIN_LOCK_UNLOCKED(deleted_ws.lock),
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun static DEFINE_IDA(wakeup_ida);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /**
85*4882a593Smuzhiyun  * wakeup_source_create - Create a struct wakeup_source object.
86*4882a593Smuzhiyun  * @name: Name of the new wakeup source.
87*4882a593Smuzhiyun  */
wakeup_source_create(const char * name)88*4882a593Smuzhiyun struct wakeup_source *wakeup_source_create(const char *name)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	struct wakeup_source *ws;
91*4882a593Smuzhiyun 	const char *ws_name;
92*4882a593Smuzhiyun 	int id;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	ws = kzalloc(sizeof(*ws), GFP_KERNEL);
95*4882a593Smuzhiyun 	if (!ws)
96*4882a593Smuzhiyun 		goto err_ws;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	ws_name = kstrdup_const(name, GFP_KERNEL);
99*4882a593Smuzhiyun 	if (!ws_name)
100*4882a593Smuzhiyun 		goto err_name;
101*4882a593Smuzhiyun 	ws->name = ws_name;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	id = ida_alloc(&wakeup_ida, GFP_KERNEL);
104*4882a593Smuzhiyun 	if (id < 0)
105*4882a593Smuzhiyun 		goto err_id;
106*4882a593Smuzhiyun 	ws->id = id;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	return ws;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun err_id:
111*4882a593Smuzhiyun 	kfree_const(ws->name);
112*4882a593Smuzhiyun err_name:
113*4882a593Smuzhiyun 	kfree(ws);
114*4882a593Smuzhiyun err_ws:
115*4882a593Smuzhiyun 	return NULL;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_source_create);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun /*
120*4882a593Smuzhiyun  * Record wakeup_source statistics being deleted into a dummy wakeup_source.
121*4882a593Smuzhiyun  */
wakeup_source_record(struct wakeup_source * ws)122*4882a593Smuzhiyun static void wakeup_source_record(struct wakeup_source *ws)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	unsigned long flags;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	spin_lock_irqsave(&deleted_ws.lock, flags);
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	if (ws->event_count) {
129*4882a593Smuzhiyun 		deleted_ws.total_time =
130*4882a593Smuzhiyun 			ktime_add(deleted_ws.total_time, ws->total_time);
131*4882a593Smuzhiyun 		deleted_ws.prevent_sleep_time =
132*4882a593Smuzhiyun 			ktime_add(deleted_ws.prevent_sleep_time,
133*4882a593Smuzhiyun 				  ws->prevent_sleep_time);
134*4882a593Smuzhiyun 		deleted_ws.max_time =
135*4882a593Smuzhiyun 			ktime_compare(deleted_ws.max_time, ws->max_time) > 0 ?
136*4882a593Smuzhiyun 				deleted_ws.max_time : ws->max_time;
137*4882a593Smuzhiyun 		deleted_ws.event_count += ws->event_count;
138*4882a593Smuzhiyun 		deleted_ws.active_count += ws->active_count;
139*4882a593Smuzhiyun 		deleted_ws.relax_count += ws->relax_count;
140*4882a593Smuzhiyun 		deleted_ws.expire_count += ws->expire_count;
141*4882a593Smuzhiyun 		deleted_ws.wakeup_count += ws->wakeup_count;
142*4882a593Smuzhiyun 	}
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	spin_unlock_irqrestore(&deleted_ws.lock, flags);
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
wakeup_source_free(struct wakeup_source * ws)147*4882a593Smuzhiyun static void wakeup_source_free(struct wakeup_source *ws)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	ida_free(&wakeup_ida, ws->id);
150*4882a593Smuzhiyun 	kfree_const(ws->name);
151*4882a593Smuzhiyun 	kfree(ws);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /**
155*4882a593Smuzhiyun  * wakeup_source_destroy - Destroy a struct wakeup_source object.
156*4882a593Smuzhiyun  * @ws: Wakeup source to destroy.
157*4882a593Smuzhiyun  *
158*4882a593Smuzhiyun  * Use only for wakeup source objects created with wakeup_source_create().
159*4882a593Smuzhiyun  */
wakeup_source_destroy(struct wakeup_source * ws)160*4882a593Smuzhiyun void wakeup_source_destroy(struct wakeup_source *ws)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	if (!ws)
163*4882a593Smuzhiyun 		return;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	__pm_relax(ws);
166*4882a593Smuzhiyun 	wakeup_source_record(ws);
167*4882a593Smuzhiyun 	wakeup_source_free(ws);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_source_destroy);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun /**
172*4882a593Smuzhiyun  * wakeup_source_add - Add given object to the list of wakeup sources.
173*4882a593Smuzhiyun  * @ws: Wakeup source object to add to the list.
174*4882a593Smuzhiyun  */
wakeup_source_add(struct wakeup_source * ws)175*4882a593Smuzhiyun void wakeup_source_add(struct wakeup_source *ws)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	unsigned long flags;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	if (WARN_ON(!ws))
180*4882a593Smuzhiyun 		return;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	spin_lock_init(&ws->lock);
183*4882a593Smuzhiyun 	timer_setup(&ws->timer, pm_wakeup_timer_fn, 0);
184*4882a593Smuzhiyun 	ws->active = false;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&events_lock, flags);
187*4882a593Smuzhiyun 	list_add_rcu(&ws->entry, &wakeup_sources);
188*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&events_lock, flags);
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_source_add);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun /**
193*4882a593Smuzhiyun  * wakeup_source_remove - Remove given object from the wakeup sources list.
194*4882a593Smuzhiyun  * @ws: Wakeup source object to remove from the list.
195*4882a593Smuzhiyun  */
wakeup_source_remove(struct wakeup_source * ws)196*4882a593Smuzhiyun void wakeup_source_remove(struct wakeup_source *ws)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	unsigned long flags;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	if (WARN_ON(!ws))
201*4882a593Smuzhiyun 		return;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&events_lock, flags);
204*4882a593Smuzhiyun 	list_del_rcu(&ws->entry);
205*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&events_lock, flags);
206*4882a593Smuzhiyun 	synchronize_srcu(&wakeup_srcu);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	del_timer_sync(&ws->timer);
209*4882a593Smuzhiyun 	/*
210*4882a593Smuzhiyun 	 * Clear timer.function to make wakeup_source_not_registered() treat
211*4882a593Smuzhiyun 	 * this wakeup source as not registered.
212*4882a593Smuzhiyun 	 */
213*4882a593Smuzhiyun 	ws->timer.function = NULL;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_source_remove);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun /**
218*4882a593Smuzhiyun  * wakeup_source_register - Create wakeup source and add it to the list.
219*4882a593Smuzhiyun  * @dev: Device this wakeup source is associated with (or NULL if virtual).
220*4882a593Smuzhiyun  * @name: Name of the wakeup source to register.
221*4882a593Smuzhiyun  */
wakeup_source_register(struct device * dev,const char * name)222*4882a593Smuzhiyun struct wakeup_source *wakeup_source_register(struct device *dev,
223*4882a593Smuzhiyun 					     const char *name)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	struct wakeup_source *ws;
226*4882a593Smuzhiyun 	int ret;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	ws = wakeup_source_create(name);
229*4882a593Smuzhiyun 	if (ws) {
230*4882a593Smuzhiyun 		if (!dev || device_is_registered(dev)) {
231*4882a593Smuzhiyun 			ret = wakeup_source_sysfs_add(dev, ws);
232*4882a593Smuzhiyun 			if (ret) {
233*4882a593Smuzhiyun 				wakeup_source_free(ws);
234*4882a593Smuzhiyun 				return NULL;
235*4882a593Smuzhiyun 			}
236*4882a593Smuzhiyun 		}
237*4882a593Smuzhiyun 		wakeup_source_add(ws);
238*4882a593Smuzhiyun 	}
239*4882a593Smuzhiyun 	return ws;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_source_register);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /**
244*4882a593Smuzhiyun  * wakeup_source_unregister - Remove wakeup source from the list and remove it.
245*4882a593Smuzhiyun  * @ws: Wakeup source object to unregister.
246*4882a593Smuzhiyun  */
wakeup_source_unregister(struct wakeup_source * ws)247*4882a593Smuzhiyun void wakeup_source_unregister(struct wakeup_source *ws)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun 	if (ws) {
250*4882a593Smuzhiyun 		wakeup_source_remove(ws);
251*4882a593Smuzhiyun 		if (ws->dev)
252*4882a593Smuzhiyun 			wakeup_source_sysfs_remove(ws);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 		wakeup_source_destroy(ws);
255*4882a593Smuzhiyun 	}
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_source_unregister);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun /**
260*4882a593Smuzhiyun  * wakeup_sources_read_lock - Lock wakeup source list for read.
261*4882a593Smuzhiyun  *
262*4882a593Smuzhiyun  * Returns an index of srcu lock for struct wakeup_srcu.
263*4882a593Smuzhiyun  * This index must be passed to the matching wakeup_sources_read_unlock().
264*4882a593Smuzhiyun  */
wakeup_sources_read_lock(void)265*4882a593Smuzhiyun int wakeup_sources_read_lock(void)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	return srcu_read_lock(&wakeup_srcu);
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_sources_read_lock);
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun /**
272*4882a593Smuzhiyun  * wakeup_sources_read_unlock - Unlock wakeup source list.
273*4882a593Smuzhiyun  * @idx: return value from corresponding wakeup_sources_read_lock()
274*4882a593Smuzhiyun  */
wakeup_sources_read_unlock(int idx)275*4882a593Smuzhiyun void wakeup_sources_read_unlock(int idx)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun 	srcu_read_unlock(&wakeup_srcu, idx);
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock);
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun /**
282*4882a593Smuzhiyun  * wakeup_sources_walk_start - Begin a walk on wakeup source list
283*4882a593Smuzhiyun  *
284*4882a593Smuzhiyun  * Returns first object of the list of wakeup sources.
285*4882a593Smuzhiyun  *
286*4882a593Smuzhiyun  * Note that to be safe, wakeup sources list needs to be locked by calling
287*4882a593Smuzhiyun  * wakeup_source_read_lock() for this.
288*4882a593Smuzhiyun  */
wakeup_sources_walk_start(void)289*4882a593Smuzhiyun struct wakeup_source *wakeup_sources_walk_start(void)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	struct list_head *ws_head = &wakeup_sources;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	return list_entry_rcu(ws_head->next, struct wakeup_source, entry);
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_sources_walk_start);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun /**
298*4882a593Smuzhiyun  * wakeup_sources_walk_next - Get next wakeup source from the list
299*4882a593Smuzhiyun  * @ws: Previous wakeup source object
300*4882a593Smuzhiyun  *
301*4882a593Smuzhiyun  * Note that to be safe, wakeup sources list needs to be locked by calling
302*4882a593Smuzhiyun  * wakeup_source_read_lock() for this.
303*4882a593Smuzhiyun  */
wakeup_sources_walk_next(struct wakeup_source * ws)304*4882a593Smuzhiyun struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun 	struct list_head *ws_head = &wakeup_sources;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	return list_next_or_null_rcu(ws_head, &ws->entry,
309*4882a593Smuzhiyun 				struct wakeup_source, entry);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(wakeup_sources_walk_next);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun /**
314*4882a593Smuzhiyun  * device_wakeup_attach - Attach a wakeup source object to a device object.
315*4882a593Smuzhiyun  * @dev: Device to handle.
316*4882a593Smuzhiyun  * @ws: Wakeup source object to attach to @dev.
317*4882a593Smuzhiyun  *
318*4882a593Smuzhiyun  * This causes @dev to be treated as a wakeup device.
319*4882a593Smuzhiyun  */
device_wakeup_attach(struct device * dev,struct wakeup_source * ws)320*4882a593Smuzhiyun static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	spin_lock_irq(&dev->power.lock);
323*4882a593Smuzhiyun 	if (dev->power.wakeup) {
324*4882a593Smuzhiyun 		spin_unlock_irq(&dev->power.lock);
325*4882a593Smuzhiyun 		return -EEXIST;
326*4882a593Smuzhiyun 	}
327*4882a593Smuzhiyun 	dev->power.wakeup = ws;
328*4882a593Smuzhiyun 	if (dev->power.wakeirq)
329*4882a593Smuzhiyun 		device_wakeup_attach_irq(dev, dev->power.wakeirq);
330*4882a593Smuzhiyun 	spin_unlock_irq(&dev->power.lock);
331*4882a593Smuzhiyun 	return 0;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun /**
335*4882a593Smuzhiyun  * device_wakeup_enable - Enable given device to be a wakeup source.
336*4882a593Smuzhiyun  * @dev: Device to handle.
337*4882a593Smuzhiyun  *
338*4882a593Smuzhiyun  * Create a wakeup source object, register it and attach it to @dev.
339*4882a593Smuzhiyun  */
device_wakeup_enable(struct device * dev)340*4882a593Smuzhiyun int device_wakeup_enable(struct device *dev)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	struct wakeup_source *ws;
343*4882a593Smuzhiyun 	int ret;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (!dev || !dev->power.can_wakeup)
346*4882a593Smuzhiyun 		return -EINVAL;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	if (pm_suspend_target_state != PM_SUSPEND_ON)
349*4882a593Smuzhiyun 		dev_dbg(dev, "Suspicious %s() during system transition!\n", __func__);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	ws = wakeup_source_register(dev, dev_name(dev));
352*4882a593Smuzhiyun 	if (!ws)
353*4882a593Smuzhiyun 		return -ENOMEM;
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	ret = device_wakeup_attach(dev, ws);
356*4882a593Smuzhiyun 	if (ret)
357*4882a593Smuzhiyun 		wakeup_source_unregister(ws);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	return ret;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(device_wakeup_enable);
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun /**
364*4882a593Smuzhiyun  * device_wakeup_attach_irq - Attach a wakeirq to a wakeup source
365*4882a593Smuzhiyun  * @dev: Device to handle
366*4882a593Smuzhiyun  * @wakeirq: Device specific wakeirq entry
367*4882a593Smuzhiyun  *
368*4882a593Smuzhiyun  * Attach a device wakeirq to the wakeup source so the device
369*4882a593Smuzhiyun  * wake IRQ can be configured automatically for suspend and
370*4882a593Smuzhiyun  * resume.
371*4882a593Smuzhiyun  *
372*4882a593Smuzhiyun  * Call under the device's power.lock lock.
373*4882a593Smuzhiyun  */
device_wakeup_attach_irq(struct device * dev,struct wake_irq * wakeirq)374*4882a593Smuzhiyun void device_wakeup_attach_irq(struct device *dev,
375*4882a593Smuzhiyun 			     struct wake_irq *wakeirq)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun 	struct wakeup_source *ws;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	ws = dev->power.wakeup;
380*4882a593Smuzhiyun 	if (!ws)
381*4882a593Smuzhiyun 		return;
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	if (ws->wakeirq)
384*4882a593Smuzhiyun 		dev_err(dev, "Leftover wakeup IRQ found, overriding\n");
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	ws->wakeirq = wakeirq;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun /**
390*4882a593Smuzhiyun  * device_wakeup_detach_irq - Detach a wakeirq from a wakeup source
391*4882a593Smuzhiyun  * @dev: Device to handle
392*4882a593Smuzhiyun  *
393*4882a593Smuzhiyun  * Removes a device wakeirq from the wakeup source.
394*4882a593Smuzhiyun  *
395*4882a593Smuzhiyun  * Call under the device's power.lock lock.
396*4882a593Smuzhiyun  */
device_wakeup_detach_irq(struct device * dev)397*4882a593Smuzhiyun void device_wakeup_detach_irq(struct device *dev)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun 	struct wakeup_source *ws;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	ws = dev->power.wakeup;
402*4882a593Smuzhiyun 	if (ws)
403*4882a593Smuzhiyun 		ws->wakeirq = NULL;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun /**
407*4882a593Smuzhiyun  * device_wakeup_arm_wake_irqs(void)
408*4882a593Smuzhiyun  *
409*4882a593Smuzhiyun  * Itereates over the list of device wakeirqs to arm them.
410*4882a593Smuzhiyun  */
device_wakeup_arm_wake_irqs(void)411*4882a593Smuzhiyun void device_wakeup_arm_wake_irqs(void)
412*4882a593Smuzhiyun {
413*4882a593Smuzhiyun 	struct wakeup_source *ws;
414*4882a593Smuzhiyun 	int srcuidx;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	srcuidx = srcu_read_lock(&wakeup_srcu);
417*4882a593Smuzhiyun 	list_for_each_entry_rcu_locked(ws, &wakeup_sources, entry)
418*4882a593Smuzhiyun 		dev_pm_arm_wake_irq(ws->wakeirq);
419*4882a593Smuzhiyun 	srcu_read_unlock(&wakeup_srcu, srcuidx);
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun /**
423*4882a593Smuzhiyun  * device_wakeup_disarm_wake_irqs(void)
424*4882a593Smuzhiyun  *
425*4882a593Smuzhiyun  * Itereates over the list of device wakeirqs to disarm them.
426*4882a593Smuzhiyun  */
device_wakeup_disarm_wake_irqs(void)427*4882a593Smuzhiyun void device_wakeup_disarm_wake_irqs(void)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun 	struct wakeup_source *ws;
430*4882a593Smuzhiyun 	int srcuidx;
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	srcuidx = srcu_read_lock(&wakeup_srcu);
433*4882a593Smuzhiyun 	list_for_each_entry_rcu_locked(ws, &wakeup_sources, entry)
434*4882a593Smuzhiyun 		dev_pm_disarm_wake_irq(ws->wakeirq);
435*4882a593Smuzhiyun 	srcu_read_unlock(&wakeup_srcu, srcuidx);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun /**
439*4882a593Smuzhiyun  * device_wakeup_detach - Detach a device's wakeup source object from it.
440*4882a593Smuzhiyun  * @dev: Device to detach the wakeup source object from.
441*4882a593Smuzhiyun  *
442*4882a593Smuzhiyun  * After it returns, @dev will not be treated as a wakeup device any more.
443*4882a593Smuzhiyun  */
device_wakeup_detach(struct device * dev)444*4882a593Smuzhiyun static struct wakeup_source *device_wakeup_detach(struct device *dev)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun 	struct wakeup_source *ws;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	spin_lock_irq(&dev->power.lock);
449*4882a593Smuzhiyun 	ws = dev->power.wakeup;
450*4882a593Smuzhiyun 	dev->power.wakeup = NULL;
451*4882a593Smuzhiyun 	spin_unlock_irq(&dev->power.lock);
452*4882a593Smuzhiyun 	return ws;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun /**
456*4882a593Smuzhiyun  * device_wakeup_disable - Do not regard a device as a wakeup source any more.
457*4882a593Smuzhiyun  * @dev: Device to handle.
458*4882a593Smuzhiyun  *
459*4882a593Smuzhiyun  * Detach the @dev's wakeup source object from it, unregister this wakeup source
460*4882a593Smuzhiyun  * object and destroy it.
461*4882a593Smuzhiyun  */
device_wakeup_disable(struct device * dev)462*4882a593Smuzhiyun int device_wakeup_disable(struct device *dev)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun 	struct wakeup_source *ws;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	if (!dev || !dev->power.can_wakeup)
467*4882a593Smuzhiyun 		return -EINVAL;
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	ws = device_wakeup_detach(dev);
470*4882a593Smuzhiyun 	wakeup_source_unregister(ws);
471*4882a593Smuzhiyun 	return 0;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(device_wakeup_disable);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun /**
476*4882a593Smuzhiyun  * device_set_wakeup_capable - Set/reset device wakeup capability flag.
477*4882a593Smuzhiyun  * @dev: Device to handle.
478*4882a593Smuzhiyun  * @capable: Whether or not @dev is capable of waking up the system from sleep.
479*4882a593Smuzhiyun  *
480*4882a593Smuzhiyun  * If @capable is set, set the @dev's power.can_wakeup flag and add its
481*4882a593Smuzhiyun  * wakeup-related attributes to sysfs.  Otherwise, unset the @dev's
482*4882a593Smuzhiyun  * power.can_wakeup flag and remove its wakeup-related attributes from sysfs.
483*4882a593Smuzhiyun  *
484*4882a593Smuzhiyun  * This function may sleep and it can't be called from any context where
485*4882a593Smuzhiyun  * sleeping is not allowed.
486*4882a593Smuzhiyun  */
device_set_wakeup_capable(struct device * dev,bool capable)487*4882a593Smuzhiyun void device_set_wakeup_capable(struct device *dev, bool capable)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun 	if (!!dev->power.can_wakeup == !!capable)
490*4882a593Smuzhiyun 		return;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	dev->power.can_wakeup = capable;
493*4882a593Smuzhiyun 	if (device_is_registered(dev) && !list_empty(&dev->power.entry)) {
494*4882a593Smuzhiyun 		if (capable) {
495*4882a593Smuzhiyun 			int ret = wakeup_sysfs_add(dev);
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 			if (ret)
498*4882a593Smuzhiyun 				dev_info(dev, "Wakeup sysfs attributes not added\n");
499*4882a593Smuzhiyun 		} else {
500*4882a593Smuzhiyun 			wakeup_sysfs_remove(dev);
501*4882a593Smuzhiyun 		}
502*4882a593Smuzhiyun 	}
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(device_set_wakeup_capable);
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun /**
507*4882a593Smuzhiyun  * device_init_wakeup - Device wakeup initialization.
508*4882a593Smuzhiyun  * @dev: Device to handle.
509*4882a593Smuzhiyun  * @enable: Whether or not to enable @dev as a wakeup device.
510*4882a593Smuzhiyun  *
511*4882a593Smuzhiyun  * By default, most devices should leave wakeup disabled.  The exceptions are
512*4882a593Smuzhiyun  * devices that everyone expects to be wakeup sources: keyboards, power buttons,
513*4882a593Smuzhiyun  * possibly network interfaces, etc.  Also, devices that don't generate their
514*4882a593Smuzhiyun  * own wakeup requests but merely forward requests from one bus to another
515*4882a593Smuzhiyun  * (like PCI bridges) should have wakeup enabled by default.
516*4882a593Smuzhiyun  */
device_init_wakeup(struct device * dev,bool enable)517*4882a593Smuzhiyun int device_init_wakeup(struct device *dev, bool enable)
518*4882a593Smuzhiyun {
519*4882a593Smuzhiyun 	int ret = 0;
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	if (!dev)
522*4882a593Smuzhiyun 		return -EINVAL;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	if (enable) {
525*4882a593Smuzhiyun 		device_set_wakeup_capable(dev, true);
526*4882a593Smuzhiyun 		ret = device_wakeup_enable(dev);
527*4882a593Smuzhiyun 	} else {
528*4882a593Smuzhiyun 		device_wakeup_disable(dev);
529*4882a593Smuzhiyun 		device_set_wakeup_capable(dev, false);
530*4882a593Smuzhiyun 	}
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	return ret;
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(device_init_wakeup);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun /**
537*4882a593Smuzhiyun  * device_set_wakeup_enable - Enable or disable a device to wake up the system.
538*4882a593Smuzhiyun  * @dev: Device to handle.
539*4882a593Smuzhiyun  */
device_set_wakeup_enable(struct device * dev,bool enable)540*4882a593Smuzhiyun int device_set_wakeup_enable(struct device *dev, bool enable)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun 	return enable ? device_wakeup_enable(dev) : device_wakeup_disable(dev);
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(device_set_wakeup_enable);
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun /**
547*4882a593Smuzhiyun  * wakeup_source_not_registered - validate the given wakeup source.
548*4882a593Smuzhiyun  * @ws: Wakeup source to be validated.
549*4882a593Smuzhiyun  */
wakeup_source_not_registered(struct wakeup_source * ws)550*4882a593Smuzhiyun static bool wakeup_source_not_registered(struct wakeup_source *ws)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	/*
553*4882a593Smuzhiyun 	 * Use timer struct to check if the given source is initialized
554*4882a593Smuzhiyun 	 * by wakeup_source_add.
555*4882a593Smuzhiyun 	 */
556*4882a593Smuzhiyun 	return ws->timer.function != pm_wakeup_timer_fn;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun /*
560*4882a593Smuzhiyun  * The functions below use the observation that each wakeup event starts a
561*4882a593Smuzhiyun  * period in which the system should not be suspended.  The moment this period
562*4882a593Smuzhiyun  * will end depends on how the wakeup event is going to be processed after being
563*4882a593Smuzhiyun  * detected and all of the possible cases can be divided into two distinct
564*4882a593Smuzhiyun  * groups.
565*4882a593Smuzhiyun  *
566*4882a593Smuzhiyun  * First, a wakeup event may be detected by the same functional unit that will
567*4882a593Smuzhiyun  * carry out the entire processing of it and possibly will pass it to user space
568*4882a593Smuzhiyun  * for further processing.  In that case the functional unit that has detected
569*4882a593Smuzhiyun  * the event may later "close" the "no suspend" period associated with it
570*4882a593Smuzhiyun  * directly as soon as it has been dealt with.  The pair of pm_stay_awake() and
571*4882a593Smuzhiyun  * pm_relax(), balanced with each other, is supposed to be used in such
572*4882a593Smuzhiyun  * situations.
573*4882a593Smuzhiyun  *
574*4882a593Smuzhiyun  * Second, a wakeup event may be detected by one functional unit and processed
575*4882a593Smuzhiyun  * by another one.  In that case the unit that has detected it cannot really
576*4882a593Smuzhiyun  * "close" the "no suspend" period associated with it, unless it knows in
577*4882a593Smuzhiyun  * advance what's going to happen to the event during processing.  This
578*4882a593Smuzhiyun  * knowledge, however, may not be available to it, so it can simply specify time
579*4882a593Smuzhiyun  * to wait before the system can be suspended and pass it as the second
580*4882a593Smuzhiyun  * argument of pm_wakeup_event().
581*4882a593Smuzhiyun  *
582*4882a593Smuzhiyun  * It is valid to call pm_relax() after pm_wakeup_event(), in which case the
583*4882a593Smuzhiyun  * "no suspend" period will be ended either by the pm_relax(), or by the timer
584*4882a593Smuzhiyun  * function executed when the timer expires, whichever comes first.
585*4882a593Smuzhiyun  */
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun /**
588*4882a593Smuzhiyun  * wakup_source_activate - Mark given wakeup source as active.
589*4882a593Smuzhiyun  * @ws: Wakeup source to handle.
590*4882a593Smuzhiyun  *
591*4882a593Smuzhiyun  * Update the @ws' statistics and, if @ws has just been activated, notify the PM
592*4882a593Smuzhiyun  * core of the event by incrementing the counter of of wakeup events being
593*4882a593Smuzhiyun  * processed.
594*4882a593Smuzhiyun  */
wakeup_source_activate(struct wakeup_source * ws)595*4882a593Smuzhiyun static void wakeup_source_activate(struct wakeup_source *ws)
596*4882a593Smuzhiyun {
597*4882a593Smuzhiyun 	unsigned int cec;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	if (WARN_ONCE(wakeup_source_not_registered(ws),
600*4882a593Smuzhiyun 			"unregistered wakeup source\n"))
601*4882a593Smuzhiyun 		return;
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	ws->active = true;
604*4882a593Smuzhiyun 	ws->active_count++;
605*4882a593Smuzhiyun 	ws->last_time = ktime_get();
606*4882a593Smuzhiyun 	if (ws->autosleep_enabled)
607*4882a593Smuzhiyun 		ws->start_prevent_time = ws->last_time;
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	/* Increment the counter of events in progress. */
610*4882a593Smuzhiyun 	cec = atomic_inc_return(&combined_event_count);
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	trace_wakeup_source_activate(ws->name, cec);
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun /**
616*4882a593Smuzhiyun  * wakeup_source_report_event - Report wakeup event using the given source.
617*4882a593Smuzhiyun  * @ws: Wakeup source to report the event for.
618*4882a593Smuzhiyun  * @hard: If set, abort suspends in progress and wake up from suspend-to-idle.
619*4882a593Smuzhiyun  */
wakeup_source_report_event(struct wakeup_source * ws,bool hard)620*4882a593Smuzhiyun static void wakeup_source_report_event(struct wakeup_source *ws, bool hard)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun 	ws->event_count++;
623*4882a593Smuzhiyun 	/* This is racy, but the counter is approximate anyway. */
624*4882a593Smuzhiyun 	if (events_check_enabled)
625*4882a593Smuzhiyun 		ws->wakeup_count++;
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	if (!ws->active)
628*4882a593Smuzhiyun 		wakeup_source_activate(ws);
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	if (hard)
631*4882a593Smuzhiyun 		pm_system_wakeup();
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun /**
635*4882a593Smuzhiyun  * __pm_stay_awake - Notify the PM core of a wakeup event.
636*4882a593Smuzhiyun  * @ws: Wakeup source object associated with the source of the event.
637*4882a593Smuzhiyun  *
638*4882a593Smuzhiyun  * It is safe to call this function from interrupt context.
639*4882a593Smuzhiyun  */
__pm_stay_awake(struct wakeup_source * ws)640*4882a593Smuzhiyun void __pm_stay_awake(struct wakeup_source *ws)
641*4882a593Smuzhiyun {
642*4882a593Smuzhiyun 	unsigned long flags;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	if (!ws)
645*4882a593Smuzhiyun 		return;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	spin_lock_irqsave(&ws->lock, flags);
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	wakeup_source_report_event(ws, false);
650*4882a593Smuzhiyun 	del_timer(&ws->timer);
651*4882a593Smuzhiyun 	ws->timer_expires = 0;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ws->lock, flags);
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__pm_stay_awake);
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun /**
658*4882a593Smuzhiyun  * pm_stay_awake - Notify the PM core that a wakeup event is being processed.
659*4882a593Smuzhiyun  * @dev: Device the wakeup event is related to.
660*4882a593Smuzhiyun  *
661*4882a593Smuzhiyun  * Notify the PM core of a wakeup event (signaled by @dev) by calling
662*4882a593Smuzhiyun  * __pm_stay_awake for the @dev's wakeup source object.
663*4882a593Smuzhiyun  *
664*4882a593Smuzhiyun  * Call this function after detecting of a wakeup event if pm_relax() is going
665*4882a593Smuzhiyun  * to be called directly after processing the event (and possibly passing it to
666*4882a593Smuzhiyun  * user space for further processing).
667*4882a593Smuzhiyun  */
pm_stay_awake(struct device * dev)668*4882a593Smuzhiyun void pm_stay_awake(struct device *dev)
669*4882a593Smuzhiyun {
670*4882a593Smuzhiyun 	unsigned long flags;
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	if (!dev)
673*4882a593Smuzhiyun 		return;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	spin_lock_irqsave(&dev->power.lock, flags);
676*4882a593Smuzhiyun 	__pm_stay_awake(dev->power.wakeup);
677*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dev->power.lock, flags);
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_stay_awake);
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun #ifdef CONFIG_PM_AUTOSLEEP
update_prevent_sleep_time(struct wakeup_source * ws,ktime_t now)682*4882a593Smuzhiyun static void update_prevent_sleep_time(struct wakeup_source *ws, ktime_t now)
683*4882a593Smuzhiyun {
684*4882a593Smuzhiyun 	ktime_t delta = ktime_sub(now, ws->start_prevent_time);
685*4882a593Smuzhiyun 	ws->prevent_sleep_time = ktime_add(ws->prevent_sleep_time, delta);
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun #else
update_prevent_sleep_time(struct wakeup_source * ws,ktime_t now)688*4882a593Smuzhiyun static inline void update_prevent_sleep_time(struct wakeup_source *ws,
689*4882a593Smuzhiyun 					     ktime_t now) {}
690*4882a593Smuzhiyun #endif
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun /**
693*4882a593Smuzhiyun  * wakup_source_deactivate - Mark given wakeup source as inactive.
694*4882a593Smuzhiyun  * @ws: Wakeup source to handle.
695*4882a593Smuzhiyun  *
696*4882a593Smuzhiyun  * Update the @ws' statistics and notify the PM core that the wakeup source has
697*4882a593Smuzhiyun  * become inactive by decrementing the counter of wakeup events being processed
698*4882a593Smuzhiyun  * and incrementing the counter of registered wakeup events.
699*4882a593Smuzhiyun  */
wakeup_source_deactivate(struct wakeup_source * ws)700*4882a593Smuzhiyun static void wakeup_source_deactivate(struct wakeup_source *ws)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun 	unsigned int cnt, inpr, cec;
703*4882a593Smuzhiyun 	ktime_t duration;
704*4882a593Smuzhiyun 	ktime_t now;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 	ws->relax_count++;
707*4882a593Smuzhiyun 	/*
708*4882a593Smuzhiyun 	 * __pm_relax() may be called directly or from a timer function.
709*4882a593Smuzhiyun 	 * If it is called directly right after the timer function has been
710*4882a593Smuzhiyun 	 * started, but before the timer function calls __pm_relax(), it is
711*4882a593Smuzhiyun 	 * possible that __pm_stay_awake() will be called in the meantime and
712*4882a593Smuzhiyun 	 * will set ws->active.  Then, ws->active may be cleared immediately
713*4882a593Smuzhiyun 	 * by the __pm_relax() called from the timer function, but in such a
714*4882a593Smuzhiyun 	 * case ws->relax_count will be different from ws->active_count.
715*4882a593Smuzhiyun 	 */
716*4882a593Smuzhiyun 	if (ws->relax_count != ws->active_count) {
717*4882a593Smuzhiyun 		ws->relax_count--;
718*4882a593Smuzhiyun 		return;
719*4882a593Smuzhiyun 	}
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	ws->active = false;
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	now = ktime_get();
724*4882a593Smuzhiyun 	duration = ktime_sub(now, ws->last_time);
725*4882a593Smuzhiyun 	ws->total_time = ktime_add(ws->total_time, duration);
726*4882a593Smuzhiyun 	if (ktime_to_ns(duration) > ktime_to_ns(ws->max_time))
727*4882a593Smuzhiyun 		ws->max_time = duration;
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	ws->last_time = now;
730*4882a593Smuzhiyun 	del_timer(&ws->timer);
731*4882a593Smuzhiyun 	ws->timer_expires = 0;
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	if (ws->autosleep_enabled)
734*4882a593Smuzhiyun 		update_prevent_sleep_time(ws, now);
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 	/*
737*4882a593Smuzhiyun 	 * Increment the counter of registered wakeup events and decrement the
738*4882a593Smuzhiyun 	 * couter of wakeup events in progress simultaneously.
739*4882a593Smuzhiyun 	 */
740*4882a593Smuzhiyun 	cec = atomic_add_return(MAX_IN_PROGRESS, &combined_event_count);
741*4882a593Smuzhiyun 	trace_wakeup_source_deactivate(ws->name, cec);
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	split_counters(&cnt, &inpr);
744*4882a593Smuzhiyun 	if (!inpr && waitqueue_active(&wakeup_count_wait_queue))
745*4882a593Smuzhiyun 		wake_up(&wakeup_count_wait_queue);
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun /**
749*4882a593Smuzhiyun  * __pm_relax - Notify the PM core that processing of a wakeup event has ended.
750*4882a593Smuzhiyun  * @ws: Wakeup source object associated with the source of the event.
751*4882a593Smuzhiyun  *
752*4882a593Smuzhiyun  * Call this function for wakeup events whose processing started with calling
753*4882a593Smuzhiyun  * __pm_stay_awake().
754*4882a593Smuzhiyun  *
755*4882a593Smuzhiyun  * It is safe to call it from interrupt context.
756*4882a593Smuzhiyun  */
__pm_relax(struct wakeup_source * ws)757*4882a593Smuzhiyun void __pm_relax(struct wakeup_source *ws)
758*4882a593Smuzhiyun {
759*4882a593Smuzhiyun 	unsigned long flags;
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	if (!ws)
762*4882a593Smuzhiyun 		return;
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 	spin_lock_irqsave(&ws->lock, flags);
765*4882a593Smuzhiyun 	if (ws->active)
766*4882a593Smuzhiyun 		wakeup_source_deactivate(ws);
767*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ws->lock, flags);
768*4882a593Smuzhiyun }
769*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__pm_relax);
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun /**
772*4882a593Smuzhiyun  * pm_relax - Notify the PM core that processing of a wakeup event has ended.
773*4882a593Smuzhiyun  * @dev: Device that signaled the event.
774*4882a593Smuzhiyun  *
775*4882a593Smuzhiyun  * Execute __pm_relax() for the @dev's wakeup source object.
776*4882a593Smuzhiyun  */
pm_relax(struct device * dev)777*4882a593Smuzhiyun void pm_relax(struct device *dev)
778*4882a593Smuzhiyun {
779*4882a593Smuzhiyun 	unsigned long flags;
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 	if (!dev)
782*4882a593Smuzhiyun 		return;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	spin_lock_irqsave(&dev->power.lock, flags);
785*4882a593Smuzhiyun 	__pm_relax(dev->power.wakeup);
786*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dev->power.lock, flags);
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_relax);
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun /**
791*4882a593Smuzhiyun  * pm_wakeup_timer_fn - Delayed finalization of a wakeup event.
792*4882a593Smuzhiyun  * @data: Address of the wakeup source object associated with the event source.
793*4882a593Smuzhiyun  *
794*4882a593Smuzhiyun  * Call wakeup_source_deactivate() for the wakeup source whose address is stored
795*4882a593Smuzhiyun  * in @data if it is currently active and its timer has not been canceled and
796*4882a593Smuzhiyun  * the expiration time of the timer is not in future.
797*4882a593Smuzhiyun  */
pm_wakeup_timer_fn(struct timer_list * t)798*4882a593Smuzhiyun static void pm_wakeup_timer_fn(struct timer_list *t)
799*4882a593Smuzhiyun {
800*4882a593Smuzhiyun 	struct wakeup_source *ws = from_timer(ws, t, timer);
801*4882a593Smuzhiyun 	unsigned long flags;
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun 	spin_lock_irqsave(&ws->lock, flags);
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	if (ws->active && ws->timer_expires
806*4882a593Smuzhiyun 	    && time_after_eq(jiffies, ws->timer_expires)) {
807*4882a593Smuzhiyun 		wakeup_source_deactivate(ws);
808*4882a593Smuzhiyun 		ws->expire_count++;
809*4882a593Smuzhiyun 	}
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ws->lock, flags);
812*4882a593Smuzhiyun }
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun /**
815*4882a593Smuzhiyun  * pm_wakeup_ws_event - Notify the PM core of a wakeup event.
816*4882a593Smuzhiyun  * @ws: Wakeup source object associated with the event source.
817*4882a593Smuzhiyun  * @msec: Anticipated event processing time (in milliseconds).
818*4882a593Smuzhiyun  * @hard: If set, abort suspends in progress and wake up from suspend-to-idle.
819*4882a593Smuzhiyun  *
820*4882a593Smuzhiyun  * Notify the PM core of a wakeup event whose source is @ws that will take
821*4882a593Smuzhiyun  * approximately @msec milliseconds to be processed by the kernel.  If @ws is
822*4882a593Smuzhiyun  * not active, activate it.  If @msec is nonzero, set up the @ws' timer to
823*4882a593Smuzhiyun  * execute pm_wakeup_timer_fn() in future.
824*4882a593Smuzhiyun  *
825*4882a593Smuzhiyun  * It is safe to call this function from interrupt context.
826*4882a593Smuzhiyun  */
pm_wakeup_ws_event(struct wakeup_source * ws,unsigned int msec,bool hard)827*4882a593Smuzhiyun void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard)
828*4882a593Smuzhiyun {
829*4882a593Smuzhiyun 	unsigned long flags;
830*4882a593Smuzhiyun 	unsigned long expires;
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	if (!ws)
833*4882a593Smuzhiyun 		return;
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 	spin_lock_irqsave(&ws->lock, flags);
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun 	wakeup_source_report_event(ws, hard);
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun 	if (!msec) {
840*4882a593Smuzhiyun 		wakeup_source_deactivate(ws);
841*4882a593Smuzhiyun 		goto unlock;
842*4882a593Smuzhiyun 	}
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun 	expires = jiffies + msecs_to_jiffies(msec);
845*4882a593Smuzhiyun 	if (!expires)
846*4882a593Smuzhiyun 		expires = 1;
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun 	if (!ws->timer_expires || time_after(expires, ws->timer_expires)) {
849*4882a593Smuzhiyun 		mod_timer(&ws->timer, expires);
850*4882a593Smuzhiyun 		ws->timer_expires = expires;
851*4882a593Smuzhiyun 	}
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun  unlock:
854*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ws->lock, flags);
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_wakeup_ws_event);
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun /**
859*4882a593Smuzhiyun  * pm_wakeup_dev_event - Notify the PM core of a wakeup event.
860*4882a593Smuzhiyun  * @dev: Device the wakeup event is related to.
861*4882a593Smuzhiyun  * @msec: Anticipated event processing time (in milliseconds).
862*4882a593Smuzhiyun  * @hard: If set, abort suspends in progress and wake up from suspend-to-idle.
863*4882a593Smuzhiyun  *
864*4882a593Smuzhiyun  * Call pm_wakeup_ws_event() for the @dev's wakeup source object.
865*4882a593Smuzhiyun  */
pm_wakeup_dev_event(struct device * dev,unsigned int msec,bool hard)866*4882a593Smuzhiyun void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard)
867*4882a593Smuzhiyun {
868*4882a593Smuzhiyun 	unsigned long flags;
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	if (!dev)
871*4882a593Smuzhiyun 		return;
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 	spin_lock_irqsave(&dev->power.lock, flags);
874*4882a593Smuzhiyun 	pm_wakeup_ws_event(dev->power.wakeup, msec, hard);
875*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dev->power.lock, flags);
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_wakeup_dev_event);
878*4882a593Smuzhiyun 
pm_get_active_wakeup_sources(char * pending_wakeup_source,size_t max)879*4882a593Smuzhiyun void pm_get_active_wakeup_sources(char *pending_wakeup_source, size_t max)
880*4882a593Smuzhiyun {
881*4882a593Smuzhiyun 	struct wakeup_source *ws, *last_active_ws = NULL;
882*4882a593Smuzhiyun 	int len = 0;
883*4882a593Smuzhiyun 	bool active = false;
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun 	rcu_read_lock();
886*4882a593Smuzhiyun 	list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
887*4882a593Smuzhiyun 		if (ws->active && len < max) {
888*4882a593Smuzhiyun 			if (!active)
889*4882a593Smuzhiyun 				len += scnprintf(pending_wakeup_source, max,
890*4882a593Smuzhiyun 						"Pending Wakeup Sources: ");
891*4882a593Smuzhiyun 			len += scnprintf(pending_wakeup_source + len, max - len,
892*4882a593Smuzhiyun 				"%s ", ws->name);
893*4882a593Smuzhiyun 			active = true;
894*4882a593Smuzhiyun 		} else if (!active &&
895*4882a593Smuzhiyun 			   (!last_active_ws ||
896*4882a593Smuzhiyun 			    ktime_to_ns(ws->last_time) >
897*4882a593Smuzhiyun 			    ktime_to_ns(last_active_ws->last_time))) {
898*4882a593Smuzhiyun 			last_active_ws = ws;
899*4882a593Smuzhiyun 		}
900*4882a593Smuzhiyun 	}
901*4882a593Smuzhiyun 	if (!active && last_active_ws) {
902*4882a593Smuzhiyun 		scnprintf(pending_wakeup_source, max,
903*4882a593Smuzhiyun 				"Last active Wakeup Source: %s",
904*4882a593Smuzhiyun 				last_active_ws->name);
905*4882a593Smuzhiyun 	}
906*4882a593Smuzhiyun 	rcu_read_unlock();
907*4882a593Smuzhiyun }
908*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_get_active_wakeup_sources);
909*4882a593Smuzhiyun 
pm_print_active_wakeup_sources(void)910*4882a593Smuzhiyun void pm_print_active_wakeup_sources(void)
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun 	struct wakeup_source *ws;
913*4882a593Smuzhiyun 	int srcuidx, active = 0;
914*4882a593Smuzhiyun 	struct wakeup_source *last_activity_ws = NULL;
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 	srcuidx = srcu_read_lock(&wakeup_srcu);
917*4882a593Smuzhiyun 	list_for_each_entry_rcu_locked(ws, &wakeup_sources, entry) {
918*4882a593Smuzhiyun 		if (ws->active) {
919*4882a593Smuzhiyun 			pm_pr_dbg("active wakeup source: %s\n", ws->name);
920*4882a593Smuzhiyun 			active = 1;
921*4882a593Smuzhiyun 		} else if (!active &&
922*4882a593Smuzhiyun 			   (!last_activity_ws ||
923*4882a593Smuzhiyun 			    ktime_to_ns(ws->last_time) >
924*4882a593Smuzhiyun 			    ktime_to_ns(last_activity_ws->last_time))) {
925*4882a593Smuzhiyun 			last_activity_ws = ws;
926*4882a593Smuzhiyun 		}
927*4882a593Smuzhiyun 	}
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun 	if (!active && last_activity_ws)
930*4882a593Smuzhiyun 		pm_pr_dbg("last active wakeup source: %s\n",
931*4882a593Smuzhiyun 			last_activity_ws->name);
932*4882a593Smuzhiyun 	srcu_read_unlock(&wakeup_srcu, srcuidx);
933*4882a593Smuzhiyun }
934*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun /**
937*4882a593Smuzhiyun  * pm_wakeup_pending - Check if power transition in progress should be aborted.
938*4882a593Smuzhiyun  *
939*4882a593Smuzhiyun  * Compare the current number of registered wakeup events with its preserved
940*4882a593Smuzhiyun  * value from the past and return true if new wakeup events have been registered
941*4882a593Smuzhiyun  * since the old value was stored.  Also return true if the current number of
942*4882a593Smuzhiyun  * wakeup events being processed is different from zero.
943*4882a593Smuzhiyun  */
pm_wakeup_pending(void)944*4882a593Smuzhiyun bool pm_wakeup_pending(void)
945*4882a593Smuzhiyun {
946*4882a593Smuzhiyun 	unsigned long flags;
947*4882a593Smuzhiyun 	bool ret = false;
948*4882a593Smuzhiyun 	char suspend_abort[MAX_SUSPEND_ABORT_LEN];
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&events_lock, flags);
951*4882a593Smuzhiyun 	if (events_check_enabled) {
952*4882a593Smuzhiyun 		unsigned int cnt, inpr;
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 		split_counters(&cnt, &inpr);
955*4882a593Smuzhiyun 		ret = (cnt != saved_count || inpr > 0);
956*4882a593Smuzhiyun 		events_check_enabled = !ret;
957*4882a593Smuzhiyun 	}
958*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&events_lock, flags);
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	if (ret) {
961*4882a593Smuzhiyun 		pm_pr_dbg("Wakeup pending, aborting suspend\n");
962*4882a593Smuzhiyun 		pm_print_active_wakeup_sources();
963*4882a593Smuzhiyun 		pm_get_active_wakeup_sources(suspend_abort,
964*4882a593Smuzhiyun 					     MAX_SUSPEND_ABORT_LEN);
965*4882a593Smuzhiyun 		log_suspend_abort_reason(suspend_abort);
966*4882a593Smuzhiyun 		pr_info("PM: %s\n", suspend_abort);
967*4882a593Smuzhiyun 	}
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun 	return ret || atomic_read(&pm_abort_suspend) > 0;
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun 
pm_system_wakeup(void)972*4882a593Smuzhiyun void pm_system_wakeup(void)
973*4882a593Smuzhiyun {
974*4882a593Smuzhiyun 	atomic_inc(&pm_abort_suspend);
975*4882a593Smuzhiyun 	s2idle_wake();
976*4882a593Smuzhiyun }
977*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pm_system_wakeup);
978*4882a593Smuzhiyun 
pm_system_cancel_wakeup(void)979*4882a593Smuzhiyun void pm_system_cancel_wakeup(void)
980*4882a593Smuzhiyun {
981*4882a593Smuzhiyun 	atomic_dec_if_positive(&pm_abort_suspend);
982*4882a593Smuzhiyun }
983*4882a593Smuzhiyun 
pm_wakeup_clear(unsigned int irq_number)984*4882a593Smuzhiyun void pm_wakeup_clear(unsigned int irq_number)
985*4882a593Smuzhiyun {
986*4882a593Smuzhiyun 	raw_spin_lock_irq(&wakeup_irq_lock);
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 	if (irq_number && wakeup_irq[0] == irq_number)
989*4882a593Smuzhiyun 		wakeup_irq[0] = wakeup_irq[1];
990*4882a593Smuzhiyun 	else
991*4882a593Smuzhiyun 		wakeup_irq[0] = 0;
992*4882a593Smuzhiyun 
993*4882a593Smuzhiyun 	wakeup_irq[1] = 0;
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 	raw_spin_unlock_irq(&wakeup_irq_lock);
996*4882a593Smuzhiyun 
997*4882a593Smuzhiyun 	if (!irq_number)
998*4882a593Smuzhiyun 		atomic_set(&pm_abort_suspend, 0);
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun 
pm_system_irq_wakeup(unsigned int irq_number)1001*4882a593Smuzhiyun void pm_system_irq_wakeup(unsigned int irq_number)
1002*4882a593Smuzhiyun {
1003*4882a593Smuzhiyun 	unsigned long flags;
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&wakeup_irq_lock, flags);
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 	if (wakeup_irq[0] == 0)
1008*4882a593Smuzhiyun 		wakeup_irq[0] = irq_number;
1009*4882a593Smuzhiyun 	else if (wakeup_irq[1] == 0)
1010*4882a593Smuzhiyun 		wakeup_irq[1] = irq_number;
1011*4882a593Smuzhiyun 	else
1012*4882a593Smuzhiyun 		irq_number = 0;
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&wakeup_irq_lock, flags);
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 	if (irq_number) {
1017*4882a593Smuzhiyun 		struct irq_desc *desc;
1018*4882a593Smuzhiyun 		const char *name = "null";
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 		desc = irq_to_desc(irq_number);
1021*4882a593Smuzhiyun 		if (desc == NULL)
1022*4882a593Smuzhiyun 			name = "stray irq";
1023*4882a593Smuzhiyun 		else if (desc->action && desc->action->name)
1024*4882a593Smuzhiyun 			name = desc->action->name;
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 		log_irq_wakeup_reason(irq_number);
1027*4882a593Smuzhiyun 		pr_warn("%s: %d triggered %s\n", __func__, irq_number, name);
1028*4882a593Smuzhiyun 		pm_system_wakeup();
1029*4882a593Smuzhiyun 	}
1030*4882a593Smuzhiyun }
1031*4882a593Smuzhiyun 
pm_wakeup_irq(void)1032*4882a593Smuzhiyun unsigned int pm_wakeup_irq(void)
1033*4882a593Smuzhiyun {
1034*4882a593Smuzhiyun 	return wakeup_irq[0];
1035*4882a593Smuzhiyun }
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun /**
1038*4882a593Smuzhiyun  * pm_get_wakeup_count - Read the number of registered wakeup events.
1039*4882a593Smuzhiyun  * @count: Address to store the value at.
1040*4882a593Smuzhiyun  * @block: Whether or not to block.
1041*4882a593Smuzhiyun  *
1042*4882a593Smuzhiyun  * Store the number of registered wakeup events at the address in @count.  If
1043*4882a593Smuzhiyun  * @block is set, block until the current number of wakeup events being
1044*4882a593Smuzhiyun  * processed is zero.
1045*4882a593Smuzhiyun  *
1046*4882a593Smuzhiyun  * Return 'false' if the current number of wakeup events being processed is
1047*4882a593Smuzhiyun  * nonzero.  Otherwise return 'true'.
1048*4882a593Smuzhiyun  */
pm_get_wakeup_count(unsigned int * count,bool block)1049*4882a593Smuzhiyun bool pm_get_wakeup_count(unsigned int *count, bool block)
1050*4882a593Smuzhiyun {
1051*4882a593Smuzhiyun 	unsigned int cnt, inpr;
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun 	if (block) {
1054*4882a593Smuzhiyun 		DEFINE_WAIT(wait);
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 		for (;;) {
1057*4882a593Smuzhiyun 			prepare_to_wait(&wakeup_count_wait_queue, &wait,
1058*4882a593Smuzhiyun 					TASK_INTERRUPTIBLE);
1059*4882a593Smuzhiyun 			split_counters(&cnt, &inpr);
1060*4882a593Smuzhiyun 			if (inpr == 0 || signal_pending(current))
1061*4882a593Smuzhiyun 				break;
1062*4882a593Smuzhiyun 			pm_print_active_wakeup_sources();
1063*4882a593Smuzhiyun 			schedule();
1064*4882a593Smuzhiyun 		}
1065*4882a593Smuzhiyun 		finish_wait(&wakeup_count_wait_queue, &wait);
1066*4882a593Smuzhiyun 	}
1067*4882a593Smuzhiyun 
1068*4882a593Smuzhiyun 	split_counters(&cnt, &inpr);
1069*4882a593Smuzhiyun 	*count = cnt;
1070*4882a593Smuzhiyun 	return !inpr;
1071*4882a593Smuzhiyun }
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun /**
1074*4882a593Smuzhiyun  * pm_save_wakeup_count - Save the current number of registered wakeup events.
1075*4882a593Smuzhiyun  * @count: Value to compare with the current number of registered wakeup events.
1076*4882a593Smuzhiyun  *
1077*4882a593Smuzhiyun  * If @count is equal to the current number of registered wakeup events and the
1078*4882a593Smuzhiyun  * current number of wakeup events being processed is zero, store @count as the
1079*4882a593Smuzhiyun  * old number of registered wakeup events for pm_check_wakeup_events(), enable
1080*4882a593Smuzhiyun  * wakeup events detection and return 'true'.  Otherwise disable wakeup events
1081*4882a593Smuzhiyun  * detection and return 'false'.
1082*4882a593Smuzhiyun  */
pm_save_wakeup_count(unsigned int count)1083*4882a593Smuzhiyun bool pm_save_wakeup_count(unsigned int count)
1084*4882a593Smuzhiyun {
1085*4882a593Smuzhiyun 	unsigned int cnt, inpr;
1086*4882a593Smuzhiyun 	unsigned long flags;
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	events_check_enabled = false;
1089*4882a593Smuzhiyun 	raw_spin_lock_irqsave(&events_lock, flags);
1090*4882a593Smuzhiyun 	split_counters(&cnt, &inpr);
1091*4882a593Smuzhiyun 	if (cnt == count && inpr == 0) {
1092*4882a593Smuzhiyun 		saved_count = count;
1093*4882a593Smuzhiyun 		events_check_enabled = true;
1094*4882a593Smuzhiyun 	}
1095*4882a593Smuzhiyun 	raw_spin_unlock_irqrestore(&events_lock, flags);
1096*4882a593Smuzhiyun 	return events_check_enabled;
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun #ifdef CONFIG_PM_AUTOSLEEP
1100*4882a593Smuzhiyun /**
1101*4882a593Smuzhiyun  * pm_wakep_autosleep_enabled - Modify autosleep_enabled for all wakeup sources.
1102*4882a593Smuzhiyun  * @enabled: Whether to set or to clear the autosleep_enabled flags.
1103*4882a593Smuzhiyun  */
pm_wakep_autosleep_enabled(bool set)1104*4882a593Smuzhiyun void pm_wakep_autosleep_enabled(bool set)
1105*4882a593Smuzhiyun {
1106*4882a593Smuzhiyun 	struct wakeup_source *ws;
1107*4882a593Smuzhiyun 	ktime_t now = ktime_get();
1108*4882a593Smuzhiyun 	int srcuidx;
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 	srcuidx = srcu_read_lock(&wakeup_srcu);
1111*4882a593Smuzhiyun 	list_for_each_entry_rcu_locked(ws, &wakeup_sources, entry) {
1112*4882a593Smuzhiyun 		spin_lock_irq(&ws->lock);
1113*4882a593Smuzhiyun 		if (ws->autosleep_enabled != set) {
1114*4882a593Smuzhiyun 			ws->autosleep_enabled = set;
1115*4882a593Smuzhiyun 			if (ws->active) {
1116*4882a593Smuzhiyun 				if (set)
1117*4882a593Smuzhiyun 					ws->start_prevent_time = now;
1118*4882a593Smuzhiyun 				else
1119*4882a593Smuzhiyun 					update_prevent_sleep_time(ws, now);
1120*4882a593Smuzhiyun 			}
1121*4882a593Smuzhiyun 		}
1122*4882a593Smuzhiyun 		spin_unlock_irq(&ws->lock);
1123*4882a593Smuzhiyun 	}
1124*4882a593Smuzhiyun 	srcu_read_unlock(&wakeup_srcu, srcuidx);
1125*4882a593Smuzhiyun }
1126*4882a593Smuzhiyun #endif /* CONFIG_PM_AUTOSLEEP */
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun /**
1129*4882a593Smuzhiyun  * print_wakeup_source_stats - Print wakeup source statistics information.
1130*4882a593Smuzhiyun  * @m: seq_file to print the statistics into.
1131*4882a593Smuzhiyun  * @ws: Wakeup source object to print the statistics for.
1132*4882a593Smuzhiyun  */
print_wakeup_source_stats(struct seq_file * m,struct wakeup_source * ws)1133*4882a593Smuzhiyun static int print_wakeup_source_stats(struct seq_file *m,
1134*4882a593Smuzhiyun 				     struct wakeup_source *ws)
1135*4882a593Smuzhiyun {
1136*4882a593Smuzhiyun 	unsigned long flags;
1137*4882a593Smuzhiyun 	ktime_t total_time;
1138*4882a593Smuzhiyun 	ktime_t max_time;
1139*4882a593Smuzhiyun 	unsigned long active_count;
1140*4882a593Smuzhiyun 	ktime_t active_time;
1141*4882a593Smuzhiyun 	ktime_t prevent_sleep_time;
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	spin_lock_irqsave(&ws->lock, flags);
1144*4882a593Smuzhiyun 
1145*4882a593Smuzhiyun 	total_time = ws->total_time;
1146*4882a593Smuzhiyun 	max_time = ws->max_time;
1147*4882a593Smuzhiyun 	prevent_sleep_time = ws->prevent_sleep_time;
1148*4882a593Smuzhiyun 	active_count = ws->active_count;
1149*4882a593Smuzhiyun 	if (ws->active) {
1150*4882a593Smuzhiyun 		ktime_t now = ktime_get();
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun 		active_time = ktime_sub(now, ws->last_time);
1153*4882a593Smuzhiyun 		total_time = ktime_add(total_time, active_time);
1154*4882a593Smuzhiyun 		if (active_time > max_time)
1155*4882a593Smuzhiyun 			max_time = active_time;
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 		if (ws->autosleep_enabled)
1158*4882a593Smuzhiyun 			prevent_sleep_time = ktime_add(prevent_sleep_time,
1159*4882a593Smuzhiyun 				ktime_sub(now, ws->start_prevent_time));
1160*4882a593Smuzhiyun 	} else {
1161*4882a593Smuzhiyun 		active_time = 0;
1162*4882a593Smuzhiyun 	}
1163*4882a593Smuzhiyun 
1164*4882a593Smuzhiyun 	seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%lld\t\t%lld\t\t%lld\t\t%lld\t\t%lld\n",
1165*4882a593Smuzhiyun 		   ws->name, active_count, ws->event_count,
1166*4882a593Smuzhiyun 		   ws->wakeup_count, ws->expire_count,
1167*4882a593Smuzhiyun 		   ktime_to_ms(active_time), ktime_to_ms(total_time),
1168*4882a593Smuzhiyun 		   ktime_to_ms(max_time), ktime_to_ms(ws->last_time),
1169*4882a593Smuzhiyun 		   ktime_to_ms(prevent_sleep_time));
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ws->lock, flags);
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun 	return 0;
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun 
wakeup_sources_stats_seq_start(struct seq_file * m,loff_t * pos)1176*4882a593Smuzhiyun static void *wakeup_sources_stats_seq_start(struct seq_file *m,
1177*4882a593Smuzhiyun 					loff_t *pos)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun 	struct wakeup_source *ws;
1180*4882a593Smuzhiyun 	loff_t n = *pos;
1181*4882a593Smuzhiyun 	int *srcuidx = m->private;
1182*4882a593Smuzhiyun 
1183*4882a593Smuzhiyun 	if (n == 0) {
1184*4882a593Smuzhiyun 		seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
1185*4882a593Smuzhiyun 			"expire_count\tactive_since\ttotal_time\tmax_time\t"
1186*4882a593Smuzhiyun 			"last_change\tprevent_suspend_time\n");
1187*4882a593Smuzhiyun 	}
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun 	*srcuidx = srcu_read_lock(&wakeup_srcu);
1190*4882a593Smuzhiyun 	list_for_each_entry_rcu_locked(ws, &wakeup_sources, entry) {
1191*4882a593Smuzhiyun 		if (n-- <= 0)
1192*4882a593Smuzhiyun 			return ws;
1193*4882a593Smuzhiyun 	}
1194*4882a593Smuzhiyun 
1195*4882a593Smuzhiyun 	return NULL;
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun 
wakeup_sources_stats_seq_next(struct seq_file * m,void * v,loff_t * pos)1198*4882a593Smuzhiyun static void *wakeup_sources_stats_seq_next(struct seq_file *m,
1199*4882a593Smuzhiyun 					void *v, loff_t *pos)
1200*4882a593Smuzhiyun {
1201*4882a593Smuzhiyun 	struct wakeup_source *ws = v;
1202*4882a593Smuzhiyun 	struct wakeup_source *next_ws = NULL;
1203*4882a593Smuzhiyun 
1204*4882a593Smuzhiyun 	++(*pos);
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	list_for_each_entry_continue_rcu(ws, &wakeup_sources, entry) {
1207*4882a593Smuzhiyun 		next_ws = ws;
1208*4882a593Smuzhiyun 		break;
1209*4882a593Smuzhiyun 	}
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 	if (!next_ws)
1212*4882a593Smuzhiyun 		print_wakeup_source_stats(m, &deleted_ws);
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun 	return next_ws;
1215*4882a593Smuzhiyun }
1216*4882a593Smuzhiyun 
wakeup_sources_stats_seq_stop(struct seq_file * m,void * v)1217*4882a593Smuzhiyun static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
1218*4882a593Smuzhiyun {
1219*4882a593Smuzhiyun 	int *srcuidx = m->private;
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	srcu_read_unlock(&wakeup_srcu, *srcuidx);
1222*4882a593Smuzhiyun }
1223*4882a593Smuzhiyun 
1224*4882a593Smuzhiyun /**
1225*4882a593Smuzhiyun  * wakeup_sources_stats_seq_show - Print wakeup sources statistics information.
1226*4882a593Smuzhiyun  * @m: seq_file to print the statistics into.
1227*4882a593Smuzhiyun  * @v: wakeup_source of each iteration
1228*4882a593Smuzhiyun  */
wakeup_sources_stats_seq_show(struct seq_file * m,void * v)1229*4882a593Smuzhiyun static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
1230*4882a593Smuzhiyun {
1231*4882a593Smuzhiyun 	struct wakeup_source *ws = v;
1232*4882a593Smuzhiyun 
1233*4882a593Smuzhiyun 	print_wakeup_source_stats(m, ws);
1234*4882a593Smuzhiyun 
1235*4882a593Smuzhiyun 	return 0;
1236*4882a593Smuzhiyun }
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun static const struct seq_operations wakeup_sources_stats_seq_ops = {
1239*4882a593Smuzhiyun 	.start = wakeup_sources_stats_seq_start,
1240*4882a593Smuzhiyun 	.next  = wakeup_sources_stats_seq_next,
1241*4882a593Smuzhiyun 	.stop  = wakeup_sources_stats_seq_stop,
1242*4882a593Smuzhiyun 	.show  = wakeup_sources_stats_seq_show,
1243*4882a593Smuzhiyun };
1244*4882a593Smuzhiyun 
wakeup_sources_stats_open(struct inode * inode,struct file * file)1245*4882a593Smuzhiyun static int wakeup_sources_stats_open(struct inode *inode, struct file *file)
1246*4882a593Smuzhiyun {
1247*4882a593Smuzhiyun 	return seq_open_private(file, &wakeup_sources_stats_seq_ops, sizeof(int));
1248*4882a593Smuzhiyun }
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun static const struct file_operations wakeup_sources_stats_fops = {
1251*4882a593Smuzhiyun 	.owner = THIS_MODULE,
1252*4882a593Smuzhiyun 	.open = wakeup_sources_stats_open,
1253*4882a593Smuzhiyun 	.read = seq_read,
1254*4882a593Smuzhiyun 	.llseek = seq_lseek,
1255*4882a593Smuzhiyun 	.release = seq_release_private,
1256*4882a593Smuzhiyun };
1257*4882a593Smuzhiyun 
wakeup_sources_debugfs_init(void)1258*4882a593Smuzhiyun static int __init wakeup_sources_debugfs_init(void)
1259*4882a593Smuzhiyun {
1260*4882a593Smuzhiyun 	debugfs_create_file("wakeup_sources", S_IRUGO, NULL, NULL,
1261*4882a593Smuzhiyun 			    &wakeup_sources_stats_fops);
1262*4882a593Smuzhiyun 	return 0;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun postcore_initcall(wakeup_sources_debugfs_init);
1266