Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __TRIGGER_H_
0003 #define __TRIGGER_H_ 1
0004 
0005 #include "asm/bug.h"
0006 
0007 /*
0008  * Use trigger to model operations which need to be executed when
0009  * an event (a signal, for example) is observed.
0010  *
0011  * States and transits:
0012  *
0013  *
0014  *  OFF--> ON --> READY --(hit)--> HIT
0015  *                 ^               |
0016  *                 |            (ready)
0017  *                 |               |
0018  *                  \_____________/
0019  *
0020  * is_hit and is_ready are two key functions to query the state of
0021  * a trigger. is_hit means the event already happen; is_ready means the
0022  * trigger is waiting for the event.
0023  */
0024 
0025 struct trigger {
0026     volatile enum {
0027         TRIGGER_ERROR       = -2,
0028         TRIGGER_OFF     = -1,
0029         TRIGGER_ON      = 0,
0030         TRIGGER_READY       = 1,
0031         TRIGGER_HIT     = 2,
0032     } state;
0033     const char *name;
0034 };
0035 
0036 #define TRIGGER_WARN_ONCE(t, exp) \
0037     WARN_ONCE(t->state != exp, "trigger '%s' state transist error: %d in %s()\n", \
0038           t->name, t->state, __func__)
0039 
0040 static inline bool trigger_is_available(struct trigger *t)
0041 {
0042     return t->state >= 0;
0043 }
0044 
0045 static inline bool trigger_is_error(struct trigger *t)
0046 {
0047     return t->state <= TRIGGER_ERROR;
0048 }
0049 
0050 static inline void trigger_on(struct trigger *t)
0051 {
0052     TRIGGER_WARN_ONCE(t, TRIGGER_OFF);
0053     t->state = TRIGGER_ON;
0054 }
0055 
0056 static inline void trigger_ready(struct trigger *t)
0057 {
0058     if (!trigger_is_available(t))
0059         return;
0060     t->state = TRIGGER_READY;
0061 }
0062 
0063 static inline void trigger_hit(struct trigger *t)
0064 {
0065     if (!trigger_is_available(t))
0066         return;
0067     TRIGGER_WARN_ONCE(t, TRIGGER_READY);
0068     t->state = TRIGGER_HIT;
0069 }
0070 
0071 static inline void trigger_off(struct trigger *t)
0072 {
0073     if (!trigger_is_available(t))
0074         return;
0075     t->state = TRIGGER_OFF;
0076 }
0077 
0078 static inline void trigger_error(struct trigger *t)
0079 {
0080     t->state = TRIGGER_ERROR;
0081 }
0082 
0083 static inline bool trigger_is_ready(struct trigger *t)
0084 {
0085     return t->state == TRIGGER_READY;
0086 }
0087 
0088 static inline bool trigger_is_hit(struct trigger *t)
0089 {
0090     return t->state == TRIGGER_HIT;
0091 }
0092 
0093 #define DEFINE_TRIGGER(n) \
0094 struct trigger n = {.state = TRIGGER_OFF, .name = #n}
0095 #endif