diff options
Diffstat (limited to 'drivers/base/regmap/regmap-irq.c')
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 369a57e6f89d..ad5c2de395d1 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -168,6 +168,14 @@ static void regmap_irq_sync_unlock(struct irq_data *data) ret = regmap_write(map, reg, ~d->mask_buf[i]); else ret = regmap_write(map, reg, d->mask_buf[i]); + if (d->chip->clear_ack) { + if (d->chip->ack_invert && !ret) + ret = regmap_write(map, reg, + d->mask_buf[i]); + else if (!ret) + ret = regmap_write(map, reg, + ~d->mask_buf[i]); + } if (ret != 0) dev_err(d->map->dev, "Failed to ack 0x%x: %d\n", reg, ret); @@ -493,7 +501,20 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) if (data->status_buf[i] && (chip->ack_base || chip->use_ack)) { reg = chip->ack_base + (i * map->reg_stride * data->irq_reg_stride); - ret = regmap_write(map, reg, data->status_buf[i]); + if (chip->ack_invert) + ret = regmap_write(map, reg, + ~data->status_buf[i]); + else + ret = regmap_write(map, reg, + data->status_buf[i]); + if (chip->clear_ack) { + if (chip->ack_invert && !ret) + ret = regmap_write(map, reg, + data->status_buf[i]); + else if (!ret) + ret = regmap_write(map, reg, + ~data->status_buf[i]); + } if (ret != 0) dev_err(map->dev, "Failed to ack 0x%x: %d\n", reg, ret); @@ -722,6 +743,16 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, else ret = regmap_write(map, reg, d->status_buf[i] & d->mask_buf[i]); + if (chip->clear_ack) { + if (chip->ack_invert && !ret) + ret = regmap_write(map, reg, + (d->status_buf[i] & + d->mask_buf[i])); + else if (!ret) + ret = regmap_write(map, reg, + ~(d->status_buf[i] & + d->mask_buf[i])); + } if (ret != 0) { dev_err(map->dev, "Failed to ack 0x%x: %d\n", reg, ret); |