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