Loading include/linux/wakeup_reason.h +15 −6 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ struct wakeup_irq_node { bool handled; }; #ifdef CONFIG_DEDUCE_WAKEUP_REASONS /* Called in the resume path, with interrupts and nonboot cpus disabled; on * need for a spinlock. */ Loading @@ -77,19 +79,26 @@ static inline bool logging_wakeup_reasons(void) return logging_wakeup_reasons_nosync(); } void log_base_wakeup_reason(int irq); void log_suspend_abort_reason(const char *fmt, ...); bool log_possible_wakeup_reason(int irq, struct irq_desc *desc, bool (*handler)(unsigned int, struct irq_desc *)); int check_wakeup_reason(int irq); #else static inline void start_logging_wakeup_reasons(void) {} static inline bool logging_wakeup_reasons_nosync(void) { return false; } static inline bool logging_wakeup_reasons(void) { return false; } static inline bool log_possible_wakeup_reason(int irq, struct irq_desc *desc, bool (*handler)(unsigned int, struct irq_desc *)) { return true; } #endif const struct list_head* get_wakeup_reasons(unsigned long timeout, struct list_head *unfinished); void log_base_wakeup_reason(int irq); void clear_wakeup_reasons(void); void log_suspend_abort_reason(const char *fmt, ...); int check_wakeup_reason(int irq); #endif /* _LINUX_WAKEUP_REASON_H */ kernel/power/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -325,3 +325,7 @@ config SUSPEND_TIME Prints the time spent in suspend in the kernel log, and keeps statistics on the time spent in suspend in /sys/kernel/debug/suspend_time config DEDUCE_WAKEUP_REASONS bool default n kernel/power/wakeup_reason.c +21 −6 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ add_to_siblings(struct wakeup_irq_node *root, int irq) return n; } #ifdef CONFIG_DEDUCE_WAKEUP_REASONS static struct wakeup_irq_node* add_child(struct wakeup_irq_node *root, int irq) { if (!root->child) { Loading Loading @@ -150,6 +151,7 @@ get_base_node(struct wakeup_irq_node *node, unsigned depth) return node; } #endif /* CONFIG_DEDUCE_WAKEUP_REASONS */ static const struct list_head* get_wakeup_reasons_nosync(void); Loading Loading @@ -194,6 +196,7 @@ static bool walk_irq_node_tree(struct wakeup_irq_node *root, return visit(root, cookie); } #ifdef CONFIG_DEDUCE_WAKEUP_REASONS static bool is_node_handled(struct wakeup_irq_node *n, void *_p) { return n->handled; Loading @@ -203,6 +206,7 @@ static bool base_irq_nodes_done(void) { return walk_irq_node_tree(base_irq_nodes, is_node_handled, NULL); } #endif struct buf_cookie { char *buf; Loading Loading @@ -308,8 +312,13 @@ void log_base_wakeup_reason(int irq) */ base_irq_nodes = add_to_siblings(base_irq_nodes, irq); BUG_ON(!base_irq_nodes); #ifndef CONFIG_DEDUCE_WAKEUP_REASONS base_irq_nodes->handled = true; #endif } #ifdef CONFIG_DEDUCE_WAKEUP_REASONS /* This function is called by generic_handle_irq, which may call itself * recursively. This happens with interrupts disabled. Using * log_possible_wakeup_reason, we build a tree of interrupts, tracing the call Loading @@ -328,7 +337,7 @@ void log_base_wakeup_reason(int irq) */ struct wakeup_irq_node * static struct wakeup_irq_node * log_possible_wakeup_reason_start(int irq, struct irq_desc *desc, unsigned depth) { BUG_ON(!irqs_disabled()); Loading Loading @@ -377,7 +386,7 @@ log_possible_wakeup_reason_start(int irq, struct irq_desc *desc, unsigned depth) return cur_irq_tree; } void log_possible_wakeup_reason_complete(struct wakeup_irq_node *n, static void log_possible_wakeup_reason_complete(struct wakeup_irq_node *n, unsigned depth, bool handled) { Loading Loading @@ -422,6 +431,8 @@ bool log_possible_wakeup_reason(int irq, return handled; } #endif /* CONFIG_DEDUCE_WAKEUP_REASONS */ void log_suspend_abort_reason(const char *fmt, ...) { va_list args; Loading Loading @@ -545,15 +556,19 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier, clear_wakeup_reasons(); break; case PM_POST_SUSPEND: /* monotonic time since boot */ curr_monotime = ktime_get(); /* monotonic time since boot including the time spent in suspend */ curr_stime = ktime_get_boottime(); #ifdef CONFIG_DEDUCE_WAKEUP_REASONS /* log_wakeups should have been cleared by now. */ if (WARN_ON(logging_wakeup_reasons())) { stop_logging_wakeup_reasons(); print_wakeup_sources(); } /* monotonic time since boot */ curr_monotime = ktime_get(); /* monotonic time since boot including the time spent in suspend */ curr_stime = ktime_get_boottime(); #else print_wakeup_sources(); #endif break; default: break; Loading Loading
include/linux/wakeup_reason.h +15 −6 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ struct wakeup_irq_node { bool handled; }; #ifdef CONFIG_DEDUCE_WAKEUP_REASONS /* Called in the resume path, with interrupts and nonboot cpus disabled; on * need for a spinlock. */ Loading @@ -77,19 +79,26 @@ static inline bool logging_wakeup_reasons(void) return logging_wakeup_reasons_nosync(); } void log_base_wakeup_reason(int irq); void log_suspend_abort_reason(const char *fmt, ...); bool log_possible_wakeup_reason(int irq, struct irq_desc *desc, bool (*handler)(unsigned int, struct irq_desc *)); int check_wakeup_reason(int irq); #else static inline void start_logging_wakeup_reasons(void) {} static inline bool logging_wakeup_reasons_nosync(void) { return false; } static inline bool logging_wakeup_reasons(void) { return false; } static inline bool log_possible_wakeup_reason(int irq, struct irq_desc *desc, bool (*handler)(unsigned int, struct irq_desc *)) { return true; } #endif const struct list_head* get_wakeup_reasons(unsigned long timeout, struct list_head *unfinished); void log_base_wakeup_reason(int irq); void clear_wakeup_reasons(void); void log_suspend_abort_reason(const char *fmt, ...); int check_wakeup_reason(int irq); #endif /* _LINUX_WAKEUP_REASON_H */
kernel/power/Kconfig +4 −0 Original line number Diff line number Diff line Loading @@ -325,3 +325,7 @@ config SUSPEND_TIME Prints the time spent in suspend in the kernel log, and keeps statistics on the time spent in suspend in /sys/kernel/debug/suspend_time config DEDUCE_WAKEUP_REASONS bool default n
kernel/power/wakeup_reason.c +21 −6 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ add_to_siblings(struct wakeup_irq_node *root, int irq) return n; } #ifdef CONFIG_DEDUCE_WAKEUP_REASONS static struct wakeup_irq_node* add_child(struct wakeup_irq_node *root, int irq) { if (!root->child) { Loading Loading @@ -150,6 +151,7 @@ get_base_node(struct wakeup_irq_node *node, unsigned depth) return node; } #endif /* CONFIG_DEDUCE_WAKEUP_REASONS */ static const struct list_head* get_wakeup_reasons_nosync(void); Loading Loading @@ -194,6 +196,7 @@ static bool walk_irq_node_tree(struct wakeup_irq_node *root, return visit(root, cookie); } #ifdef CONFIG_DEDUCE_WAKEUP_REASONS static bool is_node_handled(struct wakeup_irq_node *n, void *_p) { return n->handled; Loading @@ -203,6 +206,7 @@ static bool base_irq_nodes_done(void) { return walk_irq_node_tree(base_irq_nodes, is_node_handled, NULL); } #endif struct buf_cookie { char *buf; Loading Loading @@ -308,8 +312,13 @@ void log_base_wakeup_reason(int irq) */ base_irq_nodes = add_to_siblings(base_irq_nodes, irq); BUG_ON(!base_irq_nodes); #ifndef CONFIG_DEDUCE_WAKEUP_REASONS base_irq_nodes->handled = true; #endif } #ifdef CONFIG_DEDUCE_WAKEUP_REASONS /* This function is called by generic_handle_irq, which may call itself * recursively. This happens with interrupts disabled. Using * log_possible_wakeup_reason, we build a tree of interrupts, tracing the call Loading @@ -328,7 +337,7 @@ void log_base_wakeup_reason(int irq) */ struct wakeup_irq_node * static struct wakeup_irq_node * log_possible_wakeup_reason_start(int irq, struct irq_desc *desc, unsigned depth) { BUG_ON(!irqs_disabled()); Loading Loading @@ -377,7 +386,7 @@ log_possible_wakeup_reason_start(int irq, struct irq_desc *desc, unsigned depth) return cur_irq_tree; } void log_possible_wakeup_reason_complete(struct wakeup_irq_node *n, static void log_possible_wakeup_reason_complete(struct wakeup_irq_node *n, unsigned depth, bool handled) { Loading Loading @@ -422,6 +431,8 @@ bool log_possible_wakeup_reason(int irq, return handled; } #endif /* CONFIG_DEDUCE_WAKEUP_REASONS */ void log_suspend_abort_reason(const char *fmt, ...) { va_list args; Loading Loading @@ -545,15 +556,19 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier, clear_wakeup_reasons(); break; case PM_POST_SUSPEND: /* monotonic time since boot */ curr_monotime = ktime_get(); /* monotonic time since boot including the time spent in suspend */ curr_stime = ktime_get_boottime(); #ifdef CONFIG_DEDUCE_WAKEUP_REASONS /* log_wakeups should have been cleared by now. */ if (WARN_ON(logging_wakeup_reasons())) { stop_logging_wakeup_reasons(); print_wakeup_sources(); } /* monotonic time since boot */ curr_monotime = ktime_get(); /* monotonic time since boot including the time spent in suspend */ curr_stime = ktime_get_boottime(); #else print_wakeup_sources(); #endif break; default: break; Loading