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