blob: 4a11f9b105ea8d40e1533fda71f44a9d07899ef1 [file] [log] [blame]
Stefan Roesec2c69712022-09-02 13:57:48 +02001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * A general-purpose cyclic execution infrastructure, to allow "small"
4 * (run-time wise) functions to be executed at a specified frequency.
5 * Things like LED blinking or watchdog triggering are examples for such
6 * tasks.
7 *
8 * Copyright (C) 2022 Stefan Roese <sr@denx.de>
9 */
10
11#ifndef __cyclic_h
12#define __cyclic_h
13
14#include <linux/list.h>
15#include <asm/types.h>
16
17/**
18 * struct cyclic_drv - Cyclic driver internal data
19 *
20 * @cyclic_list: Cylic list node
Stefan Roesec2c69712022-09-02 13:57:48 +020021 */
22struct cyclic_drv {
Rasmus Villemoes28968392022-10-28 13:50:53 +020023 struct hlist_head cyclic_list;
Stefan Roesec2c69712022-09-02 13:57:48 +020024};
25
26/**
27 * struct cyclic_info - Information about cyclic execution function
28 *
29 * @func: Function to call periodically
30 * @ctx: Context pointer to get passed to this function
31 * @name: Name of the cyclic function, e.g. shown in the commands
32 * @delay_ns: Delay is ns after which this function shall get executed
33 * @start_time_us: Start time in us, when this function started its execution
34 * @cpu_time_us: Total CPU time of this function
35 * @run_cnt: Counter of executions occurances
36 * @next_call: Next time in us, when the function shall be executed again
37 * @list: List node
Stefan Roeseddc8d362022-10-17 09:00:58 +020038 * @already_warned: Flag that we've warned about exceeding CPU time usage
Stefan Roesec2c69712022-09-02 13:57:48 +020039 */
40struct cyclic_info {
41 void (*func)(void *ctx);
42 void *ctx;
43 char *name;
44 uint64_t delay_us;
45 uint64_t start_time_us;
46 uint64_t cpu_time_us;
47 uint64_t run_cnt;
48 uint64_t next_call;
Rasmus Villemoes28968392022-10-28 13:50:53 +020049 struct hlist_node list;
Stefan Roeseddc8d362022-10-17 09:00:58 +020050 bool already_warned;
Stefan Roesec2c69712022-09-02 13:57:48 +020051};
52
53/** Function type for cyclic functions */
54typedef void (*cyclic_func_t)(void *ctx);
55
56#if defined(CONFIG_CYCLIC)
57/**
58 * cyclic_register - Register a new cyclic function
59 *
60 * @func: Function to call periodically
61 * @delay_us: Delay is us after which this function shall get executed
62 * @name: Cyclic function name/id
63 * @ctx: Context to pass to the function
64 * @return: pointer to cyclic_struct if OK, NULL on error
65 */
66struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us,
67 const char *name, void *ctx);
68
69/**
70 * cyclic_unregister - Unregister a cyclic function
71 *
72 * @cyclic: Pointer to cyclic_struct of the function that shall be removed
73 * @return: 0 if OK, -ve on error
74 */
75int cyclic_unregister(struct cyclic_info *cyclic);
76
77/**
78 * cyclic_init() - Set up cyclic functions
79 *
80 * Init a list of cyclic functions, so that these can be added as needed
81 */
82int cyclic_init(void);
83
84/**
85 * cyclic_uninit() - Clean up cyclic functions
86 *
87 * This removes all cyclic functions
88 */
89int cyclic_uninit(void);
90
91/**
92 * cyclic_get_list() - Get cyclic list pointer
93 *
94 * Return the cyclic list pointer
95 *
96 * @return: pointer to cyclic_list
97 */
Rasmus Villemoes28968392022-10-28 13:50:53 +020098struct hlist_head *cyclic_get_list(void);
Stefan Roesec2c69712022-09-02 13:57:48 +020099
100/**
101 * cyclic_run() - Interate over all registered cyclic functions
102 *
103 * Interate over all registered cyclic functions and if the it's function
104 * needs to be executed, then call into these registered functions.
105 */
106void cyclic_run(void);
Stefan Roese881d4102022-09-02 14:10:45 +0200107
108/**
109 * schedule() - Schedule all potentially waiting tasks
110 *
111 * Basically a wrapper for cyclic_run(), pontentially enhanced by some
112 * other parts, that need to get handled periodically.
113 */
114void schedule(void);
Stefan Roesec2c69712022-09-02 13:57:48 +0200115#else
116static inline struct cyclic_info *cyclic_register(cyclic_func_t func,
117 uint64_t delay_us,
118 const char *name,
119 void *ctx)
120{
121 return NULL;
122}
123
124static inline int cyclic_unregister(struct cyclic_info *cyclic)
125{
126 return 0;
127}
128
129static inline void cyclic_run(void)
130{
131}
132
Stefan Roese881d4102022-09-02 14:10:45 +0200133static inline void schedule(void)
134{
135}
136
Stefan Roesec2c69712022-09-02 13:57:48 +0200137static inline int cyclic_init(void)
138{
139 return 0;
140}
141
142static inline int cyclic_uninit(void)
143{
144 return 0;
145}
146#endif
147
148#endif