blob: ce57771fab9bd45eb80e8fda8673bf49a9c7c9c8 [file] [log] [blame]
Thomas Gleixner1a59d1b82019-05-27 08:55:05 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Alan Stern9a3df1f2008-03-19 22:39:13 +01002/*
3 * pm_wakeup.h - Power management wakeup interface
4 *
5 * Copyright (C) 2008 Alan Stern
Rafael J. Wysocki074037e2010-09-22 22:09:10 +02006 * Copyright (C) 2010 Rafael J. Wysocki, Novell Inc.
Alan Stern9a3df1f2008-03-19 22:39:13 +01007 */
8
9#ifndef _LINUX_PM_WAKEUP_H
10#define _LINUX_PM_WAKEUP_H
11
12#ifndef _DEVICE_H_
13# error "please don't include this file directly"
14#endif
15
Dmitry Torokhov228c54e2010-03-15 21:44:41 +010016#include <linux/types.h>
17
Tony Lindgren4990d4f2015-05-18 15:40:29 -070018struct wake_irq;
19
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020020/**
21 * struct wakeup_source - Representation of wakeup sources
Alan Stern2430d122010-06-13 00:36:52 +020022 *
Tony Lindgren4990d4f2015-05-18 15:40:29 -070023 * @name: Name of the wakeup source
24 * @entry: Wakeup source list entry
25 * @lock: Wakeup source lock
26 * @wakeirq: Optional device specific wakeirq
27 * @timer: Wakeup timer list
28 * @timer_expires: Wakeup timer expiration
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020029 * @total_time: Total time this wakeup source has been active.
30 * @max_time: Maximum time this wakeup source has been continuously active.
Rafael J. Wysocki30e3ce62012-04-29 22:52:52 +020031 * @last_time: Monotonic clock when the wakeup source's was touched last time.
Rafael J. Wysocki55850942012-04-29 22:53:32 +020032 * @prevent_sleep_time: Total time this source has been preventing autosleep.
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020033 * @event_count: Number of signaled wakeup events.
Chanwoo Choi1258ca82013-07-11 13:55:58 +090034 * @active_count: Number of times the wakeup source was activated.
35 * @relax_count: Number of times the wakeup source was deactivated.
Rafael J. Wysocki30e3ce62012-04-29 22:52:52 +020036 * @expire_count: Number of times the wakeup source's timeout has expired.
37 * @wakeup_count: Number of times the wakeup source might abort suspend.
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020038 * @active: Status of the wakeup source.
Rafael J. Wysocki30e3ce62012-04-29 22:52:52 +020039 * @has_timeout: The wakeup source has been activated with a timeout.
Alan Stern9a3df1f2008-03-19 22:39:13 +010040 */
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020041struct wakeup_source {
Rafael J. Wysocki8671bbc2012-02-21 23:47:56 +010042 const char *name;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020043 struct list_head entry;
44 spinlock_t lock;
Tony Lindgren4990d4f2015-05-18 15:40:29 -070045 struct wake_irq *wakeirq;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020046 struct timer_list timer;
47 unsigned long timer_expires;
48 ktime_t total_time;
49 ktime_t max_time;
50 ktime_t last_time;
Rafael J. Wysocki55850942012-04-29 22:53:32 +020051 ktime_t start_prevent_time;
52 ktime_t prevent_sleep_time;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020053 unsigned long event_count;
54 unsigned long active_count;
55 unsigned long relax_count;
Rafael J. Wysocki30e3ce62012-04-29 22:52:52 +020056 unsigned long expire_count;
57 unsigned long wakeup_count;
58 bool active:1;
Rafael J. Wysocki55850942012-04-29 22:53:32 +020059 bool autosleep_enabled:1;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020060};
61
62#ifdef CONFIG_PM_SLEEP
63
64/*
65 * Changes to device_may_wakeup take effect on the next pm state change.
66 */
Alan Stern9a3df1f2008-03-19 22:39:13 +010067
Dmitry Torokhov228c54e2010-03-15 21:44:41 +010068static inline bool device_can_wakeup(struct device *dev)
Alan Stern9a3df1f2008-03-19 22:39:13 +010069{
70 return dev->power.can_wakeup;
71}
72
Dmitry Torokhov228c54e2010-03-15 21:44:41 +010073static inline bool device_may_wakeup(struct device *dev)
Alan Stern9a3df1f2008-03-19 22:39:13 +010074{
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020075 return dev->power.can_wakeup && !!dev->power.wakeup;
Alan Stern9a3df1f2008-03-19 22:39:13 +010076}
77
Ulf Hanssoncf04ce72018-01-02 17:08:52 +010078static inline void device_set_wakeup_path(struct device *dev)
79{
80 dev->power.wakeup_path = true;
81}
82
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020083/* drivers/base/power/wakeup.c */
Rafael J. Wysocki8671bbc2012-02-21 23:47:56 +010084extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name);
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020085extern struct wakeup_source *wakeup_source_create(const char *name);
86extern void wakeup_source_destroy(struct wakeup_source *ws);
87extern void wakeup_source_add(struct wakeup_source *ws);
88extern void wakeup_source_remove(struct wakeup_source *ws);
89extern struct wakeup_source *wakeup_source_register(const char *name);
90extern void wakeup_source_unregister(struct wakeup_source *ws);
91extern int device_wakeup_enable(struct device *dev);
92extern int device_wakeup_disable(struct device *dev);
Rafael J. Wysockicb8f51b2011-02-08 23:26:02 +010093extern void device_set_wakeup_capable(struct device *dev, bool capable);
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020094extern int device_init_wakeup(struct device *dev, bool val);
95extern int device_set_wakeup_enable(struct device *dev, bool enable);
96extern void __pm_stay_awake(struct wakeup_source *ws);
97extern void pm_stay_awake(struct device *dev);
98extern void __pm_relax(struct wakeup_source *ws);
99extern void pm_relax(struct device *dev);
Rafael J. Wysocki8a537ec2017-04-26 23:22:09 +0200100extern void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard);
101extern void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard);
Alan Stern9a3df1f2008-03-19 22:39:13 +0100102
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200103#else /* !CONFIG_PM_SLEEP */
Alan Stern9a3df1f2008-03-19 22:39:13 +0100104
Dmitry Torokhov228c54e2010-03-15 21:44:41 +0100105static inline void device_set_wakeup_capable(struct device *dev, bool capable)
106{
Alan Stern2430d122010-06-13 00:36:52 +0200107 dev->power.can_wakeup = capable;
Dmitry Torokhov228c54e2010-03-15 21:44:41 +0100108}
Stephen Rothwellc300bd2fb2008-07-10 02:16:44 +0200109
Dmitry Torokhov228c54e2010-03-15 21:44:41 +0100110static inline bool device_can_wakeup(struct device *dev)
Alan Stern9a3df1f2008-03-19 22:39:13 +0100111{
112 return dev->power.can_wakeup;
113}
114
Rafael J. Wysocki8671bbc2012-02-21 23:47:56 +0100115static inline void wakeup_source_prepare(struct wakeup_source *ws,
116 const char *name) {}
117
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200118static inline struct wakeup_source *wakeup_source_create(const char *name)
119{
120 return NULL;
121}
122
123static inline void wakeup_source_destroy(struct wakeup_source *ws) {}
124
125static inline void wakeup_source_add(struct wakeup_source *ws) {}
126
127static inline void wakeup_source_remove(struct wakeup_source *ws) {}
128
129static inline struct wakeup_source *wakeup_source_register(const char *name)
130{
131 return NULL;
132}
133
134static inline void wakeup_source_unregister(struct wakeup_source *ws) {}
135
136static inline int device_wakeup_enable(struct device *dev)
137{
Rafael J. Wysocki805bdae2011-02-24 11:10:01 +0100138 dev->power.should_wakeup = true;
139 return 0;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200140}
141
142static inline int device_wakeup_disable(struct device *dev)
143{
Rafael J. Wysocki805bdae2011-02-24 11:10:01 +0100144 dev->power.should_wakeup = false;
145 return 0;
146}
147
148static inline int device_set_wakeup_enable(struct device *dev, bool enable)
149{
150 dev->power.should_wakeup = enable;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200151 return 0;
152}
153
154static inline int device_init_wakeup(struct device *dev, bool val)
155{
Rafael J. Wysocki805bdae2011-02-24 11:10:01 +0100156 device_set_wakeup_capable(dev, val);
157 device_set_wakeup_enable(dev, val);
158 return 0;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200159}
160
Rafael J. Wysocki805bdae2011-02-24 11:10:01 +0100161static inline bool device_may_wakeup(struct device *dev)
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200162{
Rafael J. Wysocki805bdae2011-02-24 11:10:01 +0100163 return dev->power.can_wakeup && dev->power.should_wakeup;
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200164}
165
Ulf Hanssoncf04ce72018-01-02 17:08:52 +0100166static inline void device_set_wakeup_path(struct device *dev) {}
167
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200168static inline void __pm_stay_awake(struct wakeup_source *ws) {}
169
170static inline void pm_stay_awake(struct device *dev) {}
171
172static inline void __pm_relax(struct wakeup_source *ws) {}
173
174static inline void pm_relax(struct device *dev) {}
175
Rafael J. Wysocki8a537ec2017-04-26 23:22:09 +0200176static inline void pm_wakeup_ws_event(struct wakeup_source *ws,
177 unsigned int msec, bool hard) {}
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200178
Rafael J. Wysocki8a537ec2017-04-26 23:22:09 +0200179static inline void pm_wakeup_dev_event(struct device *dev, unsigned int msec,
180 bool hard) {}
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200181
182#endif /* !CONFIG_PM_SLEEP */
Alan Stern9a3df1f2008-03-19 22:39:13 +0100183
Rafael J. Wysocki8671bbc2012-02-21 23:47:56 +0100184static inline void wakeup_source_init(struct wakeup_source *ws,
185 const char *name)
186{
187 wakeup_source_prepare(ws, name);
188 wakeup_source_add(ws);
189}
190
Rafael J. Wysocki8a537ec2017-04-26 23:22:09 +0200191static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec)
192{
193 return pm_wakeup_ws_event(ws, msec, false);
194}
195
196static inline void pm_wakeup_event(struct device *dev, unsigned int msec)
197{
198 return pm_wakeup_dev_event(dev, msec, false);
199}
200
201static inline void pm_wakeup_hard_event(struct device *dev)
202{
203 return pm_wakeup_dev_event(dev, 0, true);
204}
205
Alan Stern9a3df1f2008-03-19 22:39:13 +0100206#endif /* _LINUX_PM_WAKEUP_H */