Re: [PATCH] regmap: move readable check before accessing regcache.

From: Mark Brown
Date: Fri Jun 18 2021 - 11:49:02 EST


On Fri, Jun 18, 2021 at 01:29:50PM +0100, Srinivas Kandagatla wrote:
> On 18/06/2021 12:51, Mark Brown wrote:

> > Why will use of regmap_update_bits() mean that a driver will never
> > notice a write failure? Shouldn't remgap_update_bits() be fixed to
> > report any errors it isn't reporting, or the driver fixed to check

> usecase is performing regmap_update_bits() on a *write-only* registers.

> _regmap_update_bits() checks _regmap_read() return value before bailing out.
> In non cache path we have this regmap_readable() check however in cached
> patch we do not have this check, so _regmap_read() will return success in
> this case so regmap_update_bits() never reports any error.

> driver in question does check the return value.

OK, so everything is working fine then - what's the problem? The value
in the register is cached, the read returns that cached value and then
the relevant bits are updated and the new value written out to both the
cache and the hardware. No part of that sounds like a problem to me.

> > error codes? I really don't understand the issue you're trying to
> > report - what is "the right thing" and what makes you believe that a
> > driver can't do an _update_bits() on a write only but cached register?
> > Can you specify in concrete terms what the problem is.

> So one of recent patch ("ASoC: qcom: Fix for DMA interrupt clear reg
> overwriting) https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?h=next-20210618&id=da0363f7bfd3c32f8d5918e40bfddb9905c86ee1
>
> broke audio on DragonBoard 410c.

> This patch simply converts writes to regmap_update_bits for that particular
> dma channel. The register that its updating is IRQ_CLEAR register which is
> software "WRITE-ONLY" and Hardware read-only register.

So the driver is buggy then, the register is clearly volatile and can't
be cached, and it sounds like it's unsafe to use _update_bits() on it.
The register is clearly not write only since it can be read and it's
volatile since the readback value does not reflect what was written (and
presumably can change),. Even without that it's buggy to use
_update_bits() here since the device needs the write to happen
regardless of the value that is read back, with the register marked as
volatile that will still potentially fail if the readback value happens
to be the same as whatever bits the driver is trying to set.

Your description of the register is being "software write only" and
"hardware read only" should be a warning sign here, think about what
that might mean for a minute.

> The bits in particular case is updating is a period interrupt clear bit.

> Because we are using regmap cache in this driver,

> first regmap_update_bits(map, 0x1, 0x1) on first period interrupt will
> update the cache and write to IRQ_CLEAR hardware register which then clears
> the interrupt latch.
> On second period interrupt we do regmap_update_bits(map, 0x1, 0x1) with the
> same bits, Because we are using cache for this regmap caches sees no change
> in the cache value vs the new value so it will never write/update IRQ_CLEAR
> hardware register, so hardware is stuck here waiting for IRQ_CLEAR write
> from driver and audio keeps repeating the last period.

This is because the register is volatile and we can't cache the written
value, it is a driver bug. If the value in the register does not change
from the value written unexpectedly then the register can be cached and
there is no problem but that's not the case here.

Attachment: signature.asc
Description: PGP signature