Commit 44658a11 authored by Andres Salomon's avatar Andres Salomon Committed by Linus Torvalds

cs5535-gpio: handle GPIO regs where higher (clear) bits are set

The default for non-READ_BACK GPIO regs is to have the clear bits set;
this means that our original errata fix was too simplistic.  This
changes it to the following behavior:

 - when setting GPIOs, ignore the higher order bits (they're for
   clearing, we don't need to care about them).

 - when clearing GPIOs, keep all the bits, but unset (via XOR) the
   lower order bit that negates the clear bit that we care about.  That
   is, if we're clearing GPIO 26 (val = 0x04000000), we first XOR what's
   currently in the register with 0x0400 (GPIO 26's SET bit), and then
   OR that with the GPIO 26's CLEAR bit.
Tested-by: default avatarDaniel Drake <dsd@laptop.org>
Signed-off-by: default avatarAndres Salomon <dilinger@queued.net>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 00185165
...@@ -70,8 +70,12 @@ static void errata_outl(struct cs5535_gpio_chip *chip, u32 val, ...@@ -70,8 +70,12 @@ static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
* Don't apply this errata to the edge status GPIOs, as writing * Don't apply this errata to the edge status GPIOs, as writing
* to their lower bits will clear them. * to their lower bits will clear them.
*/ */
if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
val |= inl(addr); if (val & 0xffff)
val |= (inl(addr) & 0xffff); /* ignore the high bits */
else
val |= (inl(addr) ^ (val >> 16));
}
outl(val, addr); outl(val, addr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment