Skip to content

Commit

Permalink
regulator: ab3100: Fix regulator register error handling
Browse files Browse the repository at this point in the history
Ensure to unregister all regulators before return error in probe().

The regulator register order depends on the regulator ID pass to
ab3100_regulator_register() function. Thus we need to scan ab3100_regulator_desc
and find the index of successfully registered regulators, or alternatively just
call ab3100_regulators_remove() to unregister all registered regulators.

Since current code uses a static ab3100_regulators table, explicitly set
reg->rdev = NULL after regulator_unregister() call to ensure calling
ab3100_regulators_remove() in the unwind path always work.

Also move ab3100_regulators_remove() to avoid forward declaration.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Axel Lin authored and Mark Brown committed Apr 26, 2013
1 parent 8735bc2 commit 018fd85
Showing 1 changed file with 19 additions and 14 deletions.
33 changes: 19 additions & 14 deletions drivers/regulator/ab3100.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,19 @@ static const u8 ab3100_reg_initvals[] = {
LDO_D_SETTING,
};

static int ab3100_regulators_remove(struct platform_device *pdev)
{
int i;

for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];

regulator_unregister(reg->rdev);
reg->rdev = NULL;
}
return 0;
}

static int
ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
{
Expand All @@ -635,8 +648,10 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
pdev, NULL, ab3100_regulator_matches[i].init_data,
ab3100_regulator_matches[i].of_node,
(int) ab3100_regulator_matches[i].driver_data);
if (err)
if (err) {
ab3100_regulators_remove(pdev);
return err;
}
}

return 0;
Expand Down Expand Up @@ -695,25 +710,15 @@ static int ab3100_regulators_probe(struct platform_device *pdev)

err = ab3100_regulator_register(pdev, plfdata, NULL, NULL,
desc->id);
if (err)
if (err) {
ab3100_regulators_remove(pdev);
return err;
}
}

return 0;
}

static int ab3100_regulators_remove(struct platform_device *pdev)
{
int i;

for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];

regulator_unregister(reg->rdev);
}
return 0;
}

static struct platform_driver ab3100_regulators_driver = {
.driver = {
.name = "ab3100-regulators",
Expand Down

0 comments on commit 018fd85

Please sign in to comment.