|
@@ -52,6 +52,23 @@ static void pm_wakeup_timer_fn(unsigned long data);
|
|
|
|
|
|
static LIST_HEAD(wakeup_sources);
|
|
|
|
|
|
+/**
|
|
|
+ * wakeup_source_prepare - Prepare a new wakeup source for initialization.
|
|
|
+ * @ws: Wakeup source to prepare.
|
|
|
+ * @name: Pointer to the name of the new wakeup source.
|
|
|
+ *
|
|
|
+ * Callers must ensure that the @name string won't be freed when @ws is still in
|
|
|
+ * use.
|
|
|
+ */
|
|
|
+void wakeup_source_prepare(struct wakeup_source *ws, const char *name)
|
|
|
+{
|
|
|
+ if (ws) {
|
|
|
+ memset(ws, 0, sizeof(*ws));
|
|
|
+ ws->name = name;
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(wakeup_source_prepare);
|
|
|
+
|
|
|
/**
|
|
|
* wakeup_source_create - Create a struct wakeup_source object.
|
|
|
* @name: Name of the new wakeup source.
|
|
@@ -60,31 +77,44 @@ struct wakeup_source *wakeup_source_create(const char *name)
|
|
|
{
|
|
|
struct wakeup_source *ws;
|
|
|
|
|
|
- ws = kzalloc(sizeof(*ws), GFP_KERNEL);
|
|
|
+ ws = kmalloc(sizeof(*ws), GFP_KERNEL);
|
|
|
if (!ws)
|
|
|
return NULL;
|
|
|
|
|
|
- if (name)
|
|
|
- ws->name = kstrdup(name, GFP_KERNEL);
|
|
|
-
|
|
|
+ wakeup_source_prepare(ws, name ? kstrdup(name, GFP_KERNEL) : NULL);
|
|
|
return ws;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(wakeup_source_create);
|
|
|
|
|
|
/**
|
|
|
- * wakeup_source_destroy - Destroy a struct wakeup_source object.
|
|
|
- * @ws: Wakeup source to destroy.
|
|
|
+ * wakeup_source_drop - Prepare a struct wakeup_source object for destruction.
|
|
|
+ * @ws: Wakeup source to prepare for destruction.
|
|
|
*
|
|
|
* Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never
|
|
|
* be run in parallel with this function for the same wakeup source object.
|
|
|
*/
|
|
|
-void wakeup_source_destroy(struct wakeup_source *ws)
|
|
|
+void wakeup_source_drop(struct wakeup_source *ws)
|
|
|
{
|
|
|
if (!ws)
|
|
|
return;
|
|
|
|
|
|
del_timer_sync(&ws->timer);
|
|
|
__pm_relax(ws);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(wakeup_source_drop);
|
|
|
+
|
|
|
+/**
|
|
|
+ * wakeup_source_destroy - Destroy a struct wakeup_source object.
|
|
|
+ * @ws: Wakeup source to destroy.
|
|
|
+ *
|
|
|
+ * Use only for wakeup source objects created with wakeup_source_create().
|
|
|
+ */
|
|
|
+void wakeup_source_destroy(struct wakeup_source *ws)
|
|
|
+{
|
|
|
+ if (!ws)
|
|
|
+ return;
|
|
|
+
|
|
|
+ wakeup_source_drop(ws);
|
|
|
kfree(ws->name);
|
|
|
kfree(ws);
|
|
|
}
|
|
@@ -147,8 +177,10 @@ EXPORT_SYMBOL_GPL(wakeup_source_register);
|
|
|
*/
|
|
|
void wakeup_source_unregister(struct wakeup_source *ws)
|
|
|
{
|
|
|
- wakeup_source_remove(ws);
|
|
|
- wakeup_source_destroy(ws);
|
|
|
+ if (ws) {
|
|
|
+ wakeup_source_remove(ws);
|
|
|
+ wakeup_source_destroy(ws);
|
|
|
+ }
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(wakeup_source_unregister);
|
|
|
|