|
@@ -56,6 +56,18 @@ static struct cs5535_gpio_chip {
|
|
|
* registers, see include/linux/cs5535.h.
|
|
|
*/
|
|
|
|
|
|
+static void errata_outl(u32 val, unsigned long addr)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * According to the CS5536 errata (#36), after suspend
|
|
|
+ * a write to the high bank GPIO register will clear all
|
|
|
+ * non-selected bits; the recommended workaround is a
|
|
|
+ * read-modify-write operation.
|
|
|
+ */
|
|
|
+ val |= inl(addr);
|
|
|
+ outl(val, addr);
|
|
|
+}
|
|
|
+
|
|
|
static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
|
|
|
unsigned int reg)
|
|
|
{
|
|
@@ -64,7 +76,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
|
|
|
outl(1 << offset, chip->base + reg);
|
|
|
else
|
|
|
/* high bank register */
|
|
|
- outl(1 << (offset - 16), chip->base + 0x80 + reg);
|
|
|
+ errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
|
|
|
}
|
|
|
|
|
|
void cs5535_gpio_set(unsigned offset, unsigned int reg)
|
|
@@ -86,7 +98,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
|
|
|
outl(1 << (offset + 16), chip->base + reg);
|
|
|
else
|
|
|
/* high bank register */
|
|
|
- outl(1 << offset, chip->base + 0x80 + reg);
|
|
|
+ errata_outl(1 << offset, chip->base + 0x80 + reg);
|
|
|
}
|
|
|
|
|
|
void cs5535_gpio_clear(unsigned offset, unsigned int reg)
|