]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pinctrl: ti: ti-iodelay: Fix some error handling paths
authorChristophe JAILLET <christophe.jaillet@wanadoo.fr>
Tue, 9 Jul 2024 20:37:43 +0000 (22:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Oct 2024 14:33:04 +0000 (16:33 +0200)
[ Upstream commit a9f2b249adeef2b9744a884355fa8f5e581d507f ]

In the probe, if an error occurs after the ti_iodelay_pinconf_init_dev()
call, it is likely that ti_iodelay_pinconf_deinit_dev() should be called,
as already done in the remove function.

Also in ti_iodelay_pinconf_init_dev(), if an error occurs after the first
regmap_update_bits() call, it is also likely that the deinit() function
should be called.

The easier way to fix it is to add a devm_add_action_or_reset() at the
rigtht place to have ti_iodelay_pinconf_deinit_dev() called when needed.

Doing so, the .remove() function can be removed, and the associated
platform_set_drvdata() call in the probe as well.

Fixes: 003910ebc83b ("pinctrl: Introduce TI IOdelay configuration driver")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/0220fa5b925bd08e361be8206a5438f6229deaac.1720556038.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/pinctrl/ti/pinctrl-ti-iodelay.c

index f5e5a23d222600e4c0eb6a2b0b37dbea99e48092..451801acdc40380dc0449588b8f8eef91276790f 100644 (file)
@@ -273,6 +273,22 @@ static int ti_iodelay_pinconf_set(struct ti_iodelay_device *iod,
        return r;
 }
 
+/**
+ * ti_iodelay_pinconf_deinit_dev() - deinit the iodelay device
+ * @data:      IODelay device
+ *
+ * Deinitialize the IODelay device (basically just lock the region back up.
+ */
+static void ti_iodelay_pinconf_deinit_dev(void *data)
+{
+       struct ti_iodelay_device *iod = data;
+       const struct ti_iodelay_reg_data *reg = iod->reg_data;
+
+       /* lock the iodelay region back again */
+       regmap_update_bits(iod->regmap, reg->reg_global_lock_offset,
+                          reg->global_lock_mask, reg->global_lock_val);
+}
+
 /**
  * ti_iodelay_pinconf_init_dev() - Initialize IODelay device
  * @iod: iodelay device
@@ -295,6 +311,11 @@ static int ti_iodelay_pinconf_init_dev(struct ti_iodelay_device *iod)
        if (r)
                return r;
 
+       r = devm_add_action_or_reset(iod->dev, ti_iodelay_pinconf_deinit_dev,
+                                    iod);
+       if (r)
+               return r;
+
        /* Read up Recalibration sequence done by bootloader */
        r = regmap_read(iod->regmap, reg->reg_refclk_offset, &val);
        if (r)
@@ -353,21 +374,6 @@ static int ti_iodelay_pinconf_init_dev(struct ti_iodelay_device *iod)
        return 0;
 }
 
-/**
- * ti_iodelay_pinconf_deinit_dev() - deinit the iodelay device
- * @iod:       IODelay device
- *
- * Deinitialize the IODelay device (basically just lock the region back up.
- */
-static void ti_iodelay_pinconf_deinit_dev(struct ti_iodelay_device *iod)
-{
-       const struct ti_iodelay_reg_data *reg = iod->reg_data;
-
-       /* lock the iodelay region back again */
-       regmap_update_bits(iod->regmap, reg->reg_global_lock_offset,
-                          reg->global_lock_mask, reg->global_lock_val);
-}
-
 /**
  * ti_iodelay_get_pingroup() - Find the group mapped by a group selector
  * @iod: iodelay device
@@ -877,27 +883,11 @@ static int ti_iodelay_probe(struct platform_device *pdev)
                return ret;
        }
 
-       platform_set_drvdata(pdev, iod);
-
        return pinctrl_enable(iod->pctl);
 }
 
-/**
- * ti_iodelay_remove() - standard remove
- * @pdev: platform device
- */
-static void ti_iodelay_remove(struct platform_device *pdev)
-{
-       struct ti_iodelay_device *iod = platform_get_drvdata(pdev);
-
-       ti_iodelay_pinconf_deinit_dev(iod);
-
-       /* Expect other allocations to be freed by devm */
-}
-
 static struct platform_driver ti_iodelay_driver = {
        .probe = ti_iodelay_probe,
-       .remove_new = ti_iodelay_remove,
        .driver = {
                   .name = DRIVER_NAME,
                   .of_match_table = ti_iodelay_of_match,