[PATCH v2 2/2] gpio: rockchip: teardown bugs and resource leaks

Bartosz Golaszewski brgl at kernel.org
Wed May 27 01:11:59 PDT 2026


On Tue, 26 May 2026 19:02:46 +0200, Marco Scardovi <scardracs at disroot.org> said:
> Address several teardown issues and resource leaks in the driver's remove
> path and error handling:
>
> 1. Debounce clock reference leak: The debounce clock (bank->db_clk) is
>    obtained using of_clk_get() which increments the clock's reference
>    count, but clk_put() is never called. Register a devm action to
>    cleanly release it on unbind. Note that of_clk_get(..., 1) remains
>    necessary over devm_clk_get() because the DT binding does not define
>    clock-names, precluding name-based lookup.
>
> 2. Unregistered chained IRQ handler: The chained IRQ handler is not
>    disconnected in remove(). If a stray interrupt fires after the driver
>    is removed, the kernel attempts to execute a stale handler, leading
>    to a panic. Fix this by clearing the handler in remove().
>
> 3. IRQ domain leak: The linear IRQ domain and its generic chips are
>    allocated manually during probe but never removed. Remove the IRQ
>    domain during driver teardown to free the associated generic chips
>    and mappings.
>
> Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
> Assisted-by: Antigravity:gemini-3.5-flash
> Signed-off-by: Marco Scardovi <scardracs at disroot.org>
> ---
>  drivers/gpio/gpio-rockchip.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
> index 33580093a4e7..c804f970d823 100644
> --- a/drivers/gpio/gpio-rockchip.c
> +++ b/drivers/gpio/gpio-rockchip.c
> @@ -638,10 +638,17 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
>  	return ret;
>  }
>
> +static void rockchip_clk_put(void *data)
> +{
> +	struct clk *clk = data;
> +
> +	clk_put(clk);
> +}
> +
>  static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
>  {
>  	struct resource res;
> -	int id = 0;
> +	int id = 0, ret;
>
>  	if (of_address_to_resource(bank->of_node, 0, &res)) {
>  		dev_err(bank->dev, "cannot find IO resource for bank\n");
> @@ -673,6 +680,13 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
>  			dev_err(bank->dev, "cannot find debounce clk\n");
>  			return -EINVAL;
>  		}
> +
> +		ret = devm_add_action_or_reset(bank->dev, rockchip_clk_put,
> +					       bank->db_clk);
> +		if (ret) {
> +			dev_err(bank->dev, "failed to register debounce clk action\n");
> +			return ret;

Use return dev_err_probe() for brevity.

> +		}
>  		break;
>  	case GPIO_TYPE_V1:
>  		bank->gpio_regs = &gpio_regs_v1;
> @@ -789,6 +803,9 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
>  {
>  	struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
>
> +	irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
> +	if (bank->domain)
> +		irq_domain_remove(bank->domain);
>  	gpiochip_remove(&bank->gpio_chip);

Maybe if you're already touching the driver, use devres for gpiochip_remove()
too and schedule an action for removing the irq handler?

>  }
>
> --
> 2.54.0
>
>

Bart



More information about the Linux-rockchip mailing list