regmap-irq: Fix a bug in regmap_irq_enable() for type_in_mask chips
authorAidan MacDonald <aidanmacdonald.0x0@gmail.com>
Mon, 20 Jun 2022 20:05:56 +0000 (21:05 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Jun 2022 07:03:25 +0000 (09:03 +0200)
[ Upstream commit 485037ae9a095491beb7f893c909a76cc4f9d1e7 ]

When enabling a type_in_mask irq, the type_buf contents must be
AND'd with the mask of the IRQ we're enabling to avoid enabling
other IRQs by accident, which can happen if several type_in_mask
irqs share a mask register.

Fixes: bc998a730367 ("regmap: irq: handle HW using separate rising/falling edge interrupts")
Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
Link: https://lore.kernel.org/r/20220620200644.1961936-2-aidanmacdonald.0x0@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/base/regmap/regmap-irq.c

index 4a44625..cd12078 100644 (file)
@@ -252,6 +252,7 @@ static void regmap_irq_enable(struct irq_data *data)
        struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
        struct regmap *map = d->map;
        const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
+       unsigned int reg = irq_data->reg_offset / map->reg_stride;
        unsigned int mask, type;
 
        type = irq_data->type.type_falling_val | irq_data->type.type_rising_val;
@@ -268,14 +269,14 @@ static void regmap_irq_enable(struct irq_data *data)
         * at the corresponding offset in regmap_irq_set_type().
         */
        if (d->chip->type_in_mask && type)
-               mask = d->type_buf[irq_data->reg_offset / map->reg_stride];
+               mask = d->type_buf[reg] & irq_data->mask;
        else
                mask = irq_data->mask;
 
        if (d->chip->clear_on_unmask)
                d->clear_status = true;
 
-       d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~mask;
+       d->mask_buf[reg] &= ~mask;
 }
 
 static void regmap_irq_disable(struct irq_data *data)