Commit 485037ae authored by Aidan MacDonald's avatar Aidan MacDonald Committed by Mark Brown

regmap-irq: Fix a bug in regmap_irq_enable() for type_in_mask chips

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: bc998a73 ("regmap: irq: handle HW using separate rising/falling edge interrupts")
Signed-off-by: default avatarAidan MacDonald <aidanmacdonald.0x0@gmail.com>
Link: https://lore.kernel.org/r/20220620200644.1961936-2-aidanmacdonald.0x0@gmail.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2a166929
...@@ -252,6 +252,7 @@ static void regmap_irq_enable(struct irq_data *data) ...@@ -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_irq_chip_data *d = irq_data_get_irq_chip_data(data);
struct regmap *map = d->map; struct regmap *map = d->map;
const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); 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; unsigned int mask, type;
type = irq_data->type.type_falling_val | irq_data->type.type_rising_val; 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) ...@@ -268,14 +269,14 @@ static void regmap_irq_enable(struct irq_data *data)
* at the corresponding offset in regmap_irq_set_type(). * at the corresponding offset in regmap_irq_set_type().
*/ */
if (d->chip->type_in_mask && 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 else
mask = irq_data->mask; mask = irq_data->mask;
if (d->chip->clear_on_unmask) if (d->chip->clear_on_unmask)
d->clear_status = true; 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) static void regmap_irq_disable(struct irq_data *data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment