diff options
| author | Geert Uytterhoeven <geert+renesas@glider.be> | 2017-07-05 08:08:35 -0400 |
|---|---|---|
| committer | John Stultz <john.stultz@linaro.org> | 2017-08-17 15:15:10 -0400 |
| commit | 47b4a457e4cc816b3fdd2ee55c65fda8ea6de051 (patch) | |
| tree | fa89b4e29c1f1a821f48244bdde9972d0ced5276 /kernel | |
| parent | a529bea8fa6b6dded6179c72d3385e0f7d0a4fde (diff) | |
alarmtimer: Fix unavailable wake-up source in sysfs
Currently the alarmtimer registers a wake-up source unconditionally,
regardless of the system having a (wake-up capable) RTC or not.
Hence the alarmtimer will always show up in
/sys/kernel/debug/wakeup_sources, even if it is not available, and thus
cannot be a wake-up source.
To fix this, postpone registration until a wake-up capable RTC device is
added.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/time/alarmtimer.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 0b8ff7d257ea..73a2b476e59f 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
| @@ -56,9 +56,9 @@ static ktime_t freezer_delta; | |||
| 56 | static DEFINE_SPINLOCK(freezer_delta_lock); | 56 | static DEFINE_SPINLOCK(freezer_delta_lock); |
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | #ifdef CONFIG_RTC_CLASS | ||
| 59 | static struct wakeup_source *ws; | 60 | static struct wakeup_source *ws; |
| 60 | 61 | ||
| 61 | #ifdef CONFIG_RTC_CLASS | ||
| 62 | /* rtc timer and device for setting alarm wakeups at suspend */ | 62 | /* rtc timer and device for setting alarm wakeups at suspend */ |
| 63 | static struct rtc_timer rtctimer; | 63 | static struct rtc_timer rtctimer; |
| 64 | static struct rtc_device *rtcdev; | 64 | static struct rtc_device *rtcdev; |
| @@ -89,6 +89,7 @@ static int alarmtimer_rtc_add_device(struct device *dev, | |||
| 89 | { | 89 | { |
| 90 | unsigned long flags; | 90 | unsigned long flags; |
| 91 | struct rtc_device *rtc = to_rtc_device(dev); | 91 | struct rtc_device *rtc = to_rtc_device(dev); |
| 92 | struct wakeup_source *__ws; | ||
| 92 | 93 | ||
| 93 | if (rtcdev) | 94 | if (rtcdev) |
| 94 | return -EBUSY; | 95 | return -EBUSY; |
| @@ -98,13 +99,20 @@ static int alarmtimer_rtc_add_device(struct device *dev, | |||
| 98 | if (!device_may_wakeup(rtc->dev.parent)) | 99 | if (!device_may_wakeup(rtc->dev.parent)) |
| 99 | return -1; | 100 | return -1; |
| 100 | 101 | ||
| 102 | __ws = wakeup_source_register("alarmtimer"); | ||
| 103 | |||
| 101 | spin_lock_irqsave(&rtcdev_lock, flags); | 104 | spin_lock_irqsave(&rtcdev_lock, flags); |
| 102 | if (!rtcdev) { | 105 | if (!rtcdev) { |
| 103 | rtcdev = rtc; | 106 | rtcdev = rtc; |
| 104 | /* hold a reference so it doesn't go away */ | 107 | /* hold a reference so it doesn't go away */ |
| 105 | get_device(dev); | 108 | get_device(dev); |
| 109 | ws = __ws; | ||
| 110 | __ws = NULL; | ||
| 106 | } | 111 | } |
| 107 | spin_unlock_irqrestore(&rtcdev_lock, flags); | 112 | spin_unlock_irqrestore(&rtcdev_lock, flags); |
| 113 | |||
| 114 | wakeup_source_unregister(__ws); | ||
| 115 | |||
| 108 | return 0; | 116 | return 0; |
| 109 | } | 117 | } |
| 110 | 118 | ||
| @@ -860,7 +868,6 @@ static int __init alarmtimer_init(void) | |||
| 860 | error = PTR_ERR(pdev); | 868 | error = PTR_ERR(pdev); |
| 861 | goto out_drv; | 869 | goto out_drv; |
| 862 | } | 870 | } |
| 863 | ws = wakeup_source_register("alarmtimer"); | ||
| 864 | return 0; | 871 | return 0; |
| 865 | 872 | ||
| 866 | out_drv: | 873 | out_drv: |
