bcm27xx: add kernel 5.10 support
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.10 / 950-0348-gpio-Add-gpio-fsm-driver.patch
1 From 69f26eddc66378e33866cb30fc36309cd1d71b4a Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Wed, 30 Sep 2020 12:00:54 +0100
4 Subject: [PATCH] gpio: Add gpio-fsm driver
5
6 The gpio-fsm driver implements simple state machines that allow GPIOs
7 to be controlled in response to inputs from other GPIOs - real and
8 soft/virtual - and time delays. It can:
9 + create dummy GPIOs for drivers that demand them,
10 + drive multiple GPIOs from a single input, with optional delays,
11 + add a debounce circuit to an input,
12 + drive pattern sequences onto LEDs
13 etc.
14
15 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
16 ---
17 drivers/gpio/Kconfig | 9 +
18 drivers/gpio/Makefile | 1 +
19 drivers/gpio/gpio-fsm.c | 1103 +++++++++++++++++++++++++++
20 include/dt-bindings/gpio/gpio-fsm.h | 21 +
21 4 files changed, 1134 insertions(+)
22 create mode 100644 drivers/gpio/gpio-fsm.c
23 create mode 100644 include/dt-bindings/gpio/gpio-fsm.h
24
25 --- a/drivers/gpio/Kconfig
26 +++ b/drivers/gpio/Kconfig
27 @@ -1164,6 +1164,15 @@ config HTC_EGPIO
28 several HTC phones. It provides basic support for input
29 pins, output pins, and irqs.
30
31 +config GPIO_FSM
32 + tristate "GPIO FSM support"
33 + help
34 + The GPIO FSM driver allows the creation of state machines for
35 + manipulating GPIOs (both real and virtual), with state transitions
36 + triggered by GPIO edges or delays.
37 +
38 + If unsure, say N.
39 +
40 config GPIO_JANZ_TTL
41 tristate "Janz VMOD-TTL Digital IO Module"
42 depends on MFD_JANZ_CMODIO
43 --- a/drivers/gpio/Makefile
44 +++ b/drivers/gpio/Makefile
45 @@ -60,6 +60,7 @@ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93x
46 obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o
47 obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
48 obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
49 +obj-$(CONFIG_GPIO_FSM) += gpio-fsm.o
50 obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
51 obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
52 obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
53 --- /dev/null
54 +++ b/drivers/gpio/gpio-fsm.c
55 @@ -0,0 +1,1103 @@
56 +// SPDX-License-Identifier: GPL-2.0+
57 +/*
58 + * GPIO FSM driver
59 + *
60 + * This driver implements simple state machines that allow real GPIOs to be
61 + * controlled in response to inputs from other GPIOs - real and soft/virtual -
62 + * and time delays. It can:
63 + * + create dummy GPIOs for drivers that demand them
64 + * + drive multiple GPIOs from a single input, with optional delays
65 + * + add a debounce circuit to an input
66 + * + drive pattern sequences onto LEDs
67 + * etc.
68 + *
69 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd.
70 + */
71 +
72 +#include <linux/err.h>
73 +#include <linux/gpio.h>
74 +#include <linux/gpio/driver.h>
75 +#include <linux/interrupt.h>
76 +#include <linux/module.h>
77 +#include <linux/platform_device.h>
78 +
79 +#include <dt-bindings/gpio/gpio-fsm.h>
80 +
81 +#define MODULE_NAME "gpio-fsm"
82 +
83 +#define GF_IO_TYPE(x) ((u32)(x) & 0xffff)
84 +#define GF_IO_INDEX(x) ((u32)(x) >> 16)
85 +
86 +enum {
87 + SIGNAL_GPIO,
88 + SIGNAL_SOFT
89 +};
90 +
91 +enum {
92 + INPUT_GPIO,
93 + INPUT_SOFT
94 +};
95 +
96 +enum {
97 + SYM_UNDEFINED,
98 + SYM_NAME,
99 + SYM_SET,
100 + SYM_START,
101 + SYM_SHUTDOWN,
102 +
103 + SYM_MAX
104 +};
105 +
106 +struct soft_gpio {
107 + int dir;
108 + int value;
109 +};
110 +
111 +struct input_gpio_state {
112 + struct gpio_fsm *gf;
113 + struct gpio_desc *desc;
114 + struct fsm_state *target;
115 + int index;
116 + int value;
117 + int irq;
118 + bool enabled;
119 + bool active_low;
120 +};
121 +
122 +struct gpio_event {
123 + int index;
124 + int value;
125 + struct fsm_state *target;
126 +};
127 +
128 +struct symtab_entry {
129 + const char *name;
130 + void *value;
131 + struct symtab_entry *next;
132 +};
133 +
134 +struct output_signal {
135 + u8 type;
136 + u8 value;
137 + u16 index;
138 +};
139 +
140 +struct fsm_state {
141 + const char *name;
142 + struct output_signal *signals;
143 + struct gpio_event *gpio_events;
144 + struct gpio_event *soft_events;
145 + struct fsm_state *delay_target;
146 + struct fsm_state *shutdown_target;
147 + unsigned int num_signals;
148 + unsigned int num_gpio_events;
149 + unsigned int num_soft_events;
150 + unsigned int delay_ms;
151 + unsigned int shutdown_ms;
152 +};
153 +
154 +struct gpio_fsm {
155 + struct gpio_chip gc;
156 + struct device *dev;
157 + spinlock_t spinlock;
158 + struct work_struct work;
159 + struct timer_list timer;
160 + wait_queue_head_t shutdown_event;
161 + struct fsm_state *states;
162 + struct input_gpio_state *input_gpio_states;
163 + struct gpio_descs *input_gpios;
164 + struct gpio_descs *output_gpios;
165 + struct soft_gpio *soft_gpios;
166 + struct fsm_state *start_state;
167 + struct fsm_state *shutdown_state;
168 + unsigned int num_states;
169 + unsigned int num_output_gpios;
170 + unsigned int num_input_gpios;
171 + unsigned int num_soft_gpios;
172 + unsigned int shutdown_timeout_ms;
173 + unsigned int shutdown_jiffies;
174 +
175 + struct fsm_state *current_state;
176 + struct fsm_state *next_state;
177 + struct fsm_state *delay_target_state;
178 + int delay_ms;
179 + unsigned int debug;
180 + bool shutting_down;
181 + struct symtab_entry *symtab;
182 +};
183 +
184 +static struct symtab_entry *do_add_symbol(struct symtab_entry **symtab,
185 + const char *name, void *value)
186 +{
187 + struct symtab_entry **p = symtab;
188 +
189 + while (*p && strcmp((*p)->name, name))
190 + p = &(*p)->next;
191 +
192 + if (*p) {
193 + /* This is an existing symbol */
194 + if ((*p)->value) {
195 + /* Already defined */
196 + if (value) {
197 + if ((uintptr_t)value < SYM_MAX)
198 + return ERR_PTR(-EINVAL);
199 + else
200 + return ERR_PTR(-EEXIST);
201 + }
202 + } else {
203 + /* Undefined */
204 + (*p)->value = value;
205 + }
206 + } else {
207 + /* This is a new symbol */
208 + *p = kmalloc(sizeof(struct symtab_entry), GFP_KERNEL);
209 + if (*p) {
210 + (*p)->name = name;
211 + (*p)->value = value;
212 + (*p)->next = NULL;
213 + }
214 + }
215 + return *p;
216 +}
217 +
218 +static int add_symbol(struct symtab_entry **symtab,
219 + const char *name, void *value)
220 +{
221 + struct symtab_entry *sym = do_add_symbol(symtab, name, value);
222 +
223 + return PTR_ERR_OR_ZERO(sym);
224 +}
225 +
226 +static struct symtab_entry *get_symbol(struct symtab_entry **symtab,
227 + const char *name)
228 +{
229 + struct symtab_entry *sym = do_add_symbol(symtab, name, NULL);
230 +
231 + if (IS_ERR(sym))
232 + return NULL;
233 + return sym;
234 +}
235 +
236 +static void free_symbols(struct symtab_entry **symtab)
237 +{
238 + struct symtab_entry *sym = *symtab;
239 + void *p;
240 +
241 + *symtab = NULL;
242 + while (sym) {
243 + p = sym;
244 + sym = sym->next;
245 + kfree(p);
246 + }
247 +}
248 +
249 +static int gpio_fsm_get_direction(struct gpio_chip *gc, unsigned int off)
250 +{
251 + struct gpio_fsm *gf = gpiochip_get_data(gc);
252 + struct soft_gpio *sg;
253 +
254 + if (off >= gf->num_soft_gpios)
255 + return -EINVAL;
256 + sg = &gf->soft_gpios[off];
257 +
258 + return sg->dir;
259 +}
260 +
261 +static int gpio_fsm_get(struct gpio_chip *gc, unsigned int off)
262 +{
263 + struct gpio_fsm *gf = gpiochip_get_data(gc);
264 + struct soft_gpio *sg;
265 +
266 + if (off >= gf->num_soft_gpios)
267 + return -EINVAL;
268 + sg = &gf->soft_gpios[off];
269 +
270 + return sg->value;
271 +}
272 +
273 +static void gpio_fsm_go_to_state(struct gpio_fsm *gf,
274 + struct fsm_state *new_state)
275 +{
276 + struct input_gpio_state *inp_state;
277 + struct gpio_event *gp_ev;
278 + struct fsm_state *state;
279 + int i;
280 +
281 + dev_dbg(gf->dev, "go_to_state(%s)\n",
282 + new_state ? new_state->name : "<unset>");
283 +
284 + spin_lock(&gf->spinlock);
285 +
286 + if (gf->next_state) {
287 + /* Something else has already requested a transition */
288 + spin_unlock(&gf->spinlock);
289 + return;
290 + }
291 +
292 + gf->next_state = new_state;
293 + state = gf->current_state;
294 + gf->delay_target_state = NULL;
295 +
296 + if (state) {
297 + /* Disarm any GPIO IRQs */
298 + for (i = 0; i < state->num_gpio_events; i++) {
299 + gp_ev = &state->gpio_events[i];
300 + inp_state = &gf->input_gpio_states[gp_ev->index];
301 + inp_state->target = NULL;
302 + }
303 + }
304 +
305 + spin_unlock(&gf->spinlock);
306 +
307 + if (new_state)
308 + schedule_work(&gf->work);
309 +}
310 +
311 +static void gpio_fsm_set_soft(struct gpio_fsm *gf,
312 + unsigned int off, int val)
313 +{
314 + struct soft_gpio *sg = &gf->soft_gpios[off];
315 + struct gpio_event *gp_ev;
316 + struct fsm_state *state;
317 + int i;
318 +
319 + dev_dbg(gf->dev, "set(%d,%d)\n", off, val);
320 + state = gf->current_state;
321 + sg->value = val;
322 + for (i = 0; i < state->num_soft_events; i++) {
323 + gp_ev = &state->soft_events[i];
324 + if (gp_ev->index == off && gp_ev->value == val) {
325 + if (gf->debug)
326 + dev_info(gf->dev,
327 + "GF_SOFT %d->%d -> %s\n", gp_ev->index,
328 + gp_ev->value, gp_ev->target->name);
329 + gpio_fsm_go_to_state(gf, gp_ev->target);
330 + break;
331 + }
332 + }
333 +}
334 +
335 +static int gpio_fsm_direction_input(struct gpio_chip *gc, unsigned int off)
336 +{
337 + struct gpio_fsm *gf = gpiochip_get_data(gc);
338 + struct soft_gpio *sg;
339 +
340 + if (off >= gf->num_soft_gpios)
341 + return -EINVAL;
342 + sg = &gf->soft_gpios[off];
343 + sg->dir = GPIOF_DIR_IN;
344 +
345 + return 0;
346 +}
347 +
348 +static int gpio_fsm_direction_output(struct gpio_chip *gc, unsigned int off,
349 + int value)
350 +{
351 + struct gpio_fsm *gf = gpiochip_get_data(gc);
352 + struct soft_gpio *sg;
353 +
354 + if (off >= gf->num_soft_gpios)
355 + return -EINVAL;
356 + sg = &gf->soft_gpios[off];
357 + sg->dir = GPIOF_DIR_OUT;
358 + gpio_fsm_set_soft(gf, off, value);
359 +
360 + return 0;
361 +}
362 +
363 +static void gpio_fsm_set(struct gpio_chip *gc, unsigned int off, int val)
364 +{
365 + struct gpio_fsm *gf;
366 +
367 + gf = gpiochip_get_data(gc);
368 + if (off < gf->num_soft_gpios)
369 + gpio_fsm_set_soft(gf, off, val);
370 +}
371 +
372 +static void gpio_fsm_enter_state(struct gpio_fsm *gf,
373 + struct fsm_state *state)
374 +{
375 + struct input_gpio_state *inp_state;
376 + struct output_signal *signal;
377 + struct gpio_event *event;
378 + struct gpio_desc *gpiod;
379 + struct soft_gpio *soft;
380 + int value;
381 + int i;
382 +
383 + dev_dbg(gf->dev, "enter_state(%s)\n", state->name);
384 +
385 + gf->current_state = state;
386 +
387 + // 1. Apply any listed signals
388 + for (i = 0; i < state->num_signals; i++) {
389 + signal = &state->signals[i];
390 +
391 + if (gf->debug)
392 + dev_info(gf->dev, " set %s %d->%d\n",
393 + (signal->type == SIGNAL_GPIO) ? "GF_OUT" :
394 + "GF_SOFT",
395 + signal->index, signal->value);
396 + switch (signal->type) {
397 + case SIGNAL_GPIO:
398 + gpiod = gf->output_gpios->desc[signal->index];
399 + gpiod_set_value_cansleep(gpiod, signal->value);
400 + break;
401 + case SIGNAL_SOFT:
402 + soft = &gf->soft_gpios[signal->index];
403 + gpio_fsm_set_soft(gf, signal->index, signal->value);
404 + break;
405 + }
406 + }
407 +
408 + // 2. Exit if successfully reached shutdown state
409 + if (gf->shutting_down && state == state->shutdown_target) {
410 + wake_up(&gf->shutdown_event);
411 + return;
412 + }
413 +
414 + // 3. Schedule a timer callback if shutting down
415 + if (state->shutdown_target) {
416 + // Remember the absolute shutdown time in case remove is called
417 + // at a later time.
418 + gf->shutdown_jiffies =
419 + jiffies + msecs_to_jiffies(state->shutdown_ms);
420 +
421 + if (gf->shutting_down) {
422 + gf->delay_target_state = state->shutdown_target;
423 + gf->delay_ms = state->shutdown_ms;
424 + mod_timer(&gf->timer, gf->shutdown_jiffies);
425 + }
426 + }
427 +
428 + // During shutdown, skip everything else
429 + if (gf->shutting_down)
430 + return;
431 +
432 + // Otherwise record what the shutdown time would be
433 + gf->shutdown_jiffies = jiffies + msecs_to_jiffies(state->shutdown_ms);
434 +
435 + // 4. Check soft inputs for transitions to take
436 + for (i = 0; i < state->num_soft_events; i++) {
437 + event = &state->soft_events[i];
438 + if (gf->soft_gpios[event->index].value == event->value) {
439 + if (gf->debug)
440 + dev_info(gf->dev,
441 + "GF_SOFT %d=%d -> %s\n", event->index,
442 + event->value, event->target->name);
443 + gpio_fsm_go_to_state(gf, event->target);
444 + return;
445 + }
446 + }
447 +
448 + // 5. Check GPIOs for transitions to take, enabling the IRQs
449 + for (i = 0; i < state->num_gpio_events; i++) {
450 + event = &state->gpio_events[i];
451 + inp_state = &gf->input_gpio_states[event->index];
452 + inp_state->target = event->target;
453 + inp_state->value = event->value;
454 + inp_state->enabled = true;
455 +
456 + value = gpiod_get_value(gf->input_gpios->desc[event->index]);
457 +
458 + // Clear stale event state
459 + disable_irq(inp_state->irq);
460 +
461 + irq_set_irq_type(inp_state->irq,
462 + (inp_state->value ^ inp_state->active_low) ?
463 + IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING);
464 + enable_irq(inp_state->irq);
465 +
466 + if (value == event->value && inp_state->target) {
467 + if (gf->debug)
468 + dev_info(gf->dev,
469 + "GF_IN %d=%d -> %s\n", event->index,
470 + event->value, event->target->name);
471 + gpio_fsm_go_to_state(gf, event->target);
472 + return;
473 + }
474 + }
475 +
476 + // 6. Schedule a timer callback if delay_target
477 + if (state->delay_target) {
478 + gf->delay_target_state = state->delay_target;
479 + gf->delay_ms = state->delay_ms;
480 + mod_timer(&gf->timer,
481 + jiffies + msecs_to_jiffies(state->delay_ms));
482 + }
483 +}
484 +
485 +static void gpio_fsm_work(struct work_struct *work)
486 +{
487 + struct input_gpio_state *inp_state;
488 + struct fsm_state *new_state;
489 + struct fsm_state *state;
490 + struct gpio_event *gp_ev;
491 + struct gpio_fsm *gf;
492 + int i;
493 +
494 + gf = container_of(work, struct gpio_fsm, work);
495 + spin_lock(&gf->spinlock);
496 + state = gf->current_state;
497 + new_state = gf->next_state;
498 + if (!new_state)
499 + new_state = gf->delay_target_state;
500 + gf->next_state = NULL;
501 + gf->delay_target_state = NULL;
502 + spin_unlock(&gf->spinlock);
503 +
504 + if (state) {
505 + /* Disable any enabled GPIO IRQs */
506 + for (i = 0; i < state->num_gpio_events; i++) {
507 + gp_ev = &state->gpio_events[i];
508 + inp_state = &gf->input_gpio_states[gp_ev->index];
509 + if (inp_state->enabled) {
510 + inp_state->enabled = false;
511 + irq_set_irq_type(inp_state->irq,
512 + IRQF_TRIGGER_NONE);
513 + }
514 + }
515 + }
516 +
517 + if (new_state)
518 + gpio_fsm_enter_state(gf, new_state);
519 +}
520 +
521 +static irqreturn_t gpio_fsm_gpio_irq_handler(int irq, void *dev_id)
522 +{
523 + struct input_gpio_state *inp_state = dev_id;
524 + struct gpio_fsm *gf = inp_state->gf;
525 + struct fsm_state *target;
526 +
527 + target = inp_state->target;
528 + if (!target)
529 + return IRQ_NONE;
530 +
531 + /* If the IRQ has fired then the desired state _must_ have occurred */
532 + inp_state->enabled = false;
533 + irq_set_irq_type(inp_state->irq, IRQF_TRIGGER_NONE);
534 + if (gf->debug)
535 + dev_info(gf->dev, "GF_IN %d->%d -> %s\n",
536 + inp_state->index, inp_state->value, target->name);
537 + gpio_fsm_go_to_state(gf, target);
538 + return IRQ_HANDLED;
539 +}
540 +
541 +static void gpio_fsm_timer(struct timer_list *timer)
542 +{
543 + struct gpio_fsm *gf = container_of(timer, struct gpio_fsm, timer);
544 + struct fsm_state *target;
545 +
546 + target = gf->delay_target_state;
547 + if (!target)
548 + return;
549 +
550 + if (gf->debug)
551 + dev_info(gf->dev, "GF_DELAY %d -> %s\n", gf->delay_ms,
552 + target->name);
553 +
554 + gpio_fsm_go_to_state(gf, target);
555 +}
556 +
557 +int gpio_fsm_parse_signals(struct gpio_fsm *gf, struct fsm_state *state,
558 + struct property *prop)
559 +{
560 + const __be32 *cells = prop->value;
561 + struct output_signal *signal;
562 + u32 io;
563 + u32 type;
564 + u32 index;
565 + u32 value;
566 + int ret = 0;
567 + int i;
568 +
569 + if (prop->length % 8) {
570 + dev_err(gf->dev, "malformed set in state %s\n",
571 + state->name);
572 + return -EINVAL;
573 + }
574 +
575 + state->num_signals = prop->length/8;
576 + state->signals = devm_kcalloc(gf->dev, state->num_signals,
577 + sizeof(struct output_signal),
578 + GFP_KERNEL);
579 + for (i = 0; i < state->num_signals; i++) {
580 + signal = &state->signals[i];
581 + io = be32_to_cpu(cells[0]);
582 + type = GF_IO_TYPE(io);
583 + index = GF_IO_INDEX(io);
584 + value = be32_to_cpu(cells[1]);
585 +
586 + if (type != GF_OUT && type != GF_SOFT) {
587 + dev_err(gf->dev,
588 + "invalid set type %d in state %s\n",
589 + type, state->name);
590 + ret = -EINVAL;
591 + break;
592 + }
593 + if (type == GF_OUT && index >= gf->num_output_gpios) {
594 + dev_err(gf->dev,
595 + "invalid GF_OUT number %d in state %s\n",
596 + index, state->name);
597 + ret = -EINVAL;
598 + break;
599 + }
600 + if (type == GF_SOFT && index >= gf->num_soft_gpios) {
601 + dev_err(gf->dev,
602 + "invalid GF_SOFT number %d in state %s\n",
603 + index, state->name);
604 + ret = -EINVAL;
605 + break;
606 + }
607 + if (value != 0 && value != 1) {
608 + dev_err(gf->dev,
609 + "invalid set value %d in state %s\n",
610 + value, state->name);
611 + ret = -EINVAL;
612 + break;
613 + }
614 + signal->type = (type == GF_OUT) ? SIGNAL_GPIO : SIGNAL_SOFT;
615 + signal->index = index;
616 + signal->value = value;
617 + cells += 2;
618 + }
619 +
620 + return ret;
621 +}
622 +
623 +struct gpio_event *new_event(struct gpio_event **events, int *num_events)
624 +{
625 + int num = ++(*num_events);
626 + *events = krealloc(*events, num * sizeof(struct gpio_event),
627 + GFP_KERNEL);
628 + return *events ? *events + (num - 1) : NULL;
629 +}
630 +
631 +int gpio_fsm_parse_events(struct gpio_fsm *gf, struct fsm_state *state,
632 + struct property *prop)
633 +{
634 + const __be32 *cells = prop->value;
635 + struct symtab_entry *sym;
636 + int num_cells;
637 + int ret = 0;
638 + int i;
639 +
640 + if (prop->length % 8) {
641 + dev_err(gf->dev,
642 + "malformed transitions from state %s to state %s\n",
643 + state->name, prop->name);
644 + return -EINVAL;
645 + }
646 +
647 + sym = get_symbol(&gf->symtab, prop->name);
648 + num_cells = prop->length / 4;
649 + i = 0;
650 + while (i < num_cells) {
651 + struct gpio_event *gp_ev;
652 + u32 event, param;
653 + u32 index;
654 +
655 + event = be32_to_cpu(cells[i++]);
656 + param = be32_to_cpu(cells[i++]);
657 + index = GF_IO_INDEX(event);
658 +
659 + switch (GF_IO_TYPE(event)) {
660 + case GF_IN:
661 + if (index >= gf->num_input_gpios) {
662 + dev_err(gf->dev,
663 + "invalid GF_IN %d in transitions from state %s to state %s\n",
664 + index, state->name, prop->name);
665 + return -EINVAL;
666 + }
667 + if (param > 1) {
668 + dev_err(gf->dev,
669 + "invalid GF_IN value %d in transitions from state %s to state %s\n",
670 + param, state->name, prop->name);
671 + return -EINVAL;
672 + }
673 + gp_ev = new_event(&state->gpio_events,
674 + &state->num_gpio_events);
675 + if (!gp_ev)
676 + return -ENOMEM;
677 + gp_ev->index = index;
678 + gp_ev->value = param;
679 + gp_ev->target = (struct fsm_state *)sym;
680 + break;
681 +
682 + case GF_SOFT:
683 + if (index >= gf->num_soft_gpios) {
684 + dev_err(gf->dev,
685 + "invalid GF_SOFT %d in transitions from state %s to state %s\n",
686 + index, state->name, prop->name);
687 + return -EINVAL;
688 + }
689 + if (param > 1) {
690 + dev_err(gf->dev,
691 + "invalid GF_SOFT value %d in transitions from state %s to state %s\n",
692 + param, state->name, prop->name);
693 + return -EINVAL;
694 + }
695 + gp_ev = new_event(&state->soft_events,
696 + &state->num_soft_events);
697 + if (!gp_ev)
698 + return -ENOMEM;
699 + gp_ev->index = index;
700 + gp_ev->value = param;
701 + gp_ev->target = (struct fsm_state *)sym;
702 + break;
703 +
704 + case GF_DELAY:
705 + if (state->delay_target) {
706 + dev_err(gf->dev,
707 + "state %s has multiple GF_DELAYs\n",
708 + state->name);
709 + return -EINVAL;
710 + }
711 + state->delay_target = (struct fsm_state *)sym;
712 + state->delay_ms = param;
713 + break;
714 +
715 + case GF_SHUTDOWN:
716 + if (state->shutdown_target == state) {
717 + dev_err(gf->dev,
718 + "shutdown state %s has GF_SHUTDOWN\n",
719 + state->name);
720 + return -EINVAL;
721 + } else if (state->shutdown_target) {
722 + dev_err(gf->dev,
723 + "state %s has multiple GF_SHUTDOWNs\n",
724 + state->name);
725 + return -EINVAL;
726 + }
727 + state->shutdown_target =
728 + (struct fsm_state *)sym;
729 + state->shutdown_ms = param;
730 + break;
731 +
732 + default:
733 + dev_err(gf->dev,
734 + "invalid event %08x in transitions from state %s to state %s\n",
735 + event, state->name, prop->name);
736 + return -EINVAL;
737 + }
738 + }
739 + if (i != num_cells) {
740 + dev_err(gf->dev,
741 + "malformed transitions from state %s to state %s\n",
742 + state->name, prop->name);
743 + return -EINVAL;
744 + }
745 +
746 + return ret;
747 +}
748 +
749 +int gpio_fsm_parse_state(struct gpio_fsm *gf,
750 + struct fsm_state *state,
751 + struct device_node *np)
752 +{
753 + struct symtab_entry *sym;
754 + struct property *prop;
755 + int ret;
756 +
757 + state->name = np->name;
758 + ret = add_symbol(&gf->symtab, np->name, state);
759 + if (ret) {
760 + switch (ret) {
761 + case -EINVAL:
762 + dev_err(gf->dev, "'%s' is not a valid state name\n",
763 + np->name);
764 + break;
765 + case -EEXIST:
766 + dev_err(gf->dev, "state %s already defined\n",
767 + np->name);
768 + break;
769 + default:
770 + dev_err(gf->dev, "error %d adding state %s symbol\n",
771 + ret, np->name);
772 + break;
773 + }
774 + return ret;
775 + }
776 +
777 + for_each_property_of_node(np, prop) {
778 + sym = get_symbol(&gf->symtab, prop->name);
779 + if (!sym) {
780 + ret = -ENOMEM;
781 + break;
782 + }
783 +
784 + switch ((uintptr_t)sym->value) {
785 + case SYM_SET:
786 + ret = gpio_fsm_parse_signals(gf, state, prop);
787 + break;
788 + case SYM_START:
789 + if (gf->start_state) {
790 + dev_err(gf->dev, "multiple start states\n");
791 + ret = -EINVAL;
792 + } else {
793 + gf->start_state = state;
794 + }
795 + break;
796 + case SYM_SHUTDOWN:
797 + state->shutdown_target = state;
798 + gf->shutdown_state = state;
799 + break;
800 + case SYM_NAME:
801 + /* Ignore */
802 + break;
803 + default:
804 + /* A set of transition events to this state */
805 + ret = gpio_fsm_parse_events(gf, state, prop);
806 + break;
807 + }
808 + }
809 +
810 + return ret;
811 +}
812 +
813 +static void dump_all(struct gpio_fsm *gf)
814 +{
815 + int i, j;
816 +
817 + dev_info(gf->dev, "Input GPIOs:\n");
818 + for (i = 0; i < gf->num_input_gpios; i++)
819 + dev_info(gf->dev, " %d: %p\n", i,
820 + gf->input_gpios->desc[i]);
821 +
822 + dev_info(gf->dev, "Output GPIOs:\n");
823 + for (i = 0; i < gf->num_output_gpios; i++)
824 + dev_info(gf->dev, " %d: %p\n", i,
825 + gf->output_gpios->desc[i]);
826 +
827 + dev_info(gf->dev, "Soft GPIOs:\n");
828 + for (i = 0; i < gf->num_soft_gpios; i++)
829 + dev_info(gf->dev, " %d: %s %d\n", i,
830 + (gf->soft_gpios[i].dir == GPIOF_DIR_IN) ? "IN" : "OUT",
831 + gf->soft_gpios[i].value);
832 +
833 + dev_info(gf->dev, "Start state: %s\n",
834 + gf->start_state ? gf->start_state->name : "-");
835 +
836 + dev_info(gf->dev, "Shutdown timeout: %d ms\n",
837 + gf->shutdown_timeout_ms);
838 +
839 + for (i = 0; i < gf->num_states; i++) {
840 + struct fsm_state *state = &gf->states[i];
841 +
842 + dev_info(gf->dev, "State %s:\n", state->name);
843 +
844 + if (state->shutdown_target == state)
845 + dev_info(gf->dev, " Shutdown state\n");
846 +
847 + dev_info(gf->dev, " Signals:\n");
848 + for (j = 0; j < state->num_signals; j++) {
849 + struct output_signal *signal = &state->signals[j];
850 +
851 + dev_info(gf->dev, " %d: %s %d=%d\n", j,
852 + (signal->type == SIGNAL_GPIO) ? "GPIO" :
853 + "SOFT",
854 + signal->index, signal->value);
855 + }
856 +
857 + dev_info(gf->dev, " GPIO events:\n");
858 + for (j = 0; j < state->num_gpio_events; j++) {
859 + struct gpio_event *event = &state->gpio_events[j];
860 +
861 + dev_info(gf->dev, " %d: %d=%d -> %s\n", j,
862 + event->index, event->value,
863 + event->target->name);
864 + }
865 +
866 + dev_info(gf->dev, " Soft events:\n");
867 + for (j = 0; j < state->num_soft_events; j++) {
868 + struct gpio_event *event = &state->soft_events[j];
869 +
870 + dev_info(gf->dev, " %d: %d=%d -> %s\n", j,
871 + event->index, event->value,
872 + event->target->name);
873 + }
874 +
875 + if (state->delay_target)
876 + dev_info(gf->dev, " Delay: %d ms -> %s\n",
877 + state->delay_ms, state->delay_target->name);
878 +
879 + if (state->shutdown_target && state->shutdown_target != state)
880 + dev_info(gf->dev, " Shutdown: %d ms -> %s\n",
881 + state->shutdown_ms,
882 + state->shutdown_target->name);
883 + }
884 + dev_info(gf->dev, "\n");
885 +}
886 +
887 +static int resolve_sym_to_state(struct gpio_fsm *gf, struct fsm_state **pstate)
888 +{
889 + struct symtab_entry *sym = (struct symtab_entry *)*pstate;
890 +
891 + if (!sym)
892 + return -ENOMEM;
893 +
894 + *pstate = sym->value;
895 +
896 + if (!*pstate) {
897 + dev_err(gf->dev, "state %s not defined\n",
898 + sym->name);
899 + return -EINVAL;
900 + }
901 +
902 + return 0;
903 +}
904 +
905 +static int gpio_fsm_probe(struct platform_device *pdev)
906 +{
907 + struct input_gpio_state *inp_state;
908 + struct device *dev = &pdev->dev;
909 + struct device_node *np = dev->of_node;
910 + struct device_node *cp;
911 + struct gpio_fsm *gf;
912 + u32 debug = 0;
913 + int num_states;
914 + u32 num_soft_gpios;
915 + int ret;
916 + int i;
917 + static const char *const reserved_symbols[] = {
918 + [SYM_NAME] = "name",
919 + [SYM_SET] = "set",
920 + [SYM_START] = "start_state",
921 + [SYM_SHUTDOWN] = "shutdown_state",
922 + };
923 +
924 + if (of_property_read_u32(np, "num-soft-gpios", &num_soft_gpios)) {
925 + dev_err(dev, "missing 'num-soft-gpios' property\n");
926 + return -EINVAL;
927 + }
928 +
929 + of_property_read_u32(np, "debug", &debug);
930 +
931 + gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL);
932 + if (!gf)
933 + return -ENOMEM;
934 +
935 + gf->dev = dev;
936 + gf->debug = debug;
937 +
938 + if (of_property_read_u32(np, "shutdown-timeout-ms",
939 + &gf->shutdown_timeout_ms))
940 + gf->shutdown_timeout_ms = 5000;
941 +
942 + gf->num_soft_gpios = num_soft_gpios;
943 + gf->soft_gpios = devm_kcalloc(dev, num_soft_gpios,
944 + sizeof(struct soft_gpio), GFP_KERNEL);
945 + if (!gf->soft_gpios)
946 + return -ENOMEM;
947 + for (i = 0; i < num_soft_gpios; i++) {
948 + struct soft_gpio *sg = &gf->soft_gpios[i];
949 +
950 + sg->dir = GPIOF_DIR_IN;
951 + sg->value = 0;
952 + }
953 +
954 + gf->input_gpios = devm_gpiod_get_array_optional(dev, "input", GPIOD_IN);
955 + if (IS_ERR(gf->input_gpios)) {
956 + ret = PTR_ERR(gf->input_gpios);
957 + dev_err(dev, "failed to get input gpios from DT - %d\n", ret);
958 + return ret;
959 + }
960 + gf->num_input_gpios = (gf->input_gpios ? gf->input_gpios->ndescs : 0);
961 +
962 + gf->input_gpio_states = devm_kcalloc(dev, gf->num_input_gpios,
963 + sizeof(struct input_gpio_state),
964 + GFP_KERNEL);
965 + if (!gf->input_gpio_states)
966 + return -ENOMEM;
967 + for (i = 0; i < gf->num_input_gpios; i++) {
968 + inp_state = &gf->input_gpio_states[i];
969 + inp_state->desc = gf->input_gpios->desc[i];
970 + inp_state->gf = gf;
971 + inp_state->index = i;
972 + inp_state->irq = gpiod_to_irq(inp_state->desc);
973 + inp_state->active_low = gpiod_is_active_low(inp_state->desc);
974 + if (inp_state->irq >= 0)
975 + ret = devm_request_irq(gf->dev, inp_state->irq,
976 + gpio_fsm_gpio_irq_handler,
977 + IRQF_TRIGGER_NONE,
978 + dev_name(dev),
979 + inp_state);
980 + else
981 + ret = inp_state->irq;
982 +
983 + if (ret) {
984 + dev_err(dev,
985 + "failed to get IRQ for input gpio - %d\n",
986 + ret);
987 + return ret;
988 + }
989 + }
990 +
991 + gf->output_gpios = devm_gpiod_get_array_optional(dev, "output",
992 + GPIOD_OUT_LOW);
993 + if (IS_ERR(gf->output_gpios)) {
994 + ret = PTR_ERR(gf->output_gpios);
995 + dev_err(dev, "failed to get output gpios from DT - %d\n", ret);
996 + return ret;
997 + }
998 + gf->num_output_gpios = (gf->output_gpios ? gf->output_gpios->ndescs :
999 + 0);
1000 +
1001 + num_states = of_get_child_count(np);
1002 + if (!num_states) {
1003 + dev_err(dev, "no states declared\n");
1004 + return -EINVAL;
1005 + }
1006 + gf->states = devm_kcalloc(dev, num_states,
1007 + sizeof(struct fsm_state), GFP_KERNEL);
1008 + if (!gf->states)
1009 + return -ENOMEM;
1010 +
1011 + // add reserved words to the symbol table
1012 + for (i = 0; i < ARRAY_SIZE(reserved_symbols); i++) {
1013 + if (reserved_symbols[i])
1014 + add_symbol(&gf->symtab, reserved_symbols[i], (void *)i);
1015 + }
1016 +
1017 + // parse the state
1018 + for_each_child_of_node(np, cp) {
1019 + struct fsm_state *state = &gf->states[gf->num_states];
1020 +
1021 + ret = gpio_fsm_parse_state(gf, state, cp);
1022 + if (ret)
1023 + return ret;
1024 + gf->num_states++;
1025 + }
1026 +
1027 + if (!gf->start_state) {
1028 + dev_err(gf->dev, "no start state defined\n");
1029 + return -EINVAL;
1030 + }
1031 +
1032 + // resolve symbol pointers into state pointers
1033 + for (i = 0; !ret && i < gf->num_states; i++) {
1034 + struct fsm_state *state = &gf->states[i];
1035 + int j;
1036 +
1037 + for (j = 0; !ret && j < state->num_gpio_events; j++) {
1038 + struct gpio_event *ev = &state->gpio_events[j];
1039 +
1040 + ret = resolve_sym_to_state(gf, &ev->target);
1041 + }
1042 +
1043 + for (j = 0; !ret && j < state->num_soft_events; j++) {
1044 + struct gpio_event *ev = &state->soft_events[j];
1045 +
1046 + ret = resolve_sym_to_state(gf, &ev->target);
1047 + }
1048 +
1049 + if (!ret) {
1050 + resolve_sym_to_state(gf, &state->delay_target);
1051 + if (state->shutdown_target != state)
1052 + resolve_sym_to_state(gf,
1053 + &state->shutdown_target);
1054 + }
1055 + }
1056 +
1057 + if (!ret && gf->debug > 1)
1058 + dump_all(gf);
1059 +
1060 + free_symbols(&gf->symtab);
1061 +
1062 + if (ret)
1063 + return ret;
1064 +
1065 + gf->gc.parent = dev;
1066 + gf->gc.label = np->name;
1067 + gf->gc.owner = THIS_MODULE;
1068 + gf->gc.of_node = np;
1069 + gf->gc.base = -1;
1070 + gf->gc.ngpio = num_soft_gpios;
1071 +
1072 + gf->gc.get_direction = gpio_fsm_get_direction;
1073 + gf->gc.direction_input = gpio_fsm_direction_input;
1074 + gf->gc.direction_output = gpio_fsm_direction_output;
1075 + gf->gc.get = gpio_fsm_get;
1076 + gf->gc.set = gpio_fsm_set;
1077 + gf->gc.can_sleep = true;
1078 + spin_lock_init(&gf->spinlock);
1079 + INIT_WORK(&gf->work, gpio_fsm_work);
1080 + timer_setup(&gf->timer, gpio_fsm_timer, 0);
1081 + init_waitqueue_head(&gf->shutdown_event);
1082 +
1083 + platform_set_drvdata(pdev, gf);
1084 +
1085 + if (gf->debug)
1086 + dev_info(gf->dev, "Start -> %s\n", gf->start_state->name);
1087 +
1088 + gpio_fsm_go_to_state(gf, gf->start_state);
1089 +
1090 + return devm_gpiochip_add_data(dev, &gf->gc, gf);
1091 +}
1092 +
1093 +static int gpio_fsm_remove(struct platform_device *pdev)
1094 +{
1095 + struct gpio_fsm *gf = platform_get_drvdata(pdev);
1096 + int i;
1097 +
1098 + if (gf->shutdown_state) {
1099 + if (gf->debug)
1100 + dev_info(gf->dev, "Shutting down...\n");
1101 +
1102 + spin_lock(&gf->spinlock);
1103 + gf->shutting_down = true;
1104 + if (gf->current_state->shutdown_target &&
1105 + gf->current_state->shutdown_target != gf->current_state) {
1106 + gf->delay_target_state =
1107 + gf->current_state->shutdown_target;
1108 + mod_timer(&gf->timer, gf->shutdown_jiffies);
1109 + }
1110 + spin_unlock(&gf->spinlock);
1111 +
1112 + wait_event_timeout(gf->shutdown_event,
1113 + gf->current_state->shutdown_target ==
1114 + gf->current_state,
1115 + msecs_to_jiffies(gf->shutdown_timeout_ms));
1116 + if (gf->current_state->shutdown_target == gf->current_state)
1117 + gpio_fsm_enter_state(gf, gf->shutdown_state);
1118 + }
1119 + cancel_work_sync(&gf->work);
1120 + del_timer_sync(&gf->timer);
1121 +
1122 + /* Events aren't allocated from managed storage */
1123 + for (i = 0; i < gf->num_states; i++) {
1124 + kfree(gf->states[i].gpio_events);
1125 + kfree(gf->states[i].soft_events);
1126 + }
1127 + if (gf->debug)
1128 + dev_info(gf->dev, "Exiting\n");
1129 +
1130 + return 0;
1131 +}
1132 +
1133 +static void gpio_fsm_shutdown(struct platform_device *pdev)
1134 +{
1135 + gpio_fsm_remove(pdev);
1136 +}
1137 +
1138 +static const struct of_device_id gpio_fsm_ids[] = {
1139 + { .compatible = "rpi,gpio-fsm" },
1140 + { }
1141 +};
1142 +MODULE_DEVICE_TABLE(of, gpio_fsm_ids);
1143 +
1144 +static struct platform_driver gpio_fsm_driver = {
1145 + .driver = {
1146 + .name = MODULE_NAME,
1147 + .of_match_table = of_match_ptr(gpio_fsm_ids),
1148 + },
1149 + .probe = gpio_fsm_probe,
1150 + .remove = gpio_fsm_remove,
1151 + .shutdown = gpio_fsm_shutdown,
1152 +};
1153 +module_platform_driver(gpio_fsm_driver);
1154 +
1155 +MODULE_LICENSE("GPL");
1156 +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
1157 +MODULE_DESCRIPTION("GPIO FSM driver");
1158 +MODULE_ALIAS("platform:gpio-fsm");
1159 --- /dev/null
1160 +++ b/include/dt-bindings/gpio/gpio-fsm.h
1161 @@ -0,0 +1,21 @@
1162 +/* SPDX-License-Identifier: GPL-2.0+ */
1163 +/*
1164 + * This header provides constants for binding rpi,gpio-fsm.
1165 + */
1166 +
1167 +#ifndef _DT_BINDINGS_GPIO_FSM_H
1168 +#define _DT_BINDINGS_GPIO_FSM_H
1169 +
1170 +#define GF_IN 0
1171 +#define GF_OUT 1
1172 +#define GF_SOFT 2
1173 +#define GF_DELAY 3
1174 +#define GF_SHUTDOWN 4
1175 +
1176 +#define GF_IO(t, v) (((v) << 16) | ((t) & 0xffff))
1177 +
1178 +#define GF_IP(x) GF_IO(GF_IN, (x))
1179 +#define GF_OP(x) GF_IO(GF_OUT, (x))
1180 +#define GF_SW(x) GF_IO(GF_SOFT, (x))
1181 +
1182 +#endif