PM / Wakeup: Introduce wakeup source objects and event statistics (v3)

Introduce struct wakeup_source for representing system wakeup sources
within the kernel and for collecting statistics related to them.
Make the recently introduced helper functions pm_wakeup_event(),
pm_stay_awake() and pm_relax() use struct wakeup_source objects
internally, so that wakeup statistics associated with wakeup devices
can be collected and reported in a consistent way (the definition of
pm_relax() is changed, which is harmless, because this function is
not called directly by anyone yet). Introduce new wakeup-related
sysfs device attributes in /sys/devices/.../power for reporting the
device wakeup statistics.

Change the global wakeup events counters event_count and
events_in_progress into atomic variables, so that it is not necessary
to acquire a global spinlock in pm_wakeup_event(), pm_stay_awake()
and pm_relax(), which should allow us to avoid lock contention in
these functions on SMP systems with many wakeup devices.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>

+762 -131
+70
Documentation/ABI/testing/sysfs-devices-power
··· 77 77 devices this attribute is set to "enabled" by bus type code or 78 78 device drivers and in that cases it should be safe to leave the 79 79 default value. 80 + 81 + What: /sys/devices/.../power/wakeup_count 82 + Date: September 2010 83 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 84 + Description: 85 + The /sys/devices/.../wakeup_count attribute contains the number 86 + of signaled wakeup events associated with the device. This 87 + attribute is read-only. If the device is not enabled to wake up 88 + the system from sleep states, this attribute is empty. 89 + 90 + What: /sys/devices/.../power/wakeup_active_count 91 + Date: September 2010 92 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 93 + Description: 94 + The /sys/devices/.../wakeup_active_count attribute contains the 95 + number of times the processing of wakeup events associated with 96 + the device was completed (at the kernel level). This attribute 97 + is read-only. If the device is not enabled to wake up the 98 + system from sleep states, this attribute is empty. 99 + 100 + What: /sys/devices/.../power/wakeup_hit_count 101 + Date: September 2010 102 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 103 + Description: 104 + The /sys/devices/.../wakeup_hit_count attribute contains the 105 + number of times the processing of a wakeup event associated with 106 + the device might prevent the system from entering a sleep state. 107 + This attribute is read-only. If the device is not enabled to 108 + wake up the system from sleep states, this attribute is empty. 109 + 110 + What: /sys/devices/.../power/wakeup_active 111 + Date: September 2010 112 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 113 + Description: 114 + The /sys/devices/.../wakeup_active attribute contains either 1, 115 + or 0, depending on whether or not a wakeup event associated with 116 + the device is being processed (1). This attribute is read-only. 117 + If the device is not enabled to wake up the system from sleep 118 + states, this attribute is empty. 119 + 120 + What: /sys/devices/.../power/wakeup_total_time_ms 121 + Date: September 2010 122 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 123 + Description: 124 + The /sys/devices/.../wakeup_total_time_ms attribute contains 125 + the total time of processing wakeup events associated with the 126 + device, in milliseconds. This attribute is read-only. If the 127 + device is not enabled to wake up the system from sleep states, 128 + this attribute is empty. 129 + 130 + What: /sys/devices/.../power/wakeup_max_time_ms 131 + Date: September 2010 132 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 133 + Description: 134 + The /sys/devices/.../wakeup_max_time_ms attribute contains 135 + the maximum time of processing a single wakeup event associated 136 + with the device, in milliseconds. This attribute is read-only. 137 + If the device is not enabled to wake up the system from sleep 138 + states, this attribute is empty. 139 + 140 + What: /sys/devices/.../power/wakeup_last_time_ms 141 + Date: September 2010 142 + Contact: Rafael J. Wysocki <rjw@sisk.pl> 143 + Description: 144 + The /sys/devices/.../wakeup_last_time_ms attribute contains 145 + the value of the monotonic clock corresponding to the time of 146 + signaling the last wakeup event associated with the device, in 147 + milliseconds. This attribute is read-only. If the device is 148 + not enabled to wake up the system from sleep states, this 149 + attribute is empty.
+3 -1
drivers/base/power/main.c
··· 60 60 dev->power.status = DPM_ON; 61 61 init_completion(&dev->power.completion); 62 62 complete_all(&dev->power.completion); 63 - dev->power.wakeup_count = 0; 63 + dev->power.wakeup = NULL; 64 + spin_lock_init(&dev->power.lock); 64 65 pm_runtime_init(dev); 65 66 } 66 67 ··· 121 120 mutex_lock(&dpm_list_mtx); 122 121 list_del_init(&dev->power.entry); 123 122 mutex_unlock(&dpm_list_mtx); 123 + device_wakeup_disable(dev); 124 124 pm_runtime_remove(dev); 125 125 } 126 126
+1
drivers/base/power/power.h
··· 34 34 35 35 static inline void device_pm_init(struct device *dev) 36 36 { 37 + spin_lock_init(&dev->power.lock); 37 38 pm_runtime_init(dev); 38 39 } 39 40
-2
drivers/base/power/runtime.c
··· 1099 1099 */ 1100 1100 void pm_runtime_init(struct device *dev) 1101 1101 { 1102 - spin_lock_init(&dev->power.lock); 1103 - 1104 1102 dev->power.runtime_status = RPM_SUSPENDED; 1105 1103 dev->power.idle_notification = false; 1106 1104
+119 -2
drivers/base/power/sysfs.c
··· 210 210 static ssize_t wakeup_count_show(struct device *dev, 211 211 struct device_attribute *attr, char *buf) 212 212 { 213 - return sprintf(buf, "%lu\n", dev->power.wakeup_count); 213 + unsigned long count = 0; 214 + bool enabled = false; 215 + 216 + spin_lock_irq(&dev->power.lock); 217 + if (dev->power.wakeup) { 218 + count = dev->power.wakeup->event_count; 219 + enabled = true; 220 + } 221 + spin_unlock_irq(&dev->power.lock); 222 + return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); 214 223 } 215 224 216 225 static DEVICE_ATTR(wakeup_count, 0444, wakeup_count_show, NULL); 217 - #endif 226 + 227 + static ssize_t wakeup_active_count_show(struct device *dev, 228 + struct device_attribute *attr, char *buf) 229 + { 230 + unsigned long count = 0; 231 + bool enabled = false; 232 + 233 + spin_lock_irq(&dev->power.lock); 234 + if (dev->power.wakeup) { 235 + count = dev->power.wakeup->active_count; 236 + enabled = true; 237 + } 238 + spin_unlock_irq(&dev->power.lock); 239 + return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); 240 + } 241 + 242 + static DEVICE_ATTR(wakeup_active_count, 0444, wakeup_active_count_show, NULL); 243 + 244 + static ssize_t wakeup_hit_count_show(struct device *dev, 245 + struct device_attribute *attr, char *buf) 246 + { 247 + unsigned long count = 0; 248 + bool enabled = false; 249 + 250 + spin_lock_irq(&dev->power.lock); 251 + if (dev->power.wakeup) { 252 + count = dev->power.wakeup->hit_count; 253 + enabled = true; 254 + } 255 + spin_unlock_irq(&dev->power.lock); 256 + return enabled ? sprintf(buf, "%lu\n", count) : sprintf(buf, "\n"); 257 + } 258 + 259 + static DEVICE_ATTR(wakeup_hit_count, 0444, wakeup_hit_count_show, NULL); 260 + 261 + static ssize_t wakeup_active_show(struct device *dev, 262 + struct device_attribute *attr, char *buf) 263 + { 264 + unsigned int active = 0; 265 + bool enabled = false; 266 + 267 + spin_lock_irq(&dev->power.lock); 268 + if (dev->power.wakeup) { 269 + active = dev->power.wakeup->active; 270 + enabled = true; 271 + } 272 + spin_unlock_irq(&dev->power.lock); 273 + return enabled ? sprintf(buf, "%u\n", active) : sprintf(buf, "\n"); 274 + } 275 + 276 + static DEVICE_ATTR(wakeup_active, 0444, wakeup_active_show, NULL); 277 + 278 + static ssize_t wakeup_total_time_show(struct device *dev, 279 + struct device_attribute *attr, char *buf) 280 + { 281 + s64 msec = 0; 282 + bool enabled = false; 283 + 284 + spin_lock_irq(&dev->power.lock); 285 + if (dev->power.wakeup) { 286 + msec = ktime_to_ms(dev->power.wakeup->total_time); 287 + enabled = true; 288 + } 289 + spin_unlock_irq(&dev->power.lock); 290 + return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); 291 + } 292 + 293 + static DEVICE_ATTR(wakeup_total_time_ms, 0444, wakeup_total_time_show, NULL); 294 + 295 + static ssize_t wakeup_max_time_show(struct device *dev, 296 + struct device_attribute *attr, char *buf) 297 + { 298 + s64 msec = 0; 299 + bool enabled = false; 300 + 301 + spin_lock_irq(&dev->power.lock); 302 + if (dev->power.wakeup) { 303 + msec = ktime_to_ms(dev->power.wakeup->max_time); 304 + enabled = true; 305 + } 306 + spin_unlock_irq(&dev->power.lock); 307 + return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); 308 + } 309 + 310 + static DEVICE_ATTR(wakeup_max_time_ms, 0444, wakeup_max_time_show, NULL); 311 + 312 + static ssize_t wakeup_last_time_show(struct device *dev, 313 + struct device_attribute *attr, char *buf) 314 + { 315 + s64 msec = 0; 316 + bool enabled = false; 317 + 318 + spin_lock_irq(&dev->power.lock); 319 + if (dev->power.wakeup) { 320 + msec = ktime_to_ms(dev->power.wakeup->last_time); 321 + enabled = true; 322 + } 323 + spin_unlock_irq(&dev->power.lock); 324 + return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); 325 + } 326 + 327 + static DEVICE_ATTR(wakeup_last_time_ms, 0444, wakeup_last_time_show, NULL); 328 + #endif /* CONFIG_PM_SLEEP */ 218 329 219 330 #ifdef CONFIG_PM_ADVANCED_DEBUG 220 331 #ifdef CONFIG_PM_RUNTIME ··· 399 288 &dev_attr_wakeup.attr, 400 289 #ifdef CONFIG_PM_SLEEP 401 290 &dev_attr_wakeup_count.attr, 291 + &dev_attr_wakeup_active_count.attr, 292 + &dev_attr_wakeup_hit_count.attr, 293 + &dev_attr_wakeup_active.attr, 294 + &dev_attr_wakeup_total_time_ms.attr, 295 + &dev_attr_wakeup_max_time_ms.attr, 296 + &dev_attr_wakeup_last_time_ms.attr, 402 297 #endif 403 298 #ifdef CONFIG_PM_ADVANCED_DEBUG 404 299 &dev_attr_async.attr,
+454 -82
drivers/base/power/wakeup.c
··· 11 11 #include <linux/sched.h> 12 12 #include <linux/capability.h> 13 13 #include <linux/suspend.h> 14 - #include <linux/pm.h> 14 + 15 + #include "power.h" 16 + 17 + #define TIMEOUT 100 15 18 16 19 /* 17 20 * If set, the suspend/hibernate code will abort transitions to a sleep state ··· 23 20 bool events_check_enabled; 24 21 25 22 /* The counter of registered wakeup events. */ 26 - static unsigned long event_count; 23 + static atomic_t event_count = ATOMIC_INIT(0); 27 24 /* A preserved old value of event_count. */ 28 - static unsigned long saved_event_count; 25 + static unsigned int saved_count; 29 26 /* The counter of wakeup events being processed. */ 30 - static unsigned long events_in_progress; 27 + static atomic_t events_in_progress = ATOMIC_INIT(0); 31 28 32 29 static DEFINE_SPINLOCK(events_lock); 33 30 34 31 static void pm_wakeup_timer_fn(unsigned long data); 35 32 36 - static DEFINE_TIMER(events_timer, pm_wakeup_timer_fn, 0, 0); 37 - static unsigned long events_timer_expires; 33 + static LIST_HEAD(wakeup_sources); 34 + 35 + /** 36 + * wakeup_source_create - Create a struct wakeup_source object. 37 + * @name: Name of the new wakeup source. 38 + */ 39 + struct wakeup_source *wakeup_source_create(const char *name) 40 + { 41 + struct wakeup_source *ws; 42 + 43 + ws = kzalloc(sizeof(*ws), GFP_KERNEL); 44 + if (!ws) 45 + return NULL; 46 + 47 + spin_lock_init(&ws->lock); 48 + if (name) 49 + ws->name = kstrdup(name, GFP_KERNEL); 50 + 51 + return ws; 52 + } 53 + EXPORT_SYMBOL_GPL(wakeup_source_create); 54 + 55 + /** 56 + * wakeup_source_destroy - Destroy a struct wakeup_source object. 57 + * @ws: Wakeup source to destroy. 58 + */ 59 + void wakeup_source_destroy(struct wakeup_source *ws) 60 + { 61 + if (!ws) 62 + return; 63 + 64 + spin_lock_irq(&ws->lock); 65 + while (ws->active) { 66 + spin_unlock_irq(&ws->lock); 67 + 68 + schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT)); 69 + 70 + spin_lock_irq(&ws->lock); 71 + } 72 + spin_unlock_irq(&ws->lock); 73 + 74 + kfree(ws->name); 75 + kfree(ws); 76 + } 77 + EXPORT_SYMBOL_GPL(wakeup_source_destroy); 78 + 79 + /** 80 + * wakeup_source_add - Add given object to the list of wakeup sources. 81 + * @ws: Wakeup source object to add to the list. 82 + */ 83 + void wakeup_source_add(struct wakeup_source *ws) 84 + { 85 + if (WARN_ON(!ws)) 86 + return; 87 + 88 + setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws); 89 + ws->active = false; 90 + 91 + spin_lock_irq(&events_lock); 92 + list_add_rcu(&ws->entry, &wakeup_sources); 93 + spin_unlock_irq(&events_lock); 94 + synchronize_rcu(); 95 + } 96 + EXPORT_SYMBOL_GPL(wakeup_source_add); 97 + 98 + /** 99 + * wakeup_source_remove - Remove given object from the wakeup sources list. 100 + * @ws: Wakeup source object to remove from the list. 101 + */ 102 + void wakeup_source_remove(struct wakeup_source *ws) 103 + { 104 + if (WARN_ON(!ws)) 105 + return; 106 + 107 + spin_lock_irq(&events_lock); 108 + list_del_rcu(&ws->entry); 109 + spin_unlock_irq(&events_lock); 110 + synchronize_rcu(); 111 + } 112 + EXPORT_SYMBOL_GPL(wakeup_source_remove); 113 + 114 + /** 115 + * wakeup_source_register - Create wakeup source and add it to the list. 116 + * @name: Name of the wakeup source to register. 117 + */ 118 + struct wakeup_source *wakeup_source_register(const char *name) 119 + { 120 + struct wakeup_source *ws; 121 + 122 + ws = wakeup_source_create(name); 123 + if (ws) 124 + wakeup_source_add(ws); 125 + 126 + return ws; 127 + } 128 + EXPORT_SYMBOL_GPL(wakeup_source_register); 129 + 130 + /** 131 + * wakeup_source_unregister - Remove wakeup source from the list and remove it. 132 + * @ws: Wakeup source object to unregister. 133 + */ 134 + void wakeup_source_unregister(struct wakeup_source *ws) 135 + { 136 + wakeup_source_remove(ws); 137 + wakeup_source_destroy(ws); 138 + } 139 + EXPORT_SYMBOL_GPL(wakeup_source_unregister); 140 + 141 + /** 142 + * device_wakeup_attach - Attach a wakeup source object to a device object. 143 + * @dev: Device to handle. 144 + * @ws: Wakeup source object to attach to @dev. 145 + * 146 + * This causes @dev to be treated as a wakeup device. 147 + */ 148 + static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) 149 + { 150 + spin_lock_irq(&dev->power.lock); 151 + if (dev->power.wakeup) { 152 + spin_unlock_irq(&dev->power.lock); 153 + return -EEXIST; 154 + } 155 + dev->power.wakeup = ws; 156 + spin_unlock_irq(&dev->power.lock); 157 + return 0; 158 + } 159 + 160 + /** 161 + * device_wakeup_enable - Enable given device to be a wakeup source. 162 + * @dev: Device to handle. 163 + * 164 + * Create a wakeup source object, register it and attach it to @dev. 165 + */ 166 + int device_wakeup_enable(struct device *dev) 167 + { 168 + struct wakeup_source *ws; 169 + int ret; 170 + 171 + if (!dev || !dev->power.can_wakeup) 172 + return -EINVAL; 173 + 174 + ws = wakeup_source_register(dev_name(dev)); 175 + if (!ws) 176 + return -ENOMEM; 177 + 178 + ret = device_wakeup_attach(dev, ws); 179 + if (ret) 180 + wakeup_source_unregister(ws); 181 + 182 + return ret; 183 + } 184 + EXPORT_SYMBOL_GPL(device_wakeup_enable); 185 + 186 + /** 187 + * device_wakeup_detach - Detach a device's wakeup source object from it. 188 + * @dev: Device to detach the wakeup source object from. 189 + * 190 + * After it returns, @dev will not be treated as a wakeup device any more. 191 + */ 192 + static struct wakeup_source *device_wakeup_detach(struct device *dev) 193 + { 194 + struct wakeup_source *ws; 195 + 196 + spin_lock_irq(&dev->power.lock); 197 + ws = dev->power.wakeup; 198 + dev->power.wakeup = NULL; 199 + spin_unlock_irq(&dev->power.lock); 200 + return ws; 201 + } 202 + 203 + /** 204 + * device_wakeup_disable - Do not regard a device as a wakeup source any more. 205 + * @dev: Device to handle. 206 + * 207 + * Detach the @dev's wakeup source object from it, unregister this wakeup source 208 + * object and destroy it. 209 + */ 210 + int device_wakeup_disable(struct device *dev) 211 + { 212 + struct wakeup_source *ws; 213 + 214 + if (!dev || !dev->power.can_wakeup) 215 + return -EINVAL; 216 + 217 + ws = device_wakeup_detach(dev); 218 + if (ws) 219 + wakeup_source_unregister(ws); 220 + 221 + return 0; 222 + } 223 + EXPORT_SYMBOL_GPL(device_wakeup_disable); 224 + 225 + /** 226 + * device_init_wakeup - Device wakeup initialization. 227 + * @dev: Device to handle. 228 + * @enable: Whether or not to enable @dev as a wakeup device. 229 + * 230 + * By default, most devices should leave wakeup disabled. The exceptions are 231 + * devices that everyone expects to be wakeup sources: keyboards, power buttons, 232 + * possibly network interfaces, etc. 233 + */ 234 + int device_init_wakeup(struct device *dev, bool enable) 235 + { 236 + int ret = 0; 237 + 238 + if (enable) { 239 + device_set_wakeup_capable(dev, true); 240 + ret = device_wakeup_enable(dev); 241 + } else { 242 + device_set_wakeup_capable(dev, false); 243 + } 244 + 245 + return ret; 246 + } 247 + EXPORT_SYMBOL_GPL(device_init_wakeup); 248 + 249 + /** 250 + * device_set_wakeup_enable - Enable or disable a device to wake up the system. 251 + * @dev: Device to handle. 252 + */ 253 + int device_set_wakeup_enable(struct device *dev, bool enable) 254 + { 255 + if (!dev || !dev->power.can_wakeup) 256 + return -EINVAL; 257 + 258 + return enable ? device_wakeup_enable(dev) : device_wakeup_disable(dev); 259 + } 260 + EXPORT_SYMBOL_GPL(device_set_wakeup_enable); 38 261 39 262 /* 40 263 * The functions below use the observation that each wakeup event starts a ··· 284 55 * knowledge, however, may not be available to it, so it can simply specify time 285 56 * to wait before the system can be suspended and pass it as the second 286 57 * argument of pm_wakeup_event(). 58 + * 59 + * It is valid to call pm_relax() after pm_wakeup_event(), in which case the 60 + * "no suspend" period will be ended either by the pm_relax(), or by the timer 61 + * function executed when the timer expires, whichever comes first. 287 62 */ 63 + 64 + /** 65 + * wakup_source_activate - Mark given wakeup source as active. 66 + * @ws: Wakeup source to handle. 67 + * 68 + * Update the @ws' statistics and, if @ws has just been activated, notify the PM 69 + * core of the event by incrementing the counter of of wakeup events being 70 + * processed. 71 + */ 72 + static void wakeup_source_activate(struct wakeup_source *ws) 73 + { 74 + ws->active = true; 75 + ws->active_count++; 76 + ws->timer_expires = jiffies; 77 + ws->last_time = ktime_get(); 78 + 79 + atomic_inc(&events_in_progress); 80 + } 81 + 82 + /** 83 + * __pm_stay_awake - Notify the PM core of a wakeup event. 84 + * @ws: Wakeup source object associated with the source of the event. 85 + * 86 + * It is safe to call this function from interrupt context. 87 + */ 88 + void __pm_stay_awake(struct wakeup_source *ws) 89 + { 90 + unsigned long flags; 91 + 92 + if (!ws) 93 + return; 94 + 95 + spin_lock_irqsave(&ws->lock, flags); 96 + ws->event_count++; 97 + if (!ws->active) 98 + wakeup_source_activate(ws); 99 + spin_unlock_irqrestore(&ws->lock, flags); 100 + } 101 + EXPORT_SYMBOL_GPL(__pm_stay_awake); 288 102 289 103 /** 290 104 * pm_stay_awake - Notify the PM core that a wakeup event is being processed. 291 105 * @dev: Device the wakeup event is related to. 292 106 * 293 - * Notify the PM core of a wakeup event (signaled by @dev) by incrementing the 294 - * counter of wakeup events being processed. If @dev is not NULL, the counter 295 - * of wakeup events related to @dev is incremented too. 107 + * Notify the PM core of a wakeup event (signaled by @dev) by calling 108 + * __pm_stay_awake for the @dev's wakeup source object. 296 109 * 297 110 * Call this function after detecting of a wakeup event if pm_relax() is going 298 111 * to be called directly after processing the event (and possibly passing it to 299 112 * user space for further processing). 300 - * 301 - * It is safe to call this function from interrupt context. 302 113 */ 303 114 void pm_stay_awake(struct device *dev) 304 115 { 305 116 unsigned long flags; 306 117 307 - spin_lock_irqsave(&events_lock, flags); 308 - if (dev) 309 - dev->power.wakeup_count++; 118 + if (!dev) 119 + return; 310 120 311 - events_in_progress++; 312 - spin_unlock_irqrestore(&events_lock, flags); 121 + spin_lock_irqsave(&dev->power.lock, flags); 122 + __pm_stay_awake(dev->power.wakeup); 123 + spin_unlock_irqrestore(&dev->power.lock, flags); 124 + } 125 + EXPORT_SYMBOL_GPL(pm_stay_awake); 126 + 127 + /** 128 + * wakup_source_deactivate - Mark given wakeup source as inactive. 129 + * @ws: Wakeup source to handle. 130 + * 131 + * Update the @ws' statistics and notify the PM core that the wakeup source has 132 + * become inactive by decrementing the counter of wakeup events being processed 133 + * and incrementing the counter of registered wakeup events. 134 + */ 135 + static void wakeup_source_deactivate(struct wakeup_source *ws) 136 + { 137 + ktime_t duration; 138 + ktime_t now; 139 + 140 + ws->relax_count++; 141 + /* 142 + * __pm_relax() may be called directly or from a timer function. 143 + * If it is called directly right after the timer function has been 144 + * started, but before the timer function calls __pm_relax(), it is 145 + * possible that __pm_stay_awake() will be called in the meantime and 146 + * will set ws->active. Then, ws->active may be cleared immediately 147 + * by the __pm_relax() called from the timer function, but in such a 148 + * case ws->relax_count will be different from ws->active_count. 149 + */ 150 + if (ws->relax_count != ws->active_count) { 151 + ws->relax_count--; 152 + return; 153 + } 154 + 155 + ws->active = false; 156 + 157 + now = ktime_get(); 158 + duration = ktime_sub(now, ws->last_time); 159 + ws->total_time = ktime_add(ws->total_time, duration); 160 + if (ktime_to_ns(duration) > ktime_to_ns(ws->max_time)) 161 + ws->max_time = duration; 162 + 163 + del_timer(&ws->timer); 164 + 165 + /* 166 + * event_count has to be incremented before events_in_progress is 167 + * modified, so that the callers of pm_check_wakeup_events() and 168 + * pm_save_wakeup_count() don't see the old value of event_count and 169 + * events_in_progress equal to zero at the same time. 170 + */ 171 + atomic_inc(&event_count); 172 + smp_mb__before_atomic_dec(); 173 + atomic_dec(&events_in_progress); 313 174 } 314 175 315 176 /** 316 - * pm_relax - Notify the PM core that processing of a wakeup event has ended. 317 - * 318 - * Notify the PM core that a wakeup event has been processed by decrementing 319 - * the counter of wakeup events being processed and incrementing the counter 320 - * of registered wakeup events. 177 + * __pm_relax - Notify the PM core that processing of a wakeup event has ended. 178 + * @ws: Wakeup source object associated with the source of the event. 321 179 * 322 180 * Call this function for wakeup events whose processing started with calling 323 - * pm_stay_awake(). 181 + * __pm_stay_awake(). 324 182 * 325 183 * It is safe to call it from interrupt context. 326 184 */ 327 - void pm_relax(void) 185 + void __pm_relax(struct wakeup_source *ws) 328 186 { 329 187 unsigned long flags; 330 188 331 - spin_lock_irqsave(&events_lock, flags); 332 - if (events_in_progress) { 333 - events_in_progress--; 334 - event_count++; 335 - } 336 - spin_unlock_irqrestore(&events_lock, flags); 189 + if (!ws) 190 + return; 191 + 192 + spin_lock_irqsave(&ws->lock, flags); 193 + if (ws->active) 194 + wakeup_source_deactivate(ws); 195 + spin_unlock_irqrestore(&ws->lock, flags); 337 196 } 197 + EXPORT_SYMBOL_GPL(__pm_relax); 198 + 199 + /** 200 + * pm_relax - Notify the PM core that processing of a wakeup event has ended. 201 + * @dev: Device that signaled the event. 202 + * 203 + * Execute __pm_relax() for the @dev's wakeup source object. 204 + */ 205 + void pm_relax(struct device *dev) 206 + { 207 + unsigned long flags; 208 + 209 + if (!dev) 210 + return; 211 + 212 + spin_lock_irqsave(&dev->power.lock, flags); 213 + __pm_relax(dev->power.wakeup); 214 + spin_unlock_irqrestore(&dev->power.lock, flags); 215 + } 216 + EXPORT_SYMBOL_GPL(pm_relax); 338 217 339 218 /** 340 219 * pm_wakeup_timer_fn - Delayed finalization of a wakeup event. 220 + * @data: Address of the wakeup source object associated with the event source. 341 221 * 342 - * Decrease the counter of wakeup events being processed after it was increased 343 - * by pm_wakeup_event(). 222 + * Call __pm_relax() for the wakeup source whose address is stored in @data. 344 223 */ 345 224 static void pm_wakeup_timer_fn(unsigned long data) 346 225 { 347 - unsigned long flags; 348 - 349 - spin_lock_irqsave(&events_lock, flags); 350 - if (events_timer_expires 351 - && time_before_eq(events_timer_expires, jiffies)) { 352 - events_in_progress--; 353 - events_timer_expires = 0; 354 - } 355 - spin_unlock_irqrestore(&events_lock, flags); 226 + __pm_relax((struct wakeup_source *)data); 356 227 } 228 + 229 + /** 230 + * __pm_wakeup_event - Notify the PM core of a wakeup event. 231 + * @ws: Wakeup source object associated with the event source. 232 + * @msec: Anticipated event processing time (in milliseconds). 233 + * 234 + * Notify the PM core of a wakeup event whose source is @ws that will take 235 + * approximately @msec milliseconds to be processed by the kernel. If @ws is 236 + * not active, activate it. If @msec is nonzero, set up the @ws' timer to 237 + * execute pm_wakeup_timer_fn() in future. 238 + * 239 + * It is safe to call this function from interrupt context. 240 + */ 241 + void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) 242 + { 243 + unsigned long flags; 244 + unsigned long expires; 245 + 246 + if (!ws) 247 + return; 248 + 249 + spin_lock_irqsave(&ws->lock, flags); 250 + 251 + ws->event_count++; 252 + if (!ws->active) 253 + wakeup_source_activate(ws); 254 + 255 + if (!msec) { 256 + wakeup_source_deactivate(ws); 257 + goto unlock; 258 + } 259 + 260 + expires = jiffies + msecs_to_jiffies(msec); 261 + if (!expires) 262 + expires = 1; 263 + 264 + if (time_after(expires, ws->timer_expires)) { 265 + mod_timer(&ws->timer, expires); 266 + ws->timer_expires = expires; 267 + } 268 + 269 + unlock: 270 + spin_unlock_irqrestore(&ws->lock, flags); 271 + } 272 + EXPORT_SYMBOL_GPL(__pm_wakeup_event); 273 + 357 274 358 275 /** 359 276 * pm_wakeup_event - Notify the PM core of a wakeup event. 360 277 * @dev: Device the wakeup event is related to. 361 278 * @msec: Anticipated event processing time (in milliseconds). 362 279 * 363 - * Notify the PM core of a wakeup event (signaled by @dev) that will take 364 - * approximately @msec milliseconds to be processed by the kernel. Increment 365 - * the counter of registered wakeup events and (if @msec is nonzero) set up 366 - * the wakeup events timer to execute pm_wakeup_timer_fn() in future (if the 367 - * timer has not been set up already, increment the counter of wakeup events 368 - * being processed). If @dev is not NULL, the counter of wakeup events related 369 - * to @dev is incremented too. 370 - * 371 - * It is safe to call this function from interrupt context. 280 + * Call __pm_wakeup_event() for the @dev's wakeup source object. 372 281 */ 373 282 void pm_wakeup_event(struct device *dev, unsigned int msec) 374 283 { 375 284 unsigned long flags; 376 285 377 - spin_lock_irqsave(&events_lock, flags); 378 - event_count++; 379 - if (dev) 380 - dev->power.wakeup_count++; 286 + if (!dev) 287 + return; 381 288 382 - if (msec) { 383 - unsigned long expires; 289 + spin_lock_irqsave(&dev->power.lock, flags); 290 + __pm_wakeup_event(dev->power.wakeup, msec); 291 + spin_unlock_irqrestore(&dev->power.lock, flags); 292 + } 293 + EXPORT_SYMBOL_GPL(pm_wakeup_event); 384 294 385 - expires = jiffies + msecs_to_jiffies(msec); 386 - if (!expires) 387 - expires = 1; 295 + /** 296 + * pm_wakeup_update_hit_counts - Update hit counts of all active wakeup sources. 297 + */ 298 + static void pm_wakeup_update_hit_counts(void) 299 + { 300 + unsigned long flags; 301 + struct wakeup_source *ws; 388 302 389 - if (!events_timer_expires 390 - || time_after(expires, events_timer_expires)) { 391 - if (!events_timer_expires) 392 - events_in_progress++; 393 - 394 - mod_timer(&events_timer, expires); 395 - events_timer_expires = expires; 396 - } 303 + rcu_read_lock(); 304 + list_for_each_entry_rcu(ws, &wakeup_sources, entry) { 305 + spin_lock_irqsave(&ws->lock, flags); 306 + if (ws->active) 307 + ws->hit_count++; 308 + spin_unlock_irqrestore(&ws->lock, flags); 397 309 } 398 - spin_unlock_irqrestore(&events_lock, flags); 310 + rcu_read_unlock(); 399 311 } 400 312 401 313 /** ··· 554 184 555 185 spin_lock_irqsave(&events_lock, flags); 556 186 if (events_check_enabled) { 557 - ret = (event_count == saved_event_count) && !events_in_progress; 187 + ret = ((unsigned int)atomic_read(&event_count) == saved_count) 188 + && !atomic_read(&events_in_progress); 558 189 events_check_enabled = ret; 559 190 } 560 191 spin_unlock_irqrestore(&events_lock, flags); 192 + if (!ret) 193 + pm_wakeup_update_hit_counts(); 561 194 return ret; 562 195 } 563 196 ··· 575 202 * drop down to zero has been interrupted by a signal (and the current number 576 203 * of wakeup events being processed is still nonzero). Otherwise return true. 577 204 */ 578 - bool pm_get_wakeup_count(unsigned long *count) 205 + bool pm_get_wakeup_count(unsigned int *count) 579 206 { 580 207 bool ret; 581 208 582 - spin_lock_irq(&events_lock); 583 209 if (capable(CAP_SYS_ADMIN)) 584 210 events_check_enabled = false; 585 211 586 - while (events_in_progress && !signal_pending(current)) { 587 - spin_unlock_irq(&events_lock); 588 - 589 - schedule_timeout_interruptible(msecs_to_jiffies(100)); 590 - 591 - spin_lock_irq(&events_lock); 212 + while (atomic_read(&events_in_progress) && !signal_pending(current)) { 213 + pm_wakeup_update_hit_counts(); 214 + schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT)); 592 215 } 593 - *count = event_count; 594 - ret = !events_in_progress; 595 - spin_unlock_irq(&events_lock); 216 + 217 + ret = !atomic_read(&events_in_progress); 218 + *count = atomic_read(&event_count); 596 219 return ret; 597 220 } 598 221 ··· 601 232 * old number of registered wakeup events to be used by pm_check_wakeup_events() 602 233 * and return true. Otherwise return false. 603 234 */ 604 - bool pm_save_wakeup_count(unsigned long count) 235 + bool pm_save_wakeup_count(unsigned int count) 605 236 { 606 237 bool ret = false; 607 238 608 239 spin_lock_irq(&events_lock); 609 - if (count == event_count && !events_in_progress) { 610 - saved_event_count = count; 240 + if (count == (unsigned int)atomic_read(&event_count) 241 + && !atomic_read(&events_in_progress)) { 242 + saved_count = count; 611 243 events_check_enabled = true; 612 244 ret = true; 613 245 } 614 246 spin_unlock_irq(&events_lock); 247 + if (!ret) 248 + pm_wakeup_update_hit_counts(); 615 249 return ret; 616 250 }
+4 -12
include/linux/pm.h
··· 448 448 RPM_REQ_RESUME, 449 449 }; 450 450 451 + struct wakeup_source; 452 + 451 453 struct dev_pm_info { 452 454 pm_message_t power_state; 453 455 unsigned int can_wakeup:1; 454 - unsigned int should_wakeup:1; 455 456 unsigned async_suspend:1; 456 457 enum dpm_state status; /* Owned by the PM core */ 458 + spinlock_t lock; 457 459 #ifdef CONFIG_PM_SLEEP 458 460 struct list_head entry; 459 461 struct completion completion; 460 - unsigned long wakeup_count; 462 + struct wakeup_source *wakeup; 461 463 #endif 462 464 #ifdef CONFIG_PM_RUNTIME 463 465 struct timer_list suspend_timer; 464 466 unsigned long timer_expires; 465 467 struct work_struct work; 466 468 wait_queue_head_t wait_queue; 467 - spinlock_t lock; 468 469 atomic_t usage_count; 469 470 atomic_t child_count; 470 471 unsigned int disable_depth:3; ··· 560 559 } while (0) 561 560 562 561 extern void device_pm_wait_for_dev(struct device *sub, struct device *dev); 563 - 564 - /* drivers/base/power/wakeup.c */ 565 - extern void pm_wakeup_event(struct device *dev, unsigned int msec); 566 - extern void pm_stay_awake(struct device *dev); 567 - extern void pm_relax(void); 568 562 #else /* !CONFIG_PM_SLEEP */ 569 563 570 564 #define device_pm_lock() do {} while (0) ··· 573 577 #define suspend_report_result(fn, ret) do {} while (0) 574 578 575 579 static inline void device_pm_wait_for_dev(struct device *a, struct device *b) {} 576 - 577 - static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} 578 - static inline void pm_stay_awake(struct device *dev) {} 579 - static inline void pm_relax(void) {} 580 580 #endif /* !CONFIG_PM_SLEEP */ 581 581 582 582 /* How to reorder dpm_list after device_move() */
+105 -26
include/linux/pm_wakeup.h
··· 2 2 * pm_wakeup.h - Power management wakeup interface 3 3 * 4 4 * Copyright (C) 2008 Alan Stern 5 + * Copyright (C) 2010 Rafael J. Wysocki, Novell Inc. 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License as published by ··· 28 27 29 28 #include <linux/types.h> 30 29 31 - #ifdef CONFIG_PM 32 - 33 - /* Changes to device_may_wakeup take effect on the next pm state change. 30 + /** 31 + * struct wakeup_source - Representation of wakeup sources 34 32 * 35 - * By default, most devices should leave wakeup disabled. The exceptions 36 - * are devices that everyone expects to be wakeup sources: keyboards, 37 - * power buttons, possibly network interfaces, etc. 33 + * @total_time: Total time this wakeup source has been active. 34 + * @max_time: Maximum time this wakeup source has been continuously active. 35 + * @last_time: Monotonic clock when the wakeup source's was activated last time. 36 + * @event_count: Number of signaled wakeup events. 37 + * @active_count: Number of times the wakeup sorce was activated. 38 + * @relax_count: Number of times the wakeup sorce was deactivated. 39 + * @hit_count: Number of times the wakeup sorce might abort system suspend. 40 + * @active: Status of the wakeup source. 38 41 */ 39 - static inline void device_init_wakeup(struct device *dev, bool val) 40 - { 41 - dev->power.can_wakeup = dev->power.should_wakeup = val; 42 - } 42 + struct wakeup_source { 43 + char *name; 44 + struct list_head entry; 45 + spinlock_t lock; 46 + struct timer_list timer; 47 + unsigned long timer_expires; 48 + ktime_t total_time; 49 + ktime_t max_time; 50 + ktime_t last_time; 51 + unsigned long event_count; 52 + unsigned long active_count; 53 + unsigned long relax_count; 54 + unsigned long hit_count; 55 + unsigned int active:1; 56 + }; 57 + 58 + #ifdef CONFIG_PM_SLEEP 59 + 60 + /* 61 + * Changes to device_may_wakeup take effect on the next pm state change. 62 + */ 43 63 44 64 static inline void device_set_wakeup_capable(struct device *dev, bool capable) 45 65 { ··· 72 50 return dev->power.can_wakeup; 73 51 } 74 52 75 - static inline void device_set_wakeup_enable(struct device *dev, bool enable) 76 - { 77 - dev->power.should_wakeup = enable; 78 - } 53 + 79 54 80 55 static inline bool device_may_wakeup(struct device *dev) 81 56 { 82 - return dev->power.can_wakeup && dev->power.should_wakeup; 57 + return dev->power.can_wakeup && !!dev->power.wakeup; 83 58 } 84 59 85 - #else /* !CONFIG_PM */ 60 + /* drivers/base/power/wakeup.c */ 61 + extern struct wakeup_source *wakeup_source_create(const char *name); 62 + extern void wakeup_source_destroy(struct wakeup_source *ws); 63 + extern void wakeup_source_add(struct wakeup_source *ws); 64 + extern void wakeup_source_remove(struct wakeup_source *ws); 65 + extern struct wakeup_source *wakeup_source_register(const char *name); 66 + extern void wakeup_source_unregister(struct wakeup_source *ws); 67 + extern int device_wakeup_enable(struct device *dev); 68 + extern int device_wakeup_disable(struct device *dev); 69 + extern int device_init_wakeup(struct device *dev, bool val); 70 + extern int device_set_wakeup_enable(struct device *dev, bool enable); 71 + extern void __pm_stay_awake(struct wakeup_source *ws); 72 + extern void pm_stay_awake(struct device *dev); 73 + extern void __pm_relax(struct wakeup_source *ws); 74 + extern void pm_relax(struct device *dev); 75 + extern void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec); 76 + extern void pm_wakeup_event(struct device *dev, unsigned int msec); 86 77 87 - /* For some reason the following routines work even without CONFIG_PM */ 88 - static inline void device_init_wakeup(struct device *dev, bool val) 89 - { 90 - dev->power.can_wakeup = val; 91 - } 78 + #else /* !CONFIG_PM_SLEEP */ 92 79 93 80 static inline void device_set_wakeup_capable(struct device *dev, bool capable) 94 81 { ··· 107 76 static inline bool device_can_wakeup(struct device *dev) 108 77 { 109 78 return dev->power.can_wakeup; 110 - } 111 - 112 - static inline void device_set_wakeup_enable(struct device *dev, bool enable) 113 - { 114 79 } 115 80 116 81 static inline bool device_may_wakeup(struct device *dev) ··· 114 87 return false; 115 88 } 116 89 117 - #endif /* !CONFIG_PM */ 90 + static inline struct wakeup_source *wakeup_source_create(const char *name) 91 + { 92 + return NULL; 93 + } 94 + 95 + static inline void wakeup_source_destroy(struct wakeup_source *ws) {} 96 + 97 + static inline void wakeup_source_add(struct wakeup_source *ws) {} 98 + 99 + static inline void wakeup_source_remove(struct wakeup_source *ws) {} 100 + 101 + static inline struct wakeup_source *wakeup_source_register(const char *name) 102 + { 103 + return NULL; 104 + } 105 + 106 + static inline void wakeup_source_unregister(struct wakeup_source *ws) {} 107 + 108 + static inline int device_wakeup_enable(struct device *dev) 109 + { 110 + return -EINVAL; 111 + } 112 + 113 + static inline int device_wakeup_disable(struct device *dev) 114 + { 115 + return 0; 116 + } 117 + 118 + static inline int device_init_wakeup(struct device *dev, bool val) 119 + { 120 + dev->power.can_wakeup = val; 121 + return val ? -EINVAL : 0; 122 + } 123 + 124 + 125 + static inline int device_set_wakeup_enable(struct device *dev, bool enable) 126 + { 127 + return -EINVAL; 128 + } 129 + 130 + static inline void __pm_stay_awake(struct wakeup_source *ws) {} 131 + 132 + static inline void pm_stay_awake(struct device *dev) {} 133 + 134 + static inline void __pm_relax(struct wakeup_source *ws) {} 135 + 136 + static inline void pm_relax(struct device *dev) {} 137 + 138 + static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) {} 139 + 140 + static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} 141 + 142 + #endif /* !CONFIG_PM_SLEEP */ 118 143 119 144 #endif /* _LINUX_PM_WAKEUP_H */
+2 -2
include/linux/suspend.h
··· 293 293 extern bool events_check_enabled; 294 294 295 295 extern bool pm_check_wakeup_events(void); 296 - extern bool pm_get_wakeup_count(unsigned long *count); 297 - extern bool pm_save_wakeup_count(unsigned long count); 296 + extern bool pm_get_wakeup_count(unsigned int *count); 297 + extern bool pm_save_wakeup_count(unsigned int count); 298 298 #else /* !CONFIG_PM_SLEEP */ 299 299 300 300 static inline int register_pm_notifier(struct notifier_block *nb)
+4 -4
kernel/power/main.c
··· 237 237 struct kobj_attribute *attr, 238 238 char *buf) 239 239 { 240 - unsigned long val; 240 + unsigned int val; 241 241 242 - return pm_get_wakeup_count(&val) ? sprintf(buf, "%lu\n", val) : -EINTR; 242 + return pm_get_wakeup_count(&val) ? sprintf(buf, "%u\n", val) : -EINTR; 243 243 } 244 244 245 245 static ssize_t wakeup_count_store(struct kobject *kobj, 246 246 struct kobj_attribute *attr, 247 247 const char *buf, size_t n) 248 248 { 249 - unsigned long val; 249 + unsigned int val; 250 250 251 - if (sscanf(buf, "%lu", &val) == 1) { 251 + if (sscanf(buf, "%u", &val) == 1) { 252 252 if (pm_save_wakeup_count(val)) 253 253 return n; 254 254 }