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: 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>
This commit is contained in:
parent
2a166929bc
commit
485037ae9a
@ -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)
|
|||||||
* 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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user