Message ID | 20220620200644.1961936-16-aidanmacdonald.0x0@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | regmap-irq cleanups and refactoring | expand |
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);
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);
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 --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); }
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(-)