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.
87 struct rtc_device *rtc = to_rtc_device(dev); in alarmtimer_rtc_add_device() local
92 return -EBUSY; in alarmtimer_rtc_add_device()
94 if (!test_bit(RTC_FEATURE_ALARM, rtc->features)) in alarmtimer_rtc_add_device()
95 return -1; in alarmtimer_rtc_add_device()
96 if (!device_may_wakeup(rtc->dev.parent)) in alarmtimer_rtc_add_device()
97 return -1; in alarmtimer_rtc_add_device()
102 device_init_wakeup(&pdev->dev, true); in alarmtimer_rtc_add_device()
106 if (!try_module_get(rtc->owner)) { in alarmtimer_rtc_add_device()
107 ret = -1; in alarmtimer_rtc_add_device()
111 rtcdev = rtc; in alarmtimer_rtc_add_device()
116 ret = -1; in alarmtimer_rtc_add_device()
151 * alarmtimer_enqueue - Adds an alarm timer to an alarm_base timerqueue
152 * @base: pointer to the base where the timer is being run
157 * Must hold base->lock when calling.
161 if (alarm->state & ALARMTIMER_STATE_ENQUEUED) in alarmtimer_enqueue()
162 timerqueue_del(&base->timerqueue, &alarm->node); in alarmtimer_enqueue()
164 timerqueue_add(&base->timerqueue, &alarm->node); in alarmtimer_enqueue()
165 alarm->state |= ALARMTIMER_STATE_ENQUEUED; in alarmtimer_enqueue()
169 * alarmtimer_dequeue - Removes an alarm timer from an alarm_base timerqueue
170 * @base: pointer to the base where the timer is running
175 * Must hold base->lock when calling.
179 if (!(alarm->state & ALARMTIMER_STATE_ENQUEUED)) in alarmtimer_dequeue()
182 timerqueue_del(&base->timerqueue, &alarm->node); in alarmtimer_dequeue()
183 alarm->state &= ~ALARMTIMER_STATE_ENQUEUED; in alarmtimer_dequeue()
188 * alarmtimer_fired - Handles alarm hrtimer being fired.
189 * @timer: pointer to hrtimer being run
191 * When a alarm timer fires, this runs through the timerqueue to
194 * the next future alarm timer expires.
196 static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) in alarmtimer_fired() argument
198 struct alarm *alarm = container_of(timer, struct alarm, timer); in alarmtimer_fired()
199 struct alarm_base *base = &alarm_bases[alarm->type]; in alarmtimer_fired()
201 scoped_guard (spinlock_irqsave, &base->lock) in alarmtimer_fired()
204 if (alarm->function) in alarmtimer_fired()
205 alarm->function(alarm, base->get_ktime()); in alarmtimer_fired()
207 trace_alarmtimer_fired(alarm, base->get_ktime()); in alarmtimer_fired()
213 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_expires_remaining()
214 return ktime_sub(alarm->node.expires, base->get_ktime()); in alarm_expires_remaining()
220 * alarmtimer_suspend - Suspend time callback
224 * to see which is the soonest timer to expire. We then
225 * set an rtc timer to fire that far into the future, which
232 struct rtc_device *rtc; in alarmtimer_suspend() local
243 rtc = alarmtimer_get_rtcdev(); in alarmtimer_suspend()
245 if (!rtc) in alarmtimer_suspend()
248 /* Find the soonest timer to expire*/ in alarmtimer_suspend()
254 spin_lock_irqsave(&base->lock, flags); in alarmtimer_suspend()
255 next = timerqueue_getnext(&base->timerqueue); in alarmtimer_suspend()
256 spin_unlock_irqrestore(&base->lock, flags); in alarmtimer_suspend()
259 delta = ktime_sub(next->expires, base->get_ktime()); in alarmtimer_suspend()
261 expires = next->expires; in alarmtimer_suspend()
271 return -EBUSY; in alarmtimer_suspend()
276 /* Setup an rtc timer to fire that far in the future */ in alarmtimer_suspend()
277 rtc_timer_cancel(rtc, &rtctimer); in alarmtimer_suspend()
278 rtc_read_time(rtc, &tm); in alarmtimer_suspend()
282 * If the RTC alarm timer only supports a limited time offset, set the in alarmtimer_suspend()
286 * the alarmtimer exceeds the time that the rtc device can be programmed in alarmtimer_suspend()
289 min = rtc_bound_alarmtime(rtc, min); in alarmtimer_suspend()
294 ret = rtc_timer_start(rtc, &rtctimer, now, 0); in alarmtimer_suspend()
302 struct rtc_device *rtc; in alarmtimer_resume() local
304 rtc = alarmtimer_get_rtcdev(); in alarmtimer_resume()
305 if (rtc) in alarmtimer_resume()
306 rtc_timer_cancel(rtc, &rtctimer); in alarmtimer_resume()
326 timerqueue_init(&alarm->node); in __alarm_init()
327 alarm->function = function; in __alarm_init()
328 alarm->type = type; in __alarm_init()
329 alarm->state = ALARMTIMER_STATE_INACTIVE; in __alarm_init()
333 * alarm_init - Initialize an alarm structure
341 hrtimer_setup(&alarm->timer, alarmtimer_fired, alarm_bases[type].base_clockid, in alarm_init()
348 * alarm_start - Sets an absolute alarm to fire
354 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_start()
357 spin_lock_irqsave(&base->lock, flags); in alarm_start()
358 alarm->node.expires = start; in alarm_start()
360 hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); in alarm_start()
361 spin_unlock_irqrestore(&base->lock, flags); in alarm_start()
363 trace_alarmtimer_start(alarm, base->get_ktime()); in alarm_start()
368 * alarm_start_relative - Sets a relative alarm to fire
374 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_start_relative()
376 start = ktime_add_safe(start, base->get_ktime()); in alarm_start_relative()
383 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_restart()
386 spin_lock_irqsave(&base->lock, flags); in alarm_restart()
387 hrtimer_set_expires(&alarm->timer, alarm->node.expires); in alarm_restart()
388 hrtimer_restart(&alarm->timer); in alarm_restart()
390 spin_unlock_irqrestore(&base->lock, flags); in alarm_restart()
395 * alarm_try_to_cancel - Tries to cancel an alarm timer
398 * Returns 1 if the timer was canceled, 0 if it was not running,
399 * and -1 if the callback was running
403 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_try_to_cancel()
407 spin_lock_irqsave(&base->lock, flags); in alarm_try_to_cancel()
408 ret = hrtimer_try_to_cancel(&alarm->timer); in alarm_try_to_cancel()
411 spin_unlock_irqrestore(&base->lock, flags); in alarm_try_to_cancel()
413 trace_alarmtimer_cancel(alarm, base->get_ktime()); in alarm_try_to_cancel()
420 * alarm_cancel - Spins trying to cancel an alarm timer until it is done
423 * Returns 1 if the timer was canceled, 0 if it was not active.
431 hrtimer_cancel_wait_running(&alarm->timer); in alarm_cancel()
442 delta = ktime_sub(now, alarm->node.expires); in alarm_forward()
452 alarm->node.expires = ktime_add_ns(alarm->node.expires, in alarm_forward()
455 if (alarm->node.expires > now) in alarm_forward()
464 alarm->node.expires = ktime_add_safe(alarm->node.expires, interval); in alarm_forward()
471 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_forward_now()
473 return alarm_forward(alarm, base->get_ktime(), interval); in alarm_forward_now()
499 delta = ktime_sub(absexp, base->get_ktime()); in alarmtimer_freezerset()
511 * clock2alarm - helper that converts from clockid to alarmtypes
520 return -1; in clock2alarm()
524 * alarm_handle_timer - Callback for posix timers
526 * @now: time at the timer expiration
528 * Posix timer callback for expired alarm timers.
530 * Return: whether the timer is to be restarted
536 guard(spinlock_irqsave)(&ptr->it_lock); in alarm_handle_timer()
541 * alarm_timer_rearm - Posix timer callback for rearming timer
546 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_rearm()
548 timr->it_overrun += alarm_forward_now(alarm, timr->it_interval); in alarm_timer_rearm()
549 alarm_start(alarm, alarm->node.expires); in alarm_timer_rearm()
553 * alarm_timer_forward - Posix timer callback for forwarding timer
555 * @now: Current time to forward the timer against
559 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_forward()
561 return alarm_forward(alarm, timr->it_interval, now); in alarm_timer_forward()
565 * alarm_timer_remaining - Posix timer callback to retrieve remaining time
571 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_remaining()
573 return ktime_sub(alarm->node.expires, now); in alarm_timer_remaining()
577 * alarm_timer_try_to_cancel - Posix timer callback to cancel a timer
582 return alarm_try_to_cancel(&timr->it.alarm.alarmtimer); in alarm_timer_try_to_cancel()
586 * alarm_timer_wait_running - Posix timer callback to wait for a timer
589 * Called from the core code when timer cancel detected that the callback
595 hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer); in alarm_timer_wait_running()
599 * alarm_timer_arm - Posix timer callback to arm a timer
603 * @sigev_none: Posix timer does not deliver signals
608 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_arm()
609 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_timer_arm()
612 expires = ktime_add_safe(expires, base->get_ktime()); in alarm_timer_arm()
614 alarm->node.expires = expires; in alarm_timer_arm()
616 alarm_start(&timr->it.alarm.alarmtimer, expires); in alarm_timer_arm()
620 * alarm_clock_getres - posix getres interface
629 return -EINVAL; in alarm_clock_getres()
631 tp->tv_sec = 0; in alarm_clock_getres()
632 tp->tv_nsec = hrtimer_resolution; in alarm_clock_getres()
637 * alarm_clock_get_timespec - posix clock_get_timespec interface
648 return -EINVAL; in alarm_clock_get_timespec()
650 base->get_timespec(tp); in alarm_clock_get_timespec()
656 * alarm_clock_get_ktime - posix clock_get_ktime interface
666 return -EINVAL; in alarm_clock_get_ktime()
668 return base->get_ktime(); in alarm_clock_get_ktime()
672 * alarm_timer_create - posix timer_create interface
682 return -EOPNOTSUPP; in alarm_timer_create()
685 return -EPERM; in alarm_timer_create()
687 type = clock2alarm(new_timer->it_clock); in alarm_timer_create()
688 alarm_init(&new_timer->it.alarm.alarmtimer, type, alarm_handle_timer); in alarm_timer_create()
693 * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
695 * @now: time at the timer expiration
701 struct task_struct *task = alarm->data; in alarmtimer_nsleep_wakeup()
703 alarm->data = NULL; in alarmtimer_nsleep_wakeup()
709 * alarmtimer_do_nsleep - Internal alarmtimer nsleep implementation
714 * Sets the alarm timer and sleeps until it is fired or interrupted.
720 alarm->data = (void *)current; in alarmtimer_do_nsleep()
724 if (likely(alarm->data)) in alarmtimer_do_nsleep()
728 } while (alarm->data && !signal_pending(current)); in alarmtimer_do_nsleep()
732 destroy_hrtimer_on_stack(&alarm->timer); in alarmtimer_do_nsleep()
734 if (!alarm->data) in alarmtimer_do_nsleep()
739 restart = &current->restart_block; in alarmtimer_do_nsleep()
740 if (restart->nanosleep.type != TT_NONE) { in alarmtimer_do_nsleep()
752 return -ERESTART_RESTARTBLOCK; in alarmtimer_do_nsleep()
759 hrtimer_setup_on_stack(&alarm->timer, alarmtimer_fired, alarm_bases[type].base_clockid, in alarm_init_on_stack()
765 * alarm_timer_nsleep_restart - restartblock alarmtimer nsleep
772 enum alarmtimer_type type = restart->nanosleep.clockid; in alarm_timer_nsleep_restart()
773 ktime_t exp = restart->nanosleep.expires; in alarm_timer_nsleep_restart()
782 * alarm_timer_nsleep - alarmtimer nanosleep
793 struct restart_block *restart = &current->restart_block; in alarm_timer_nsleep()
799 return -EOPNOTSUPP; in alarm_timer_nsleep()
802 return -EINVAL; in alarm_timer_nsleep()
805 return -EPERM; in alarm_timer_nsleep()
820 if (ret != -ERESTART_RESTARTBLOCK) in alarm_timer_nsleep()
825 return -ERESTARTNOHAND; in alarm_timer_nsleep()
827 restart->nanosleep.clockid = type; in alarm_timer_nsleep()
828 restart->nanosleep.expires = exp; in alarm_timer_nsleep()
872 * alarmtimer_init - Initialize alarm timer code