aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/wakeup.c50
-rw-r--r--include/linux/pm_wakeup.h22
2 files changed, 62 insertions, 10 deletions
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 7c5ab70b9ef3..2a3e581b8dcd 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -53,6 +53,23 @@ static void pm_wakeup_timer_fn(unsigned long data);
53static LIST_HEAD(wakeup_sources); 53static LIST_HEAD(wakeup_sources);
54 54
55/** 55/**
56 * wakeup_source_prepare - Prepare a new wakeup source for initialization.
57 * @ws: Wakeup source to prepare.
58 * @name: Pointer to the name of the new wakeup source.
59 *
60 * Callers must ensure that the @name string won't be freed when @ws is still in
61 * use.
62 */
63void wakeup_source_prepare(struct wakeup_source *ws, const char *name)
64{
65 if (ws) {
66 memset(ws, 0, sizeof(*ws));
67 ws->name = name;
68 }
69}
70EXPORT_SYMBOL_GPL(wakeup_source_prepare);
71
72/**
56 * wakeup_source_create - Create a struct wakeup_source object. 73 * wakeup_source_create - Create a struct wakeup_source object.
57 * @name: Name of the new wakeup source. 74 * @name: Name of the new wakeup source.
58 */ 75 */
@@ -60,31 +77,44 @@ struct wakeup_source *wakeup_source_create(const char *name)
60{ 77{
61 struct wakeup_source *ws; 78 struct wakeup_source *ws;
62 79
63 ws = kzalloc(sizeof(*ws), GFP_KERNEL); 80 ws = kmalloc(sizeof(*ws), GFP_KERNEL);
64 if (!ws) 81 if (!ws)
65 return NULL; 82 return NULL;
66 83
67 if (name) 84 wakeup_source_prepare(ws, name ? kstrdup(name, GFP_KERNEL) : NULL);
68 ws->name = kstrdup(name, GFP_KERNEL);
69
70 return ws; 85 return ws;
71} 86}
72EXPORT_SYMBOL_GPL(wakeup_source_create); 87EXPORT_SYMBOL_GPL(wakeup_source_create);
73 88
74/** 89/**
75 * wakeup_source_destroy - Destroy a struct wakeup_source object. 90 * wakeup_source_drop - Prepare a struct wakeup_source object for destruction.
76 * @ws: Wakeup source to destroy. 91 * @ws: Wakeup source to prepare for destruction.
77 * 92 *
78 * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never 93 * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never
79 * be run in parallel with this function for the same wakeup source object. 94 * be run in parallel with this function for the same wakeup source object.
80 */ 95 */
81void wakeup_source_destroy(struct wakeup_source *ws) 96void wakeup_source_drop(struct wakeup_source *ws)
82{ 97{
83 if (!ws) 98 if (!ws)
84 return; 99 return;
85 100
86 del_timer_sync(&ws->timer); 101 del_timer_sync(&ws->timer);
87 __pm_relax(ws); 102 __pm_relax(ws);
103}
104EXPORT_SYMBOL_GPL(wakeup_source_drop);
105
106/**
107 * wakeup_source_destroy - Destroy a struct wakeup_source object.
108 * @ws: Wakeup source to destroy.
109 *
110 * Use only for wakeup source objects created with wakeup_source_create().
111 */
112void wakeup_source_destroy(struct wakeup_source *ws)
113{
114 if (!ws)
115 return;
116
117 wakeup_source_drop(ws);
88 kfree(ws->name); 118 kfree(ws->name);
89 kfree(ws); 119 kfree(ws);
90} 120}
@@ -147,8 +177,10 @@ EXPORT_SYMBOL_GPL(wakeup_source_register);
147 */ 177 */
148void wakeup_source_unregister(struct wakeup_source *ws) 178void wakeup_source_unregister(struct wakeup_source *ws)
149{ 179{
150 wakeup_source_remove(ws); 180 if (ws) {
151 wakeup_source_destroy(ws); 181 wakeup_source_remove(ws);
182 wakeup_source_destroy(ws);
183 }
152} 184}
153EXPORT_SYMBOL_GPL(wakeup_source_unregister); 185EXPORT_SYMBOL_GPL(wakeup_source_unregister);
154 186
diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h
index a32da962d693..d9f05113e5fb 100644
--- a/include/linux/pm_wakeup.h
+++ b/include/linux/pm_wakeup.h
@@ -41,7 +41,7 @@
41 * @active: Status of the wakeup source. 41 * @active: Status of the wakeup source.
42 */ 42 */
43struct wakeup_source { 43struct wakeup_source {
44 char *name; 44 const char *name;
45 struct list_head entry; 45 struct list_head entry;
46 spinlock_t lock; 46 spinlock_t lock;
47 struct timer_list timer; 47 struct timer_list timer;
@@ -73,7 +73,9 @@ static inline bool device_may_wakeup(struct device *dev)
73} 73}
74 74
75/* drivers/base/power/wakeup.c */ 75/* drivers/base/power/wakeup.c */
76extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name);
76extern struct wakeup_source *wakeup_source_create(const char *name); 77extern struct wakeup_source *wakeup_source_create(const char *name);
78extern void wakeup_source_drop(struct wakeup_source *ws);
77extern void wakeup_source_destroy(struct wakeup_source *ws); 79extern void wakeup_source_destroy(struct wakeup_source *ws);
78extern void wakeup_source_add(struct wakeup_source *ws); 80extern void wakeup_source_add(struct wakeup_source *ws);
79extern void wakeup_source_remove(struct wakeup_source *ws); 81extern void wakeup_source_remove(struct wakeup_source *ws);
@@ -103,11 +105,16 @@ static inline bool device_can_wakeup(struct device *dev)
103 return dev->power.can_wakeup; 105 return dev->power.can_wakeup;
104} 106}
105 107
108static inline void wakeup_source_prepare(struct wakeup_source *ws,
109 const char *name) {}
110
106static inline struct wakeup_source *wakeup_source_create(const char *name) 111static inline struct wakeup_source *wakeup_source_create(const char *name)
107{ 112{
108 return NULL; 113 return NULL;
109} 114}
110 115
116static inline void wakeup_source_drop(struct wakeup_source *ws) {}
117
111static inline void wakeup_source_destroy(struct wakeup_source *ws) {} 118static inline void wakeup_source_destroy(struct wakeup_source *ws) {}
112 119
113static inline void wakeup_source_add(struct wakeup_source *ws) {} 120static inline void wakeup_source_add(struct wakeup_source *ws) {}
@@ -165,4 +172,17 @@ static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {}
165 172
166#endif /* !CONFIG_PM_SLEEP */ 173#endif /* !CONFIG_PM_SLEEP */
167 174
175static inline void wakeup_source_init(struct wakeup_source *ws,
176 const char *name)
177{
178 wakeup_source_prepare(ws, name);
179 wakeup_source_add(ws);
180}
181
182static inline void wakeup_source_trash(struct wakeup_source *ws)
183{
184 wakeup_source_remove(ws);
185 wakeup_source_drop(ws);
186}
187
168#endif /* _LINUX_PM_WAKEUP_H */ 188#endif /* _LINUX_PM_WAKEUP_H */