From 2f529f9b558ca1c1bd74be7437a84e4711743404 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 01 Nov 2024 02:11:33 +0000 Subject: [PATCH] add xenomai --- kernel/include/linux/clockchips.h | 71 +++++++++++++++++++++++++++++++++++ 1 files changed, 70 insertions(+), 1 deletions(-) diff --git a/kernel/include/linux/clockchips.h b/kernel/include/linux/clockchips.h index 8ae9a95..bda5d7d 100644 --- a/kernel/include/linux/clockchips.h +++ b/kernel/include/linux/clockchips.h @@ -15,6 +15,7 @@ # include <linux/cpumask.h> # include <linux/ktime.h> # include <linux/notifier.h> +# include <linux/irqstage.h> struct clock_event_device; struct module; @@ -31,6 +32,7 @@ * from DETACHED or SHUTDOWN. * ONESHOT_STOPPED: Device was programmed in ONESHOT mode and is temporarily * stopped. + * RESERVED: Device is controlled by an out-of-band core via a proxy. */ enum clock_event_state { CLOCK_EVT_STATE_DETACHED, @@ -38,6 +40,7 @@ CLOCK_EVT_STATE_PERIODIC, CLOCK_EVT_STATE_ONESHOT, CLOCK_EVT_STATE_ONESHOT_STOPPED, + CLOCK_EVT_STATE_RESERVED, }; /* @@ -67,6 +70,17 @@ */ # define CLOCK_EVT_FEAT_HRTIMER 0x000080 +/* + * Interrupt pipeline support: + * + * - Clockevent device can work with pipelined timer events (i.e. proxied). + * - Device currently delivers high-precision events via out-of-band interrupts. + * - Device acts as a proxy for timer interrupt pipelining. + */ +# define CLOCK_EVT_FEAT_PIPELINE 0x000100 +# define CLOCK_EVT_FEAT_OOB 0x000200 +# define CLOCK_EVT_FEAT_PROXY 0x000400 + /** * struct clock_event_device - clock event device descriptor * @event_handler: Assigned by the framework to be called by the low @@ -91,7 +105,7 @@ * @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) + * @irq: IRQ number (only for non CPU local devices, or pipelined timers) * @bound_on: Bound on CPU * @cpumask: cpumask to indicate for which CPUs this device works * @list: list head for the management code @@ -137,6 +151,11 @@ return dev->state_use_accessors == CLOCK_EVT_STATE_DETACHED; } +static inline bool clockevent_state_reserved(struct clock_event_device *dev) +{ + return dev->state_use_accessors == CLOCK_EVT_STATE_RESERVED; +} + static inline bool clockevent_state_shutdown(struct clock_event_device *dev) { return dev->state_use_accessors == CLOCK_EVT_STATE_SHUTDOWN; @@ -155,6 +174,11 @@ static inline bool clockevent_state_oneshot_stopped(struct clock_event_device *dev) { return dev->state_use_accessors == CLOCK_EVT_STATE_ONESHOT_STOPPED; +} + +static inline bool clockevent_is_oob(struct clock_event_device *dev) +{ + return !!(dev->features & CLOCK_EVT_FEAT_OOB); } /* @@ -186,6 +210,8 @@ extern void clockevents_config_and_register(struct clock_event_device *dev, u32 freq, unsigned long min_delta, unsigned long max_delta); +extern void clockevents_switch_state(struct clock_event_device *dev, + enum clock_event_state state); extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq); @@ -215,6 +241,49 @@ static inline void tick_setup_hrtimer_broadcast(void) { } # endif +#ifdef CONFIG_IRQ_PIPELINE + +struct clock_proxy_device { + struct clock_event_device proxy_device; + struct clock_event_device *real_device; + void (*handle_oob_event)(struct clock_event_device *dev); + void (*__setup_handler)(struct clock_proxy_device *dev); + void (*__original_handler)(struct clock_event_device *dev); +}; + +void tick_notify_proxy(void); + +static inline +void clockevents_handle_event(struct clock_event_device *ced) +{ + /* + * If called from the in-band stage, or for delivering a + * high-precision timer event to the out-of-band stage, call + * the event handler immediately. + * + * Otherwise, ced is still the in-band tick device for the + * current CPU, so just relay the incoming tick to the in-band + * stage via tick_notify_proxy(). This situation can happen + * when all CPUs receive the same out-of-band IRQ from a given + * clock event device, but only a subset of the online CPUs has + * enabled a proxy. + */ + if (clockevent_is_oob(ced) || running_inband()) + ced->event_handler(ced); + else + tick_notify_proxy(); +} + +#else + +static inline +void clockevents_handle_event(struct clock_event_device *ced) +{ + ced->event_handler(ced); +} + +#endif /* !CONFIG_IRQ_PIPELINE */ + #else /* !CONFIG_GENERIC_CLOCKEVENTS: */ static inline void clockevents_suspend(void) { } -- Gitblit v1.6.2