regmap-irq: Fix inverted handling of unmask registers
authorAidan MacDonald <aidanmacdonald.0x0@gmail.com>
Thu, 23 Jun 2022 21:14:18 +0000 (22:14 +0100)
committerMark Brown <broonie@kernel.org>
Wed, 29 Jun 2022 17:13:15 +0000 (18:13 +0100)
commite8ffb12e7f065db616a3eba79ff138bececf0825
tree2083afe8534172480753d78da201829fbc69bb61
parent9edd4f5aee8470dcfd0db04005908f61fbfae8e0
regmap-irq: Fix inverted handling of unmask registers

To me "unmask" suggests that we write 1s to the register when
an interrupt is enabled. This also makes sense because it's the
opposite of what the "mask" register does (write 1s to disable
an interrupt).

But regmap-irq does the opposite: for a disabled interrupt, it
writes 1s to "unmask" and 0s to "mask". This is surprising and
deviates from the usual way mask registers are handled.

Additionally, mask_invert didn't interact with unmask registers
properly -- it caused them to be ignored entirely.

Fix this by making mask and unmask registers orthogonal, using
the following behavior:

* Mask registers are written with 1s for disabled interrupts.
* Unmask registers are written with 1s for enabled interrupts.

This behavior supports both normal or inverted mask registers
and separate set/clear registers via different combinations of
mask_base/unmask_base.

The old unmask register behavior is deprecated. Drivers need to
opt-in to the new behavior by setting mask_unmask_non_inverted.
Warnings are issued if the driver relies on deprecated behavior.
Chips that only set one of mask_base/unmask_base don't have to
use the mask_unmask_non_inverted flag because that use case was
previously not supported.

The mask_invert flag is also deprecated in favor of describing
inverted mask registers as unmask registers.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
Link: https://lore.kernel.org/r/20220623211420.918875-11-aidanmacdonald.0x0@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/base/regmap/regmap-irq.c
include/linux/regmap.h