# Base git commit: a188339ca5a3
# (Linux 5.2-rc1)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: irq_startup() must not return error codes
# 
#   The irq_startup() method returns an unsigned int, but in __irq_startup()
#   it is assigned to an int.  However, nothing checks for errors, so any
#   error that is returned is ignored.
# 
#   Remove the check for GPIO-input mode and the error return.
# 
#   Signed-off-by: Russell King
# 
#   02f32d78c8ead67f19791cfdeb5a8d8af6c8a7a1
#    drivers/gpio/gpio-omap.c | 5 -----
#    1 file changed, 5 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: clean up wakeup handling
# 
#   Signed-off-by: Russell King
# 
#   c4136c5d2163d13a5fc33d638cc46d0f0302dd30
#    drivers/gpio/gpio-omap.c | 36 +++++++++++++-----------------------
#    1 file changed, 13 insertions(+), 23 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: constify register tables
# 
#   We must never alter the register tables; these are read-only as far
#   as the driver is concerned.  Constify these tables.
# 
#   Signed-off-by: Russell King
# 
#   133c4d8b1a053d663d99ad3efd0a71d2b4840ef1
#    drivers/gpio/gpio-omap.c                | 12 ++++++------
#    include/linux/platform_data/gpio-omap.h |  2 +-
#    2 files changed, 7 insertions(+), 7 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: simplify omap_set_gpio_irqenable()
# 
#   omap_set_gpio_irqenable() calls two helpers that are almost the same
#   apart from whether they set or clear bits. We can consolidate these:
# 
#   - in the set/clear bit register case, we can perform the operation on
#     our saved context copy and write the appropriate set/clear register.
#   - otherwise, we can use our read-modify-write helper and invert enable
#     if irqenable_inv is set.
# 
#   Signed-off-by: Russell King
# 
#   7c6ed0362dcac2f61858455ac28b1c0abd90f51c
#    drivers/gpio/gpio-omap.c | 61 ++++++++++++------------------------------------
#    1 file changed, 15 insertions(+), 46 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: simplify omap_toggle_gpio_edge_triggering()
# 
#   This function open-codes an exclusive-or bitwise operation using an
#   if() statement and explicitly setting or clearing the bit. Instead,
#   use an exclusive-or operation instead, and simplify the function.
# 
#   We can combine the preprocessor conditional using IS_ENABLED() and
#   gain some additional compilation coverage.
# 
#   Signed-off-by: Russell King
# 
#   3069fa88d8141c4ed005ebcb115836819f91772c
#    drivers/gpio/gpio-omap.c | 22 ++++------------------
#    1 file changed, 4 insertions(+), 18 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: simplify bank->level_mask
# 
#   bank->level_mask is merely the bitwise or of the level detection
#   context which we have already read in this function.  Rather than
#   repeating additional reads, compute it from the values already
#   read.
# 
#   Signed-off-by: Russell King
# 
#   6980ef154cd0ea3202239e9db22d55b2ee38d5a1
#    drivers/gpio/gpio-omap.c | 7 +++----
#    1 file changed, 3 insertions(+), 4 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: simplify omap_gpio_get_direction()
# 
#   Architectures are single-copy atomic, which means that simply reading
#   a register is an inherently atomic operation.  There is no need to
#   take a spinlock here.
# 
#   Signed-off-by: Russell King
# 
#   8f43e1e03cccec98e24d2769d00e0d48122bf711
#    drivers/gpio/gpio-omap.c | 13 +++----------
#    1 file changed, 3 insertions(+), 10 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: move omap_gpio_request() and omap_gpio_free()
# 
#   Move these two functions to live beside the rest of the gpio chip
#   implementation, rather than in the middle of the irq chip
#   implementation.
# 
#   Signed-off-by: Russell King
# 
#   516d19dc7c6e8690bb97da5273fa288cab2eeccb
#    drivers/gpio/gpio-omap.c | 64 ++++++++++++++++++++++++------------------------
#    1 file changed, 32 insertions(+), 32 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: remove remainder of list management
# 
#   Commit c4791bc6e3a6 ("gpio: omap: drop omap_gpio_list") removed the
#   list head and addition to the list head of each gpio bank, but failed
#   to remove the list_del() call and the node inside struct gpio_bank.
#   Remove these too.
# 
#   Fixes: c4791bc6e3a6 ("gpio: omap: drop omap_gpio_list")
#   Signed-off-by: Russell King
# 
#   e3aae00e78a0578862ca5c31caf450b70f051bca
#    drivers/gpio/gpio-omap.c | 2 --
#    1 file changed, 2 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: fix debounce configuration
# 
#   There are several issues with the debounce configuration:
#   1. when we unidle, having potentially lost all context, we configure the
#      debounce enables with the debounce time set to minimum.  Only later
#      do we configure the debounce time (in omap_gpio_restore_context()).
#      This leaves a window for undebounced transitions to be detected.
# 
#   2. if a gpio is configured for debounce, and omap_gpio_set_config() is
#      called for a different gpio in the same bank to disable debounce,
#      we clear the debounce time, setting it to minimum.
# 
#   3. we potentially glitch the slow debounce clock during initial setup
#      with an enable-disable-enable transition.
# 
#   Work around all these by tracking the desired debounce state and the
#   real hardware state, updating the registers when something changes.
# 
#   Signed-off-by: Russell King
# 
#   87e3c61de9c1202ff9b0c960cb617e9374179e28
#    drivers/gpio/gpio-omap.c | 119 +++++++++++++++++++++++------------------------
#    1 file changed, 57 insertions(+), 62 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: clean up register access in omap2_set_gpio_debounce()
# 
#   Signed-off-by: Russell King
# 
#   33e9bccbfbd94f0c0a8d72cbf1029204a40c0e6e
#    drivers/gpio/gpio-omap.c | 4 +---
#    1 file changed, 1 insertion(+), 3 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: clean up omap_gpio_restore_context()
# 
#   Use local variables to store the base iomem address and regs table
#   pointer like omap_gpio_init_context() does. Not only does this make
#   the function neater, it also avoids unnecessary reloads of the same
#   data multiple times.
# 
#   Signed-off-by: Russell King
# 
#   ecf2c201a9d0f95a81189e8a3b277e6823050efe
#    drivers/gpio/gpio-omap.c | 36 +++++++++++++++---------------------
#    1 file changed, 15 insertions(+), 21 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: remove dataout variation in context handling
# 
#   When a GPIO block has the set/clear dataout registers implemented, it
#   also has the normal dataout register implemented. Reading this register
#   reads the current GPIO output state, and writing it sets the GPIOs to
#   the explicit state. This is the behaviour that we want when saving and
#   restoring the context, so use the dataout register exclusively.
# 
#   Signed-off-by: Russell King
# 
#   c755c8c97ae15b16f4e542ddf8f588085562c99a
#    drivers/gpio/gpio-omap.c | 12 ++----------
#    1 file changed, 2 insertions(+), 10 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:06 BST 2019)
# 
#   gpio: gpio-omap: simplify read-modify-write
# 
#   We already have a read-modify-write helper, but there's more that can
#   be done with a read-modify-write helper if it returned the new value.
#   Modify the existing helper to return the new value, and arrange for
#   it to take one less argument by having the caller compute the register
#   address.
# 
#   Signed-off-by: Russell King
# 
#   fac88b2559f308ac1babca6e81142319fd02f31e
#    drivers/gpio/gpio-omap.c | 83 +++++++++++++++++-------------------------------
#    1 file changed, 30 insertions(+), 53 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:42:02 BST 2019)
# 
#   gpio: gpio-omap: simplify and fix set_multiple()
# 
#   One of the reasons for set_multiple() to exist is to allow multiple
#   GPIOs on the same chip to be changed simultaneously - see commit
#   5f42424354f5 ("gpiolib: allow simultaneous setting of multiple GPIO
#   outputs"):
# 
#    - Simultaneous glitch-free setting of multiple pins on any kind of
#      parallel bus attached to GPIOs provided they all reside on the
#      same chip and bank.
# 
#   In order for this to work, we should not use the atomic set/clear
#   registers, but instead read-modify-write the dataout register.  We
#   already take the spinlock to ensure that happens atomically, so
#   move the code into the set_multiple() function and kill the two
#   helper functions.
# 
#   Signed-off-by: Russell King
# 
#   98fc526a30255cbbfe694b173fc4d7862f8fa0c1
#    drivers/gpio/gpio-omap.c | 45 +++++++--------------------------------------
#    1 file changed, 7 insertions(+), 38 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:21:41 BST 2019)
# 
#   gpio: gpio-omap: simplify get_multiple()
# 
#   There is no reason to have helper functions to read the datain and
#   dataout registers when they are only used in one location.  Simplify
#   this code to make it more readable.
# 
#   Signed-off-by: Russell King
# 
#   b0617cbc4744c41d05b82d274e3d3e668c382817
#    drivers/gpio/gpio-omap.c | 36 +++++++++++-------------------------
#    1 file changed, 11 insertions(+), 25 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:21:41 BST 2019)
# 
#   gpio: gpio-omap: simplify get() method
# 
#   omap_gpio_get() calls omap_get_gpio_datain() or omap_get_gpio_dataout()
#   to read the GPIO state. These two functions are only called from this
#   method, so they don't add much value.  Move their contents into
#   omap_gpio_get() method and simplify.
# 
#   Signed-off-by: Russell King
# 
#   5d4b5ad24e0e386fe810f908d58c17fd6e6c09e6
#    drivers/gpio/gpio-omap.c | 25 ++++++-------------------
#    1 file changed, 6 insertions(+), 19 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:21:11 BST 2019)
# 
#   gpio: gpio-omap: ensure irq is enabled before wakeup
# 
#   Documentation states:
# 
#     NOTE: There must be a correlation between the wake-up enable and
#     interrupt-enable registers. If a GPIO pin has a wake-up configured
#     on it, it must also have the corresponding interrupt enabled (on
#     one of the two interrupt lines).
# 
#   Ensure that this condition is always satisfied by enabling the detection
#   events after enabling the interrupt, and disabling the detection before
#   disabling the interrupt.  This ensures interrupt/wakeup events can not
#   happen until both the wakeup and interrupt enables correlate.
# 
#   If we do any clearing, clear between the interrupt enable/disable and
#   trigger setting.
# 
#   Signed-off-by: Russell King
# 
#   4dcbc09308389ce6e9c58630ffb2efe1f19e4e45
#    drivers/gpio/gpio-omap.c | 15 ++++++++-------
#    1 file changed, 8 insertions(+), 7 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:21:11 BST 2019)
# 
#   gpio: gpio-omap: avoid unnecessary IRQ clearance
# 
#   The irq_ack method does not fit our hardware requirements. Edge
#   interrupts must be cleared before we handle them, and level interrupts
#   must be cleared after handling them.
# 
#   We already handle the interrupt clearance in our interrupt dispatch
#   handler for edge IRQs and in the unmask method for level IRQs.
# 
#   In any case, it has been observed that clearing interrupts after they
#   have been disabled causes wakeups to get stuck, so this patch in part
#   fixes that issue.
# 
#   Replace the irq_ack method with the no-op method from the dummy irq
#   chip.
# 
#   Signed-off-by: Russell King
# 
#   6801e7776ee0215e6a8d62e04d931b14fb24158d
#    drivers/gpio/gpio-omap.c | 17 +++--------------
#    1 file changed, 3 insertions(+), 14 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 12:19:44 BST 2019)
# 
#   gpio: gpio-omap: clean up edge interrupt handling
# 
#   The edge interrupt handling was effectively:
# 
#   	isr = ISR_reg & enabled;
#   	if (bank->level_mask)
#   		level_mask = bank->level_mask & enabled;
#   	else
#   		level_mask = 0;
# 
#   	edge = isr & ~level_mask;
# 
#   When bank->level_mask is zero, level_mask will be computed as zero
#   anyway, so the if() statement is redundant.  We are then left with:
# 
#   	isr = ISR_reg & enabled;
#   	level_mask = bank->level_mask & enabled;
#   	edge = isr & ~level_mask;
# 
#   This can be simplified further to:
# 
#   	isr = ISR_reg & enabled;
#   	edge = isr & ~bank->level_mask;
# 
#   since the second mask with 'enabled' is redundant.
# 
#   Improve the associated comment as well.
# 
#   This makes it obvious what this convoluted code is trying to do, which
#   is to clear pending edge interrupts.
# 
#   Signed-off-by: Russell King
# 
#   c284b6aa3dafece0984fe8b931c554f1335cc632
#    drivers/gpio/gpio-omap.c | 20 +++++++++-----------
#    1 file changed, 9 insertions(+), 11 deletions(-)
# 
# Author:    Russell King (Fri 14 Dec 14:46:58 GMT 2018)
# Committer: Russell King (Tue 21 May 11:05:55 BST 2019)
# 
#   gpio: gpio-omap: fix lack of irqstatus_raw0 for OMAP4
# 
#   Commit 384ebe1c2849 ("gpio/omap: Add DT support to GPIO driver") added
#   the register definition tables to the gpio-omap driver. Subsequently to
#   that commit, commit 4e962e8998cc ("gpio/omap: remove cpu_is_omapxxxx()
#   checks from *_runtime_resume()") added definitions for irqstatus_raw*
#   registers to the legacy OMAP4 definitions, but missed the DT
#   definitions.
# 
#   This causes an unintentional change of behaviour for the 1.101 errata
#   workaround on OMAP4 platforms. Fix this oversight.
# 
#   Fixes: 4e962e8998cc ("gpio/omap: remove cpu_is_omapxxxx() checks from *_runtime_resume()")
#   Signed-off-by: Russell King
# 
#   62b5ad85d836c3a34fb9100f337c14f616a6b0f0
#    drivers/gpio/gpio-omap.c | 2 ++
#    1 file changed, 2 insertions(+)
# 
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 16289bafa001..1cbb7dbecff0 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -47,8 +47,9 @@ struct gpio_regs {
 };
 
 struct gpio_bank {
-	struct list_head node;
 	void __iomem *base;
+	const struct omap_gpio_reg_offs *regs;
+
 	int irq;
 	u32 non_wakeup_gpios;
 	u32 enabled_non_wakeup_gpios;
@@ -64,8 +65,8 @@ struct gpio_bank {
 	unsigned int is_suspended:1;
 	u32 mod_usage;
 	u32 irq_usage;
-	u32 dbck_enable_mask;
-	bool dbck_enabled;
+	u32 desired_debounce_en;
+	u32 desired_debounce;
 	bool is_mpuio;
 	bool dbck_flag;
 	bool loses_context;
@@ -75,11 +76,7 @@ struct gpio_bank {
 	int context_loss_count;
 
 	void (*set_dataout)(struct gpio_bank *bank, unsigned gpio, int enable);
-	void (*set_dataout_multiple)(struct gpio_bank *bank,
-				     unsigned long *mask, unsigned long *bits);
 	int (*get_context_loss_count)(struct device *dev);
-
-	struct omap_gpio_reg_offs *regs;
 };
 
 #define GPIO_MOD_CTRL_BIT	BIT(0)
@@ -95,20 +92,25 @@ static inline struct gpio_bank *omap_irq_data_get_bank(struct irq_data *d)
 	return gpiochip_get_data(chip);
 }
 
-static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio,
-				    int is_input)
+static inline u32 omap_gpio_rmw(void __iomem *reg, u32 mask, bool set)
 {
-	void __iomem *reg = bank->base;
-	u32 l;
+	u32 val = readl_relaxed(reg);
 
-	reg += bank->regs->direction;
-	l = readl_relaxed(reg);
-	if (is_input)
-		l |= BIT(gpio);
+	if (set)
+		val |= mask;
 	else
-		l &= ~(BIT(gpio));
-	writel_relaxed(l, reg);
-	bank->context.oe = l;
+		val &= ~mask;
+
+	writel_relaxed(val, reg);
+
+	return val;
+}
+
+static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio,
+				    int is_input)
+{
+	bank->context.oe = omap_gpio_rmw(bank->base + bank->regs->direction,
+					 BIT(gpio), is_input);
 }
 
 
