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

Bartosz Golaszewski brgl at kernel.org
Tue May 26 03:53:27 PDT 2026


On Mon, May 25, 2026 at 6:42 PM Marco Scardovi (scardracs)
<scardracs at disroot.org> wrote:
>
> This commit addresses 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) was
>    obtained using of_clk_get() which increments the clock's reference
>    count, but clk_put() was never called. A devm action is now registered
>    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 was not
>    disconnected in remove(). If a stray interrupt fired after the driver
>    was removed, the kernel would attempt to execute a stale handler,
>    leading to a panic. This is fixed by clearing the handler in remove().
>
> 3. IRQ domain leak: The linear IRQ domain and its generic chips were
>    allocated manually during probe but never removed. The IRQ domain is
>    now removed during driver teardown to free the associated generic chips
>    and mappings.
>

I suppose the description comes from the LMM. Please use imperative
mode as is customary in kernel commit messages.

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

Is there any reason to not convert his call into a devm_clk_get() variant too?

> +               if (ret) {
> +                       dev_err(bank->dev, "failed to register debounce clk action\n");
> +                       return ret;
> +               }
>                 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);
>  }
>
> --
> 2.54.0
>
>

Bart



More information about the linux-arm-kernel mailing list