summaryrefslogtreecommitdiff
path: root/include/cyclic.h
blob: 9c5c4fcc54681680540487ba0b7af9fde66405e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * A general-purpose cyclic execution infrastructure, to allow "small"
 * (run-time wise) functions to be executed at a specified frequency.
 * Things like LED blinking or watchdog triggering are examples for such
 * tasks.
 *
 * Copyright (C) 2022 Stefan Roese <sr@denx.de>
 */

#ifndef __cyclic_h
#define __cyclic_h

#include <linux/list.h>
#include <asm/types.h>

/**
 * struct cyclic_drv - Cyclic driver internal data
 *
 * @cyclic_list: Cylic list node
 * @cyclic_ready: Flag if cyclic infrastructure is ready
 * @cyclic_running: Flag if cyclic infrastructure is running
 */
struct cyclic_drv {
	struct list_head cyclic_list;
	bool cyclic_ready;
	bool cyclic_running;
};

/**
 * struct cyclic_info - Information about cyclic execution function
 *
 * @func: Function to call periodically
 * @ctx: Context pointer to get passed to this function
 * @name: Name of the cyclic function, e.g. shown in the commands
 * @delay_ns: Delay is ns after which this function shall get executed
 * @start_time_us: Start time in us, when this function started its execution
 * @cpu_time_us: Total CPU time of this function
 * @run_cnt: Counter of executions occurances
 * @next_call: Next time in us, when the function shall be executed again
 * @list: List node
 * @already_warned: Flag that we've warned about exceeding CPU time usage
 */
struct cyclic_info {
	void (*func)(void *ctx);
	void *ctx;
	char *name;
	uint64_t delay_us;
	uint64_t start_time_us;
	uint64_t cpu_time_us;
	uint64_t run_cnt;
	uint64_t next_call;
	struct list_head list;
	bool already_warned;
};

/** Function type for cyclic functions */
typedef void (*cyclic_func_t)(void *ctx);

#if defined(CONFIG_CYCLIC)
/**
 * cyclic_register - Register a new cyclic function
 *
 * @func: Function to call periodically
 * @delay_us: Delay is us after which this function shall get executed
 * @name: Cyclic function name/id
 * @ctx: Context to pass to the function
 * @return: pointer to cyclic_struct if OK, NULL on error
 */
struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us,
				    const char *name, void *ctx);

/**
 * cyclic_unregister - Unregister a cyclic function
 *
 * @cyclic: Pointer to cyclic_struct of the function that shall be removed
 * @return: 0 if OK, -ve on error
 */
int cyclic_unregister(struct cyclic_info *cyclic);

/**
 * cyclic_init() - Set up cyclic functions
 *
 * Init a list of cyclic functions, so that these can be added as needed
 */
int cyclic_init(void);

/**
 * cyclic_uninit() - Clean up cyclic functions
 *
 * This removes all cyclic functions
 */
int cyclic_uninit(void);

/**
 * cyclic_get_list() - Get cyclic list pointer
 *
 * Return the cyclic list pointer
 *
 * @return: pointer to cyclic_list
 */
struct list_head *cyclic_get_list(void);

/**
 * cyclic_run() - Interate over all registered cyclic functions
 *
 * Interate over all registered cyclic functions and if the it's function
 * needs to be executed, then call into these registered functions.
 */
void cyclic_run(void);

/**
 * schedule() - Schedule all potentially waiting tasks
 *
 * Basically a wrapper for cyclic_run(), pontentially enhanced by some
 * other parts, that need to get handled periodically.
 */
void schedule(void);
#else
static inline struct cyclic_info *cyclic_register(cyclic_func_t func,
						  uint64_t delay_us,
						  const char *name,
						  void *ctx)
{
	return NULL;
}

static inline int cyclic_unregister(struct cyclic_info *cyclic)
{
	return 0;
}

static inline void cyclic_run(void)
{
}

static inline void schedule(void)
{
}

static inline int cyclic_init(void)
{
	return 0;
}

static inline int cyclic_uninit(void)
{
	return 0;
}
#endif

#endif