@@ -134,113 +136,64 @@ static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, unsigned offset,
 static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, unsigned offset,
 				       int enable)
 {
-	void __iomem *reg = bank->base + bank->regs->dataout;
-	u32 gpio_bit = BIT(offset);
-	u32 l;
-
-	l = readl_relaxed(reg);
-	if (enable)
-		l |= gpio_bit;
-	else
-		l &= ~gpio_bit;
-	writel_relaxed(l, reg);
-	bank->context.dataout = l;
-}
-
-static int omap_get_gpio_datain(struct gpio_bank *bank, int offset)
-{
-	void __iomem *reg = bank->base + bank->regs->datain;
-
-	return (readl_relaxed(reg) & (BIT(offset))) != 0;
-}
-
-static int omap_get_gpio_dataout(struct gpio_bank *bank, int offset)
-{
-	void __iomem *reg = bank->base + bank->regs->dataout;
-
-	return (readl_relaxed(reg) & (BIT(offset))) != 0;
-}
-
-/* set multiple data out values using dedicate set/clear register */
-static void omap_set_gpio_dataout_reg_multiple(struct gpio_bank *bank,
-					       unsigned long *mask,
-					       unsigned long *bits)
-{
-	void __iomem *reg = bank->base;
-	u32 l;
-
-	l = *bits & *mask;
-	writel_relaxed(l, reg + bank->regs->set_dataout);
-	bank->context.dataout |= l;
-
-	l = ~*bits & *mask;
-	writel_relaxed(l, reg + bank->regs->clr_dataout);
-	bank->context.dataout &= ~l;
+	bank->context.dataout = omap_gpio_rmw(bank->base + bank->regs->dataout,
+					      BIT(offset), enable);
 }
 
