Messages in this thread Patch in this message | | | From | Yi Zhang <> | Subject | [PATCH v2] regmap: irq: clear status when disable irq | Date | Tue, 15 Oct 2013 20:23:30 +0800 |
| |
clear the status bit if the mask register doesn't prevent the chip level irq from being asserted
OR in the following sequence, there will be irq storm happens: 1) interrupt is triggered; 2) another thread disables it(the mask bit is set); 3) _Then_ the interrupt thread is not ACKed(the status bit is not cleared), and it's ignored; 4) if the irq is still asserted because of the uncleared status bit, the irq storm happens;
Signed-off-by: Yi Zhang <yizhang@marvell.com> --- drivers/base/regmap/regmap-irq.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index d10456f..9b0148f 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -61,7 +61,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data) { struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); struct regmap *map = d->map; - int i, ret; + int i, j, ret, bits_length; u32 reg; if (d->chip->runtime_pm) { @@ -105,6 +105,31 @@ static void regmap_irq_sync_unlock(struct irq_data *data) "Failed to sync wakes in %x: %d\n", reg, ret); } + + if (!d->chip->init_ack_masked) + continue; + /* + * Ack all the masked interrupts uncondictionly, + * OR if there is masked interrupt which hasn't been Acked, + * it'll be ignored in irq handler, then may introduce irq storm + */ + if (d->chip->ack_base) { + reg = d->chip->ack_base + + (i * map->reg_stride * d->irq_reg_stride); + + bits_length = d->map->format.val_bytes * BITS_PER_BYTE; + for (j = 0; j < bits_length; j++) { + if (!(d->mask_buf[i] & (0x1 << j))) { + ret = regmap_update_bits(d->map, reg, + (0x1 << j), 0); + if (ret != 0) + dev_err(d->map->dev, + "Failed to ack 0x%x: %d\n", + reg, ret); + } + } + /* no need to sync status_buf, update in irq handler */ + } } if (d->chip->runtime_pm) -- 1.7.9.5
| |