2022-01-17 17:03:41

by Prasad Kumpatla

[permalink] [raw]
Subject: [PATCH 1/1] regmap-irq: Use regmap_irq_update_bits instead of regmap_write

With the existing interrupt ack and clear ack logic, only the first
interrupt gets processed properly and further interrupts will not as
the ack register is not reset as expected. Use regmap_irq_update_bits
to update the required bits instead of regmap_write to fix the ack and
clear ack sequence.

Fixes: 3a6f0fb7b8eb ("regmap: irq: Add support to clear ack registers")
Signed-off-by: Prasad Kumpatla <[email protected]>
---
drivers/base/regmap/regmap-irq.c | 52 ++++++++++++++++++--------------
1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index d2656581a608..bb9d07960dd0 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -184,16 +184,18 @@ static void regmap_irq_sync_unlock(struct irq_data *data)

/* some chips ack by write 0 */
if (d->chip->ack_invert)
- ret = regmap_write(map, reg, ~d->mask_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ d->mask_buf[i], 0x00);
else
- ret = regmap_write(map, reg, d->mask_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ d->mask_buf[i], d->mask_buf[i]);
if (d->chip->clear_ack) {
if (d->chip->ack_invert && !ret)
- ret = regmap_write(map, reg,
- d->mask_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ d->mask_buf[i], d->mask_buf[i]);
else if (!ret)
- ret = regmap_write(map, reg,
- ~d->mask_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ d->mask_buf[i], 0x00);
}
if (ret != 0)
dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
@@ -549,18 +551,20 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
reg = sub_irq_reg(data, data->chip->ack_base, i);

if (chip->ack_invert)
- ret = regmap_write(map, reg,
- ~data->status_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ data->status_buf[i], 0x00);
else
- ret = regmap_write(map, reg,
+ ret = regmap_irq_update_bits(d, reg,
+ data->status_buf[i],
data->status_buf[i]);
if (chip->clear_ack) {
if (chip->ack_invert && !ret)
- ret = regmap_write(map, reg,
- data->status_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ data->status_buf[i],
+ data->status_buf[i]);
else if (!ret)
- ret = regmap_write(map, reg,
- ~data->status_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ data->status_buf[i], 0x00);
}
if (ret != 0)
dev_err(map->dev, "Failed to ack 0x%x: %d\n",
@@ -810,20 +814,22 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
if (d->status_buf[i] && (chip->ack_base || chip->use_ack)) {
reg = sub_irq_reg(d, d->chip->ack_base, i);
if (chip->ack_invert)
- ret = regmap_write(map, reg,
- ~(d->status_buf[i] & d->mask_buf[i]));
+ ret = regmap_irq_update_bits(d, reg,
+ (d->status_buf[i] & d->mask_buf[i]),
+ 0x00);
else
- ret = regmap_write(map, reg,
- d->status_buf[i] & d->mask_buf[i]);
+ ret = regmap_irq_update_bits(d, reg,
+ (d->status_buf[i] & d->mask_buf[i]),
+ (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]));
+ ret = regmap_irq_update_bits(d, reg,
+ (d->status_buf[i] & d->mask_buf[i]),
+ (d->status_buf[i] & d->mask_buf[i]));
else if (!ret)
- ret = regmap_write(map, reg,
- ~(d->status_buf[i] &
- d->mask_buf[i]));
+ ret = regmap_irq_update_bits(d, reg,
+ (d->status_buf[i] & d->mask_buf[i]),
+ 0x00);
}
if (ret != 0) {
dev_err(map->dev, "Failed to ack 0x%x: %d\n",
--
2.17.1


2022-01-20 19:15:38

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 1/1] regmap-irq: Use regmap_irq_update_bits instead of regmap_write

On Mon, Jan 17, 2022 at 02:46:21PM +0530, Prasad Kumpatla wrote:
> With the existing interrupt ack and clear ack logic, only the first
> interrupt gets processed properly and further interrupts will not as
> the ack register is not reset as expected. Use regmap_irq_update_bits

In what way is only the first interrupt processed properly? How is the
ack register not reset as expected? Please write a clearer changelog -
I can't tell what problem you're trying to fix here or how the change is
intended to fix it.


Attachments:
(No filename) (525.00 B)
signature.asc (499.00 B)
Download all attachments