-/* set multiple data out values using mask register */
-static void omap_set_gpio_dataout_mask_multiple(struct gpio_bank *bank,
-						unsigned long *mask,
-						unsigned long *bits)
-{
-	void __iomem *reg = bank->base + bank->regs->dataout;
-	u32 l = (readl_relaxed(reg) & ~*mask) | (*bits & *mask);
-
-	writel_relaxed(l, reg);
-	bank->context.dataout = l;
-}
-
-static unsigned long omap_get_gpio_datain_multiple(struct gpio_bank *bank,
-					      unsigned long *mask)
-{
-	void __iomem *reg = bank->base + bank->regs->datain;
-
-	return readl_relaxed(reg) & *mask;
-}
-
-static unsigned long omap_get_gpio_dataout_multiple(struct gpio_bank *bank,
-					       unsigned long *mask)
-{
-	void __iomem *reg = bank->base + bank->regs->dataout;
-
-	return readl_relaxed(reg) & *mask;
-}
-
-static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
+/*
+ * omap_gpio_dbck_update() is the primary manager of the debounce clock.
+ * We implicitly track the state using bank->context.debounce_en, which
+ * reflects the setting of the debounce enable register.
+ *
+ * When bank->context.debounce_en is zero, it means the clock is shut
+ * off, so if we have a non-zero desired_debounce_en, it means we are
+ * wanting to enable the clock and program the debounce.
+ *
+ * If bank->context.debounce_en is non-zero, it means the clock is
+ * currently enabled.  If we have a zero desired_debounce_en, it means
+ * we're wanting to disable debounce and shut off the debounce clock.
+ *
+ * The only other function that is allowed to change context.debounce_en
+ * and the state of the debounce clock is omap_gpio_dbck_disable()
+ * which also follows this rule.
+ */
+static inline void omap_gpio_dbck_update(struct gpio_bank *bank)
 {
-	int l = readl_relaxed(base + reg);
-
-	if (set)
-		l |= mask;
-	else
-		l &= ~mask;
-
-	writel_relaxed(l, base + reg);
-}
+	void __iomem *base = bank->base;
 
