Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / gpio-omap.c
index c4ed1722734c9eadb190c0ccaa19a9c2eb3b2d39..e6efd77668f0fb5ccab3a917629b07134885ee73 100644 (file)
@@ -174,12 +174,22 @@ static inline void _gpio_dbck_enable(struct gpio_bank *bank)
        if (bank->dbck_enable_mask && !bank->dbck_enabled) {
                clk_enable(bank->dbck);
                bank->dbck_enabled = true;
+
+               __raw_writel(bank->dbck_enable_mask,
+                            bank->base + bank->regs->debounce_en);
        }
 }
 
 static inline void _gpio_dbck_disable(struct gpio_bank *bank)
 {
        if (bank->dbck_enable_mask && bank->dbck_enabled) {
+               /*
+                * 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.
+                */
+               __raw_writel(0, bank->base + bank->regs->debounce_en);
+
                clk_disable(bank->dbck);
                bank->dbck_enabled = false;
        }
@@ -889,12 +899,6 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
 
        bank = container_of(chip, struct gpio_bank, chip);
 
-       if (!bank->dbck) {
-               bank->dbck = clk_get(bank->dev, "dbclk");
-               if (IS_ERR(bank->dbck))
-                       dev_err(bank->dev, "Could not get gpio dbck\n");
-       }
-
        spin_lock_irqsave(&bank->lock, flags);
        _set_gpio_debounce(bank, offset, debounce);
        spin_unlock_irqrestore(&bank->lock, flags);
@@ -966,6 +970,10 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
         /* Initialize interface clk ungated, module enabled */
        if (bank->regs->ctrl)
                __raw_writel(0, base + bank->regs->ctrl);
+
+       bank->dbck = clk_get(bank->dev, "dbclk");
+       if (IS_ERR(bank->dbck))
+               dev_err(bank->dev, "Could not get gpio dbck\n");
 }
 
 static __devinit void
@@ -1081,7 +1089,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        bank->is_mpuio = pdata->is_mpuio;
        bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
        bank->loses_context = pdata->loses_context;
-       bank->get_context_loss_count = pdata->get_context_loss_count;
        bank->regs = pdata->regs;
 #ifdef CONFIG_OF_GPIO
        bank->chip.of_node = of_node_get(node);
@@ -1135,6 +1142,9 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        omap_gpio_chip_init(bank);
        omap_gpio_show_rev(bank);
 
+       if (bank->loses_context)
+               bank->get_context_loss_count = pdata->get_context_loss_count;
+
        pm_runtime_put(bank->dev);
 
        list_add_tail(&bank->node, &omap_gpio_list);