mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-07 18:05:21 +02:00
pinctrl: ti: ti-iodelay: Fix some error handling paths
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: 003910ebc8
("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>
This commit is contained in:
parent
bebf833d33
commit
a9f2b249ad
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue
Block a user