Lines Matching +full:next +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
3 * This file contains functions which emulate a local clock-event
6 * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
7 * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
8 * Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
20 #include "tick-internal.h"
75 * Start the device in periodic mode
89 if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) || in tick_check_broadcast_device()
90 (newdev->features & CLOCK_EVT_FEAT_PERCPU) || in tick_check_broadcast_device()
91 (newdev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_check_broadcast_device()
94 if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT && in tick_check_broadcast_device()
95 !(newdev->features & CLOCK_EVT_FEAT_ONESHOT)) in tick_check_broadcast_device()
98 return !curdev || newdev->rating > curdev->rating; in tick_check_broadcast_device()
124 if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) || in tick_set_oneshot_wakeup_device()
125 (newdev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_set_oneshot_wakeup_device()
128 if (!(newdev->features & CLOCK_EVT_FEAT_PERCPU) || in tick_set_oneshot_wakeup_device()
129 !(newdev->features & CLOCK_EVT_FEAT_ONESHOT)) in tick_set_oneshot_wakeup_device()
132 if (!cpumask_equal(newdev->cpumask, cpumask_of(cpu))) in tick_set_oneshot_wakeup_device()
135 if (curdev && newdev->rating <= curdev->rating) in tick_set_oneshot_wakeup_device()
138 if (!try_module_get(newdev->owner)) in tick_set_oneshot_wakeup_device()
141 newdev->event_handler = tick_oneshot_wakeup_handler; in tick_set_oneshot_wakeup_device()
173 if (!try_module_get(dev->owner)) in tick_install_broadcast_device()
178 cur->event_handler = clockevents_handle_noop; in tick_install_broadcast_device()
183 if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT)) in tick_install_broadcast_device()
187 * If the system already runs in oneshot mode, switch the newly in tick_install_broadcast_device()
188 * registered broadcast device to oneshot mode explicitly. in tick_install_broadcast_device()
197 * where we did not switch to oneshot mode because the per cpu in tick_install_broadcast_device()
200 * notification the systems stays stuck in periodic mode in tick_install_broadcast_device()
216 int ret = -ENODEV; in tick_broadcast_update_freq()
234 if (!dev->broadcast) in tick_device_setup_broadcast_func()
235 dev->broadcast = tick_broadcast; in tick_device_setup_broadcast_func()
236 if (!dev->broadcast) { in tick_device_setup_broadcast_func()
238 dev->name); in tick_device_setup_broadcast_func()
239 dev->broadcast = err_broadcast; in tick_device_setup_broadcast_func()
257 * mode disabled. This signals, that the device needs to be in tick_device_uses_broadcast()
262 dev->event_handler = tick_handle_periodic; in tick_device_uses_broadcast()
265 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) in tick_device_uses_broadcast()
275 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_device_uses_broadcast()
287 switch (tick_broadcast_device.mode) { in tick_device_uses_broadcast()
290 * If the system is in oneshot mode we can in tick_device_uses_broadcast()
303 * If the system is in periodic mode, check in tick_device_uses_broadcast()
317 if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER)) in tick_device_uses_broadcast()
331 struct clock_event_device *evt = td->evtdev; in tick_receive_broadcast()
334 return -ENODEV; in tick_receive_broadcast()
336 if (!evt->event_handler) in tick_receive_broadcast()
337 return -EINVAL; in tick_receive_broadcast()
339 evt->event_handler(evt); in tick_receive_broadcast()
371 local = !(bc->features & CLOCK_EVT_FEAT_HRTIMER); in tick_do_broadcast()
382 td->evtdev->broadcast(mask); in tick_do_broadcast()
389 * - invoke the broadcast handlers
416 ktime_t next = ktime_add_ns(dev->next_event, TICK_NSEC); in tick_handle_periodic_broadcast() local
418 clockevents_program_event(dev, next, true); in tick_handle_periodic_broadcast()
425 * trying to switch to oneshot mode. in tick_handle_periodic_broadcast()
428 td->evtdev->event_handler(td->evtdev); in tick_handle_periodic_broadcast()
432 * tick_broadcast_control - Enable/disable or force broadcast mode
433 * @mode: The selected broadcast mode
438 void tick_broadcast_control(enum tick_broadcast_mode mode) in tick_broadcast_control() argument
448 dev = td->evtdev; in tick_broadcast_control()
453 if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_broadcast_control()
463 switch (mode) { in tick_broadcast_control()
473 * - the broadcast device exists in tick_broadcast_control()
474 * - the broadcast device is not a hrtimer based one in tick_broadcast_control()
475 * - the broadcast device is in periodic mode to in tick_broadcast_control()
476 * avoid a hiccup during switch to oneshot mode in tick_broadcast_control()
478 if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER) && in tick_broadcast_control()
479 tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) in tick_broadcast_control()
489 if (tick_broadcast_device.mode == in tick_broadcast_control()
501 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) in tick_broadcast_control()
518 dev->event_handler = tick_handle_periodic; in tick_set_periodic_handler()
520 dev->event_handler = tick_handle_periodic_broadcast; in tick_set_periodic_handler()
528 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { in tick_shutdown_broadcast()
568 * In none of these cases the broadcast device mode can change and the
573 if (tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT) in tick_resume_check_broadcast()
591 switch (tick_broadcast_device.mode) { in tick_resume_broadcast()
641 if (!(bc->features & CLOCK_EVT_FEAT_DYNIRQ)) in tick_broadcast_set_affinity()
644 if (cpumask_equal(bc->cpumask, cpumask)) in tick_broadcast_set_affinity()
647 bc->cpumask = cpumask; in tick_broadcast_set_affinity()
648 irq_set_affinity(bc->irq, bc->cpumask); in tick_broadcast_set_affinity()
680 if (td->mode == TICKDEV_MODE_ONESHOT) { in tick_check_oneshot_broadcast_this_cpu()
681 clockevents_switch_state(td->evtdev, in tick_check_oneshot_broadcast_this_cpu()
688 * Handle oneshot mode broadcasting
698 dev->next_event = KTIME_MAX; in tick_handle_oneshot_broadcast()
713 if (td->evtdev->next_event <= now) { in tick_handle_oneshot_broadcast()
721 } else if (td->evtdev->next_event < next_event) { in tick_handle_oneshot_broadcast()
722 next_event = td->evtdev->next_event; in tick_handle_oneshot_broadcast()
752 * - The global event did not expire any CPU local in tick_handle_oneshot_broadcast()
753 * events. This happens in dyntick mode, as the maximum PIT in tick_handle_oneshot_broadcast()
756 * - There are pending events on sleeping CPUs which were not in tick_handle_oneshot_broadcast()
766 td->evtdev->event_handler(td->evtdev); in tick_handle_oneshot_broadcast()
772 if (!(bc->features & CLOCK_EVT_FEAT_HRTIMER)) in broadcast_needs_cpu()
774 if (bc->next_event == KTIME_MAX) in broadcast_needs_cpu()
776 return bc->bound_on == cpu ? -EBUSY : 0; in broadcast_needs_cpu()
787 if (bc->features & CLOCK_EVT_FEAT_HRTIMER) { in broadcast_shutdown_local()
790 if (dev->next_event < bc->next_event) in broadcast_shutdown_local()
800 struct clock_event_device *bc, *dev = td->evtdev; in ___tick_broadcast_oneshot_control()
820 * If the broadcast device is in periodic mode, we in ___tick_broadcast_oneshot_control()
823 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { in ___tick_broadcast_oneshot_control()
825 if (bc->features & CLOCK_EVT_FEAT_HRTIMER) in ___tick_broadcast_oneshot_control()
826 ret = -EBUSY; in ___tick_broadcast_oneshot_control()
847 ret = -EBUSY; in ___tick_broadcast_oneshot_control()
848 } else if (dev->next_event < bc->next_event) { in ___tick_broadcast_oneshot_control()
849 tick_broadcast_set_event(bc, cpu, dev->next_event); in ___tick_broadcast_oneshot_control()
881 * Bail out if there is no next event. in ___tick_broadcast_oneshot_control()
883 if (dev->next_event == KTIME_MAX) in ___tick_broadcast_oneshot_control()
895 * This can lead to a ping-pong when we return in ___tick_broadcast_oneshot_control()
902 * enough out that the ping-pong starts. in ___tick_broadcast_oneshot_control()
918 if (dev->next_event <= now) { in ___tick_broadcast_oneshot_control()
926 tick_program_event(dev->next_event, 1); in ___tick_broadcast_oneshot_control()
940 dev = td->evtdev; in tick_oneshot_wakeup_control()
941 if (td->mode != TICKDEV_MODE_ONESHOT) in tick_oneshot_wakeup_control()
942 return -EINVAL; in tick_oneshot_wakeup_control()
946 return -ENODEV; in tick_oneshot_wakeup_control()
952 clockevents_program_event(wd, dev->next_event, 1); in tick_oneshot_wakeup_control()
955 /* We may have transitioned to oneshot mode while idle */ in tick_oneshot_wakeup_control()
957 return -ENODEV; in tick_oneshot_wakeup_control()
978 return -EBUSY; in __tick_broadcast_oneshot_control()
1000 if (td->evtdev) in tick_broadcast_init_next_event()
1001 td->evtdev->next_event = expires; in tick_broadcast_init_next_event()
1007 ktime_t next; in tick_get_next_period() local
1016 next = tick_next_period; in tick_get_next_period()
1018 return next; in tick_get_next_period()
1022 * tick_broadcast_setup_oneshot - setup the broadcast device
1036 * code via hrtimer_run_queues() -> tick_check_oneshot_change() in tick_broadcast_setup_oneshot()
1039 if (bc->event_handler == tick_handle_oneshot_broadcast) { in tick_broadcast_setup_oneshot()
1041 * The CPU which switched from periodic to oneshot mode in tick_broadcast_setup_oneshot()
1063 bc->event_handler = tick_handle_oneshot_broadcast; in tick_broadcast_setup_oneshot()
1064 bc->next_event = KTIME_MAX; in tick_broadcast_setup_oneshot()
1067 * When the tick mode is switched from periodic to oneshot it must in tick_broadcast_setup_oneshot()
1069 * get their wake-up at the next tick. This is achieved by ORing in tick_broadcast_setup_oneshot()
1075 * next tick_broadcast_enter() would observe the bit set and fail in tick_broadcast_setup_oneshot()
1094 * The device was already armed for the next tick in tick_broadcast_setup_oneshot()
1102 * When switching from periodic to oneshot mode arm the broadcast in tick_broadcast_setup_oneshot()
1103 * device for the next tick. in tick_broadcast_setup_oneshot()
1105 * If the broadcast device has been replaced in oneshot mode and in tick_broadcast_setup_oneshot()
1107 * immediately in order to reevaluate the next expiring timer. in tick_broadcast_setup_oneshot()
1122 * Select oneshot operating mode for the broadcast device
1132 oldmode = tick_broadcast_device.mode; in tick_broadcast_switch_to_oneshot()
1133 tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; in tick_broadcast_switch_to_oneshot()
1154 * timer device to avoid a ping-pong race. See in hotplug_cpu__broadcast_tick_pull()
1172 tick_program_event(td->evtdev->next_event, 1); in hotplug_cpu__broadcast_tick_pull()
1176 clockevents_program_event(bc, bc->next_event, 1); in hotplug_cpu__broadcast_tick_pull()
1200 * Check, whether the broadcast device is in one shot mode
1204 return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT; in tick_broadcast_oneshot_active()
1214 return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false; in tick_broadcast_oneshot_available()
1222 if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER)) in __tick_broadcast_oneshot_control()
1223 return -EBUSY; in __tick_broadcast_oneshot_control()