regulator: da9063: Fix up irq leak
authorAxel Lin <axel.lin@ingics.com>
Sun, 31 May 2015 04:27:38 +0000 (12:27 +0800)
committerMark Brown <broonie@kernel.org>
Tue, 2 Jun 2015 14:38:36 +0000 (15:38 +0100)
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>
drivers/regulator/da9063-regulator.c

index 31c2c59..aed1ad3 100644 (file)
@@ -117,9 +117,6 @@ struct da9063_regulator {
 
 /* Encapsulates all information for the regulators driver */
 struct da9063_regulators {
-       int                                     irq_ldo_lim;
-       int                                     irq_uvov;
-
        unsigned                                n_regulators;
        /* Array size to be defined during init. Keep at end. */
        struct da9063_regulator                 regulator[0];
@@ -867,35 +864,23 @@ static int da9063_regulator_probe(struct platform_device *pdev)
                return irq;
        }
 
-       ret = request_threaded_irq(irq,
+       ret = devm_request_threaded_irq(&pdev->dev, irq,
                                NULL, da9063_ldo_lim_event,
                                IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                "LDO_LIM", regulators);
        if (ret) {
-               dev_err(&pdev->dev,
-                               "Failed to request LDO_LIM IRQ.\n");
-               regulators->irq_ldo_lim = -ENXIO;
+               dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n");
+               return ret;
        }
 
        return 0;
 }
 
-static int da9063_regulator_remove(struct platform_device *pdev)
-{
-       struct da9063_regulators *regulators = platform_get_drvdata(pdev);
-
-       free_irq(regulators->irq_ldo_lim, regulators);
-       free_irq(regulators->irq_uvov, regulators);
-
-       return 0;
-}
-
 static struct platform_driver da9063_regulator_driver = {
        .driver = {
                .name = DA9063_DRVNAME_REGULATORS,
        },
        .probe = da9063_regulator_probe,
-       .remove = da9063_regulator_remove,
 };
 
 static int __init da9063_regulator_init(void)