aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAidan MacDonald <aidanmacdonald.0x0@gmail.com>2022-06-20 21:05:56 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-06-29 08:58:47 +0200
commita5ed066bc2461659acbbbaf788a5c327d666e81d (patch)
tree9cd137ddd5a82cc55ab40d35af1266596dbe0b7c
parentice: ethtool: advertise 1000M speeds properly (diff)
downloadwireguard-linux-a5ed066bc2461659acbbbaf788a5c327d666e81d.tar.xz
wireguard-linux-a5ed066bc2461659acbbbaf788a5c327d666e81d.zip
regmap-irq: Fix a bug in regmap_irq_enable() for type_in_mask chips
[ 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>
-rw-r--r--drivers/base/regmap/regmap-irq.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 3d64c9331a82..3c1e554df4eb 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -214,6 +214,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;
@@ -230,14 +231,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)