Merge 5.18-rc5 into tty-next
[linux-2.6-microblaze.git] / drivers / pinctrl / stm32 / pinctrl-stm32.c
index 9ed7647..f7c9459 100644 (file)
@@ -225,6 +225,13 @@ static void stm32_gpio_free(struct gpio_chip *chip, unsigned offset)
        pinctrl_gpio_free(chip->base + offset);
 }
 
+static int stm32_gpio_get_noclk(struct gpio_chip *chip, unsigned int offset)
+{
+       struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
+
+       return !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
+}
+
 static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
@@ -232,7 +239,7 @@ static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset)
 
        clk_enable(bank->clk);
 
-       ret = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
+       ret = stm32_gpio_get_noclk(chip, offset);
 
        clk_disable(bank->clk);
 
@@ -311,8 +318,12 @@ static void stm32_gpio_irq_trigger(struct irq_data *d)
        struct stm32_gpio_bank *bank = d->domain->host_data;
        int level;
 
+       /* Do not access the GPIO if this is not LEVEL triggered IRQ. */
+       if (!(bank->irq_type[d->hwirq] & IRQ_TYPE_LEVEL_MASK))
+               return;
+
        /* If level interrupt type then retrig */
-       level = stm32_gpio_get(&bank->gpio_chip, d->hwirq);
+       level = stm32_gpio_get_noclk(&bank->gpio_chip, d->hwirq);
        if ((level == 0 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_LOW) ||
            (level == 1 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_HIGH))
                irq_chip_retrigger_hierarchy(d);
@@ -354,6 +365,7 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
 {
        struct stm32_gpio_bank *bank = irq_data->domain->host_data;
        struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
+       unsigned long flags;
        int ret;
 
        ret = stm32_gpio_direction_input(&bank->gpio_chip, irq_data->hwirq);
@@ -367,6 +379,10 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
                return ret;
        }
 
+       flags = irqd_get_trigger_type(irq_data);
+       if (flags & IRQ_TYPE_LEVEL_MASK)
+               clk_enable(bank->clk);
+
        return 0;
 }
 
@@ -374,6 +390,9 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data)
 {
        struct stm32_gpio_bank *bank = irq_data->domain->host_data;
 
+       if (bank->irq_type[irq_data->hwirq] & IRQ_TYPE_LEVEL_MASK)
+               clk_disable(bank->clk);
+
        gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq);
 }