drivers: gpio: mcux_igpio: serialize DR and GDIR read-modify-writes
The port writers update the data register with an unlocked read-modify-
write. port_set_masked_raw() reads and writes DR directly, and on parts
without the DR_SET/DR_CLEAR/DR_TOGGLE aliases the HAL degrades
GPIO_PortSet/Clear/Toggle() to "DR |= mask" and friends. Pin
configuration is affected too: GPIO_PinWrite() falls back the same way,
and the GDIR update is a read-modify-write on every part.
Two contexts touching different pins of the same port therefore race:
each reads the register, changes its own bits and writes the whole value
back, so the last writer reverts the other's pin.
Serialize the accesses with a spinlock, which unlike irq_lock() also
covers a concurrent write from another CPU on an SMP build. The lock
cannot be limited to the parts that lack the set/clear aliases, because
port_set_masked_raw() read-modify-writes DR everywhere: an atomic DR_SET
from another context would still be clobbered by it.
While here, use GPIO_PinWrite() instead of the deprecated
GPIO_WritePinOutput() wrapper.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Marvin Gnad <marvin.gnad@gmail.com>
1 file changed