Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge back earlier 'pm-sleep' material for v4.4.

+47 -3
+12
Documentation/ABI/testing/sysfs-power
··· 256 256 Writing a "1" enables this printing while writing a "0" 257 257 disables it. The default value is "0". Reading from this file 258 258 will display the current value. 259 + 260 + What: /sys/power/pm_wakeup_irq 261 + Date: April 2015 262 + Contact: Alexandra Yates <alexandra.yates@linux.intel.org> 263 + Description: 264 + The /sys/power/pm_wakeup_irq file reports to user space the IRQ 265 + number of the first wakeup interrupt (that is, the first 266 + interrupt from an IRQ line armed for system wakeup) seen by the 267 + kernel during the most recent system suspend/resume cycle. 268 + 269 + This output is useful for system wakeup diagnostics of spurious 270 + wakeup interrupts.
+14 -2
drivers/base/power/wakeup.c
··· 25 25 */ 26 26 bool events_check_enabled __read_mostly; 27 27 28 + /* First wakeup IRQ seen by the kernel in the last cycle. */ 29 + unsigned int pm_wakeup_irq __read_mostly; 30 + 28 31 /* If set and the system is suspending, terminate the suspend. */ 29 32 static bool pm_abort_suspend __read_mostly; 30 33 ··· 94 91 if (!ws) 95 92 return NULL; 96 93 97 - wakeup_source_prepare(ws, name ? kstrdup(name, GFP_KERNEL) : NULL); 94 + wakeup_source_prepare(ws, name ? kstrdup_const(name, GFP_KERNEL) : NULL); 98 95 return ws; 99 96 } 100 97 EXPORT_SYMBOL_GPL(wakeup_source_create); ··· 157 154 158 155 wakeup_source_drop(ws); 159 156 wakeup_source_record(ws); 160 - kfree(ws->name); 157 + kfree_const(ws->name); 161 158 kfree(ws); 162 159 } 163 160 EXPORT_SYMBOL_GPL(wakeup_source_destroy); ··· 871 868 void pm_wakeup_clear(void) 872 869 { 873 870 pm_abort_suspend = false; 871 + pm_wakeup_irq = 0; 872 + } 873 + 874 + void pm_system_irq_wakeup(unsigned int irq_number) 875 + { 876 + if (pm_wakeup_irq == 0) { 877 + pm_wakeup_irq = irq_number; 878 + pm_system_wakeup(); 879 + } 874 880 } 875 881 876 882 /**
+3
include/linux/suspend.h
··· 387 387 388 388 /* drivers/base/power/wakeup.c */ 389 389 extern bool events_check_enabled; 390 + extern unsigned int pm_wakeup_irq; 390 391 391 392 extern bool pm_wakeup_pending(void); 392 393 extern void pm_system_wakeup(void); 393 394 extern void pm_wakeup_clear(void); 395 + extern void pm_system_irq_wakeup(unsigned int irq_number); 394 396 extern bool pm_get_wakeup_count(unsigned int *count, bool block); 395 397 extern bool pm_save_wakeup_count(unsigned int count); 396 398 extern void pm_wakep_autosleep_enabled(bool set); ··· 442 440 static inline bool pm_wakeup_pending(void) { return false; } 443 441 static inline void pm_system_wakeup(void) {} 444 442 static inline void pm_wakeup_clear(void) {} 443 + static inline void pm_system_irq_wakeup(unsigned int irq_number) {} 445 444 446 445 static inline void lock_system_sleep(void) {} 447 446 static inline void unlock_system_sleep(void) {}
+1 -1
kernel/irq/pm.c
··· 21 21 desc->istate |= IRQS_SUSPENDED | IRQS_PENDING; 22 22 desc->depth++; 23 23 irq_disable(desc); 24 - pm_system_wakeup(); 24 + pm_system_irq_wakeup(irq_desc_get_irq(desc)); 25 25 return true; 26 26 } 27 27 return false;
+17
kernel/power/main.c
··· 272 272 { 273 273 pm_print_times_enabled = !!initcall_debug; 274 274 } 275 + 276 + static ssize_t pm_wakeup_irq_show(struct kobject *kobj, 277 + struct kobj_attribute *attr, 278 + char *buf) 279 + { 280 + return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA; 281 + } 282 + 283 + static ssize_t pm_wakeup_irq_store(struct kobject *kobj, 284 + struct kobj_attribute *attr, 285 + const char *buf, size_t n) 286 + { 287 + return -EINVAL; 288 + } 289 + power_attr(pm_wakeup_irq); 290 + 275 291 #else /* !CONFIG_PM_SLEEP_DEBUG */ 276 292 static inline void pm_print_times_init(void) {} 277 293 #endif /* CONFIG_PM_SLEEP_DEBUG */ ··· 620 604 #endif 621 605 #ifdef CONFIG_PM_SLEEP_DEBUG 622 606 &pm_print_times_attr.attr, 607 + &pm_wakeup_irq_attr.attr, 623 608 #endif 624 609 #endif 625 610 #ifdef CONFIG_FREEZER