-static inline void omap_gpio_dbck_enable(struct gpio_bank *bank)
-{
-	if (bank->dbck_enable_mask && !bank->dbck_enabled) {
-		clk_enable(bank->dbck);
-		bank->dbck_enabled = true;
+	if (bank->desired_debounce_en != bank->context.debounce_en) {
+		if (!bank->context.debounce_en)
+			clk_enable(bank->dbck);
 
-		writel_relaxed(bank->dbck_enable_mask,
-			     bank->base + bank->regs->debounce_en);
+		bank->context.debounce_en = bank->desired_debounce_en;
+		writel_relaxed(bank->context.debounce_en,
+			       base + bank->regs->debounce_en);
+
+		bank->context.debounce = bank->desired_debounce;
+		writel_relaxed(bank->context.debounce,
+			       base + bank->regs->debounce);
+
+		if (!bank->desired_debounce_en)
+			clk_disable(bank->dbck);
+	} else if (bank->context.debounce != bank->desired_debounce) {
+		WARN_ON(!bank->context.debounce_en);
+		bank->context.debounce = bank->desired_debounce;
+		writel_relaxed(bank->context.debounce,
+			       base + bank->regs->debounce);
 	}
 }
 
 static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
 {
-	if (bank->dbck_enable_mask && bank->dbck_enabled) {
+	if (bank->context.debounce_en) {
 		/*
 		 * Disable debounce before cutting it's clock. If debounce is
 		 * enabled but the clock is not, GPIO module seems to be unable
 		 * to detect events and generate interrupts at least on OMAP3.
 		 */
+		bank->context.debounce_en = 0;
 		writel_relaxed(0, bank->base + bank->regs->debounce_en);
-
 		clk_disable(bank->dbck);
-		bank->dbck_enabled = false;
 	}
 }
 
@@ -259,10 +212,8 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
 static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
 				   unsigned debounce)
 {
-	void __iomem		*reg;
-	u32			val;
-	u32			l;
-	bool			enable = !!debounce;
+	u32 gpio_bit = BIT(offset);
+	bool enable = !!debounce;
 
 	if (!bank->dbck_flag)
 		return -ENOTSUPP;
@@ -271,38 +222,20 @@ static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
 		debounce = DIV_ROUND_UP(debounce, 31) - 1;
 		if ((debounce & OMAP4_GPIO_DEBOUNCINGTIME_MASK) != debounce)
 			return -EINVAL;
-	}
-
-	l = BIT(offset);
-
-	clk_enable(bank->dbck);
-	reg = bank->base + bank->regs->debounce;
-	writel_relaxed(debounce, reg);
 
-	reg = bank->base + bank->regs->debounce_en;
-	val = readl_relaxed(reg);
-
-	if (enable)
-		val |= l;
-	else
-		val &= ~l;
-	bank->dbck_enable_mask = val;
+		bank->desired_debounce = debounce;
+		bank->desired_debounce_en |= gpio_bit;
+	} else {
+		bank->desired_debounce_en &= ~gpio_bit;
+		if (!bank->desired_debounce_en)
+			bank->desired_debounce = 0;
+	}
 
-	writel_relaxed(val, reg);
-	clk_disable(bank->dbck);
 	/*
-	 * Enable debounce clock per module.
-	 * This call is mandatory because in omap_gpio_request() when
-	 * *_runtime_get_sync() is called,  _gpio_dbck_enable() within
-	 * runtime callbck fails to turn on dbck because dbck_enable_mask
-	 * used within _gpio_dbck_enable() is still not initialized at
-	 * that point. Therefore we have to enable dbck here.
+	 * Update the debounce settings. This will enable or disable the
+	 * debounce clock as required.
 	 */
-	omap_gpio_dbck_enable(bank);
-	if (bank->dbck_enable_mask) {
-		bank->context.debounce = debounce;
-		bank->context.debounce_en = val;
-	}
+	omap_gpio_dbck_update(bank);
 
 	return 0;
 }
@@ -319,26 +252,7 @@ static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
  */
 static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset)
 {
-	u32 gpio_bit = BIT(offset);
-
-	if (!bank->dbck_flag)
-		return;
-
-	if (!(bank->dbck_enable_mask & gpio_bit))
-		return;
-
-	bank->dbck_enable_mask &= ~gpio_bit;
-	bank->context.debounce_en &= ~gpio_bit;
-        writel_relaxed(bank->context.debounce_en,
-		     bank->base + bank->regs->debounce_en);
-
-	if (!bank->dbck_enable_mask) {
-		bank->context.debounce = 0;
-		writel_relaxed(bank->context.debounce, bank->base +
-			     bank->regs->debounce);
-		clk_disable(bank->dbck);
-		bank->dbck_enabled = false;
-	}
+	omap2_set_gpio_debounce(bank, offset, 0);
 }
 
 /*
@@ -363,9 +277,9 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
 	void __iomem *base = bank->base;
 	u32 gpio_bit = BIT(gpio);
 
-	omap_gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
+	omap_gpio_rmw(base + bank->regs->leveldetect0, gpio_bit,
 		      trigger & IRQ_TYPE_LEVEL_LOW);
-	omap_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit,
+	omap_gpio_rmw(base + bank->regs->leveldetect1, gpio_bit,
 		      trigger & IRQ_TYPE_LEVEL_HIGH);
 
 	/*
@@ -373,9 +287,9 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
 	 * to be woken from idle state.  Set the appropriate edge detection
 	 * in addition to the level detection.
 	 */
-	omap_gpio_rmw(base, bank->regs->risingdetect, gpio_bit,
+	omap_gpio_rmw(base + bank->regs->risingdetect, gpio_bit,
 		      trigger & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH));
