1 From f0061ffc98c6e027c5774e2a24ceadcfee4167ea Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Tue, 5 Sep 2023 12:01:13 +0100
4 Subject: [PATCH] gpio_fsm: Rework the atomic-vs-non-atomic split
6 Partition the code to separate atomic and non-atomic methods so that
7 none of them have to handle both cases. The result avoids using deferred
8 work unless necessary, and should be easier to understand.
10 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
12 drivers/gpio/gpio-fsm.c | 84 ++++++++++++++++++++---------------------
13 1 file changed, 41 insertions(+), 43 deletions(-)
15 --- a/drivers/gpio/gpio-fsm.c
16 +++ b/drivers/gpio/gpio-fsm.c
17 @@ -193,9 +193,6 @@ static void free_symbols(struct symtab_e
21 -static void gpio_fsm_go_to_state(struct gpio_fsm *gf,
22 - struct fsm_state *new_state);
24 static void gpio_fsm_set_soft(struct gpio_fsm *gf,
25 unsigned int off, int val);
27 @@ -213,6 +210,7 @@ static void gpio_fsm_enter_state(struct
28 dev_dbg(gf->dev, "enter_state(%s)\n", state->name);
30 gf->current_state = state;
31 + gf->delay_target_state = NULL;
33 // 1. Apply any listed signals
34 for (i = 0; i < state->num_signals; i++) {
35 @@ -271,7 +269,7 @@ static void gpio_fsm_enter_state(struct
37 "GF_SOFT %d=%d -> %s\n", event->index,
38 event->value, event->target->name);
39 - gpio_fsm_go_to_state(gf, event->target);
40 + gpio_fsm_enter_state(gf, event->target);
44 @@ -284,7 +282,7 @@ static void gpio_fsm_enter_state(struct
45 inp_state->value = event->value;
46 inp_state->enabled = true;
48 - value = gpiod_get_value(gf->input_gpios->desc[event->index]);
49 + value = gpiod_get_value_cansleep(gf->input_gpios->desc[event->index]);
51 // Clear stale event state
52 disable_irq(inp_state->irq);
53 @@ -299,7 +297,7 @@ static void gpio_fsm_enter_state(struct
55 "GF_IN %d=%d -> %s\n", event->index,
56 event->value, event->target->name);
57 - gpio_fsm_go_to_state(gf, event->target);
58 + gpio_fsm_enter_state(gf, event->target);
62 @@ -325,6 +323,33 @@ static void gpio_fsm_go_to_state(struct
63 dev_dbg(gf->dev, "go_to_state(%s)\n",
64 new_state ? new_state->name : "<unset>");
66 + state = gf->current_state;
68 + /* Disable any enabled GPIO IRQs */
69 + for (i = 0; i < state->num_gpio_events; i++) {
70 + gp_ev = &state->gpio_events[i];
71 + inp_state = &gf->input_gpio_states[gp_ev->index];
72 + if (inp_state->enabled) {
73 + inp_state->enabled = false;
74 + irq_set_irq_type(inp_state->irq,
79 + gpio_fsm_enter_state(gf, new_state);
82 +static void gpio_fsm_go_to_state_deferred(struct gpio_fsm *gf,
83 + struct fsm_state *new_state)
85 + struct input_gpio_state *inp_state;
86 + struct gpio_event *gp_ev;
87 + struct fsm_state *state;
90 + dev_dbg(gf->dev, "go_to_state_deferred(%s)\n",
91 + new_state ? new_state->name : "<unset>");
93 spin_lock(&gf->spinlock);
96 @@ -335,57 +360,31 @@ static void gpio_fsm_go_to_state(struct
98 gf->next_state = new_state;
99 state = gf->current_state;
100 - gf->delay_target_state = NULL;
103 - /* Disarm any GPIO IRQs */
104 - for (i = 0; i < state->num_gpio_events; i++) {
105 - gp_ev = &state->gpio_events[i];
106 - inp_state = &gf->input_gpio_states[gp_ev->index];
107 - inp_state->target = NULL;
109 + /* Disarm any GPIO IRQs */
110 + for (i = 0; i < state->num_gpio_events; i++) {
111 + gp_ev = &state->gpio_events[i];
112 + inp_state = &gf->input_gpio_states[gp_ev->index];
113 + inp_state->target = NULL;
116 spin_unlock(&gf->spinlock);
119 - schedule_work(&gf->work);
120 + schedule_work(&gf->work);
123 static void gpio_fsm_work(struct work_struct *work)
125 - struct input_gpio_state *inp_state;
126 struct fsm_state *new_state;
127 - struct fsm_state *state;
128 - struct gpio_event *gp_ev;
132 gf = container_of(work, struct gpio_fsm, work);
133 spin_lock(&gf->spinlock);
134 - state = gf->current_state;
135 new_state = gf->next_state;
137 - new_state = gf->delay_target_state;
138 gf->next_state = NULL;
139 - gf->delay_target_state = NULL;
140 spin_unlock(&gf->spinlock);
143 - /* Disable any enabled GPIO IRQs */
144 - for (i = 0; i < state->num_gpio_events; i++) {
145 - gp_ev = &state->gpio_events[i];
146 - inp_state = &gf->input_gpio_states[gp_ev->index];
147 - if (inp_state->enabled) {
148 - inp_state->enabled = false;
149 - irq_set_irq_type(inp_state->irq,
150 - IRQF_TRIGGER_NONE);
156 - gpio_fsm_enter_state(gf, new_state);
157 + gpio_fsm_go_to_state(gf, new_state);
160 static irqreturn_t gpio_fsm_gpio_irq_handler(int irq, void *dev_id)
161 @@ -404,7 +403,7 @@ static irqreturn_t gpio_fsm_gpio_irq_han
163 dev_info(gf->dev, "GF_IN %d->%d -> %s\n",
164 inp_state->index, inp_state->value, target->name);
165 - gpio_fsm_go_to_state(gf, target);
166 + gpio_fsm_go_to_state_deferred(gf, target);
170 @@ -416,12 +415,11 @@ static void gpio_fsm_timer(struct timer_
171 target = gf->delay_target_state;
176 dev_info(gf->dev, "GF_DELAY %d -> %s\n", gf->delay_ms,
179 - gpio_fsm_go_to_state(gf, target);
180 + gpio_fsm_go_to_state_deferred(gf, target);
183 int gpio_fsm_parse_signals(struct gpio_fsm *gf, struct fsm_state *state,
184 @@ -1119,7 +1117,7 @@ static int gpio_fsm_probe(struct platfor
186 dev_info(gf->dev, "Start -> %s\n", gf->start_state->name);
188 - gpio_fsm_go_to_state(gf, gf->start_state);
189 + gpio_fsm_enter_state(gf, gf->start_state);
191 return devm_gpiochip_add_data(dev, &gf->gc, gf);