diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-09-17 14:25:38 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-09-17 14:25:38 -0400 |
commit | d6a56ae7ac6121ef99500b3380e98f83a3d9e102 (patch) | |
tree | 372217920c4cbbf11eb7e332ddfa54e63eaa9d25 /drivers/base | |
parent | 079d364b042afbe811c4bb0cb57fcbf4f1cfab6d (diff) | |
parent | bbdc18a3fb6740619f0d037241c85dc6cd4517aa (diff) |
Merge branch 'pm-sleep'
* pm-sleep:
properly __init-annotate pm_sysrq_init()
PM / wakeup: Use irqsave/irqrestore for events_lock
PM / Freezer: Fix small typo "regrigerator"
PM / Sleep: Print name of wakeup source that aborts suspend
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/wakeup.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index cbb463b3a750..e6ee5e80e546 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -127,6 +127,8 @@ EXPORT_SYMBOL_GPL(wakeup_source_destroy); | |||
127 | */ | 127 | */ |
128 | void wakeup_source_add(struct wakeup_source *ws) | 128 | void wakeup_source_add(struct wakeup_source *ws) |
129 | { | 129 | { |
130 | unsigned long flags; | ||
131 | |||
130 | if (WARN_ON(!ws)) | 132 | if (WARN_ON(!ws)) |
131 | return; | 133 | return; |
132 | 134 | ||
@@ -135,9 +137,9 @@ void wakeup_source_add(struct wakeup_source *ws) | |||
135 | ws->active = false; | 137 | ws->active = false; |
136 | ws->last_time = ktime_get(); | 138 | ws->last_time = ktime_get(); |
137 | 139 | ||
138 | spin_lock_irq(&events_lock); | 140 | spin_lock_irqsave(&events_lock, flags); |
139 | list_add_rcu(&ws->entry, &wakeup_sources); | 141 | list_add_rcu(&ws->entry, &wakeup_sources); |
140 | spin_unlock_irq(&events_lock); | 142 | spin_unlock_irqrestore(&events_lock, flags); |
141 | } | 143 | } |
142 | EXPORT_SYMBOL_GPL(wakeup_source_add); | 144 | EXPORT_SYMBOL_GPL(wakeup_source_add); |
143 | 145 | ||
@@ -147,12 +149,14 @@ EXPORT_SYMBOL_GPL(wakeup_source_add); | |||
147 | */ | 149 | */ |
148 | void wakeup_source_remove(struct wakeup_source *ws) | 150 | void wakeup_source_remove(struct wakeup_source *ws) |
149 | { | 151 | { |
152 | unsigned long flags; | ||
153 | |||
150 | if (WARN_ON(!ws)) | 154 | if (WARN_ON(!ws)) |
151 | return; | 155 | return; |
152 | 156 | ||
153 | spin_lock_irq(&events_lock); | 157 | spin_lock_irqsave(&events_lock, flags); |
154 | list_del_rcu(&ws->entry); | 158 | list_del_rcu(&ws->entry); |
155 | spin_unlock_irq(&events_lock); | 159 | spin_unlock_irqrestore(&events_lock, flags); |
156 | synchronize_rcu(); | 160 | synchronize_rcu(); |
157 | } | 161 | } |
158 | EXPORT_SYMBOL_GPL(wakeup_source_remove); | 162 | EXPORT_SYMBOL_GPL(wakeup_source_remove); |
@@ -649,6 +653,31 @@ void pm_wakeup_event(struct device *dev, unsigned int msec) | |||
649 | } | 653 | } |
650 | EXPORT_SYMBOL_GPL(pm_wakeup_event); | 654 | EXPORT_SYMBOL_GPL(pm_wakeup_event); |
651 | 655 | ||
656 | static void print_active_wakeup_sources(void) | ||
657 | { | ||
658 | struct wakeup_source *ws; | ||
659 | int active = 0; | ||
660 | struct wakeup_source *last_activity_ws = NULL; | ||
661 | |||
662 | rcu_read_lock(); | ||
663 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { | ||
664 | if (ws->active) { | ||
665 | pr_info("active wakeup source: %s\n", ws->name); | ||
666 | active = 1; | ||
667 | } else if (!active && | ||
668 | (!last_activity_ws || | ||
669 | ktime_to_ns(ws->last_time) > | ||
670 | ktime_to_ns(last_activity_ws->last_time))) { | ||
671 | last_activity_ws = ws; | ||
672 | } | ||
673 | } | ||
674 | |||
675 | if (!active && last_activity_ws) | ||
676 | pr_info("last active wakeup source: %s\n", | ||
677 | last_activity_ws->name); | ||
678 | rcu_read_unlock(); | ||
679 | } | ||
680 | |||
652 | /** | 681 | /** |
653 | * pm_wakeup_pending - Check if power transition in progress should be aborted. | 682 | * pm_wakeup_pending - Check if power transition in progress should be aborted. |
654 | * | 683 | * |
@@ -671,6 +700,10 @@ bool pm_wakeup_pending(void) | |||
671 | events_check_enabled = !ret; | 700 | events_check_enabled = !ret; |
672 | } | 701 | } |
673 | spin_unlock_irqrestore(&events_lock, flags); | 702 | spin_unlock_irqrestore(&events_lock, flags); |
703 | |||
704 | if (ret) | ||
705 | print_active_wakeup_sources(); | ||
706 | |||
674 | return ret; | 707 | return ret; |
675 | } | 708 | } |
676 | 709 | ||
@@ -723,15 +756,16 @@ bool pm_get_wakeup_count(unsigned int *count, bool block) | |||
723 | bool pm_save_wakeup_count(unsigned int count) | 756 | bool pm_save_wakeup_count(unsigned int count) |
724 | { | 757 | { |
725 | unsigned int cnt, inpr; | 758 | unsigned int cnt, inpr; |
759 | unsigned long flags; | ||
726 | 760 | ||
727 | events_check_enabled = false; | 761 | events_check_enabled = false; |
728 | spin_lock_irq(&events_lock); | 762 | spin_lock_irqsave(&events_lock, flags); |
729 | split_counters(&cnt, &inpr); | 763 | split_counters(&cnt, &inpr); |
730 | if (cnt == count && inpr == 0) { | 764 | if (cnt == count && inpr == 0) { |
731 | saved_count = count; | 765 | saved_count = count; |
732 | events_check_enabled = true; | 766 | events_check_enabled = true; |
733 | } | 767 | } |
734 | spin_unlock_irq(&events_lock); | 768 | spin_unlock_irqrestore(&events_lock, flags); |
735 | return events_check_enabled; | 769 | return events_check_enabled; |
736 | } | 770 | } |
737 | 771 | ||