mfd: arizona: Correctly clean up after IRQs
Currently we leak a lot of things when tearing down the IRQs this patch fixes this cleaning up both the IRQ mappings and the IRQ domain itself. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
This commit is contained in:
parent
1a86dcb3f1
commit
3dfaff274d
|
@ -210,6 +210,7 @@ int arizona_irq_init(struct arizona *arizona)
|
|||
int ret;
|
||||
const struct regmap_irq_chip *aod, *irq;
|
||||
struct irq_data *irq_data;
|
||||
unsigned int virq;
|
||||
|
||||
arizona->ctrlif_error = true;
|
||||
|
||||
|
@ -321,26 +322,34 @@ int arizona_irq_init(struct arizona *arizona)
|
|||
}
|
||||
|
||||
if (aod) {
|
||||
ret = regmap_add_irq_chip(arizona->regmap,
|
||||
irq_create_mapping(arizona->virq,
|
||||
ARIZONA_AOD_IRQ_INDEX),
|
||||
IRQF_ONESHOT, 0, aod,
|
||||
&arizona->aod_irq_chip);
|
||||
virq = irq_create_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX);
|
||||
if (!virq) {
|
||||
dev_err(arizona->dev, "Failed to map AOD IRQs\n");
|
||||
ret = -EINVAL;
|
||||
goto err_domain;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
|
||||
0, aod, &arizona->aod_irq_chip);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev,
|
||||
"Failed to add AOD IRQs: %d\n", ret);
|
||||
goto err;
|
||||
goto err_map_aod;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(arizona->regmap,
|
||||
irq_create_mapping(arizona->virq,
|
||||
ARIZONA_MAIN_IRQ_INDEX),
|
||||
IRQF_ONESHOT, 0, irq,
|
||||
&arizona->irq_chip);
|
||||
virq = irq_create_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX);
|
||||
if (!virq) {
|
||||
dev_err(arizona->dev, "Failed to map main IRQs\n");
|
||||
ret = -EINVAL;
|
||||
goto err_aod;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
|
||||
0, irq, &arizona->irq_chip);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev, "Failed to add main IRQs: %d\n", ret);
|
||||
goto err_aod;
|
||||
goto err_map_main_irq;
|
||||
}
|
||||
|
||||
/* Used to emulate edge trigger and to work around broken pinmux */
|
||||
|
@ -404,26 +413,40 @@ int arizona_irq_init(struct arizona *arizona)
|
|||
regmap_del_irq_chip(irq_find_mapping(arizona->virq,
|
||||
ARIZONA_MAIN_IRQ_INDEX),
|
||||
arizona->irq_chip);
|
||||
err_map_main_irq:
|
||||
irq_dispose_mapping(irq_find_mapping(arizona->virq,
|
||||
ARIZONA_MAIN_IRQ_INDEX));
|
||||
err_aod:
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq,
|
||||
ARIZONA_AOD_IRQ_INDEX),
|
||||
arizona->aod_irq_chip);
|
||||
err_map_aod:
|
||||
irq_dispose_mapping(irq_find_mapping(arizona->virq,
|
||||
ARIZONA_AOD_IRQ_INDEX));
|
||||
err_domain:
|
||||
irq_domain_remove(arizona->virq);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int arizona_irq_exit(struct arizona *arizona)
|
||||
{
|
||||
unsigned int virq;
|
||||
|
||||
if (arizona->ctrlif_error)
|
||||
arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
|
||||
arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
|
||||
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq,
|
||||
ARIZONA_MAIN_IRQ_INDEX),
|
||||
arizona->irq_chip);
|
||||
regmap_del_irq_chip(irq_find_mapping(arizona->virq,
|
||||
ARIZONA_AOD_IRQ_INDEX),
|
||||
arizona->aod_irq_chip);
|
||||
virq = irq_find_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX);
|
||||
regmap_del_irq_chip(virq, arizona->irq_chip);
|
||||
irq_dispose_mapping(virq);
|
||||
|
||||
virq = irq_find_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX);
|
||||
regmap_del_irq_chip(virq, arizona->aod_irq_chip);
|
||||
irq_dispose_mapping(virq);
|
||||
|
||||
irq_domain_remove(arizona->virq);
|
||||
|
||||
free_irq(arizona->irq, arizona);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user