diff options
Diffstat (limited to 'kernel/time/alarmtimer.c')
| -rw-r--r-- | kernel/time/alarmtimer.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index aa27d391bfc8..54e7145c5414 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
| @@ -46,6 +46,8 @@ static struct alarm_base { | |||
| 46 | static ktime_t freezer_delta; | 46 | static ktime_t freezer_delta; |
| 47 | static DEFINE_SPINLOCK(freezer_delta_lock); | 47 | static DEFINE_SPINLOCK(freezer_delta_lock); |
| 48 | 48 | ||
| 49 | static struct wakeup_source *ws; | ||
| 50 | |||
| 49 | #ifdef CONFIG_RTC_CLASS | 51 | #ifdef CONFIG_RTC_CLASS |
| 50 | /* rtc timer and device for setting alarm wakeups at suspend */ | 52 | /* rtc timer and device for setting alarm wakeups at suspend */ |
| 51 | static struct rtc_timer rtctimer; | 53 | static struct rtc_timer rtctimer; |
| @@ -250,6 +252,7 @@ static int alarmtimer_suspend(struct device *dev) | |||
| 250 | unsigned long flags; | 252 | unsigned long flags; |
| 251 | struct rtc_device *rtc; | 253 | struct rtc_device *rtc; |
| 252 | int i; | 254 | int i; |
| 255 | int ret; | ||
| 253 | 256 | ||
| 254 | spin_lock_irqsave(&freezer_delta_lock, flags); | 257 | spin_lock_irqsave(&freezer_delta_lock, flags); |
| 255 | min = freezer_delta; | 258 | min = freezer_delta; |
| @@ -279,8 +282,10 @@ static int alarmtimer_suspend(struct device *dev) | |||
| 279 | if (min.tv64 == 0) | 282 | if (min.tv64 == 0) |
| 280 | return 0; | 283 | return 0; |
| 281 | 284 | ||
| 282 | /* XXX - Should we enforce a minimum sleep time? */ | 285 | if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) { |
| 283 | WARN_ON(min.tv64 < NSEC_PER_SEC); | 286 | __pm_wakeup_event(ws, 2 * MSEC_PER_SEC); |
| 287 | return -EBUSY; | ||
| 288 | } | ||
| 284 | 289 | ||
| 285 | /* Setup an rtc timer to fire that far in the future */ | 290 | /* Setup an rtc timer to fire that far in the future */ |
| 286 | rtc_timer_cancel(rtc, &rtctimer); | 291 | rtc_timer_cancel(rtc, &rtctimer); |
| @@ -288,9 +293,11 @@ static int alarmtimer_suspend(struct device *dev) | |||
| 288 | now = rtc_tm_to_ktime(tm); | 293 | now = rtc_tm_to_ktime(tm); |
| 289 | now = ktime_add(now, min); | 294 | now = ktime_add(now, min); |
| 290 | 295 | ||
| 291 | rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0)); | 296 | /* Set alarm, if in the past reject suspend briefly to handle */ |
| 292 | 297 | ret = rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0)); | |
| 293 | return 0; | 298 | if (ret < 0) |
| 299 | __pm_wakeup_event(ws, MSEC_PER_SEC); | ||
| 300 | return ret; | ||
| 294 | } | 301 | } |
| 295 | #else | 302 | #else |
| 296 | static int alarmtimer_suspend(struct device *dev) | 303 | static int alarmtimer_suspend(struct device *dev) |
| @@ -821,6 +828,7 @@ static int __init alarmtimer_init(void) | |||
| 821 | error = PTR_ERR(pdev); | 828 | error = PTR_ERR(pdev); |
| 822 | goto out_drv; | 829 | goto out_drv; |
| 823 | } | 830 | } |
| 831 | ws = wakeup_source_register("alarmtimer"); | ||
| 824 | return 0; | 832 | return 0; |
| 825 | 833 | ||
| 826 | out_drv: | 834 | out_drv: |
