* state.  If so, generate an IRQ by software.  This is
                 * horribly racy, but it's the best we can do to work around
                 * this silicon bug. */
 -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
 -                      defined(CONFIG_ARCH_OMAP4)
 -              l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
 -#endif
                l ^= bank->saved_datain;
                l &= bank->non_wakeup_gpios;
-               if (l) {
+ 
+               /*
+                * No need to generate IRQs for the rising edge for gpio IRQs
+                * configured with falling edge only; and vice versa.
+                */
+               gen0 = l & bank->saved_fallingdetect;
+               gen0 &= bank->saved_datain;
+ 
+               gen1 = l & bank->saved_risingdetect;
+               gen1 &= ~(bank->saved_datain);
+ 
+               /* FIXME: Consider GPIO IRQs with level detections properly! */
+               gen = l & (~(bank->saved_fallingdetect) &
+                               ~(bank->saved_risingdetect));
+               /* Consider all GPIO IRQs needed to be updated */
+               gen |= gen0 | gen1;
+ 
+               if (gen) {
                        u32 old0, old1;
 -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
 -                      defined(CONFIG_ARCH_OMAP4)
 +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
                        old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
                        old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-                       __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-                       __raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+                       __raw_writel(old0 | gen, bank->base +
+                                       OMAP24XX_GPIO_LEVELDETECT0);
+                       __raw_writel(old1 | gen, bank->base +
+                                       OMAP24XX_GPIO_LEVELDETECT1);
                        __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
                        __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
 +#endif
 +#ifdef CONFIG_ARCH_OMAP4
 +                      old0 = __raw_readl(bank->base +
 +                                              OMAP4_GPIO_LEVELDETECT0);
 +                      old1 = __raw_readl(bank->base +
 +                                              OMAP4_GPIO_LEVELDETECT1);
 +                      __raw_writel(old0 | l, bank->base +
 +                                              OMAP4_GPIO_LEVELDETECT0);
 +                      __raw_writel(old1 | l, bank->base +
 +                                              OMAP4_GPIO_LEVELDETECT1);
 +                      __raw_writel(old0, bank->base +
 +                                              OMAP4_GPIO_LEVELDETECT0);
 +                      __raw_writel(old1, bank->base +
 +                                              OMAP4_GPIO_LEVELDETECT1);
  #endif
                }
        }