Lines Matching +full:wakeup +full:- +full:rtc +full:- +full:timer
1 // SPDX-License-Identifier: GPL-2.0
5 * This interface provides a timer which is similar to hrtimers,
6 * but triggers a RTC alarm if the box is suspend.
8 * This interface is influenced by the Android RTC Alarm timer
18 #include <linux/rtc.h>
24 #include <linux/posix-timers.h>
31 #include "posix-timers.h"
37 * struct alarm_base - Alarm timer bases
61 /* rtc timer and device for setting alarm wakeups at suspend */
67 * alarmtimer_get_rtcdev - Return selected rtcdevice
69 * This function returns the rtc device to use for wakealarms.
84 struct rtc_device *rtc = to_rtc_device(dev); in alarmtimer_rtc_add_device() local
89 return -EBUSY; in alarmtimer_rtc_add_device()
91 if (!test_bit(RTC_FEATURE_ALARM, rtc->features)) in alarmtimer_rtc_add_device()
92 return -1; in alarmtimer_rtc_add_device()
93 if (!device_may_wakeup(rtc->dev.parent)) in alarmtimer_rtc_add_device()
94 return -1; in alarmtimer_rtc_add_device()
99 device_init_wakeup(&pdev->dev, true); in alarmtimer_rtc_add_device()
102 if (!IS_ERR(pdev) && !rtcdev && try_module_get(rtc->owner)) { in alarmtimer_rtc_add_device()
103 rtcdev = rtc; in alarmtimer_rtc_add_device()
108 ret = -1; in alarmtimer_rtc_add_device()
141 * alarmtimer_enqueue - Adds an alarm timer to an alarm_base timerqueue
142 * @base: pointer to the base where the timer is being run
147 * Must hold base->lock when calling.
151 if (alarm->state & ALARMTIMER_STATE_ENQUEUED) in alarmtimer_enqueue()
152 timerqueue_del(&base->timerqueue, &alarm->node); in alarmtimer_enqueue()
154 timerqueue_add(&base->timerqueue, &alarm->node); in alarmtimer_enqueue()
155 alarm->state |= ALARMTIMER_STATE_ENQUEUED; in alarmtimer_enqueue()
159 * alarmtimer_dequeue - Removes an alarm timer from an alarm_base timerqueue
160 * @base: pointer to the base where the timer is running
165 * Must hold base->lock when calling.
169 if (!(alarm->state & ALARMTIMER_STATE_ENQUEUED)) in alarmtimer_dequeue()
172 timerqueue_del(&base->timerqueue, &alarm->node); in alarmtimer_dequeue()
173 alarm->state &= ~ALARMTIMER_STATE_ENQUEUED; in alarmtimer_dequeue()
178 * alarmtimer_fired - Handles alarm hrtimer being fired.
179 * @timer: pointer to hrtimer being run
181 * When a alarm timer fires, this runs through the timerqueue to
184 * the next future alarm timer expires.
186 static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) in alarmtimer_fired() argument
188 struct alarm *alarm = container_of(timer, struct alarm, timer); in alarmtimer_fired()
189 struct alarm_base *base = &alarm_bases[alarm->type]; in alarmtimer_fired()
191 scoped_guard(spinlock_irqsave, &base->lock) in alarmtimer_fired()
194 if (alarm->function) in alarmtimer_fired()
195 alarm->function(alarm, base->get_ktime()); in alarmtimer_fired()
197 trace_alarmtimer_fired(alarm, base->get_ktime()); in alarmtimer_fired()
203 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_expires_remaining()
204 return ktime_sub(alarm->node.expires, base->get_ktime()); in alarm_expires_remaining()
210 * alarmtimer_suspend - Suspend time callback
214 * to see which is the soonest timer to expire. We then
215 * set an rtc timer to fire that far into the future, which
221 struct rtc_device *rtc; in alarmtimer_suspend() local
232 rtc = alarmtimer_get_rtcdev(); in alarmtimer_suspend()
234 if (!rtc) in alarmtimer_suspend()
237 /* Find the soonest timer to expire*/ in alarmtimer_suspend()
243 scoped_guard(spinlock_irqsave, &base->lock) in alarmtimer_suspend()
244 next = timerqueue_getnext(&base->timerqueue); in alarmtimer_suspend()
247 delta = ktime_sub(next->expires, base->get_ktime()); in alarmtimer_suspend()
249 expires = next->expires; in alarmtimer_suspend()
259 return -EBUSY; in alarmtimer_suspend()
264 /* Setup an rtc timer to fire that far in the future */ in alarmtimer_suspend()
265 rtc_timer_cancel(rtc, &rtctimer); in alarmtimer_suspend()
266 rtc_read_time(rtc, &tm); in alarmtimer_suspend()
270 * If the RTC alarm timer only supports a limited time offset, set the in alarmtimer_suspend()
274 * the alarmtimer exceeds the time that the rtc device can be programmed in alarmtimer_suspend()
277 min = rtc_bound_alarmtime(rtc, min); in alarmtimer_suspend()
282 ret = rtc_timer_start(rtc, &rtctimer, now, 0); in alarmtimer_suspend()
290 struct rtc_device *rtc; in alarmtimer_resume() local
292 rtc = alarmtimer_get_rtcdev(); in alarmtimer_resume()
293 if (rtc) in alarmtimer_resume()
294 rtc_timer_cancel(rtc, &rtctimer); in alarmtimer_resume()
314 timerqueue_init(&alarm->node); in __alarm_init()
315 alarm->function = function; in __alarm_init()
316 alarm->type = type; in __alarm_init()
317 alarm->state = ALARMTIMER_STATE_INACTIVE; in __alarm_init()
321 * alarm_init - Initialize an alarm structure
329 hrtimer_setup(&alarm->timer, alarmtimer_fired, alarm_bases[type].base_clockid, in alarm_init()
336 * alarm_start - Sets an absolute alarm to fire
342 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_start()
344 scoped_guard(spinlock_irqsave, &base->lock) { in alarm_start()
345 alarm->node.expires = start; in alarm_start()
347 hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); in alarm_start()
350 trace_alarmtimer_start(alarm, base->get_ktime()); in alarm_start()
355 * alarm_start_relative - Sets a relative alarm to fire
361 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_start_relative()
363 start = ktime_add_safe(start, base->get_ktime()); in alarm_start_relative()
370 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_restart()
372 guard(spinlock_irqsave)(&base->lock); in alarm_restart()
373 hrtimer_set_expires(&alarm->timer, alarm->node.expires); in alarm_restart()
374 hrtimer_restart(&alarm->timer); in alarm_restart()
380 * alarm_try_to_cancel - Tries to cancel an alarm timer
383 * Returns 1 if the timer was canceled, 0 if it was not running,
384 * and -1 if the callback was running
388 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_try_to_cancel()
391 scoped_guard(spinlock_irqsave, &base->lock) { in alarm_try_to_cancel()
392 ret = hrtimer_try_to_cancel(&alarm->timer); in alarm_try_to_cancel()
397 trace_alarmtimer_cancel(alarm, base->get_ktime()); in alarm_try_to_cancel()
404 * alarm_cancel - Spins trying to cancel an alarm timer until it is done
407 * Returns 1 if the timer was canceled, 0 if it was not active.
415 hrtimer_cancel_wait_running(&alarm->timer); in alarm_cancel()
426 delta = ktime_sub(now, alarm->node.expires); in alarm_forward()
436 alarm->node.expires = ktime_add_ns(alarm->node.expires, in alarm_forward()
439 if (alarm->node.expires > now) in alarm_forward()
448 alarm->node.expires = ktime_add_safe(alarm->node.expires, interval); in alarm_forward()
455 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_forward_now()
457 return alarm_forward(alarm, base->get_ktime(), interval); in alarm_forward_now()
482 delta = ktime_sub(absexp, base->get_ktime()); in alarmtimer_freezerset()
493 * clock2alarm - helper that converts from clockid to alarmtypes
506 * alarm_handle_timer - Callback for posix timers
508 * @now: time at the timer expiration
510 * Posix timer callback for expired alarm timers.
512 * Return: whether the timer is to be restarted
518 guard(spinlock_irqsave)(&ptr->it_lock); in alarm_handle_timer()
523 * alarm_timer_rearm - Posix timer callback for rearming timer
528 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_rearm()
530 timr->it_overrun += alarm_forward_now(alarm, timr->it_interval); in alarm_timer_rearm()
531 alarm_start(alarm, alarm->node.expires); in alarm_timer_rearm()
535 * alarm_timer_forward - Posix timer callback for forwarding timer
537 * @now: Current time to forward the timer against
541 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_forward()
543 return alarm_forward(alarm, timr->it_interval, now); in alarm_timer_forward()
547 * alarm_timer_remaining - Posix timer callback to retrieve remaining time
553 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_remaining()
555 return ktime_sub(alarm->node.expires, now); in alarm_timer_remaining()
559 * alarm_timer_try_to_cancel - Posix timer callback to cancel a timer
564 return alarm_try_to_cancel(&timr->it.alarm.alarmtimer); in alarm_timer_try_to_cancel()
568 * alarm_timer_wait_running - Posix timer callback to wait for a timer
571 * Called from the core code when timer cancel detected that the callback
577 hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer); in alarm_timer_wait_running()
581 * alarm_timer_arm - Posix timer callback to arm a timer
585 * @sigev_none: Posix timer does not deliver signals
590 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_arm()
591 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_timer_arm()
594 expires = ktime_add_safe(expires, base->get_ktime()); in alarm_timer_arm()
596 alarm->node.expires = expires; in alarm_timer_arm()
598 alarm_start(&timr->it.alarm.alarmtimer, expires); in alarm_timer_arm()
602 * alarm_clock_getres - posix getres interface
611 return -EINVAL; in alarm_clock_getres()
613 tp->tv_sec = 0; in alarm_clock_getres()
614 tp->tv_nsec = hrtimer_resolution; in alarm_clock_getres()
619 * alarm_clock_get_timespec - posix clock_get_timespec interface
630 return -EINVAL; in alarm_clock_get_timespec()
632 base->get_timespec(tp); in alarm_clock_get_timespec()
638 * alarm_clock_get_ktime - posix clock_get_ktime interface
648 return -EINVAL; in alarm_clock_get_ktime()
650 return base->get_ktime(); in alarm_clock_get_ktime()
654 * alarm_timer_create - posix timer_create interface
664 return -EOPNOTSUPP; in alarm_timer_create()
667 return -EPERM; in alarm_timer_create()
669 type = clock2alarm(new_timer->it_clock); in alarm_timer_create()
670 alarm_init(&new_timer->it.alarm.alarmtimer, type, alarm_handle_timer); in alarm_timer_create()
675 * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
677 * @now: time at the timer expiration
683 struct task_struct *task = alarm->data; in alarmtimer_nsleep_wakeup()
685 alarm->data = NULL; in alarmtimer_nsleep_wakeup()
691 * alarmtimer_do_nsleep - Internal alarmtimer nsleep implementation
696 * Sets the alarm timer and sleeps until it is fired or interrupted.
702 alarm->data = (void *)current; in alarmtimer_do_nsleep()
706 if (likely(alarm->data)) in alarmtimer_do_nsleep()
710 } while (alarm->data && !signal_pending(current)); in alarmtimer_do_nsleep()
714 destroy_hrtimer_on_stack(&alarm->timer); in alarmtimer_do_nsleep()
716 if (!alarm->data) in alarmtimer_do_nsleep()
721 restart = ¤t->restart_block; in alarmtimer_do_nsleep()
722 if (restart->nanosleep.type != TT_NONE) { in alarmtimer_do_nsleep()
734 return -ERESTART_RESTARTBLOCK; in alarmtimer_do_nsleep()
741 hrtimer_setup_on_stack(&alarm->timer, alarmtimer_fired, alarm_bases[type].base_clockid, in alarm_init_on_stack()
747 * alarm_timer_nsleep_restart - restartblock alarmtimer nsleep
754 enum alarmtimer_type type = restart->nanosleep.clockid; in alarm_timer_nsleep_restart()
755 ktime_t exp = restart->nanosleep.expires; in alarm_timer_nsleep_restart()
764 * alarm_timer_nsleep - alarmtimer nanosleep
775 struct restart_block *restart = ¤t->restart_block; in alarm_timer_nsleep()
781 return -EOPNOTSUPP; in alarm_timer_nsleep()
784 return -EINVAL; in alarm_timer_nsleep()
787 return -EPERM; in alarm_timer_nsleep()
802 if (ret != -ERESTART_RESTARTBLOCK) in alarm_timer_nsleep()
807 return -ERESTARTNOHAND; in alarm_timer_nsleep()
809 restart->nanosleep.clockid = type; in alarm_timer_nsleep()
810 restart->nanosleep.expires = exp; in alarm_timer_nsleep()
854 * alarmtimer_init - Initialize alarm timer code