From 64729c88f4a6ccf8995f9da2f9115095a0b132e0 Mon Sep 17 00:00:00 2001 From: Nicolai Buchwitz Date: Sat, 25 Jul 2026 20:59:40 +0200 Subject: [PATCH 1/2] pinctrl: rp1: Honour direction in legacy brcm,function in/out The legacy brcm,function values 0 and 1 select GPIO input and output as on BCM283x, but on RP1 the legacy map only muxes the pin to GPIO and never programs the RIO output enable, so the direction is left as-is. An interrupt line declared with brcm,function = <0> can stay an output. On Pi 5 the sc16is7xx overlay then storms its shared IRQ and saturates a CPU core. Many overlays declare their input and interrupt pins this way, so they share the same latent misconfiguration on RP1. Emit a direction config from the legacy map and let input and output enable program the RIO direction when the pin is a GPIO. Fixes: e3ce7b897388 ("pinctrl: rp1: Implement RaspberryPi RP1 pinmux/pinconf support") Link: https://github.com/raspberrypi/linux/issues/7520 Signed-off-by: Nicolai Buchwitz --- drivers/pinctrl/pinctrl-rp1.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c index 7e8f5f600ea495..3ccdf05c3096e7 100644 --- a/drivers/pinctrl/pinctrl-rp1.c +++ b/drivers/pinctrl/pinctrl-rp1.c @@ -1082,6 +1082,31 @@ static int rp1_pctl_legacy_map_func(struct rp1_pinctrl *pc, return 0; } +static int rp1_pctl_legacy_map_dir(struct rp1_pinctrl *pc, + struct device_node *np, u32 pin, u32 fnum, + struct pinctrl_map *maps, + unsigned int *num_maps) +{ + struct pinctrl_map *map = &maps[*num_maps]; + enum pin_config_param param; + unsigned long *configs; + + param = fnum ? PIN_CONFIG_OUTPUT_ENABLE : PIN_CONFIG_INPUT_ENABLE; + + configs = kzalloc(sizeof(*configs), GFP_KERNEL); + if (!configs) + return -ENOMEM; + + configs[0] = pinconf_to_config_packed(param, 1); + map->type = PIN_MAP_TYPE_CONFIGS_PIN; + map->data.configs.group_or_pin = rp1_gpio_pins[pin].name; + map->data.configs.configs = configs; + map->data.configs.num_configs = 1; + (*num_maps)++; + + return 0; +} + static int rp1_pctl_legacy_map_pull(struct rp1_pinctrl *pc, struct device_node *np, u32 pin, u32 pull, struct pinctrl_map *maps, @@ -1178,6 +1203,8 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, maps_per_pin = 0; if (function || num_funcs) maps_per_pin++; + if (num_funcs) + maps_per_pin++; /* legacy GPIO in/out direction */ if (num_configs || num_pulls) maps_per_pin++; reserved_maps = num_pins * maps_per_pin; @@ -1199,6 +1226,9 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, goto out; err = rp1_pctl_legacy_map_func(pc, np, pin, func, maps, num_maps); + if (!err && func < 2) + err = rp1_pctl_legacy_map_dir(pc, np, pin, func, + maps, num_maps); } else if (function) { err = pinctrl_utils_add_map_mux(pctldev, &maps, &reserved_maps, num_maps, @@ -1383,10 +1413,14 @@ static int rp1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int offset, case PIN_CONFIG_INPUT_ENABLE: rp1_input_enable(pin, arg); + if (arg && rp1_get_fsel(pin) == RP1_FSEL_GPIO) + rp1_set_dir(pin, RP1_DIR_INPUT); break; case PIN_CONFIG_OUTPUT_ENABLE: rp1_output_enable(pin, arg); + if (arg && rp1_get_fsel(pin) == RP1_FSEL_GPIO) + rp1_set_dir(pin, RP1_DIR_OUTPUT); break; case PIN_CONFIG_LEVEL: From 07ada0cb3127ba49c0ed7d0244d735d9bae39d80 Mon Sep 17 00:00:00 2001 From: Nicolai Buchwitz Date: Sat, 25 Jul 2026 23:46:32 +0200 Subject: [PATCH 2/2] pinctrl: rp1: Fix node leak and mapping check in probe Drop the leaked rp1_node reference and test of_iomap() for NULL instead of IS_ERR(), which never matches its return value. Fixes: df868dcd8b11 ("pinctrl: Reinstate the downstream pinctrl-rp1 driver") Signed-off-by: Nicolai Buchwitz --- drivers/pinctrl/pinctrl-rp1.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c index 3ccdf05c3096e7..51f07d954fb731 100644 --- a/drivers/pinctrl/pinctrl-rp1.c +++ b/drivers/pinctrl/pinctrl-rp1.c @@ -1638,11 +1638,10 @@ static int rp1_pinctrl_probe(struct platform_device *pdev) else if (pace_pin_updates && of_device_is_compatible(rp1_node->parent, "brcm,bcm2712-pcie")) { pc->dummy_base = of_iomap(rp1_node->parent, 0); - if (IS_ERR(pc->dummy_base)) { + if (!pc->dummy_base) dev_warn(&pdev->dev, "could not map bcm2712 root complex registers\n"); - pc->dummy_base = NULL; - } } + of_node_put(rp1_node); for (i = 0; i < RP1_NUM_BANKS; i++) { const struct rp1_iobank_desc *bank = &rp1_iobanks[i];