Default mask value is used when updating irq registers. Rather than using mask_buf_def[], use mask and value explicitly. (a) remove default mask buffer : mask_buf_def[] (b) add 'val_buf' for storing value of registers : val_buf is updated only when the irq is enabled or disabled (c) In irq_sync_unlock, use 'mask_buf' and 'val_buf' on updating interrupt registers Signed-off-by: Milo(Woogyom) Kim <milo.kim@xxxxxx> --- drivers/base/regmap/regmap-irq.c | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index a897346..ed36ea2 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -34,7 +34,7 @@ struct regmap_irq_chip_data { unsigned int *status_buf; unsigned int *mask_buf; - unsigned int *mask_buf_def; + unsigned int *val_buf; unsigned int *wake_buf; unsigned int irq_reg_stride; @@ -69,7 +69,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) ret = regmap_update_bits(d->map, d->chip->mask_base + (i * map->reg_stride * d->irq_reg_stride), - d->mask_buf_def[i], d->mask_buf[i]); + d->mask_buf[i], d->val_buf[i]); if (ret != 0) dev_err(d->map->dev, "Failed to sync masks in %x\n", d->chip->mask_base + (i * map->reg_stride)); @@ -94,7 +94,7 @@ static void regmap_irq_enable(struct irq_data *data) struct regmap *map = d->map; const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); - d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; + d->val_buf[irq_data->reg_offset / map->reg_stride] &= ~irq_data->mask; } static void regmap_irq_disable(struct irq_data *data) @@ -103,7 +103,7 @@ static void regmap_irq_disable(struct irq_data *data) struct regmap *map = d->map; const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); - d->mask_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; + d->val_buf[irq_data->reg_offset / map->reg_stride] |= irq_data->mask; } static int regmap_irq_set_wake(struct irq_data *data, unsigned int on) @@ -272,9 +272,9 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, if (!d->mask_buf) goto err_alloc; - d->mask_buf_def = kzalloc(sizeof(unsigned int) * chip->num_regs, + d->val_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, GFP_KERNEL); - if (!d->mask_buf_def) + if (!d->val_buf) goto err_alloc; if (chip->wake_base) { @@ -297,12 +297,11 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, mutex_init(&d->lock); for (i = 0; i < chip->num_irqs; i++) - d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] + d->mask_buf[chip->irqs[i].reg_offset / map->reg_stride] |= chip->irqs[i].mask; /* Mask all the interrupts by default */ for (i = 0; i < chip->num_regs; i++) { - d->mask_buf[i] = d->mask_buf_def[i]; ret = regmap_write(map, chip->mask_base + (i * map->reg_stride * d->irq_reg_stride), d->mask_buf[i]); @@ -340,7 +339,7 @@ err_domain: /* Should really dispose of the domain but... */ err_alloc: kfree(d->wake_buf); - kfree(d->mask_buf_def); + kfree(d->val_buf); kfree(d->mask_buf); kfree(d->status_buf); kfree(d); @@ -362,7 +361,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) free_irq(irq, d); /* We should unmap the domain but... */ kfree(d->wake_buf); - kfree(d->mask_buf_def); + kfree(d->val_buf); kfree(d->mask_buf); kfree(d->status_buf); kfree(d); -- 1.7.2.5 Best Regards, Milo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/