On error handling paths, gpiolib_cdev_register() doesn't free the
allocated resources which results leaks.  Fix it.

Cc: [email protected]
Fixes: 7b9b77a8bba9 ("gpiolib: add a per-gpio_device line state notification 
workqueue")
Fixes: d83cee3d2bb1 ("gpio: protect the pointer to gpio_chip in gpio_device 
with SRCU")
Signed-off-by: Tzung-Bi Shih <[email protected]>
---
 drivers/gpio/gpiolib-cdev.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 3735c9fe1502..ba1eae15852d 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -2797,16 +2797,23 @@ int gpiolib_cdev_register(struct gpio_device *gdev, 
dev_t devt)
 
        ret = cdev_device_add(&gdev->chrdev, &gdev->dev);
        if (ret)
-               return ret;
+               goto err_free_workqueue;
 
        guard(srcu)(&gdev->srcu);
        gc = srcu_dereference(gdev->chip, &gdev->srcu);
-       if (!gc)
-               return -ENODEV;
+       if (!gc) {
+               ret = -ENODEV;
+               goto err_free_cdev;
+       }
 
        gpiochip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id);
 
        return 0;
+err_free_cdev:
+       cdev_device_del(&gdev->chrdev, &gdev->dev);
+err_free_workqueue:
+       destroy_workqueue(gdev->line_state_wq);
+       return ret;
 }
 
 void gpiolib_cdev_unregister(struct gpio_device *gdev)
-- 
2.52.0.457.g6b5491de43-goog


Reply via email to