From bbc932a230ed3fd182a2fca72df2c6232bcc3b3d Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Wed, 28 Sep 2011 09:40:11 +0100 Subject: [PATCH] --- yaml --- r: 279839 b: refs/heads/master c: 1558368eb5d67a41d4199db32d3f5858660b44cf h: refs/heads/master i: 279837: a03e94bd5f0ae637980b0d37b6ce0861a7f4c392 279835: a793a0de5930eaacf3204a6d03c8cf29be81c675 279831: 6a31b41152ed2b01ccb0ca43344f7dc4566846ba 279823: 948e4be1315f852f5c1941bc2710c292c6cba303 279807: 4dbbc53f673237fbf4451f3ab7c9d72e4f7cb661 v: v3 --- [refs] | 2 +- trunk/arch/arm/common/vic.c | 38 +++++++++++++++++++++++ trunk/arch/arm/include/asm/hardware/vic.h | 3 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 07a63009b176..d99244bf0701 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f9b28ccbc7139af656147dcbba9c5425d5706b7d +refs/heads/master: 1558368eb5d67a41d4199db32d3f5858660b44cf diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index a227a7d53700..0a69547e0312 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -428,3 +429,40 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) return -EIO; } #endif /* CONFIG OF */ + +#ifdef CONFIG_MULTI_IRQ_HANDLER +/* + * Handle each interrupt in a single VIC. Returns non-zero if we've + * handled at least one interrupt. This does a single read of the + * status register and handles all interrupts in order from LSB first. + */ +static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) +{ + u32 stat, irq; + int handled = 0; + + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); + while (stat) { + irq = ffs(stat) - 1; + handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); + stat &= ~(1 << irq); + handled = 1; + } + + return handled; +} + +/* + * Keep iterating over all registered VIC's until there are no pending + * interrupts. + */ +asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs) +{ + int i, handled; + + do { + for (i = 0, handled = 0; i < vic_id; ++i) + handled |= handle_one_vic(&vic_devices[i], regs); + } while (handled); +} +#endif /* CONFIG_MULTI_IRQ_HANDLER */ diff --git a/trunk/arch/arm/include/asm/hardware/vic.h b/trunk/arch/arm/include/asm/hardware/vic.h index b348a545de23..f42ebd619590 100644 --- a/trunk/arch/arm/include/asm/hardware/vic.h +++ b/trunk/arch/arm/include/asm/hardware/vic.h @@ -45,8 +45,11 @@ #include struct device_node; +struct pt_regs; + void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); int vic_of_init(struct device_node *node, struct device_node *parent); +void vic_handle_irq(struct pt_regs *regs); #endif /* __ASSEMBLY__ */ #endif