xref: /OK3568_Linux_fs/kernel/include/linux/pm_wakeup.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  pm_wakeup.h - Power management wakeup interface
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Copyright (C) 2008 Alan Stern
6*4882a593Smuzhiyun  *  Copyright (C) 2010 Rafael J. Wysocki, Novell Inc.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _LINUX_PM_WAKEUP_H
10*4882a593Smuzhiyun #define _LINUX_PM_WAKEUP_H
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #ifndef _DEVICE_H_
13*4882a593Smuzhiyun # error "please don't include this file directly"
14*4882a593Smuzhiyun #endif
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include <linux/types.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun struct wake_irq;
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /**
21*4882a593Smuzhiyun  * struct wakeup_source - Representation of wakeup sources
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * @name: Name of the wakeup source
24*4882a593Smuzhiyun  * @id: Wakeup source id
25*4882a593Smuzhiyun  * @entry: Wakeup source list entry
26*4882a593Smuzhiyun  * @lock: Wakeup source lock
27*4882a593Smuzhiyun  * @wakeirq: Optional device specific wakeirq
28*4882a593Smuzhiyun  * @timer: Wakeup timer list
29*4882a593Smuzhiyun  * @timer_expires: Wakeup timer expiration
30*4882a593Smuzhiyun  * @total_time: Total time this wakeup source has been active.
31*4882a593Smuzhiyun  * @max_time: Maximum time this wakeup source has been continuously active.
32*4882a593Smuzhiyun  * @last_time: Monotonic clock when the wakeup source's was touched last time.
33*4882a593Smuzhiyun  * @prevent_sleep_time: Total time this source has been preventing autosleep.
34*4882a593Smuzhiyun  * @event_count: Number of signaled wakeup events.
35*4882a593Smuzhiyun  * @active_count: Number of times the wakeup source was activated.
36*4882a593Smuzhiyun  * @relax_count: Number of times the wakeup source was deactivated.
37*4882a593Smuzhiyun  * @expire_count: Number of times the wakeup source's timeout has expired.
38*4882a593Smuzhiyun  * @wakeup_count: Number of times the wakeup source might abort suspend.
39*4882a593Smuzhiyun  * @dev: Struct device for sysfs statistics about the wakeup source.
40*4882a593Smuzhiyun  * @active: Status of the wakeup source.
41*4882a593Smuzhiyun  * @autosleep_enabled: Autosleep is active, so update @prevent_sleep_time.
42*4882a593Smuzhiyun  */
43*4882a593Smuzhiyun struct wakeup_source {
44*4882a593Smuzhiyun 	const char 		*name;
45*4882a593Smuzhiyun 	int			id;
46*4882a593Smuzhiyun 	struct list_head	entry;
47*4882a593Smuzhiyun 	spinlock_t		lock;
48*4882a593Smuzhiyun 	struct wake_irq		*wakeirq;
49*4882a593Smuzhiyun 	struct timer_list	timer;
50*4882a593Smuzhiyun 	unsigned long		timer_expires;
51*4882a593Smuzhiyun 	ktime_t total_time;
52*4882a593Smuzhiyun 	ktime_t max_time;
53*4882a593Smuzhiyun 	ktime_t last_time;
54*4882a593Smuzhiyun 	ktime_t start_prevent_time;
55*4882a593Smuzhiyun 	ktime_t prevent_sleep_time;
56*4882a593Smuzhiyun 	unsigned long		event_count;
57*4882a593Smuzhiyun 	unsigned long		active_count;
58*4882a593Smuzhiyun 	unsigned long		relax_count;
59*4882a593Smuzhiyun 	unsigned long		expire_count;
60*4882a593Smuzhiyun 	unsigned long		wakeup_count;
61*4882a593Smuzhiyun 	struct device		*dev;
62*4882a593Smuzhiyun 	bool			active:1;
63*4882a593Smuzhiyun 	bool			autosleep_enabled:1;
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #define for_each_wakeup_source(ws) \
67*4882a593Smuzhiyun 	for ((ws) = wakeup_sources_walk_start();	\
68*4882a593Smuzhiyun 	     (ws);					\
69*4882a593Smuzhiyun 	     (ws) = wakeup_sources_walk_next((ws)))
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun  * Changes to device_may_wakeup take effect on the next pm state change.
75*4882a593Smuzhiyun  */
76*4882a593Smuzhiyun 
device_can_wakeup(struct device * dev)77*4882a593Smuzhiyun static inline bool device_can_wakeup(struct device *dev)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	return dev->power.can_wakeup;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
device_may_wakeup(struct device * dev)82*4882a593Smuzhiyun static inline bool device_may_wakeup(struct device *dev)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun 	return dev->power.can_wakeup && !!dev->power.wakeup;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun 
device_set_wakeup_path(struct device * dev)87*4882a593Smuzhiyun static inline void device_set_wakeup_path(struct device *dev)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun 	dev->power.wakeup_path = true;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* drivers/base/power/wakeup.c */
93*4882a593Smuzhiyun extern struct wakeup_source *wakeup_source_create(const char *name);
94*4882a593Smuzhiyun extern void wakeup_source_destroy(struct wakeup_source *ws);
95*4882a593Smuzhiyun extern void wakeup_source_add(struct wakeup_source *ws);
96*4882a593Smuzhiyun extern void wakeup_source_remove(struct wakeup_source *ws);
97*4882a593Smuzhiyun extern struct wakeup_source *wakeup_source_register(struct device *dev,
98*4882a593Smuzhiyun 						    const char *name);
99*4882a593Smuzhiyun extern void wakeup_source_unregister(struct wakeup_source *ws);
100*4882a593Smuzhiyun extern int wakeup_sources_read_lock(void);
101*4882a593Smuzhiyun extern void wakeup_sources_read_unlock(int idx);
102*4882a593Smuzhiyun extern struct wakeup_source *wakeup_sources_walk_start(void);
103*4882a593Smuzhiyun extern struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws);
104*4882a593Smuzhiyun extern int device_wakeup_enable(struct device *dev);
105*4882a593Smuzhiyun extern int device_wakeup_disable(struct device *dev);
106*4882a593Smuzhiyun extern void device_set_wakeup_capable(struct device *dev, bool capable);
107*4882a593Smuzhiyun extern int device_init_wakeup(struct device *dev, bool val);
108*4882a593Smuzhiyun extern int device_set_wakeup_enable(struct device *dev, bool enable);
109*4882a593Smuzhiyun extern void __pm_stay_awake(struct wakeup_source *ws);
110*4882a593Smuzhiyun extern void pm_stay_awake(struct device *dev);
111*4882a593Smuzhiyun extern void __pm_relax(struct wakeup_source *ws);
112*4882a593Smuzhiyun extern void pm_relax(struct device *dev);
113*4882a593Smuzhiyun extern void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard);
114*4882a593Smuzhiyun extern void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun #else /* !CONFIG_PM_SLEEP */
117*4882a593Smuzhiyun 
device_set_wakeup_capable(struct device * dev,bool capable)118*4882a593Smuzhiyun static inline void device_set_wakeup_capable(struct device *dev, bool capable)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	dev->power.can_wakeup = capable;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
device_can_wakeup(struct device * dev)123*4882a593Smuzhiyun static inline bool device_can_wakeup(struct device *dev)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	return dev->power.can_wakeup;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
wakeup_source_create(const char * name)128*4882a593Smuzhiyun static inline struct wakeup_source *wakeup_source_create(const char *name)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	return NULL;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
wakeup_source_destroy(struct wakeup_source * ws)133*4882a593Smuzhiyun static inline void wakeup_source_destroy(struct wakeup_source *ws) {}
134*4882a593Smuzhiyun 
wakeup_source_add(struct wakeup_source * ws)135*4882a593Smuzhiyun static inline void wakeup_source_add(struct wakeup_source *ws) {}
136*4882a593Smuzhiyun 
wakeup_source_remove(struct wakeup_source * ws)137*4882a593Smuzhiyun static inline void wakeup_source_remove(struct wakeup_source *ws) {}
138*4882a593Smuzhiyun 
wakeup_source_register(struct device * dev,const char * name)139*4882a593Smuzhiyun static inline struct wakeup_source *wakeup_source_register(struct device *dev,
140*4882a593Smuzhiyun 							   const char *name)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun 	return NULL;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
wakeup_source_unregister(struct wakeup_source * ws)145*4882a593Smuzhiyun static inline void wakeup_source_unregister(struct wakeup_source *ws) {}
146*4882a593Smuzhiyun 
device_wakeup_enable(struct device * dev)147*4882a593Smuzhiyun static inline int device_wakeup_enable(struct device *dev)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	dev->power.should_wakeup = true;
150*4882a593Smuzhiyun 	return 0;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
device_wakeup_disable(struct device * dev)153*4882a593Smuzhiyun static inline int device_wakeup_disable(struct device *dev)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	dev->power.should_wakeup = false;
156*4882a593Smuzhiyun 	return 0;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
device_set_wakeup_enable(struct device * dev,bool enable)159*4882a593Smuzhiyun static inline int device_set_wakeup_enable(struct device *dev, bool enable)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	dev->power.should_wakeup = enable;
162*4882a593Smuzhiyun 	return 0;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
device_init_wakeup(struct device * dev,bool val)165*4882a593Smuzhiyun static inline int device_init_wakeup(struct device *dev, bool val)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun 	device_set_wakeup_capable(dev, val);
168*4882a593Smuzhiyun 	device_set_wakeup_enable(dev, val);
169*4882a593Smuzhiyun 	return 0;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun 
device_may_wakeup(struct device * dev)172*4882a593Smuzhiyun static inline bool device_may_wakeup(struct device *dev)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	return dev->power.can_wakeup && dev->power.should_wakeup;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
device_set_wakeup_path(struct device * dev)177*4882a593Smuzhiyun static inline void device_set_wakeup_path(struct device *dev) {}
178*4882a593Smuzhiyun 
__pm_stay_awake(struct wakeup_source * ws)179*4882a593Smuzhiyun static inline void __pm_stay_awake(struct wakeup_source *ws) {}
180*4882a593Smuzhiyun 
pm_stay_awake(struct device * dev)181*4882a593Smuzhiyun static inline void pm_stay_awake(struct device *dev) {}
182*4882a593Smuzhiyun 
__pm_relax(struct wakeup_source * ws)183*4882a593Smuzhiyun static inline void __pm_relax(struct wakeup_source *ws) {}
184*4882a593Smuzhiyun 
pm_relax(struct device * dev)185*4882a593Smuzhiyun static inline void pm_relax(struct device *dev) {}
186*4882a593Smuzhiyun 
pm_wakeup_ws_event(struct wakeup_source * ws,unsigned int msec,bool hard)187*4882a593Smuzhiyun static inline void pm_wakeup_ws_event(struct wakeup_source *ws,
188*4882a593Smuzhiyun 				      unsigned int msec, bool hard) {}
189*4882a593Smuzhiyun 
pm_wakeup_dev_event(struct device * dev,unsigned int msec,bool hard)190*4882a593Smuzhiyun static inline void pm_wakeup_dev_event(struct device *dev, unsigned int msec,
191*4882a593Smuzhiyun 				       bool hard) {}
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun #endif /* !CONFIG_PM_SLEEP */
194*4882a593Smuzhiyun 
__pm_wakeup_event(struct wakeup_source * ws,unsigned int msec)195*4882a593Smuzhiyun static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	return pm_wakeup_ws_event(ws, msec, false);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
pm_wakeup_event(struct device * dev,unsigned int msec)200*4882a593Smuzhiyun static inline void pm_wakeup_event(struct device *dev, unsigned int msec)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	return pm_wakeup_dev_event(dev, msec, false);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
pm_wakeup_hard_event(struct device * dev)205*4882a593Smuzhiyun static inline void pm_wakeup_hard_event(struct device *dev)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	return pm_wakeup_dev_event(dev, 0, true);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun #endif /* _LINUX_PM_WAKEUP_H */
211