pinctrl: ti: ti-iodelay: Fix some error handling paths
[ Upstream commita9f2b249ad] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b6c01b4dbe
commit
a69def698a
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user