From 16338d32818ba0140c5eb03a71f69dd12bdfd234 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 8 Mar 2024 14:50:54 +0000 Subject: [PATCH 1/6] ARM: dts: rp1: Add a gpio-ranges property gpio-ranges declares a relationship between pinctrl and GPIO controllers. It is required for "strict" mode to work. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/broadcom/rp1.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/broadcom/rp1.dtsi b/arch/arm/boot/dts/broadcom/rp1.dtsi index 965b614a5f0af7..fd9fb2dde0f7ba 100644 --- a/arch/arm/boot/dts/broadcom/rp1.dtsi +++ b/arch/arm/boot/dts/broadcom/rp1.dtsi @@ -465,6 +465,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&rp1_gpio 0 0 54>; rp1_uart0_14_15: rp1_uart0_14_15 { pin_txd { From 0c92311572bb6391d02e2de1d0c76dd0d030ced2 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 19 Apr 2024 14:56:32 +0100 Subject: [PATCH 2/6] pinctrl: bcm2835: Add strict_gpiod module parameter Setting strict_gpiod to Y makes libgpiod and the gpiod utilities behave as documented, i.e. pins are returned to being GPIO inputs when they are released. drivers/pinctrl/bcm/pinctrl-bcm2835.c Signed-off-by: Phil Elwell --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 8b178b8d72420b..675cf96d7465bd 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -244,6 +244,10 @@ static const char * const irq_type_names[] = { [IRQ_TYPE_LEVEL_LOW] = "level-low", }; +static bool strict_gpiod; +module_param(strict_gpiod, bool, 0644); +MODULE_PARM_DESC(strict_gpiod, "unless true, outputs remain outputs when freed"); + static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg) { return readl(pc->base + reg); @@ -941,8 +945,8 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev, struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset); - /* Return non-GPIOs to GPIO_IN */ - if (fsel != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_OUT) + /* Return non-GPIOs to GPIO_IN, unless strict_gpiod is set */ + if (strict_gpiod || (fsel != BCM2835_FSEL_GPIO_IN && fsel != BCM2835_FSEL_GPIO_OUT)) bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); return 0; From f28e9dc64526e8a30b2025c283925955a9b4c4a2 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 19 Apr 2024 15:00:52 +0100 Subject: [PATCH 3/6] pinctrl: rp1: Add strict_gpiod module parameter Setting strict_gpiod to Y makes libgpiod and the gpiod utilities behave as documented, i.e. pins are returned to being GPIO inputs when they are released. Signed-off-by: Phil Elwell --- drivers/pinctrl/pinctrl-rp1.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c index b2729c5e6a924b..292051168b61f7 100644 --- a/drivers/pinctrl/pinctrl-rp1.c +++ b/drivers/pinctrl/pinctrl-rp1.c @@ -573,6 +573,10 @@ static const char * const irq_type_names[] = { [IRQ_TYPE_LEVEL_LOW] = "level-low", }; +static bool strict_gpiod; +module_param(strict_gpiod, bool, 0644); +MODULE_PARM_DESC(strict_gpiod, "unless true, outputs remain outputs when freed"); + static int rp1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int offset, unsigned long *configs, unsigned int num_configs); @@ -1201,8 +1205,8 @@ static int rp1_pmx_free(struct pinctrl_dev *pctldev, unsigned offset) struct rp1_pin_info *pin = rp1_get_pin_pctl(pctldev, offset); u32 fsel = rp1_get_fsel(pin); - /* Return non-GPIOs to GPIO_IN */ - if (fsel != RP1_FSEL_GPIO) { + /* Return non-GPIOs to GPIO_IN, unless strict_gpiod is set */ + if (strict_gpiod || fsel != RP1_FSEL_GPIO) { rp1_set_dir(pin, RP1_DIR_INPUT); rp1_set_fsel(pin, RP1_FSEL_GPIO); } From 3c77f5f1ebd1406da1e5b897d330d054e2dd9217 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 19 Apr 2024 15:02:02 +0100 Subject: [PATCH 4/6] ARM: dts: Add strict_gpiod dtparam Setting strict_gpiod disables the GPIO output persistence, such that pins are returned to being inputs when they are released. Note that this applies to the GPIO/pinctrl driver for the user-facing GPIOs, not the SoC GPIOs on Pi 5. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi | 2 ++ arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi index 1d45fba0b3928b..f997d908e4b4ce 100644 --- a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi @@ -110,6 +110,8 @@ cam0_sync_inverted = <&csi0>, "sync-gpios:0=", <&gpio>, <&csi0>, "sync-gpios:4", <&csi0>, "sync-gpios:8=0", ; + + strict_gpiod = <&chosen>, "bootargs=pinctrl_bcm2835.strict_gpiod=y"; }; }; diff --git a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi b/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi index 359a30d6ef5ff7..89d12634f20b81 100644 --- a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi +++ b/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi @@ -99,6 +99,7 @@ nvmem_cust_rw = <&nvmem_cust>,"rw?"; nvmem_priv_rw = <&nvmem_priv>,"rw?"; nvmem_mac_rw = <&nvmem_mac>,"rw?"; + strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.strict_gpiod=y"; }; }; From 2e661e1b2a757d3119b62c6c2d4bbfbea52e7995 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 19 Apr 2024 15:26:50 +0100 Subject: [PATCH 5/6] overlays: README: Sort the dtparam names There are enough dtparams now that not having them in alphabetical order makes them hard to find. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/overlays/README | 58 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index b2a13ed7d9a2a5..5c817ef09ac471 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -130,6 +130,23 @@ Name: Info: Configures the base Raspberry Pi hardware Load: Params: + act_led_trigger Choose which activity the LED tracks. + Use "heartbeat" for a nice load indicator. + (default "mmc") + + act_led_activelow Set to "on" to invert the sense of the LED + (default "off") + N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led + overlay. + + act_led_gpio Set which GPIO to use for the activity LED + (in case you want to connect it to an external + device) + (default "16" on a non-Plus board, "47" on a + Plus or Pi 2) + N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led + overlay. + ant1 Select antenna 1 (default). CM4/5 only. ant2 Select antenna 2. CM4/5 only. @@ -340,12 +357,11 @@ Params: pciex1_tperst_clk_ms Alias for pcie_tperst_clk_ms (2712 only, default "0") - spi Set to "on" to enable the spi interfaces - (default "off") - - spi_dma4 Use to enable 40-bit DMA on spi interfaces - (the assigned value doesn't matter) - (2711 only) + pwr_led_trigger + pwr_led_activelow + pwr_led_gpio + As for act_led_*, but using the PWR LED. + Not available on Model A/B boards. random Set to "on" to enable the hardware random number generator (default "on") @@ -386,6 +402,13 @@ Params: sdio_overclock Clock (in MHz) to use when the MMC framework requests 50MHz for the SDIO/WLAN interface. + spi Set to "on" to enable the spi interfaces + (default "off") + + spi_dma4 Use to enable 40-bit DMA on spi interfaces + (the assigned value doesn't matter) + (2711 only) + suspend Make the power button trigger a suspend rather than a power-off (2712 only, default "off") @@ -410,29 +433,6 @@ Params: with or without colon separators, written in the natural (big-endian) order. - act_led_trigger Choose which activity the LED tracks. - Use "heartbeat" for a nice load indicator. - (default "mmc") - - act_led_activelow Set to "on" to invert the sense of the LED - (default "off") - N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led - overlay. - - act_led_gpio Set which GPIO to use for the activity LED - (in case you want to connect it to an external - device) - (default "16" on a non-Plus board, "47" on a - Plus or Pi 2) - N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led - overlay. - - pwr_led_trigger - pwr_led_activelow - pwr_led_gpio - As for act_led_*, but using the PWR LED. - Not available on Model A/B boards. - N.B. It is recommended to only enable those interfaces that are needed. Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) From 8546dd0d3cb41fc52f14abfa51cbde8f1e922711 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 19 Apr 2024 15:31:20 +0100 Subject: [PATCH 6/6] overlays: README: Document the strict_gpiod dtparam Describe the function of the strict_gpiod dtparam. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/overlays/README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 5c817ef09ac471..ec4d4a28eed317 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -409,6 +409,12 @@ Params: (the assigned value doesn't matter) (2711 only) + strict_gpiod Return GPIOs to inputs when they are released. + If using the gpiod utilities, it is necessary + to keep a gpioset running (e.g. with + --mode=wait) in order for an output value to + persist. + suspend Make the power button trigger a suspend rather than a power-off (2712 only, default "off")