Lines Matching +full:clock +full:- +full:mult
1 // SPDX-License-Identifier: GPL-2.0
3 * This file contains functions which manage clock event devices.
5 * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
6 * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
7 * Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
17 #include "tick-internal.h"
19 /* The registered clock event devices */
35 u64 clc = (u64) latch << evt->shift; in cev_delta2ns()
38 if (WARN_ON(!evt->mult)) in cev_delta2ns()
39 evt->mult = 1; in cev_delta2ns()
40 rnd = (u64) evt->mult - 1; in cev_delta2ns()
46 if ((clc >> evt->shift) != (u64)latch) in cev_delta2ns()
52 * For mult <= (1 << shift) we can safely add mult - 1 to in cev_delta2ns()
56 * For mult > (1 << shift), i.e. device frequency is > 1GHz we in cev_delta2ns()
57 * need to be careful. Adding mult - 1 will result in a value in cev_delta2ns()
59 * than latch by up to (mult - 1) >> shift. For the min_delta in cev_delta2ns()
68 if ((~0ULL - clc > rnd) && in cev_delta2ns()
69 (!ismax || evt->mult <= (1ULL << evt->shift))) in cev_delta2ns()
72 do_div(clc, evt->mult); in cev_delta2ns()
79 * clockevent_delta2ns - Convert a latch value (device ticks) to nanoseconds
81 * @evt: pointer to clock event device descriptor
94 if (dev->features & CLOCK_EVT_FEAT_DUMMY) in __clockevents_switch_state()
97 /* Transition with new state-specific callbacks */ in __clockevents_switch_state()
103 if (dev->set_state_shutdown) in __clockevents_switch_state()
104 return dev->set_state_shutdown(dev); in __clockevents_switch_state()
109 if (!(dev->features & CLOCK_EVT_FEAT_PERIODIC)) in __clockevents_switch_state()
110 return -ENOSYS; in __clockevents_switch_state()
111 if (dev->set_state_periodic) in __clockevents_switch_state()
112 return dev->set_state_periodic(dev); in __clockevents_switch_state()
117 if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT)) in __clockevents_switch_state()
118 return -ENOSYS; in __clockevents_switch_state()
119 if (dev->set_state_oneshot) in __clockevents_switch_state()
120 return dev->set_state_oneshot(dev); in __clockevents_switch_state()
128 return -EINVAL; in __clockevents_switch_state()
130 if (dev->set_state_oneshot_stopped) in __clockevents_switch_state()
131 return dev->set_state_oneshot_stopped(dev); in __clockevents_switch_state()
133 return -ENOSYS; in __clockevents_switch_state()
136 return -ENOSYS; in __clockevents_switch_state()
141 * clockevents_switch_state - set the operating state of a clock event device
161 if (WARN_ON(!dev->mult)) in clockevents_switch_state()
162 dev->mult = 1; in clockevents_switch_state()
168 * clockevents_shutdown - shutdown the device and clear next_event
174 dev->next_event = KTIME_MAX; in clockevents_shutdown()
178 * clockevents_tick_resume - Resume the tick device before using it again
185 if (dev->tick_resume) in clockevents_tick_resume()
186 ret = dev->tick_resume(dev); in clockevents_tick_resume()
197 * clockevents_increase_min_delta - raise minimum delta of a clock event device
200 * Returns 0 on success, -ETIME when the minimum delta reached the limit.
205 if (dev->min_delta_ns >= MIN_DELTA_LIMIT) { in clockevents_increase_min_delta()
208 dev->next_event = KTIME_MAX; in clockevents_increase_min_delta()
209 return -ETIME; in clockevents_increase_min_delta()
212 if (dev->min_delta_ns < 5000) in clockevents_increase_min_delta()
213 dev->min_delta_ns = 5000; in clockevents_increase_min_delta()
215 dev->min_delta_ns += dev->min_delta_ns >> 1; in clockevents_increase_min_delta()
217 if (dev->min_delta_ns > MIN_DELTA_LIMIT) in clockevents_increase_min_delta()
218 dev->min_delta_ns = MIN_DELTA_LIMIT; in clockevents_increase_min_delta()
222 dev->name ? dev->name : "?", in clockevents_increase_min_delta()
223 (unsigned long long) dev->min_delta_ns); in clockevents_increase_min_delta()
228 * clockevents_program_min_delta - Set clock event device to the minimum delay.
231 * Returns 0 on success, -ETIME when the retry loop failed.
240 delta = dev->min_delta_ns; in clockevents_program_min_delta()
241 dev->next_event = ktime_add_ns(ktime_get(), delta); in clockevents_program_min_delta()
246 dev->retries++; in clockevents_program_min_delta()
247 clc = ((unsigned long long) delta * dev->mult) >> dev->shift; in clockevents_program_min_delta()
248 if (dev->set_next_event((unsigned long) clc, dev) == 0) in clockevents_program_min_delta()
258 return -ETIME; in clockevents_program_min_delta()
267 * clockevents_program_min_delta - Set clock event device to the minimum delay.
270 * Returns 0 on success, -ETIME when the retry loop failed.
279 delta += dev->min_delta_ns; in clockevents_program_min_delta()
280 dev->next_event = ktime_add_ns(ktime_get(), delta); in clockevents_program_min_delta()
285 dev->retries++; in clockevents_program_min_delta()
286 clc = ((unsigned long long) delta * dev->mult) >> dev->shift; in clockevents_program_min_delta()
287 if (dev->set_next_event((unsigned long) clc, dev) == 0) in clockevents_program_min_delta()
290 return -ETIME; in clockevents_program_min_delta()
296 * clockevents_program_event - Reprogram the clock event device.
298 * @expires: absolute expiry time (monotonic clock)
301 * Returns 0 on success, -ETIME when the event is in the past.
311 return -ETIME; in clockevents_program_event()
313 dev->next_event = expires; in clockevents_program_event()
323 if (dev->features & CLOCK_EVT_FEAT_KTIME) in clockevents_program_event()
324 return dev->set_next_ktime(expires, dev); in clockevents_program_event()
328 return force ? clockevents_program_min_delta(dev) : -ETIME; in clockevents_program_event()
330 delta = min(delta, (int64_t) dev->max_delta_ns); in clockevents_program_event()
331 delta = max(delta, (int64_t) dev->min_delta_ns); in clockevents_program_event()
333 clc = ((unsigned long long) delta * dev->mult) >> dev->shift; in clockevents_program_event()
334 rc = dev->set_next_event((unsigned long) clc, dev); in clockevents_program_event()
350 list_move(&dev->list, &clockevent_devices); in clockevents_notify_released()
356 * Try to install a replacement clock event device
369 if (!try_module_get(dev->owner)) in clockevents_replace()
373 module_put(newdev->owner); in clockevents_replace()
378 list_del_init(&ced->list); in clockevents_replace()
380 return newdev ? 0 : -EBUSY; in clockevents_replace()
390 list_del_init(&ced->list); in __clockevents_try_unbind()
394 return ced == per_cpu(tick_cpu_device, cpu).evtdev ? -EAGAIN : -EBUSY; in __clockevents_try_unbind()
406 res = __clockevents_try_unbind(cu->ce, smp_processor_id()); in __clockevents_unbind()
407 if (res == -EAGAIN) in __clockevents_unbind()
408 res = clockevents_replace(cu->ce); in __clockevents_unbind()
409 cu->res = res; in __clockevents_unbind()
419 struct ce_unbind cu = { .ce = ced, .res = -ENODEV }; in clockevents_unbind()
440 * clockevents_register_device - register a clock event device
450 if (!dev->cpumask) { in clockevents_register_device()
452 dev->cpumask = cpumask_of(smp_processor_id()); in clockevents_register_device()
455 if (dev->cpumask == cpu_all_mask) { in clockevents_register_device()
457 dev->name); in clockevents_register_device()
458 dev->cpumask = cpu_possible_mask; in clockevents_register_device()
463 list_add(&dev->list, &clockevent_devices); in clockevents_register_device()
475 if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT)) in clockevents_config()
483 sec = dev->max_delta_ticks; in clockevents_config()
487 else if (sec > 600 && dev->max_delta_ticks > UINT_MAX) in clockevents_config()
491 dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false); in clockevents_config()
492 dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true); in clockevents_config()
496 * clockevents_config_and_register - Configure and register a clock event device
498 * @freq: The clock frequency
499 * @min_delta: The minimum clock ticks to program in oneshot mode
500 * @max_delta: The maximum clock ticks to program in oneshot mode
508 dev->min_delta_ticks = min_delta; in clockevents_config_and_register()
509 dev->max_delta_ticks = max_delta; in clockevents_config_and_register()
520 return clockevents_program_event(dev, dev->next_event, false); in __clockevents_update_freq()
529 * clockevents_update_freq - Update frequency and reprogram a clock event device.
533 * Reconfigure and reprogram a clock event device in oneshot
538 * Returns 0 on success, -ETIME when the event is in the past.
547 if (ret == -ENODEV) in clockevents_update_freq()
561 * clockevents_exchange_device - release and request clock devices
572 * Caller releases a clock event device. We queue it into the in clockevents_exchange_device()
576 module_put(old->owner); in clockevents_exchange_device()
578 list_move(&old->list, &clockevents_released); in clockevents_exchange_device()
588 * clockevents_suspend - suspend clock devices
595 if (dev->suspend && !clockevent_state_detached(dev)) in clockevents_suspend()
596 dev->suspend(dev); in clockevents_suspend()
600 * clockevents_resume - resume clock devices
607 if (dev->resume && !clockevent_state_detached(dev)) in clockevents_resume()
608 dev->resume(dev); in clockevents_resume()
615 * tick_offline_cpu - Take CPU out of the broadcast mechanism
629 * tick_cleanup_dead_cpu - Cleanup the tick and clockevents of a dead cpu
641 * Unregister the clock event devices which were in tick_cleanup_dead_cpu()
645 list_del(&dev->list); in tick_cleanup_dead_cpu()
650 if (cpumask_test_cpu(cpu, dev->cpumask) && in tick_cleanup_dead_cpu()
651 cpumask_weight(dev->cpumask) == 1 && in tick_cleanup_dead_cpu()
654 list_del(&dev->list); in tick_cleanup_dead_cpu()
679 if (td && td->evtdev) in current_device_show()
680 count = sysfs_emit(buf, "%s\n", td->evtdev->name); in current_device_show()
698 ret = -ENODEV; in unbind_device_store()
702 if (!strcmp(iter->name, name)) { in unbind_device_store()
703 ret = __clockevents_try_unbind(iter, dev->id); in unbind_device_store()
712 if (ret == -EAGAIN) in unbind_device_store()
713 ret = clockevents_unbind(ce, dev->id); in unbind_device_store()
729 &per_cpu(tick_cpu_device, dev->id); in tick_get_tick_dev()
743 return &per_cpu(tick_cpu_device, dev->id); in tick_get_tick_dev()
756 dev->id = cpu; in tick_init_sysfs()
757 dev->bus = &clockevents_subsys; in tick_init_sysfs()