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

regulator: da9063: Fix up irq leak

Current code does not set regulators->irq_ldo_lim and regulators->irq_uvov,
so it actually calls free_irq(0, regulators) twice in remove() but does not
free the irq actually used.

Convert to use devm_request_threaded_irq instead and then we don't need to
take care the clean up irq so remove irq_ldo_lim and irq_uvov from
struct da9063_regulators. Note, regulators->irq_uvov is not used at all in
current code.

There is a slightly change in this patch, it will return error in probe()
if devm_request_threaded_irq fails. If the irq is optional, it should be
fine to allow platform_get_irq_byname fails. But current code does not
allow platform_get_irq_byname fails. So I think the reason to allow
request irq failure is just because the irq leak.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Axel Lin and committed by
Mark Brown
d87aef91 b787f68c

+3 -18
+3 -18
drivers/regulator/da9063-regulator.c
··· 117 117 118 118 /* Encapsulates all information for the regulators driver */ 119 119 struct da9063_regulators { 120 - int irq_ldo_lim; 121 - int irq_uvov; 122 - 123 120 unsigned n_regulators; 124 121 /* Array size to be defined during init. Keep at end. */ 125 122 struct da9063_regulator regulator[0]; ··· 864 867 return irq; 865 868 } 866 869 867 - ret = request_threaded_irq(irq, 870 + ret = devm_request_threaded_irq(&pdev->dev, irq, 868 871 NULL, da9063_ldo_lim_event, 869 872 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 870 873 "LDO_LIM", regulators); 871 874 if (ret) { 872 - dev_err(&pdev->dev, 873 - "Failed to request LDO_LIM IRQ.\n"); 874 - regulators->irq_ldo_lim = -ENXIO; 875 + dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); 876 + return ret; 875 877 } 876 - 877 - return 0; 878 - } 879 - 880 - static int da9063_regulator_remove(struct platform_device *pdev) 881 - { 882 - struct da9063_regulators *regulators = platform_get_drvdata(pdev); 883 - 884 - free_irq(regulators->irq_ldo_lim, regulators); 885 - free_irq(regulators->irq_uvov, regulators); 886 878 887 879 return 0; 888 880 } ··· 881 895 .name = DA9063_DRVNAME_REGULATORS, 882 896 }, 883 897 .probe = da9063_regulator_probe, 884 - .remove = da9063_regulator_remove, 885 898 }; 886 899 887 900 static int __init da9063_regulator_init(void)