-	omap_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit,
+	omap_gpio_rmw(base + bank->regs->fallingdetect, gpio_bit,
 		      trigger & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW));
 
 	bank->context.leveldetect0 =
@@ -387,11 +301,8 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
 	bank->context.fallingdetect =
 			readl_relaxed(bank->base + bank->regs->fallingdetect);
 
-	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-		omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
-		bank->context.wake_en =
-			readl_relaxed(bank->base + bank->regs->wkup_en);
-	}
+	bank->level_mask = bank->context.leveldetect0 |
+			   bank->context.leveldetect1;
 
 	/* This part needs to be executed always for OMAP{34xx, 44xx} */
 	if (!bank->regs->irqctrl && !omap_gpio_is_off_wakeup_capable(bank, gpio)) {
@@ -406,44 +317,25 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
 		else
 			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
 	}
-
-	bank->level_mask =
-		readl_relaxed(bank->base + bank->regs->leveldetect0) |
-		readl_relaxed(bank->base + bank->regs->leveldetect1);
 }
 
-#ifdef CONFIG_ARCH_OMAP1
 /*
  * This only applies to chips that can't do both rising and falling edge
  * detection at once.  For all other chips, this function is a noop.
  */
 static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 {
-	void __iomem *reg = bank->base;
-	u32 l = 0;
-
-	if (!bank->regs->irqctrl)
-		return;
+	if (IS_ENABLED(CONFIG_ARCH_OMAP1) && bank->regs->irqctrl) {
+		void __iomem *reg = bank->base + bank->regs->irqctrl;
 
-	reg += bank->regs->irqctrl;
-
-	l = readl_relaxed(reg);
-	if ((l >> gpio) & 1)
-		l &= ~(BIT(gpio));
-	else
-		l |= BIT(gpio);
-
-	writel_relaxed(l, reg);
+		writel_relaxed(readl_relaxed(reg) ^ BIT(gpio), reg);
+	}
 }
-#else
-static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {}
-#endif
 
 static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio,
 				    unsigned trigger)
 {
 	void __iomem *reg = bank->base;
-	void __iomem *base = bank->base;
 	u32 l = 0;
 
 	if (bank->regs->leveldetect0 && bank->regs->wkup_en) {
@@ -475,11 +367,6 @@ static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio,
 			l |= 2 << (gpio << 1);
 		if (trigger & IRQ_TYPE_EDGE_FALLING)
 			l |= BIT(gpio << 1);
-
-		/* Enable wake-up during idle for dynamic tick */
-		omap_gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger);
-		bank->context.wake_en =
-			readl_relaxed(bank->base + bank->regs->wkup_en);
 		writel_relaxed(l, reg);
 	}
 	return 0;
@@ -508,17 +395,6 @@ static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned offset)
 
 static void omap_disable_gpio_module(struct gpio_bank *bank, unsigned offset)
 {
-	void __iomem *base = bank->base;
-
-	if (bank->regs->wkup_en &&
-	    !LINE_USED(bank->mod_usage, offset) &&
-	    !LINE_USED(bank->irq_usage, offset)) {
-		/* Disable wake-up during idle for dynamic tick */
-		omap_gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0);
-		bank->context.wake_en =
-			readl_relaxed(bank->base + bank->regs->wkup_en);
-	}
-
 	if (bank->regs->ctrl && !BANK_USED(bank)) {
 		void __iomem *reg = bank->base + bank->regs->ctrl;
 		u32 ctrl;
@@ -629,57 +505,39 @@ static u32 omap_get_gpio_irqbank_mask(struct gpio_bank *bank)
 	return l;
 }
 
-static void omap_enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
+static inline void omap_set_gpio_irqenable(struct gpio_bank *bank,
+					   unsigned offset, int enable)
 {
 	void __iomem *reg = bank->base;
-	u32 l;
+	u32 gpio_mask = BIT(offset);
 
-	if (bank->regs->set_irqenable) {
-		reg += bank->regs->set_irqenable;
-		l = gpio_mask;
-		bank->context.irqenable1 |= gpio_mask;
+	if (bank->regs->set_irqenable && bank->regs->clr_irqenable) {
+		if (enable) {
+			reg += bank->regs->set_irqenable;
+			bank->context.irqenable1 |= gpio_mask;
+		} else {
+			reg += bank->regs->clr_irqenable;
+			bank->context.irqenable1 &= ~gpio_mask;
+		}
+		writel_relaxed(gpio_mask, reg);
 	} else {
-		reg += bank->regs->irqenable;
-		l = readl_relaxed(reg);
-		if (bank->regs->irqenable_inv)
-			l &= ~gpio_mask;
-		else
-			l |= gpio_mask;
-		bank->context.irqenable1 = l;
+		bank->context.irqenable1 =
+			omap_gpio_rmw(reg + bank->regs->irqenable, gpio_mask,
+				      enable ^ bank->regs->irqenable_inv);
 	}
 
-	writel_relaxed(l, reg);
-}
-
-static void omap_disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
-{
-	void __iomem *reg = bank->base;
-	u32 l;
-
-	if (bank->regs->clr_irqenable) {
-		reg += bank->regs->clr_irqenable;
-		l = gpio_mask;
-		bank->context.irqenable1 &= ~gpio_mask;
-	} else {
-		reg += bank->regs->irqenable;
-		l = readl_relaxed(reg);
-		if (bank->regs->irqenable_inv)
-			l |= gpio_mask;
-		else
-			l &= ~gpio_mask;
-		bank->context.irqenable1 = l;
+	/*
+	 * Program GPIO wakeup along with IRQ enable to satisfy OMAP4430 TRM
+	 * note requiring correlation between the IRQ enable registers and
+	 * the wakeup registers.  In any case, we want wakeup from idle
+	 * enabled for the GPIOs which support this feature.
+	 */
+	if (bank->regs->wkup_en &&
+	    (bank->regs->edgectrl1 || !(bank->non_wakeup_gpios & gpio_mask))) {
+		bank->context.wake_en =
+			omap_gpio_rmw(bank->base + bank->regs->wkup_en,
+				      gpio_mask, enable);
 	}
-
-	writel_relaxed(l, reg);
-}
-
-static inline void omap_set_gpio_irqenable(struct gpio_bank *bank,
-					   unsigned offset, int enable)
-{
-	if (enable)
-		omap_enable_gpio_irqbank(bank, BIT(offset));
-	else
-		omap_disable_gpio_irqbank(bank, BIT(offset));
 }
 
 /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
@@ -690,38 +548,6 @@ static int omap_gpio_wake_enable(struct irq_data *d, unsigned int enable)
 	return irq_set_irq_wake(bank->irq, enable);
 }
 
-static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank = gpiochip_get_data(chip);
-	unsigned long flags;
-
-	pm_runtime_get_sync(chip->parent);
-
-	raw_spin_lock_irqsave(&bank->lock, flags);
-	omap_enable_gpio_module(bank, offset);
-	bank->mod_usage |= BIT(offset);
-	raw_spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank = gpiochip_get_data(chip);
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&bank->lock, flags);
-	bank->mod_usage &= ~(BIT(offset));
-	if (!LINE_USED(bank->irq_usage, offset)) {
-		omap_set_gpio_direction(bank, offset, 1);
-		omap_clear_gpio_debounce(bank, offset);
-	}
-	omap_disable_gpio_module(bank, offset);
-	raw_spin_unlock_irqrestore(&bank->lock, flags);
-
-	pm_runtime_put(chip->parent);
-}
-
 /*
  * We need to unmask the GPIO bank interrupt as soon as possible to
  * avoid missing GPIO interrupts for other lines in the bank.
@@ -734,7 +560,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
 {
 	void __iomem *isr_reg = NULL;
-	u32 enabled, isr, level_mask;
+	u32 enabled, isr, edge;
 	unsigned int bit;
 	struct gpio_bank *bank = gpiobank;
 	unsigned long wa_lock_flags;
@@ -754,16 +580,14 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
 		enabled = omap_get_gpio_irqbank_mask(bank);
 		isr = readl_relaxed(isr_reg) & enabled;
 
-		if (bank->level_mask)
-			level_mask = bank->level_mask & enabled;
-		else
-			level_mask = 0;
-
-		/* clear edge sensitive interrupts before handler(s) are
-		called so that we don't miss any interrupt occurred while
-		executing them */
-		if (isr & ~level_mask)
-			omap_clear_gpio_irqbank(bank, isr & ~level_mask);
+		/*
+		 * Clear edge sensitive interrupts before calling handler(s)
+		 * so subsequent edge transitions are not missed while the
+		 * handlers are running.
+		 */
+		edge = isr & ~bank->level_mask;
+		if (edge)
+			omap_clear_gpio_irqbank(bank, edge);
 
 		raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
 
