1 #ifndef __TIMER_H
2 #define __TIMER_H
3 
4 #include <stdint.h>
5 #include <ccan/list/list.h>
6 
7 struct timer;
8 
9 typedef void (*timer_func_t)(struct timer *t, void *data, uint64_t now);
10 
11 /* Structure exposed in order to be able to allocate it
12  * statically but otherwise, use accessors, don't access
13  * the fields directly
14  *
15  * WARNING: Do not free a timer object unless you have cancelled
16  * it first or you know it won't reschedule itself and have done
17  * a sync_timer() on it. The timer core *will* access the object
18  * again after you return from the expiry callback so it must not
19  * be freed from the callback itself.
20  */
21 struct timer {
22 	struct list_node	link;
23 	uint64_t		target;
24 	timer_func_t		expiry;
25 	void *			user_data;
26 	void *			running;
27 	uint64_t		gen;
28 };
29 
30 extern void init_timer(struct timer *t, timer_func_t expiry, void *data);
31 
32 /* (re)schedule a timer. If already scheduled, it's expiry will be updated
33  *
34  * This doesn't synchronize so if the timer also reschedules itself there
35  * is no telling which one "wins". The advantage is that this can be called
36  * with any lock held or from the timer expiry itself.
37  *
38  * We support a magic expiry of TIMER_POLL which causes a given timer to
39  * be called whenever OPAL main polling loop is run, which is often during
40  * boot and occasionally while Linux is up. This can be used with both
41  * schedule_timer() and schedule_timer_at()
42  *
43  * This is useful for a number of interrupt driven drivers to have a way
44  * to crank their state machine at times when the interrupt isn't available
45  * such as during early boot.
46  *
47  * Note: For convenience, schedule_timer() returns the current TB value
48  */
49 #define TIMER_POLL	((uint64_t)-1)
50 extern uint64_t schedule_timer(struct timer *t, uint64_t how_long);
51 extern void schedule_timer_at(struct timer *t, uint64_t when);
52 
53 /* Synchronization point with the timer. If the callback has started before
54  * that function is called, it will be complete when this function returns.
55  *
56  * It might start *again* but at least anything before this will be visible
57  * to any subsequent occurrence.
58  *
59  * The usual issue of such sync functions exist: don't call it while holding
60  * a lock that the timer callback might take or from the timer expiry itself.
61  */
62 extern void sync_timer(struct timer *t);
63 
64 /* cancel_timer() will ensure the timer isn't concurrently running so
65  * the cancellation is guaranteed even if the timer reschedules itself.
66  *
67  * This uses sync_timer() internally so don't call this while holding a
68  * lock the timer might use.
69  */
70 extern void cancel_timer(struct timer *t);
71 
72 /* cancel_timer_async() allows to remove the timer from the schedule
73  * list without trying to synchronize. This is useful if the cancellation
74  * must happen while holding locks that would make the synchronization
75  * impossible. The user is responsible of ensuring it deals with potentially
76  * spurrious occurrences
77  */
78 extern void cancel_timer_async(struct timer *t);
79 
80 /* Run the timers */
81 extern void check_timers(bool from_interrupt);
82 
83 /* Core init */
84 void late_init_timers(void);
85 
86 #endif /* __TIMER_H */
87