Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234/* SPDX-License-Identifier: GPL-2.0 *//* linux/include/linux/clockchips.h * * This file contains the structure definitions for clockchips. * * If you are not a clockchip, or the time of day code, you should * not be including this file! */#ifndef _LINUX_CLOCKCHIPS_H#define _LINUX_CLOCKCHIPS_H
#ifdef CONFIG_GENERIC_CLOCKEVENTS
# include <linux/clocksource.h># include <linux/cpumask_types.h># include <linux/ktime.h># include <linux/notifier.h>
struct clock_event_device;struct module;
/* * Possible states of a clock event device. * * DETACHED: Device is not used by clockevents core. Initial state or can be * reached from SHUTDOWN. * SHUTDOWN: Device is powered-off. Can be reached from PERIODIC or ONESHOT. * PERIODIC: Device is programmed to generate events periodically. Can be * reached from DETACHED or SHUTDOWN. * ONESHOT: Device is programmed to generate event only once. Can be reached * from DETACHED or SHUTDOWN. * ONESHOT_STOPPED: Device was programmed in ONESHOT mode and is temporarily * stopped. */enum clock_event_state { CLOCK_EVT_STATE_DETACHED, CLOCK_EVT_STATE_SHUTDOWN, CLOCK_EVT_STATE_PERIODIC, CLOCK_EVT_STATE_ONESHOT, CLOCK_EVT_STATE_ONESHOT_STOPPED,};
/* * Clock event features */# define CLOCK_EVT_FEAT_PERIODIC 0x000001# define CLOCK_EVT_FEAT_ONESHOT 0x000002# define CLOCK_EVT_FEAT_CLOCKSOURCE_COUPLED 0x000004
/* * x86(64) specific (mis)features: * * - Clockevent source stops in C3 State and needs broadcast support. * - Local APIC timer is used as a dummy device. */# define CLOCK_EVT_FEAT_C3STOP 0x000008# define CLOCK_EVT_FEAT_DUMMY 0x000010
/* * Core shall set the interrupt affinity dynamically in broadcast mode */# define CLOCK_EVT_FEAT_DYNIRQ 0x000020# define CLOCK_EVT_FEAT_PERCPU 0x000040
/* * Clockevent device is based on a hrtimer for broadcast */# define CLOCK_EVT_FEAT_HRTIMER 0x000080
/** * struct clock_event_device - clock event device descriptor * @event_handler: Assigned by the framework to be called by the low * level handler of the event source * @set_next_event: set next event function using a clocksource delta * @set_next_ktime: set next event function using a direct ktime value * @set_next_coupled: set next event function for clocksource coupled mode * @next_event: local storage for the next event in oneshot mode * @max_delta_ns: maximum delta value in ns * @min_delta_ns: minimum delta value in ns * @mult: nanosecond to cycles multiplier * @shift: nanoseconds to cycles divisor (power of two) * @state_use_accessors:current state of the device, assigned by the core code * @features: features * @cs_id: Clocksource ID to denote the clocksource for coupled mode * @next_event_forced: True if the last programming was a forced event * @retries: number of forced programming retries * @set_state_periodic: switch state to periodic * @set_state_oneshot: switch state to oneshot * @set_state_oneshot_stopped: switch state to oneshot_stopped * @set_state_shutdown: switch state to shutdown * @tick_resume: resume clkevt device * @broadcast: function to broadcast events * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration * @name: ptr to clock event name * @rating: variable to rate clock event devices * @irq: IRQ number (only for non CPU local devices) * @bound_on: Bound on CPU * @cpumask: cpumask to indicate for which CPUs this device works * @list: list head for the management code * @owner: module reference */struct clock_event_device { void (*event_handler)(struct clock_event_device *); int (*set_next_event)(unsigned long evt, struct clock_event_device *); int (*set_next_ktime)(ktime_t expires, struct clock_event_device *); void (*set_next_coupled)(u64 cycles, struct clock_event_device *); ktime_t next_event; u64 max_delta_ns; u64 min_delta_ns; u32 mult; u32 shift; enum clock_event_state state_use_accessors; unsigned int features; enum clocksource_ids cs_id; unsigned int next_event_forced; unsigned long retries;
int (*set_state_periodic)(struct clock_event_device *); int (*set_state_oneshot)(struct clock_event_device *); int (*set_state_oneshot_stopped)(struct clock_event_device *); int (*set_state_shutdown)(struct clock_event_device *); int (*tick_resume)(struct clock_event_device *);
void (*broadcast)(const struct cpumask *mask); void (*suspend)(struct clock_event_device *); void (*resume)(struct clock_event_device *); unsigned long min_delta_ticks; unsigned long max_delta_ticks;
const char *name; int rating; int irq; int bound_on; const struct cpumask *cpumask; struct list_head list; struct module *owner;} ____cacheline_aligned;
/* Helpers to verify state of a clockevent device */static inline bool clockevent_state_detached(struct clock_event_device *dev){ return dev->state_use_accessors == CLOCK_EVT_STATE_DETACHED;}
static inline bool clockevent_state_shutdown(struct clock_event_device *dev){ return dev->state_use_accessors == CLOCK_EVT_STATE_SHUTDOWN;}
static inline bool clockevent_state_periodic(struct clock_event_device *dev){ return dev->state_use_accessors == CLOCK_EVT_STATE_PERIODIC;}
static inline bool clockevent_state_oneshot(struct clock_event_device *dev){ return dev->state_use_accessors == CLOCK_EVT_STATE_ONESHOT;}
static inline bool clockevent_state_oneshot_stopped(struct clock_event_device *dev){ return dev->state_use_accessors == CLOCK_EVT_STATE_ONESHOT_STOPPED;}
/* * Calculate a multiplication factor for scaled math, which is used to convert * nanoseconds based values to clock ticks: * * clock_ticks = (nanoseconds * factor) >> shift. * * div_sc is the rearranged equation to calculate a factor from a given clock * ticks / nanoseconds ratio: * * factor = (clock_ticks << shift) / nanoseconds */static inline unsigned longdiv_sc(unsigned long ticks, unsigned long nsec, int shift){ u64 tmp = ((u64)ticks) << shift;
do_div(tmp, nsec);
return (unsigned long) tmp;}
/* Clock event layer functions */extern u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt);extern void clockevents_register_device(struct clock_event_device *dev);extern int clockevents_unbind_device(struct clock_event_device *ced, int cpu);
extern void clockevents_config_and_register(struct clock_event_device *dev, u32 freq, unsigned long min_delta, unsigned long max_delta);
extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq);
static inline voidclockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 maxsec){ return clocks_calc_mult_shift(&ce->mult, &ce->shift, NSEC_PER_SEC, freq, maxsec);}
extern void clockevents_suspend(void);extern void clockevents_resume(void);
# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST# ifdef CONFIG_ARCH_HAS_TICK_BROADCASTextern void tick_broadcast(const struct cpumask *mask);# else# define tick_broadcast NULL# endifextern int tick_receive_broadcast(void);# endif
# if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)extern void tick_setup_hrtimer_broadcast(void);extern int tick_check_broadcast_expired(void);# elsestatic __always_inline int tick_check_broadcast_expired(void) { return 0; }static inline void tick_setup_hrtimer_broadcast(void) { }# endif
#else /* !CONFIG_GENERIC_CLOCKEVENTS: */
static inline void clockevents_suspend(void) { }static inline void clockevents_resume(void) { }static __always_inline int tick_check_broadcast_expired(void) { return 0; }static inline void tick_setup_hrtimer_broadcast(void) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
#endif /* _LINUX_CLOCKCHIPS_H */