@@ -810,8 +634,6 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
 
 	if (!LINE_USED(bank->mod_usage, offset))
 		omap_set_gpio_direction(bank, offset, 1);
-	else if (!omap_gpio_is_input(bank, offset))
-		goto err;
 	omap_enable_gpio_module(bank, offset);
 	bank->irq_usage |= BIT(offset);
 
@@ -819,9 +641,6 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
 	omap_gpio_unmask_irq(d);
 
 	return 0;
-err:
-	raw_spin_unlock_irqrestore(&bank->lock, flags);
-	return -EINVAL;
 }
 
 static void omap_gpio_irq_shutdown(struct irq_data *d)
@@ -832,9 +651,9 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
 
 	raw_spin_lock_irqsave(&bank->lock, flags);
 	bank->irq_usage &= ~(BIT(offset));
-	omap_set_gpio_irqenable(bank, offset, 0);
-	omap_clear_gpio_irqstatus(bank, offset);
 	omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
+	omap_clear_gpio_irqstatus(bank, offset);
+	omap_set_gpio_irqenable(bank, offset, 0);
 	if (!LINE_USED(bank->mod_usage, offset))
 		omap_clear_gpio_debounce(bank, offset);
 	omap_disable_gpio_module(bank, offset);
@@ -855,14 +674,6 @@ static void gpio_irq_bus_sync_unlock(struct irq_data *data)
 	pm_runtime_put(bank->chip.parent);
 }
 
-static void omap_gpio_ack_irq(struct irq_data *d)
-{
-	struct gpio_bank *bank = omap_irq_data_get_bank(d);
-	unsigned offset = d->hwirq;
-
-	omap_clear_gpio_irqstatus(bank, offset);
-}
-
 static void omap_gpio_mask_irq(struct irq_data *d)
 {
 	struct gpio_bank *bank = omap_irq_data_get_bank(d);
@@ -870,8 +681,8 @@ static void omap_gpio_mask_irq(struct irq_data *d)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&bank->lock, flags);
-	omap_set_gpio_irqenable(bank, offset, 0);
 	omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
+	omap_set_gpio_irqenable(bank, offset, 0);
 	raw_spin_unlock_irqrestore(&bank->lock, flags);
 }
 
@@ -883,9 +694,6 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&bank->lock, flags);
-	if (trigger)
-		omap_set_gpio_triggering(bank, offset, trigger);
-
 	omap_set_gpio_irqenable(bank, offset, 1);
 
 	/*
@@ -893,9 +701,13 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
 	 * is cleared, thus after the handler has run. OMAP4 needs this done
 	 * after enabing the interrupt to clear the wakeup status.
 	 */
-	if (bank->level_mask & BIT(offset))
+	if (bank->regs->leveldetect0 && bank->regs->wkup_en &&
+	    trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
 		omap_clear_gpio_irqstatus(bank, offset);
 
+	if (trigger)
+		omap_set_gpio_triggering(bank, offset, trigger);
+
 	raw_spin_unlock_irqrestore(&bank->lock, flags);
 }
 
@@ -961,19 +773,44 @@ static inline void omap_mpuio_init(struct gpio_bank *bank)
 
 /*---------------------------------------------------------------------*/
 
-static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 {
-	struct gpio_bank *bank;
+	struct gpio_bank *bank = gpiochip_get_data(chip);
 	unsigned long flags;
-	void __iomem *reg;
-	int dir;
 
-	bank = gpiochip_get_data(chip);
-	reg = bank->base + bank->regs->direction;
+	pm_runtime_get_sync(chip->parent);
+
 	raw_spin_lock_irqsave(&bank->lock, flags);
-	dir = !!(readl_relaxed(reg) & BIT(offset));
+	omap_enable_gpio_module(bank, offset);
+	bank->mod_usage |= BIT(offset);
 	raw_spin_unlock_irqrestore(&bank->lock, flags);
-	return dir;
+
+	return 0;
+}
+
+static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = gpiochip_get_data(chip);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&bank->lock, flags);
+	bank->mod_usage &= ~(BIT(offset));
+	if (!LINE_USED(bank->irq_usage, offset)) {
+		omap_set_gpio_direction(bank, offset, 1);
+		omap_clear_gpio_debounce(bank, offset);
+	}
+	omap_disable_gpio_module(bank, offset);
+	raw_spin_unlock_irqrestore(&bank->lock, flags);
+
+	pm_runtime_put(chip->parent);
+}
+
+static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = gpiochip_get_data(chip);
+
+	return !!(readl_relaxed(bank->base + bank->regs->direction) &
+		  BIT(offset));
 }
 
 static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
