Lines Matching +full:event +full:- +full:deep
1 // SPDX-License-Identifier: GPL-2.0
3 * This file contains functions which emulate a local clock-event
4 * device via a broadcast event source.
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"
79 if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) || in tick_check_broadcast_device()
80 (newdev->features & CLOCK_EVT_FEAT_PERCPU) || in tick_check_broadcast_device()
81 (newdev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_check_broadcast_device()
85 !(newdev->features & CLOCK_EVT_FEAT_ONESHOT)) in tick_check_broadcast_device()
88 return !curdev || newdev->rating > curdev->rating; in tick_check_broadcast_device()
101 if (!try_module_get(dev->owner)) in tick_install_broadcast_device()
106 cur->event_handler = clockevents_handle_noop; in tick_install_broadcast_device()
118 if (dev->features & CLOCK_EVT_FEAT_ONESHOT) in tick_install_broadcast_device()
132 int ret = -ENODEV; in tick_broadcast_update_freq()
150 if (!dev->broadcast) in tick_device_setup_broadcast_func()
151 dev->broadcast = tick_broadcast; in tick_device_setup_broadcast_func()
152 if (!dev->broadcast) { in tick_device_setup_broadcast_func()
154 dev->name); in tick_device_setup_broadcast_func()
155 dev->broadcast = err_broadcast; in tick_device_setup_broadcast_func()
178 dev->event_handler = tick_handle_periodic; in tick_device_uses_broadcast()
191 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_device_uses_broadcast()
233 if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER)) in tick_device_uses_broadcast()
248 struct clock_event_device *evt = td->evtdev; in tick_receive_broadcast()
251 return -ENODEV; in tick_receive_broadcast()
253 if (!evt->event_handler) in tick_receive_broadcast()
254 return -EINVAL; in tick_receive_broadcast()
256 evt->event_handler(evt); in tick_receive_broadcast()
262 * Broadcast the event to the cpus, which are set in the mask (mangled).
289 local = !(bc->features & CLOCK_EVT_FEAT_HRTIMER); in tick_do_broadcast()
300 td->evtdev->broadcast(mask); in tick_do_broadcast()
307 * - invoke the broadcast handlers
316 * Event handler for periodic broadcast ticks
334 ktime_t next = ktime_add(dev->next_event, tick_period); in tick_handle_periodic_broadcast()
346 td->evtdev->event_handler(td->evtdev); in tick_handle_periodic_broadcast()
350 * tick_broadcast_control - Enable/disable or force broadcast mode
366 dev = td->evtdev; in tick_broadcast_control()
371 if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP)) in tick_broadcast_control()
391 * - the broadcast device exists in tick_broadcast_control()
392 * - the broadcast device is not a hrtimer based one in tick_broadcast_control()
393 * - the broadcast device is in periodic mode to in tick_broadcast_control()
396 if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER) && in tick_broadcast_control()
436 dev->event_handler = tick_handle_periodic; in tick_set_periodic_handler()
438 dev->event_handler = tick_handle_periodic_broadcast; in tick_set_periodic_handler()
539 * broadcast event from the other core is about to happen. We detected
541 * to avoid a deep idle transition as we are about to get the
555 if (!(bc->features & CLOCK_EVT_FEAT_DYNIRQ)) in tick_broadcast_set_affinity()
558 if (cpumask_equal(bc->cpumask, cpumask)) in tick_broadcast_set_affinity()
561 bc->cpumask = cpumask; in tick_broadcast_set_affinity()
562 irq_set_affinity(bc->irq, bc->cpumask); in tick_broadcast_set_affinity()
594 if (td->mode == TICKDEV_MODE_ONESHOT) { in tick_check_oneshot_broadcast_this_cpu()
595 clockevents_switch_state(td->evtdev, in tick_check_oneshot_broadcast_this_cpu()
612 dev->next_event = KTIME_MAX; in tick_handle_oneshot_broadcast()
627 if (td->evtdev->next_event <= now) { in tick_handle_oneshot_broadcast()
635 } else if (td->evtdev->next_event < next_event) { in tick_handle_oneshot_broadcast()
636 next_event = td->evtdev->next_event; in tick_handle_oneshot_broadcast()
642 * Remove the current cpu from the pending mask. The event is in tick_handle_oneshot_broadcast()
659 * Wakeup the cpus which have an expired event. in tick_handle_oneshot_broadcast()
666 * - The global event did not expire any CPU local in tick_handle_oneshot_broadcast()
670 * - There are pending events on sleeping CPUs which were not in tick_handle_oneshot_broadcast()
671 * in the event mask in tick_handle_oneshot_broadcast()
680 td->evtdev->event_handler(td->evtdev); in tick_handle_oneshot_broadcast()
686 if (!(bc->features & CLOCK_EVT_FEAT_HRTIMER)) in broadcast_needs_cpu()
688 if (bc->next_event == KTIME_MAX) in broadcast_needs_cpu()
690 return bc->bound_on == cpu ? -EBUSY : 0; in broadcast_needs_cpu()
698 * local device if our own event is the first one to expire or in broadcast_shutdown_local()
701 if (bc->features & CLOCK_EVT_FEAT_HRTIMER) { in broadcast_shutdown_local()
704 if (dev->next_event < bc->next_event) in broadcast_shutdown_local()
718 * into deep idle. in __tick_broadcast_oneshot_control()
721 return -EBUSY; in __tick_broadcast_oneshot_control()
723 dev = this_cpu_ptr(&tick_cpu_device)->evtdev; in __tick_broadcast_oneshot_control()
732 * mechanism, it cannot go deep idle and we do not add in __tick_broadcast_oneshot_control()
747 if (bc->features & CLOCK_EVT_FEAT_HRTIMER) in __tick_broadcast_oneshot_control()
748 ret = -EBUSY; in __tick_broadcast_oneshot_control()
761 * if the cpu local event is earlier than the in __tick_broadcast_oneshot_control()
762 * broadcast event. If the current CPU is in in __tick_broadcast_oneshot_control()
765 * busy, so the CPU does not try to go deep in __tick_broadcast_oneshot_control()
769 ret = -EBUSY; in __tick_broadcast_oneshot_control()
770 } else if (dev->next_event < bc->next_event) { in __tick_broadcast_oneshot_control()
771 tick_broadcast_set_event(bc, cpu, dev->next_event); in __tick_broadcast_oneshot_control()
794 * event anyway via the broadcast IPI in __tick_broadcast_oneshot_control()
796 * with an already expired event. in __tick_broadcast_oneshot_control()
803 * Bail out if there is no next event. in __tick_broadcast_oneshot_control()
805 if (dev->next_event == KTIME_MAX) in __tick_broadcast_oneshot_control()
815 * timer with an already expired event. in __tick_broadcast_oneshot_control()
817 * This can lead to a ping-pong when we return in __tick_broadcast_oneshot_control()
821 * reprogramming makes sure that the event in __tick_broadcast_oneshot_control()
824 * enough out that the ping-pong starts. in __tick_broadcast_oneshot_control()
840 if (dev->next_event <= now) { in __tick_broadcast_oneshot_control()
848 tick_program_event(dev->next_event, 1); in __tick_broadcast_oneshot_control()
875 if (td->evtdev) in tick_broadcast_init_next_event()
876 td->evtdev->next_event = expires; in tick_broadcast_init_next_event()
881 * tick_broadcast_setup_oneshot - setup the broadcast device
891 if (bc->event_handler != tick_handle_oneshot_broadcast) { in tick_broadcast_setup_oneshot()
894 bc->event_handler = tick_handle_oneshot_broadcast; in tick_broadcast_setup_oneshot()
913 bc->next_event = KTIME_MAX; in tick_broadcast_setup_oneshot()
955 clockevents_program_event(bc, bc->next_event, 1); in hotplug_cpu__broadcast_tick_pull()
990 return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false; in tick_broadcast_oneshot_available()
998 if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER)) in __tick_broadcast_oneshot_control()
999 return -EBUSY; in __tick_broadcast_oneshot_control()