Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a strict_gpiod option #6117

Merged
merged 6 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@
cam0_sync_inverted = <&csi0>, "sync-gpios:0=", <&gpio>,
<&csi0>, "sync-gpios:4",
<&csi0>, "sync-gpios:8=0", <GPIO_ACTIVE_LOW>;

strict_gpiod = <&chosen>, "bootargs=pinctrl_bcm2835.strict_gpiod=y";
};
};

Expand Down
1 change: 1 addition & 0 deletions arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -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";
};
};

Expand Down
1 change: 1 addition & 0 deletions arch/arm/boot/dts/broadcom/rp1.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
64 changes: 35 additions & 29 deletions arch/arm/boot/dts/overlays/README
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,23 @@ Name: <The base DTB>
Info: Configures the base Raspberry Pi hardware
Load: <loaded automatically>
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.
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -386,6 +402,19 @@ 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)

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")

Expand All @@ -410,29 +439,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.)
Expand Down
8 changes: 6 additions & 2 deletions drivers/pinctrl/bcm/pinctrl-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions drivers/pinctrl/pinctrl-rp1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down