1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __TRIGGER_H_ 3 #define __TRIGGER_H_ 1 4 5 #include "util/debug.h" 6 #include "asm/bug.h" 7 8 /* 9 * Use trigger to model operations which need to be executed when 10 * an event (a signal, for example) is observed. 11 * 12 * States and transits: 13 * 14 * 15 * OFF--> ON --> READY --(hit)--> HIT 16 * ^ | 17 * | (ready) 18 * | | 19 * \_____________/ 20 * 21 * is_hit and is_ready are two key functions to query the state of 22 * a trigger. is_hit means the event already happen; is_ready means the 23 * trigger is waiting for the event. 24 */ 25 26 struct trigger { 27 volatile enum { 28 TRIGGER_ERROR = -2, 29 TRIGGER_OFF = -1, 30 TRIGGER_ON = 0, 31 TRIGGER_READY = 1, 32 TRIGGER_HIT = 2, 33 } state; 34 const char *name; 35 }; 36 37 #define TRIGGER_WARN_ONCE(t, exp) \ 38 WARN_ONCE(t->state != exp, "trigger '%s' state transist error: %d in %s()\n", \ 39 t->name, t->state, __func__) 40 41 static inline bool trigger_is_available(struct trigger *t) 42 { 43 return t->state >= 0; 44 } 45 46 static inline bool trigger_is_error(struct trigger *t) 47 { 48 return t->state <= TRIGGER_ERROR; 49 } 50 51 static inline void trigger_on(struct trigger *t) 52 { 53 TRIGGER_WARN_ONCE(t, TRIGGER_OFF); 54 t->state = TRIGGER_ON; 55 } 56 57 static inline void trigger_ready(struct trigger *t) 58 { 59 if (!trigger_is_available(t)) 60 return; 61 t->state = TRIGGER_READY; 62 } 63 64 static inline void trigger_hit(struct trigger *t) 65 { 66 if (!trigger_is_available(t)) 67 return; 68 TRIGGER_WARN_ONCE(t, TRIGGER_READY); 69 t->state = TRIGGER_HIT; 70 } 71 72 static inline void trigger_off(struct trigger *t) 73 { 74 if (!trigger_is_available(t)) 75 return; 76 t->state = TRIGGER_OFF; 77 } 78 79 static inline void trigger_error(struct trigger *t) 80 { 81 t->state = TRIGGER_ERROR; 82 } 83 84 static inline bool trigger_is_ready(struct trigger *t) 85 { 86 return t->state == TRIGGER_READY; 87 } 88 89 static inline bool trigger_is_hit(struct trigger *t) 90 { 91 return t->state == TRIGGER_HIT; 92 } 93 94 #define DEFINE_TRIGGER(n) \ 95 struct trigger n = {.state = TRIGGER_OFF, .name = #n} 96 #endif 97