Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: ab3100: Fix regulator register error handling

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>

authored by

Axel Lin and committed by
Mark Brown
018fd856 8735bc2f

+19 -14
+19 -14
drivers/regulator/ab3100.c
··· 609 609 LDO_D_SETTING, 610 610 }; 611 611 612 + static int ab3100_regulators_remove(struct platform_device *pdev) 613 + { 614 + int i; 615 + 616 + for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 617 + struct ab3100_regulator *reg = &ab3100_regulators[i]; 618 + 619 + regulator_unregister(reg->rdev); 620 + reg->rdev = NULL; 621 + } 622 + return 0; 623 + } 624 + 612 625 static int 613 626 ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) 614 627 { ··· 648 635 pdev, NULL, ab3100_regulator_matches[i].init_data, 649 636 ab3100_regulator_matches[i].of_node, 650 637 (int) ab3100_regulator_matches[i].driver_data); 651 - if (err) 638 + if (err) { 639 + ab3100_regulators_remove(pdev); 652 640 return err; 641 + } 653 642 } 654 643 655 644 return 0; ··· 710 695 711 696 err = ab3100_regulator_register(pdev, plfdata, NULL, NULL, 712 697 desc->id); 713 - if (err) 698 + if (err) { 699 + ab3100_regulators_remove(pdev); 714 700 return err; 701 + } 715 702 } 716 703 717 - return 0; 718 - } 719 - 720 - static int ab3100_regulators_remove(struct platform_device *pdev) 721 - { 722 - int i; 723 - 724 - for (i = 0; i < AB3100_NUM_REGULATORS; i++) { 725 - struct ab3100_regulator *reg = &ab3100_regulators[i]; 726 - 727 - regulator_unregister(reg->rdev); 728 - } 729 704 return 0; 730 705 } 731 706