aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/alarmtimer.c18
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 {
46static ktime_t freezer_delta; 46static ktime_t freezer_delta;
47static DEFINE_SPINLOCK(freezer_delta_lock); 47static DEFINE_SPINLOCK(freezer_delta_lock);
48 48
49static 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 */
51static struct rtc_timer rtctimer; 53static 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
296static int alarmtimer_suspend(struct device *dev) 303static 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
826out_drv: 834out_drv: