Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: meson: meson8b: fix requesting GPIOs greater than GPIOZ_3

Meson8b is a cost reduced variant of the Meson8 SoC. It's package size
is smaller than Meson8.
Unfortunately there are a few key differences which cannot be seen
without close inspection of the code and the public S805 datasheet:
- the GPIOX bank is missing the GPIOX_12, GPIOX_13, GPIOX_14 and
GPIOX_15 GPIOs
- the GPIOY bank is missing the GPIOY_2, GPIOY_4, GPIOY_5, GPIOY_15 and
GPIOY_16 GPIOs
- the GPIODV bank is missing all GPIOs except GPIODV_9, GPIODV_24,
GPIODV_25, GPIODV_26, GPIODV_27, GPIODV_28 and GPIODV_29
- the GPIOZ bank is missing completely
- there is a new GPIO bank called "DIF"

This means that Meson8b only has 83 actual GPIO lines. Without any holes
there would be 130 GPIO lines in total (120 are inherited from Meson8
plus 10 new from the DIF bank).

GPIOs greater GPIOZ_3 (whose ID is 83 - as a reminder: this is exactly
the number of actual GPIO lines on Meson8b and also the value of
meson8b_cbus_pinctrl_data.num_pins) cannot berequested. Using CARD_6
(which used ID 100 prior to this patch, "base of the GPIO controller was
382) as an example:
$ echo 482 > /sys/class/gpio/export
export_store: invalid GPIO 482

This removes all non-existing pins from to dt-bindings header file
(include/dt-bindings/gpio/meson8b-gpio.h). This allows us to have a
consecutive numbering for the GPIO #defines (GPIOY_2 doesn't exist for
example, so previously the GPIOY_3 ID was "GPIOY_1 + 2", after this
patch it is "GPIOY_1 + 1"). As a nice side-effect this means that we get
compile-time (instead of runtime) errors if Meson8b .dts uses a pin that
only exists on Meson8.

Additionally the pinctrl-meson8b driver has to be updated to handle this
new GPIO numbering. By default a struct meson_bank only handles GPIO
banks where the pins are numbered consecutively because it calculates
the bit offsets based on the GPIO IDs.
This is solved by taking the original BANK() definition and splitting it
into consecutive subsets (X0..11 and X16..21). The bit offsets for each
new bank includes the skipped GPIOs (the definition of the "X0..11" bank
is identical to the old "X" bank apart from the "last IRQ" field, the
definition of the new, split "X16..21" bank takes the original "X" bank
and adds 16 - the start of the new split bank - to the "first IRQ",
pullen bit, pull bit, dir bit, out bit and in bit).

Commit 984cffdeaeb7ea ("pinctrl: Fix gpio/pin mapping for Meson8b")
fixed the same issue by setting "ngpio" (of the gpio_chip) to 130.
Unfortunately this broke in db80f0e158e621 ("pinctrl: meson: get rid of
unneeded domain structures").
The solution from this patch was considered to be better than the
previous attempt at fixing this because it provides compile-time error
checking for the GPIOs that exist on Meson8 but don't exist on Meson8b.

The following pins were tested on an Odroid-C1 using the sysfs GPIO
interface checking that their value (high or low) could be read:
- GPIOX_0, GPIOX_1, GPIOX_2, GPIOX_3, GPIOX_4, GPIOX_5, GPIOX_6,
GPIOX_7, GPIOX_8, GPIOX_9, GPIOX_10, GPIOX_11, GPIOX_18, GPIOX_19,
GPIOX_20, GPIOX_21
- GPIOY_3, GPIOY_7, GPIOY_8
(some of these had to be pulled up because they were low by default,
others were high by default so these had to be pulled down)

Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
Suggested-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Martin Blumenstingl and committed by
Linus Walleij
55af415b b89405b6

+119 -20
+12 -8
drivers/pinctrl/meson/pinctrl-meson8b.c
··· 884 884 }; 885 885 886 886 static struct meson_bank meson8b_cbus_banks[] = { 887 - /* name first last irq pullen pull dir out in */ 888 - BANK("X", GPIOX_0, GPIOX_21, 97, 118, 4, 0, 4, 0, 0, 0, 1, 0, 2, 0), 889 - BANK("Y", GPIOY_0, GPIOY_14, 80, 96, 3, 0, 3, 0, 3, 0, 4, 0, 5, 0), 890 - BANK("DV", GPIODV_9, GPIODV_29, 59, 79, 0, 0, 0, 0, 7, 0, 8, 0, 9, 0), 891 - BANK("H", GPIOH_0, GPIOH_9, 14, 23, 1, 16, 1, 16, 9, 19, 10, 19, 11, 19), 892 - BANK("CARD", CARD_0, CARD_6, 43, 49, 2, 20, 2, 20, 0, 22, 1, 22, 2, 22), 893 - BANK("BOOT", BOOT_0, BOOT_18, 24, 42, 2, 0, 2, 0, 9, 0, 10, 0, 11, 0), 887 + /* name first last irq pullen pull dir out in */ 888 + BANK("X0..11", GPIOX_0, GPIOX_11, 97, 108, 4, 0, 4, 0, 0, 0, 1, 0, 2, 0), 889 + BANK("X16..21", GPIOX_16, GPIOX_21, 113, 118, 4, 16, 4, 16, 0, 16, 1, 16, 2, 16), 890 + BANK("Y0..1", GPIOY_0, GPIOY_1, 80, 81, 3, 0, 3, 0, 3, 0, 4, 0, 5, 0), 891 + BANK("Y3", GPIOY_3, GPIOY_3, 83, 83, 3, 3, 3, 3, 3, 3, 4, 3, 5, 3), 892 + BANK("Y6..14", GPIOY_6, GPIOY_14, 86, 94, 3, 6, 3, 6, 3, 6, 4, 6, 5, 6), 893 + BANK("DV9", GPIODV_9, GPIODV_9, 59, 59, 0, 9, 0, 9, 7, 9, 8, 9, 9, 9), 894 + BANK("DV24..29", GPIODV_24, GPIODV_29, 74, 79, 0, 24, 0, 24, 7, 24, 8, 24, 9, 24), 895 + BANK("H", GPIOH_0, GPIOH_9, 14, 23, 1, 16, 1, 16, 9, 19, 10, 19, 11, 19), 896 + BANK("CARD", CARD_0, CARD_6, 43, 49, 2, 20, 2, 20, 0, 22, 1, 22, 2, 22), 897 + BANK("BOOT", BOOT_0, BOOT_18, 24, 42, 2, 0, 2, 0, 9, 0, 10, 0, 11, 0), 894 898 895 899 /* 896 900 * The following bank is not mentionned in the public datasheet 897 901 * There is no information whether it can be used with the gpio 898 902 * interrupt controller 899 903 */ 900 - BANK("DIF", DIF_0_P, DIF_4_N, -1, -1, 5, 8, 5, 8, 12, 12, 13, 12, 14, 12), 904 + BANK("DIF", DIF_0_P, DIF_4_N, -1, -1, 5, 8, 5, 8, 12, 12, 13, 12, 14, 12), 901 905 }; 902 906 903 907 static struct meson_bank meson8b_aobus_banks[] = {
+107 -12
include/dt-bindings/gpio/meson8b-gpio.h
··· 15 15 #ifndef _DT_BINDINGS_MESON8B_GPIO_H 16 16 #define _DT_BINDINGS_MESON8B_GPIO_H 17 17 18 - #include <dt-bindings/gpio/meson8-gpio.h> 18 + /* EE (CBUS) GPIO chip */ 19 + #define GPIOX_0 0 20 + #define GPIOX_1 1 21 + #define GPIOX_2 2 22 + #define GPIOX_3 3 23 + #define GPIOX_4 4 24 + #define GPIOX_5 5 25 + #define GPIOX_6 6 26 + #define GPIOX_7 7 27 + #define GPIOX_8 8 28 + #define GPIOX_9 9 29 + #define GPIOX_10 10 30 + #define GPIOX_11 11 31 + #define GPIOX_16 12 32 + #define GPIOX_17 13 33 + #define GPIOX_18 14 34 + #define GPIOX_19 15 35 + #define GPIOX_20 16 36 + #define GPIOX_21 17 19 37 20 - /* GPIO Bank DIF */ 21 - #define DIF_0_P 120 22 - #define DIF_0_N 121 23 - #define DIF_1_P 122 24 - #define DIF_1_N 123 25 - #define DIF_2_P 124 26 - #define DIF_2_N 125 27 - #define DIF_3_P 126 28 - #define DIF_3_N 127 29 - #define DIF_4_P 128 30 - #define DIF_4_N 129 38 + #define GPIOY_0 18 39 + #define GPIOY_1 19 40 + #define GPIOY_3 20 41 + #define GPIOY_6 21 42 + #define GPIOY_7 22 43 + #define GPIOY_8 23 44 + #define GPIOY_9 24 45 + #define GPIOY_10 25 46 + #define GPIOY_11 26 47 + #define GPIOY_12 27 48 + #define GPIOY_13 28 49 + #define GPIOY_14 29 50 + 51 + #define GPIODV_9 30 52 + #define GPIODV_24 31 53 + #define GPIODV_25 32 54 + #define GPIODV_26 33 55 + #define GPIODV_27 34 56 + #define GPIODV_28 35 57 + #define GPIODV_29 36 58 + 59 + #define GPIOH_0 37 60 + #define GPIOH_1 38 61 + #define GPIOH_2 39 62 + #define GPIOH_3 40 63 + #define GPIOH_4 41 64 + #define GPIOH_5 42 65 + #define GPIOH_6 43 66 + #define GPIOH_7 44 67 + #define GPIOH_8 45 68 + #define GPIOH_9 46 69 + 70 + #define CARD_0 47 71 + #define CARD_1 48 72 + #define CARD_2 49 73 + #define CARD_3 50 74 + #define CARD_4 51 75 + #define CARD_5 52 76 + #define CARD_6 53 77 + 78 + #define BOOT_0 54 79 + #define BOOT_1 55 80 + #define BOOT_2 56 81 + #define BOOT_3 57 82 + #define BOOT_4 58 83 + #define BOOT_5 59 84 + #define BOOT_6 60 85 + #define BOOT_7 61 86 + #define BOOT_8 62 87 + #define BOOT_9 63 88 + #define BOOT_10 64 89 + #define BOOT_11 65 90 + #define BOOT_12 66 91 + #define BOOT_13 67 92 + #define BOOT_14 68 93 + #define BOOT_15 69 94 + #define BOOT_16 70 95 + #define BOOT_17 71 96 + #define BOOT_18 72 97 + 98 + #define DIF_0_P 73 99 + #define DIF_0_N 74 100 + #define DIF_1_P 75 101 + #define DIF_1_N 76 102 + #define DIF_2_P 77 103 + #define DIF_2_N 78 104 + #define DIF_3_P 79 105 + #define DIF_3_N 80 106 + #define DIF_4_P 81 107 + #define DIF_4_N 82 108 + 109 + /* AO GPIO chip */ 110 + #define GPIOAO_0 0 111 + #define GPIOAO_1 1 112 + #define GPIOAO_2 2 113 + #define GPIOAO_3 3 114 + #define GPIOAO_4 4 115 + #define GPIOAO_5 5 116 + #define GPIOAO_6 6 117 + #define GPIOAO_7 7 118 + #define GPIOAO_8 8 119 + #define GPIOAO_9 9 120 + #define GPIOAO_10 10 121 + #define GPIOAO_11 11 122 + #define GPIOAO_12 12 123 + #define GPIOAO_13 13 124 + #define GPIO_BSD_EN 14 125 + #define GPIO_TEST_N 15 31 126 32 127 #endif /* _DT_BINDINGS_MESON8B_GPIO_H */