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