diff mbox series

[15/49] regmap-irq: Change the behavior of mask_writeonly

Message ID 20220620200644.1961936-16-aidanmacdonald.0x0@gmail.com (mailing list archive)
State New, archived
Headers show
Series regmap-irq cleanups and refactoring | expand

Commit Message

Aidan MacDonald June 20, 2022, 8:06 p.m. UTC
No drivers currently use mask_writeonly, and in its current form
it seems a bit misleading. When set, mask registers will be
updated with regmap_write_bits() instead of regmap_update_bits(),
but regmap_write_bits() still does a read-modify-write under the
hood. It's not a write-only operation.

Performing a simple regmap_write() is probably more useful, since
it can be used for chips that have separate set & clear registers
for controlling mask bits. Such registers are normally volatile
and read as 0, so avoiding a register read minimizes bus traffic.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
---
 drivers/base/regmap/regmap-irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Andy Shevchenko June 21, 2022, 9:29 a.m. UTC | #1
On Mon, Jun 20, 2022 at 10:08 PM Aidan MacDonald
<aidanmacdonald.0x0@gmail.com> wrote:
>
> No drivers currently use mask_writeonly, and in its current form
> it seems a bit misleading. When set, mask registers will be
> updated with regmap_write_bits() instead of regmap_update_bits(),
> but regmap_write_bits() still does a read-modify-write under the
> hood. It's not a write-only operation.
>
> Performing a simple regmap_write() is probably more useful, since
> it can be used for chips that have separate set & clear registers
> for controlling mask bits. Such registers are normally volatile
> and read as 0, so avoiding a register read minimizes bus traffic.

Reading your explanations and the code, I would rather think about
fixing the regmap_write_bits() to be writeonly op.

Otherwise it's unclear what's the difference between
regmap_write_bits() vs. regmap_update_bits().

...

>         if (d->chip->mask_writeonly)
> -               return regmap_write_bits(d->map, reg, mask, val);
> +               return regmap_write(d->map, reg, val & mask);
>         else
>                 return regmap_update_bits(d->map, reg, mask, val);
Aidan MacDonald June 21, 2022, 9:13 p.m. UTC | #2
Andy Shevchenko <andy.shevchenko@gmail.com> writes:

> On Mon, Jun 20, 2022 at 10:08 PM Aidan MacDonald
> <aidanmacdonald.0x0@gmail.com> wrote:
>>
>> No drivers currently use mask_writeonly, and in its current form
>> it seems a bit misleading. When set, mask registers will be
>> updated with regmap_write_bits() instead of regmap_update_bits(),
>> but regmap_write_bits() still does a read-modify-write under the
>> hood. It's not a write-only operation.
>>
>> Performing a simple regmap_write() is probably more useful, since
>> it can be used for chips that have separate set & clear registers
>> for controlling mask bits. Such registers are normally volatile
>> and read as 0, so avoiding a register read minimizes bus traffic.
>
> Reading your explanations and the code, I would rather think about
> fixing the regmap_write_bits() to be writeonly op.

That's impossible without special hardware support.

> Otherwise it's unclear what's the difference between
> regmap_write_bits() vs. regmap_update_bits().

This was not obvious to me either. They're the same except in how they
issue the low-level write op -- regmap_update_bits() will only do the
write if the new value differs from the current one. regmap_write_bits()
will always do a write, even if the new value is the same.

I think the problem is lack of documentation. I only figured this out
by reading the implementation.

>>         if (d->chip->mask_writeonly)
>> -               return regmap_write_bits(d->map, reg, mask, val);
>> +               return regmap_write(d->map, reg, val & mask);
>>         else
>>                 return regmap_update_bits(d->map, reg, mask, val);
Andy Shevchenko June 21, 2022, 10:42 p.m. UTC | #3
On Tuesday, June 21, 2022, Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
wrote:

>
> Andy Shevchenko <andy.shevchenko@gmail.com> writes:
>
> > On Mon, Jun 20, 2022 at 10:08 PM Aidan MacDonald
> > <aidanmacdonald.0x0@gmail.com> wrote:
> >>
> >> No drivers currently use mask_writeonly, and in its current form
> >> it seems a bit misleading. When set, mask registers will be
> >> updated with regmap_write_bits() instead of regmap_update_bits(),
> >> but regmap_write_bits() still does a read-modify-write under the
> >> hood. It's not a write-only operation.
> >>
> >> Performing a simple regmap_write() is probably more useful, since
> >> it can be used for chips that have separate set & clear registers
> >> for controlling mask bits. Such registers are normally volatile
> >> and read as 0, so avoiding a register read minimizes bus traffic.
> >
> > Reading your explanations and the code, I would rather think about
> > fixing the regmap_write_bits() to be writeonly op.
>
> That's impossible without special hardware support.
>
> > Otherwise it's unclear what's the difference between
> > regmap_write_bits() vs. regmap_update_bits().
>
> This was not obvious to me either. They're the same except in how they
> issue the low-level write op -- regmap_update_bits() will only do the
> write if the new value differs from the current one. regmap_write_bits()
> will always do a write, even if the new value is the same.


Okay, it makes a lot of sense for W1C type of bits in the register. Also,
“reading” might imply to restore last value from cache, no?


>
> I think the problem is lack of documentation. I only figured this out
> by reading the implementation.
>
> >>         if (d->chip->mask_writeonly)
> >> -               return regmap_write_bits(d->map, reg, mask, val);
> >> +               return regmap_write(d->map, reg, val & mask);
> >>         else
> >>                 return regmap_update_bits(d->map, reg, mask, val);
>
diff mbox series

Patch

diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index dd22d13c54c8..4c0d7f7aa544 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -84,7 +84,7 @@  static int regmap_irq_update_bits(struct regmap_irq_chip_data *d,
 				  unsigned int val)
 {
 	if (d->chip->mask_writeonly)
-		return regmap_write_bits(d->map, reg, mask, val);
+		return regmap_write(d->map, reg, val & mask);
 	else
 		return regmap_update_bits(d->map, reg, mask, val);
 }