@@ -990,14 +827,15 @@ static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
 
 static int omap_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	struct gpio_bank *bank;
-
-	bank = gpiochip_get_data(chip);
+	struct gpio_bank *bank = gpiochip_get_data(chip);
+	void __iomem *reg;
 
 	if (omap_gpio_is_input(bank, offset))
-		return omap_get_gpio_datain(bank, offset);
+		reg = bank->base + bank->regs->datain;
 	else
-		return omap_get_gpio_dataout(bank, offset);
+		reg = bank->base + bank->regs->dataout;
+
+	return (readl_relaxed(reg) & BIT(offset)) != 0;
 }
 
 static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value)
@@ -1017,18 +855,20 @@ static int omap_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
 				  unsigned long *bits)
 {
 	struct gpio_bank *bank = gpiochip_get_data(chip);
-	void __iomem *reg = bank->base + bank->regs->direction;
-	unsigned long in = readl_relaxed(reg), l;
+	void __iomem *base = bank->base;
+	u32 direction, m, val = 0;
+
+	direction = readl_relaxed(base + bank->regs->direction);
 
-	*bits = 0;
+	m = direction & *mask;
+	if (m)
+		val |= readl_relaxed(base + bank->regs->datain) & m;
 
-	l = in & *mask;
-	if (l)
-		*bits |= omap_get_gpio_datain_multiple(bank, &l);
+	m = ~direction & *mask;
+	if (m)
+		val |= readl_relaxed(base + bank->regs->dataout) & m;
 
-	l = ~in & *mask;
-	if (l)
-		*bits |= omap_get_gpio_dataout_multiple(bank, &l);
+	*bits = val;
 
 	return 0;
 }
@@ -1081,10 +921,14 @@ static void omap_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask,
 				   unsigned long *bits)
 {
 	struct gpio_bank *bank = gpiochip_get_data(chip);
+	void __iomem *reg = bank->base + bank->regs->dataout;
 	unsigned long flags;
+	u32 l;
 
 	raw_spin_lock_irqsave(&bank->lock, flags);
-	bank->set_dataout_multiple(bank, mask, bits);
+	l = (readl_relaxed(reg) & ~*mask) | (*bits & *mask);
+	writel_relaxed(l, reg);
+	bank->context.dataout = l;
 	raw_spin_unlock_irqrestore(&bank->lock, flags);
 }
 
@@ -1118,9 +962,9 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
 		return;
 	}
 
-	omap_gpio_rmw(base, bank->regs->irqenable, l,
+	omap_gpio_rmw(base + bank->regs->irqenable, l,
 		      bank->regs->irqenable_inv);
-	omap_gpio_rmw(base, bank->regs->irqstatus, l,
+	omap_gpio_rmw(base + bank->regs->irqstatus, l,
 		      !bank->regs->irqenable_inv);
 	if (bank->regs->debounce_en)
 		writel_relaxed(0, base + bank->regs->debounce_en);
@@ -1183,11 +1027,8 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
 #endif
 
 	/* MPUIO is a bit different, reading IRQ status clears it */
-	if (bank->is_mpuio) {
-		irqc->irq_ack = dummy_irq_chip.irq_ack;
-		if (!bank->regs->wkup_en)
-			irqc->irq_set_wake = NULL;
-	}
+	if (bank->is_mpuio && !bank->regs->wkup_en)
+		irqc->irq_set_wake = NULL;
 
 	irq = &bank->chip.irq;
 	irq->chip = irqc;
@@ -1218,7 +1059,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
 
 static void omap_gpio_init_context(struct gpio_bank *p)
 {
-	struct omap_gpio_reg_offs *regs = p->regs;
+	const struct omap_gpio_reg_offs *regs = p->regs;
 	void __iomem *base = p->base;
 
 	p->context.ctrl		= readl_relaxed(base + regs->ctrl);
@@ -1230,47 +1071,27 @@ static void omap_gpio_init_context(struct gpio_bank *p)
 	p->context.fallingdetect = readl_relaxed(base + regs->fallingdetect);
 	p->context.irqenable1	= readl_relaxed(base + regs->irqenable);
 	p->context.irqenable2	= readl_relaxed(base + regs->irqenable2);
-
-	if (regs->set_dataout && p->regs->clr_dataout)
-		p->context.dataout = readl_relaxed(base + regs->set_dataout);
-	else
-		p->context.dataout = readl_relaxed(base + regs->dataout);
+	p->context.dataout	= readl_relaxed(base + regs->dataout);
 
 	p->context_valid = true;
 }
 
 static void omap_gpio_restore_context(struct gpio_bank *bank)
 {
-	writel_relaxed(bank->context.wake_en,
-				bank->base + bank->regs->wkup_en);
-	writel_relaxed(bank->context.ctrl, bank->base + bank->regs->ctrl);
-	writel_relaxed(bank->context.leveldetect0,
-				bank->base + bank->regs->leveldetect0);
-	writel_relaxed(bank->context.leveldetect1,
-				bank->base + bank->regs->leveldetect1);
-	writel_relaxed(bank->context.risingdetect,
-				bank->base + bank->regs->risingdetect);
-	writel_relaxed(bank->context.fallingdetect,
-				bank->base + bank->regs->fallingdetect);
-	if (bank->regs->set_dataout && bank->regs->clr_dataout)
-		writel_relaxed(bank->context.dataout,
-				bank->base + bank->regs->set_dataout);
-	else
-		writel_relaxed(bank->context.dataout,
-				bank->base + bank->regs->dataout);
-	writel_relaxed(bank->context.oe, bank->base + bank->regs->direction);
-
-	if (bank->dbck_enable_mask) {
-		writel_relaxed(bank->context.debounce, bank->base +
-					bank->regs->debounce);
-		writel_relaxed(bank->context.debounce_en,
-					bank->base + bank->regs->debounce_en);
-	}
+	const struct omap_gpio_reg_offs *regs = bank->regs;
+	void __iomem *base = bank->base;
 
-	writel_relaxed(bank->context.irqenable1,
-				bank->base + bank->regs->irqenable);
-	writel_relaxed(bank->context.irqenable2,
-				bank->base + bank->regs->irqenable2);
+	writel_relaxed(bank->context.wake_en, base + regs->wkup_en);
+	writel_relaxed(bank->context.ctrl, base + regs->ctrl);
+	writel_relaxed(bank->context.leveldetect0, base + regs->leveldetect0);
+	writel_relaxed(bank->context.leveldetect1, base + regs->leveldetect1);
+	writel_relaxed(bank->context.risingdetect, base + regs->risingdetect);
+	writel_relaxed(bank->context.fallingdetect, base + regs->fallingdetect);
+	writel_relaxed(bank->context.dataout, base + regs->dataout);
+	writel_relaxed(bank->context.oe, base + regs->direction);
+	/* debounce is already restored via omap_gpio_dbck_update() */
+	writel_relaxed(bank->context.irqenable1, base + regs->irqenable);
+	writel_relaxed(bank->context.irqenable2, base + regs->irqenable2);
 }
 
 static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context)
@@ -1294,8 +1115,8 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context)
 	 */
 	if (!bank->loses_context && bank->enabled_non_wakeup_gpios) {
 		nowake = bank->enabled_non_wakeup_gpios;
-		omap_gpio_rmw(base, bank->regs->fallingdetect, nowake, ~nowake);
-		omap_gpio_rmw(base, bank->regs->risingdetect, nowake, ~nowake);
+		omap_gpio_rmw(base + bank->regs->fallingdetect, nowake, ~nowake);
+		omap_gpio_rmw(base + bank->regs->risingdetect, nowake, ~nowake);
 	}
 
 update_gpio_context_count:
