Commit 115ccd22 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gpio-fixes-for-v5.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - fix an bug generating spurious interrupts in gpio-rockchip

 - fix a race condition in gpiod_to_irq() called by GPIO consumers

* tag 'gpio-fixes-for-v5.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: Return EPROBE_DEFER if gc->to_irq is NULL
  gpio: rockchip: Reset int_bothedge when changing trigger
parents 4b23c6ec ae42f928
...@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
switch (type) { if (type == IRQ_TYPE_EDGE_BOTH) {
case IRQ_TYPE_EDGE_BOTH:
if (bank->gpio_type == GPIO_TYPE_V2) { if (bank->gpio_type == GPIO_TYPE_V2) {
bank->toggle_edge_mode &= ~mask;
rockchip_gpio_writel_bit(bank, d->hwirq, 1, rockchip_gpio_writel_bit(bank, d->hwirq, 1,
bank->gpio_regs->int_bothedge); bank->gpio_regs->int_bothedge);
goto out; goto out;
...@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
else else
polarity |= mask; polarity |= mask;
} }
break; } else {
case IRQ_TYPE_EDGE_RISING: if (bank->gpio_type == GPIO_TYPE_V2) {
bank->toggle_edge_mode &= ~mask; rockchip_gpio_writel_bit(bank, d->hwirq, 0,
level |= mask; bank->gpio_regs->int_bothedge);
polarity |= mask; } else {
break; bank->toggle_edge_mode &= ~mask;
case IRQ_TYPE_EDGE_FALLING: }
bank->toggle_edge_mode &= ~mask; switch (type) {
level |= mask; case IRQ_TYPE_EDGE_RISING:
polarity &= ~mask; level |= mask;
break; polarity |= mask;
case IRQ_TYPE_LEVEL_HIGH: break;
bank->toggle_edge_mode &= ~mask; case IRQ_TYPE_EDGE_FALLING:
level &= ~mask; level |= mask;
polarity |= mask; polarity &= ~mask;
break; break;
case IRQ_TYPE_LEVEL_LOW: case IRQ_TYPE_LEVEL_HIGH:
bank->toggle_edge_mode &= ~mask; level &= ~mask;
level &= ~mask; polarity |= mask;
polarity &= ~mask; break;
break; case IRQ_TYPE_LEVEL_LOW:
default: level &= ~mask;
ret = -EINVAL; polarity &= ~mask;
goto out; break;
default:
ret = -EINVAL;
goto out;
}
} }
rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);
......
...@@ -3147,6 +3147,16 @@ int gpiod_to_irq(const struct gpio_desc *desc) ...@@ -3147,6 +3147,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
return retirq; return retirq;
} }
#ifdef CONFIG_GPIOLIB_IRQCHIP
if (gc->irq.chip) {
/*
* Avoid race condition with other code, which tries to lookup
* an IRQ before the irqchip has been properly registered,
* i.e. while gpiochip is still being brought up.
*/
return -EPROBE_DEFER;
}
#endif
return -ENXIO; return -ENXIO;
} }
EXPORT_SYMBOL_GPL(gpiod_to_irq); EXPORT_SYMBOL_GPL(gpiod_to_irq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment