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)
level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
switch (type) {
case IRQ_TYPE_EDGE_BOTH:
if (type == IRQ_TYPE_EDGE_BOTH) {
if (bank->gpio_type == GPIO_TYPE_V2) {
bank->toggle_edge_mode &= ~mask;
rockchip_gpio_writel_bit(bank, d->hwirq, 1,
bank->gpio_regs->int_bothedge);
goto out;
......@@ -431,24 +429,27 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
else
polarity |= mask;
}
break;
case IRQ_TYPE_EDGE_RISING:
} else {
if (bank->gpio_type == GPIO_TYPE_V2) {
rockchip_gpio_writel_bit(bank, d->hwirq, 0,
bank->gpio_regs->int_bothedge);
} else {
bank->toggle_edge_mode &= ~mask;
}
switch (type) {
case IRQ_TYPE_EDGE_RISING:
level |= mask;
polarity |= mask;
break;
case IRQ_TYPE_EDGE_FALLING:
bank->toggle_edge_mode &= ~mask;
level |= mask;
polarity &= ~mask;
break;
case IRQ_TYPE_LEVEL_HIGH:
bank->toggle_edge_mode &= ~mask;
level &= ~mask;
polarity |= mask;
break;
case IRQ_TYPE_LEVEL_LOW:
bank->toggle_edge_mode &= ~mask;
level &= ~mask;
polarity &= ~mask;
break;
......@@ -456,6 +457,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
ret = -EINVAL;
goto out;
}
}
rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);
rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity);
......
......@@ -3147,6 +3147,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
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;
}
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