Skip to content

Commit 115ccd2

Browse files
committed
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
2 parents 4b23c6e + ae42f92 commit 115ccd2

2 files changed

Lines changed: 39 additions & 27 deletions

File tree

drivers/gpio/gpio-rockchip.c

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
410410
level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
411411
polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
412412

413-
switch (type) {
414-
case IRQ_TYPE_EDGE_BOTH:
413+
if (type == IRQ_TYPE_EDGE_BOTH) {
415414
if (bank->gpio_type == GPIO_TYPE_V2) {
416-
bank->toggle_edge_mode &= ~mask;
417415
rockchip_gpio_writel_bit(bank, d->hwirq, 1,
418416
bank->gpio_regs->int_bothedge);
419417
goto out;
@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
431429
else
432430
polarity |= mask;
433431
}
434-
break;
435-
case IRQ_TYPE_EDGE_RISING:
436-
bank->toggle_edge_mode &= ~mask;
437-
level |= mask;
438-
polarity |= mask;
439-
break;
440-
case IRQ_TYPE_EDGE_FALLING:
441-
bank->toggle_edge_mode &= ~mask;
442-
level |= mask;
443-
polarity &= ~mask;
444-
break;
445-
case IRQ_TYPE_LEVEL_HIGH:
446-
bank->toggle_edge_mode &= ~mask;
447-
level &= ~mask;
448-
polarity |= mask;
449-
break;
450-
case IRQ_TYPE_LEVEL_LOW:
451-
bank->toggle_edge_mode &= ~mask;
452-
level &= ~mask;
453-
polarity &= ~mask;
454-
break;
455-
default:
456-
ret = -EINVAL;
457-
goto out;
432+
} else {
433+
if (bank->gpio_type == GPIO_TYPE_V2) {
434+
rockchip_gpio_writel_bit(bank, d->hwirq, 0,
435+
bank->gpio_regs->int_bothedge);
436+
} else {
437+
bank->toggle_edge_mode &= ~mask;
438+
}
439+
switch (type) {
440+
case IRQ_TYPE_EDGE_RISING:
441+
level |= mask;
442+
polarity |= mask;
443+
break;
444+
case IRQ_TYPE_EDGE_FALLING:
445+
level |= mask;
446+
polarity &= ~mask;
447+
break;
448+
case IRQ_TYPE_LEVEL_HIGH:
449+
level &= ~mask;
450+
polarity |= mask;
451+
break;
452+
case IRQ_TYPE_LEVEL_LOW:
453+
level &= ~mask;
454+
polarity &= ~mask;
455+
break;
456+
default:
457+
ret = -EINVAL;
458+
goto out;
459+
}
458460
}
459461

460462
rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);

drivers/gpio/gpiolib.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,6 +3147,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
31473147

31483148
return retirq;
31493149
}
3150+
#ifdef CONFIG_GPIOLIB_IRQCHIP
3151+
if (gc->irq.chip) {
3152+
/*
3153+
* Avoid race condition with other code, which tries to lookup
3154+
* an IRQ before the irqchip has been properly registered,
3155+
* i.e. while gpiochip is still being brought up.
3156+
*/
3157+
return -EPROBE_DEFER;
3158+
}
3159+
#endif
31503160
return -ENXIO;
31513161
}
31523162
EXPORT_SYMBOL_GPL(gpiod_to_irq);

0 commit comments

Comments
 (0)