From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> Drop calling rzg2l_gpio_request() in rzg2l_gpio_interrupt_input_mode() this was added to handle special case of bootloader setting the same gpio pin as function. When GPIO pin is requested as interrupt through `gpios` DT property the gpio_request() is called through the code path and when releasing GPIO pin it goes through the gpio_free() path, so drop calling gpio_request() in rzg2l_gpio_child_to_parent_hwirq() path and also drop rzg2l_gpio_free() in rzg2l_gpio_irq_domain_free(). This fixes case where rzg2l_gpio_free() was being called twice after the GPIO interrupt pin is freed (after unbinding the module). When GPIO pin is requested as interrupt through `interrupt` DT property this doesn't go through gpio_request()/gpio_free() code path. Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> --- v1->v2 - No change --- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 33 +++---------------------- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index d8b942fbf537..b9a8bf43a92a 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -2372,26 +2372,6 @@ static const struct irq_chip rzg2l_gpio_irqchip = { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; -static int rzg2l_gpio_interrupt_input_mode(struct gpio_chip *chip, unsigned int offset) -{ - struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip); - const struct pinctrl_pin_desc *pin_desc = &pctrl->desc.pins[offset]; - u64 *pin_data = pin_desc->drv_data; - u32 off = RZG2L_PIN_CFG_TO_PORT_OFFSET(*pin_data); - u8 bit = RZG2L_PIN_ID_TO_PIN(offset); - u8 reg8; - int ret; - - reg8 = readb(pctrl->base + PMC(off)); - if (reg8 & BIT(bit)) { - ret = rzg2l_gpio_request(chip, offset); - if (ret) - return ret; - } - - return rzg2l_gpio_direction_input(chip, offset); -} - static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc, unsigned int child, unsigned int child_type, @@ -2407,17 +2387,15 @@ static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc, if (gpioint < 0) return gpioint; - ret = rzg2l_gpio_interrupt_input_mode(gc, child); + ret = rzg2l_gpio_direction_input(gc, child); if (ret) return ret; spin_lock_irqsave(&pctrl->bitmap_lock, flags); irq = bitmap_find_free_region(pctrl->tint_slot, RZG2L_TINT_MAX_INTERRUPT, get_order(1)); spin_unlock_irqrestore(&pctrl->bitmap_lock, flags); - if (irq < 0) { - ret = -ENOSPC; - goto err; - } + if (irq < 0) + return -ENOSPC; rzg2l_gpio_irq_endisable(pctrl, child, true); pctrl->hwirq[irq] = child; @@ -2427,10 +2405,6 @@ static int rzg2l_gpio_child_to_parent_hwirq(struct gpio_chip *gc, *parent_type = IRQ_TYPE_LEVEL_HIGH; *parent = RZG2L_PACK_HWIRQ(gpioint, irq); return 0; - -err: - rzg2l_gpio_free(gc, child); - return ret; } static void rzg2l_gpio_irq_restore(struct rzg2l_pinctrl *pctrl) @@ -2494,7 +2468,6 @@ static void rzg2l_gpio_irq_domain_free(struct irq_domain *domain, unsigned int v for (i = 0; i < RZG2L_TINT_MAX_INTERRUPT; i++) { if (pctrl->hwirq[i] == hwirq) { rzg2l_gpio_irq_endisable(pctrl, hwirq, false); - rzg2l_gpio_free(gc, hwirq); spin_lock_irqsave(&pctrl->bitmap_lock, flags); bitmap_release_region(pctrl->tint_slot, i, get_order(1)); spin_unlock_irqrestore(&pctrl->bitmap_lock, flags); -- 2.43.0