/* * Event handler for periodic broadcast ticks */ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) { ktime_t next; tick_do_periodic_broadcast(); /* * The device is in periodic mode. No reprogramming necessary: */ if (dev->mode == CLOCK_EVT_MODE_PERIODIC) return; /* * Setup the next period for devices, which do not have * periodic mode. We read dev->next_event first and add to it * when the event alrady expired. clockevents_program_event() * sets dev->next_event only when the event is really * programmed to the device. */ for (next = dev->next_event; ;) { next = ktime_add(next, tick_period); if (!clockevents_program_event(dev, next, ktime_get())) return; tick_do_periodic_broadcast(); } }
/* * Event handler for periodic broadcast ticks */ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) { ktime_t next; raw_spin_lock(&tick_broadcast_lock); tick_do_periodic_broadcast(); /* * The device is in periodic mode. No reprogramming necessary: */ if (dev->state == CLOCK_EVT_STATE_PERIODIC) goto unlock; /* * Setup the next period for devices, which do not have * periodic mode. We read dev->next_event first and add to it * when the event already expired. clockevents_program_event() * sets dev->next_event only when the event is really * programmed to the device. */ for (next = dev->next_event; ;) { next = ktime_add(next, tick_period); if (!clockevents_program_event(dev, next, false)) goto unlock; tick_do_periodic_broadcast(); } unlock: raw_spin_unlock(&tick_broadcast_lock); }
/* * Event handler for periodic broadcast ticks */ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) { struct tick_device *td = this_cpu_ptr(&tick_cpu_device); bool bc_local; raw_spin_lock(&tick_broadcast_lock); /* Handle spurious interrupts gracefully */ if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) { raw_spin_unlock(&tick_broadcast_lock); return; } bc_local = tick_do_periodic_broadcast(); if (clockevent_state_oneshot(dev)) { ktime_t next = ktime_add(dev->next_event, tick_period); clockevents_program_event(dev, next, true); } raw_spin_unlock(&tick_broadcast_lock); /* * We run the handler of the local cpu after dropping * tick_broadcast_lock because the handler might deadlock when * trying to switch to oneshot mode. */ if (bc_local) td->evtdev->event_handler(td->evtdev); }
static void tick_handle_periodic_broadcast(struct clock_event_device *dev) { ktime_t next; tick_do_periodic_broadcast(); if (dev->mode == CLOCK_EVT_MODE_PERIODIC) return; for (next = dev->next_event; ;) { next = ktime_add(next, tick_period); if (!clockevents_program_event(dev, next, false)) return; tick_do_periodic_broadcast(); } }
/* * Event handler for periodic broadcast ticks */ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) { dev->next_event.tv64 = KTIME_MAX; tick_do_periodic_broadcast(); /* * The device is in periodic mode. No reprogramming necessary: */ if (dev->mode == CLOCK_EVT_MODE_PERIODIC) return; /* * Setup the next period for devices, which do not have * periodic mode: */ for (;;) { ktime_t next = ktime_add(dev->next_event, tick_period); if (!clockevents_program_event(dev, next, ktime_get())) return; tick_do_periodic_broadcast(); } }