mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +08:00
pinctrl: sunxi: use chained_irq_{enter, exit} for GIC compatibility
On tha Allwinner A20 SoC, the external interrupts on the pin controller device are connected to the GIC. Without chained_irq_{enter, exit}, external GPIO interrupts, such as used by mmc core card detect, cause the system to hang. This issue was first encountered during my attempt to get out-of-band interrupts for WiFi on the Cubietruck working. With David's new series of sunci-mci using mmc slot-gpio for (GPIO interrupt based) card detection, removing the SD card also causes my Cubietruck to hang. This problem should extend to all Allwinner A20 based boards. With this fix, the system no longer hangs when I remove or insert the SD card. /proc/interrupts show that the interrupt has correctly fired. However the system still does not detect card removal/insertion. I believe this is another unrelated issue. Cc: stable@vger.kernel.org Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
0414855fdc
commit
905a5117e7
@ -14,6 +14,7 @@
|
|||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/irqdomain.h>
|
||||||
|
#include <linux/irqchip/chained_irq.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
@ -665,6 +666,7 @@ static struct irq_chip sunxi_pinctrl_irq_chip = {
|
|||||||
|
|
||||||
static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
|
static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||||
{
|
{
|
||||||
|
struct irq_chip *chip = irq_get_chip(irq);
|
||||||
struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
|
struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
|
||||||
const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
|
const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
|
||||||
|
|
||||||
@ -674,10 +676,12 @@ static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
|
|||||||
if (reg) {
|
if (reg) {
|
||||||
int irqoffset;
|
int irqoffset;
|
||||||
|
|
||||||
|
chained_irq_enter(chip, desc);
|
||||||
for_each_set_bit(irqoffset, ®, SUNXI_IRQ_NUMBER) {
|
for_each_set_bit(irqoffset, ®, SUNXI_IRQ_NUMBER) {
|
||||||
int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
|
int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
|
||||||
generic_handle_irq(pin_irq);
|
generic_handle_irq(pin_irq);
|
||||||
}
|
}
|
||||||
|
chained_irq_exit(chip, desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user