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