@@ -1325,7 +1146,7 @@ static void omap_gpio_unidle(struct gpio_bank *bank)
 				bank->get_context_loss_count(dev);
 	}
 
-	omap_gpio_dbck_enable(bank);
+	omap_gpio_dbck_update(bank);
 
 	if (bank->loses_context) {
 		if (!bank->get_context_loss_count) {
@@ -1424,7 +1245,7 @@ static int gpio_omap_cpu_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
-static struct omap_gpio_reg_offs omap2_gpio_regs = {
+static const struct omap_gpio_reg_offs omap2_gpio_regs = {
 	.revision =		OMAP24XX_GPIO_REVISION,
 	.direction =		OMAP24XX_GPIO_OE,
 	.datain =		OMAP24XX_GPIO_DATAIN,
@@ -1447,7 +1268,7 @@ static struct omap_gpio_reg_offs omap2_gpio_regs = {
 	.fallingdetect =	OMAP24XX_GPIO_FALLINGDETECT,
 };
 
-static struct omap_gpio_reg_offs omap4_gpio_regs = {
+static const struct omap_gpio_reg_offs omap4_gpio_regs = {
 	.revision =		OMAP4_GPIO_REVISION,
 	.direction =		OMAP4_GPIO_OE,
 	.datain =		OMAP4_GPIO_DATAIN,
@@ -1456,6 +1277,8 @@ static struct omap_gpio_reg_offs omap4_gpio_regs = {
 	.clr_dataout =		OMAP4_GPIO_CLEARDATAOUT,
 	.irqstatus =		OMAP4_GPIO_IRQSTATUS0,
 	.irqstatus2 =		OMAP4_GPIO_IRQSTATUS1,
+	.irqstatus_raw0 =	OMAP4_GPIO_IRQSTATUSRAW0,
+	.irqstatus_raw1 =	OMAP4_GPIO_IRQSTATUSRAW1,
 	.irqenable =		OMAP4_GPIO_IRQSTATUSSET0,
 	.irqenable2 =		OMAP4_GPIO_IRQSTATUSSET1,
 	.set_irqenable =	OMAP4_GPIO_IRQSTATUSSET0,
@@ -1531,7 +1354,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
 
 	irqc->irq_startup = omap_gpio_irq_startup,
 	irqc->irq_shutdown = omap_gpio_irq_shutdown,
-	irqc->irq_ack = omap_gpio_ack_irq,
+	irqc->irq_ack = dummy_irq_chip.irq_ack,
 	irqc->irq_mask = omap_gpio_mask_irq,
 	irqc->irq_unmask = omap_gpio_unmask_irq,
 	irqc->irq_set_type = omap_gpio_irq_type,
@@ -1575,14 +1398,10 @@ static int omap_gpio_probe(struct platform_device *pdev)
 				pdata->get_context_loss_count;
 	}
 
-	if (bank->regs->set_dataout && bank->regs->clr_dataout) {
+	if (bank->regs->set_dataout && bank->regs->clr_dataout)
 		bank->set_dataout = omap_set_gpio_dataout_reg;
-		bank->set_dataout_multiple = omap_set_gpio_dataout_reg_multiple;
-	} else {
+	else
 		bank->set_dataout = omap_set_gpio_dataout_mask;
-		bank->set_dataout_multiple =
-				omap_set_gpio_dataout_mask_multiple;
-	}
 
 	raw_spin_lock_init(&bank->lock);
 	raw_spin_lock_init(&bank->wa_lock);
@@ -1638,7 +1457,6 @@ static int omap_gpio_remove(struct platform_device *pdev)
 	struct gpio_bank *bank = platform_get_drvdata(pdev);
 
 	cpu_pm_unregister_notifier(&bank->nb);
-	list_del(&bank->node);
 	gpiochip_remove(&bank->chip);
 	pm_runtime_disable(&pdev->dev);
 	if (bank->dbck_flag)
diff --git a/include/linux/platform_data/gpio-omap.h b/include/linux/platform_data/gpio-omap.h
index 7c36370c062e..1ca400005233 100644
--- a/include/linux/platform_data/gpio-omap.h
+++ b/include/linux/platform_data/gpio-omap.h
@@ -200,7 +200,7 @@ struct omap_gpio_platform_data {
 	bool is_mpuio;		/* whether the bank is of type MPUIO */
 	u32 non_wakeup_gpios;
 
-	struct omap_gpio_reg_offs *regs;
+	const struct omap_gpio_reg_offs *regs;
 
 	/* Return context loss count due to PM states changing */
 	int (*get_context_loss_count)(struct device *dev);
