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()
204 spin_lock_irqsave(&base->lock, flags); in alarmtimer_fired()
206 spin_unlock_irqrestore(&base->lock, flags); in alarmtimer_fired()
208 if (alarm->function) in alarmtimer_fired()
209 restart = alarm->function(alarm, base->get_ktime()); in alarmtimer_fired()
211 spin_lock_irqsave(&base->lock, flags); in alarmtimer_fired()
213 hrtimer_set_expires(&alarm->timer, alarm->node.expires); in alarmtimer_fired()
217 spin_unlock_irqrestore(&base->lock, flags); in alarmtimer_fired()
219 trace_alarmtimer_fired(alarm, base->get_ktime()); in alarmtimer_fired()
226 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_expires_remaining()
227 return ktime_sub(alarm->node.expires, base->get_ktime()); in alarm_expires_remaining()
233 * alarmtimer_suspend - Suspend time callback
237 * to see which is the soonest timer to expire. We then
238 * set an rtc timer to fire that far into the future, which
245 struct rtc_device *rtc; in alarmtimer_suspend() local
256 rtc = alarmtimer_get_rtcdev(); in alarmtimer_suspend()
258 if (!rtc) in alarmtimer_suspend()
261 /* Find the soonest timer to expire*/ in alarmtimer_suspend()
267 spin_lock_irqsave(&base->lock, flags); in alarmtimer_suspend()
268 next = timerqueue_getnext(&base->timerqueue); in alarmtimer_suspend()
269 spin_unlock_irqrestore(&base->lock, flags); in alarmtimer_suspend()
272 delta = ktime_sub(next->expires, base->get_ktime()); in alarmtimer_suspend()
274 expires = next->expires; in alarmtimer_suspend()
284 return -EBUSY; in alarmtimer_suspend()
289 /* Setup an rtc timer to fire that far in the future */ in alarmtimer_suspend()
290 rtc_timer_cancel(rtc, &rtctimer); in alarmtimer_suspend()
291 rtc_read_time(rtc, &tm); in alarmtimer_suspend()
295 * If the RTC alarm timer only supports a limited time offset, set the in alarmtimer_suspend()
299 * the alarmtimer exceeds the time that the rtc device can be programmed in alarmtimer_suspend()
302 min = rtc_bound_alarmtime(rtc, min); in alarmtimer_suspend()
307 ret = rtc_timer_start(rtc, &rtctimer, now, 0); in alarmtimer_suspend()
315 struct rtc_device *rtc; in alarmtimer_resume() local
317 rtc = alarmtimer_get_rtcdev(); in alarmtimer_resume()
318 if (rtc) in alarmtimer_resume()
319 rtc_timer_cancel(rtc, &rtctimer); in alarmtimer_resume()
339 timerqueue_init(&alarm->node); in __alarm_init()
340 alarm->timer.function = alarmtimer_fired; in __alarm_init()
341 alarm->function = function; in __alarm_init()
342 alarm->type = type; in __alarm_init()
343 alarm->state = ALARMTIMER_STATE_INACTIVE; in __alarm_init()
347 * alarm_init - Initialize an alarm structure
355 hrtimer_init(&alarm->timer, alarm_bases[type].base_clockid, in alarm_init()
362 * alarm_start - Sets an absolute alarm to fire
368 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_start()
371 spin_lock_irqsave(&base->lock, flags); in alarm_start()
372 alarm->node.expires = start; in alarm_start()
374 hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); in alarm_start()
375 spin_unlock_irqrestore(&base->lock, flags); in alarm_start()
377 trace_alarmtimer_start(alarm, base->get_ktime()); in alarm_start()
382 * alarm_start_relative - Sets a relative alarm to fire
388 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_start_relative()
390 start = ktime_add_safe(start, base->get_ktime()); in alarm_start_relative()
397 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_restart()
400 spin_lock_irqsave(&base->lock, flags); in alarm_restart()
401 hrtimer_set_expires(&alarm->timer, alarm->node.expires); in alarm_restart()
402 hrtimer_restart(&alarm->timer); in alarm_restart()
404 spin_unlock_irqrestore(&base->lock, flags); in alarm_restart()
409 * alarm_try_to_cancel - Tries to cancel an alarm timer
412 * Returns 1 if the timer was canceled, 0 if it was not running,
413 * and -1 if the callback was running
417 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_try_to_cancel()
421 spin_lock_irqsave(&base->lock, flags); in alarm_try_to_cancel()
422 ret = hrtimer_try_to_cancel(&alarm->timer); in alarm_try_to_cancel()
425 spin_unlock_irqrestore(&base->lock, flags); in alarm_try_to_cancel()
427 trace_alarmtimer_cancel(alarm, base->get_ktime()); in alarm_try_to_cancel()
434 * alarm_cancel - Spins trying to cancel an alarm timer until it is done
437 * Returns 1 if the timer was canceled, 0 if it was not active.
445 hrtimer_cancel_wait_running(&alarm->timer); in alarm_cancel()
456 delta = ktime_sub(now, alarm->node.expires); in alarm_forward()
466 alarm->node.expires = ktime_add_ns(alarm->node.expires, in alarm_forward()
469 if (alarm->node.expires > now) in alarm_forward()
478 alarm->node.expires = ktime_add_safe(alarm->node.expires, interval); in alarm_forward()
485 struct alarm_base *base = &alarm_bases[alarm->type]; in __alarm_forward_now()
486 ktime_t now = base->get_ktime(); in __alarm_forward_now()
537 delta = ktime_sub(absexp, base->get_ktime()); in alarmtimer_freezerset()
549 * clock2alarm - helper that converts from clockid to alarmtypes
558 return -1; in clock2alarm()
562 * alarm_handle_timer - Callback for posix timers
564 * @now: time at the timer expiration
566 * Posix timer callback for expired alarm timers.
568 * Return: whether the timer is to be restarted
579 spin_lock_irqsave(&ptr->it_lock, flags); in alarm_handle_timer()
581 ptr->it_active = 0; in alarm_handle_timer()
582 if (ptr->it_interval) in alarm_handle_timer()
583 si_private = ++ptr->it_requeue_pending; in alarm_handle_timer()
585 if (posix_timer_event(ptr, si_private) && ptr->it_interval) { in alarm_handle_timer()
587 * Handle ignored signals and rearm the timer. This will go in alarm_handle_timer()
591 ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true); in alarm_handle_timer()
592 ++ptr->it_requeue_pending; in alarm_handle_timer()
593 ptr->it_active = 1; in alarm_handle_timer()
596 spin_unlock_irqrestore(&ptr->it_lock, flags); in alarm_handle_timer()
602 * alarm_timer_rearm - Posix timer callback for rearming timer
607 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_rearm()
609 timr->it_overrun += alarm_forward_now(alarm, timr->it_interval); in alarm_timer_rearm()
610 alarm_start(alarm, alarm->node.expires); in alarm_timer_rearm()
614 * alarm_timer_forward - Posix timer callback for forwarding timer
616 * @now: Current time to forward the timer against
620 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_forward()
622 return alarm_forward(alarm, timr->it_interval, now); in alarm_timer_forward()
626 * alarm_timer_remaining - Posix timer callback to retrieve remaining time
632 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_remaining()
634 return ktime_sub(alarm->node.expires, now); in alarm_timer_remaining()
638 * alarm_timer_try_to_cancel - Posix timer callback to cancel a timer
643 return alarm_try_to_cancel(&timr->it.alarm.alarmtimer); in alarm_timer_try_to_cancel()
647 * alarm_timer_wait_running - Posix timer callback to wait for a timer
650 * Called from the core code when timer cancel detected that the callback
656 hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer); in alarm_timer_wait_running()
660 * alarm_timer_arm - Posix timer callback to arm a timer
664 * @sigev_none: Posix timer does not deliver signals
669 struct alarm *alarm = &timr->it.alarm.alarmtimer; in alarm_timer_arm()
670 struct alarm_base *base = &alarm_bases[alarm->type]; in alarm_timer_arm()
673 expires = ktime_add_safe(expires, base->get_ktime()); in alarm_timer_arm()
675 alarm->node.expires = expires; in alarm_timer_arm()
677 alarm_start(&timr->it.alarm.alarmtimer, expires); in alarm_timer_arm()
681 * alarm_clock_getres - posix getres interface
690 return -EINVAL; in alarm_clock_getres()
692 tp->tv_sec = 0; in alarm_clock_getres()
693 tp->tv_nsec = hrtimer_resolution; in alarm_clock_getres()
698 * alarm_clock_get_timespec - posix clock_get_timespec interface
709 return -EINVAL; in alarm_clock_get_timespec()
711 base->get_timespec(tp); in alarm_clock_get_timespec()
717 * alarm_clock_get_ktime - posix clock_get_ktime interface
727 return -EINVAL; in alarm_clock_get_ktime()
729 return base->get_ktime(); in alarm_clock_get_ktime()
733 * alarm_timer_create - posix timer_create interface
743 return -EOPNOTSUPP; in alarm_timer_create()
746 return -EPERM; in alarm_timer_create()
748 type = clock2alarm(new_timer->it_clock); in alarm_timer_create()
749 alarm_init(&new_timer->it.alarm.alarmtimer, type, alarm_handle_timer); in alarm_timer_create()
754 * alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
756 * @now: time at the timer expiration
765 struct task_struct *task = alarm->data; in alarmtimer_nsleep_wakeup()
767 alarm->data = NULL; in alarmtimer_nsleep_wakeup()
774 * alarmtimer_do_nsleep - Internal alarmtimer nsleep implementation
779 * Sets the alarm timer and sleeps until it is fired or interrupted.
785 alarm->data = (void *)current; in alarmtimer_do_nsleep()
789 if (likely(alarm->data)) in alarmtimer_do_nsleep()
793 } while (alarm->data && !signal_pending(current)); in alarmtimer_do_nsleep()
797 destroy_hrtimer_on_stack(&alarm->timer); in alarmtimer_do_nsleep()
799 if (!alarm->data) in alarmtimer_do_nsleep()
804 restart = ¤t->restart_block; in alarmtimer_do_nsleep()
805 if (restart->nanosleep.type != TT_NONE) { in alarmtimer_do_nsleep()
817 return -ERESTART_RESTARTBLOCK; in alarmtimer_do_nsleep()
824 hrtimer_init_on_stack(&alarm->timer, alarm_bases[type].base_clockid, in alarm_init_on_stack()
830 * alarm_timer_nsleep_restart - restartblock alarmtimer nsleep
837 enum alarmtimer_type type = restart->nanosleep.clockid; in alarm_timer_nsleep_restart()
838 ktime_t exp = restart->nanosleep.expires; in alarm_timer_nsleep_restart()
847 * alarm_timer_nsleep - alarmtimer nanosleep
858 struct restart_block *restart = ¤t->restart_block; in alarm_timer_nsleep()
864 return -EOPNOTSUPP; in alarm_timer_nsleep()
867 return -EINVAL; in alarm_timer_nsleep()
870 return -EPERM; in alarm_timer_nsleep()
885 if (ret != -ERESTART_RESTARTBLOCK) in alarm_timer_nsleep()
890 return -ERESTARTNOHAND; in alarm_timer_nsleep()
892 restart->nanosleep.clockid = type; in alarm_timer_nsleep()
893 restart->nanosleep.expires = exp; in alarm_timer_nsleep()
937 * alarmtimer_init - Initialize alarm timer code