lkml.org 
[lkml]   [2022]   [Jan]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 1/1] regmap-irq: Use regmap_irq_update_bits instead of regmap_write
Date
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 <quic_pkumpatl@quicinc.com>
---
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
\
 
 \ /
  Last update: 2022-01-17 10:17    [W:0.039 / U:0.112 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site