From 76ba59f8366f2d9282cb5bda9de75b4b68cbe55f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:16 +0100 Subject: genirq: Add irq_domain-aware core IRQ handler Calling irq_find_mapping from outside a irq_{enter,exit} section is unsafe and produces ugly messages if CONFIG_PROVE_RCU is enabled: If coming from the idle state, the rcu_read_lock call in irq_find_mapping will generate an unpleasant warning: =============================== [ INFO: suspicious RCU usage. ] 3.16.0-rc1+ #135 Not tainted ------------------------------- include/linux/rcupdate.h:871 rcu_read_lock() used illegally while idle! other info that might help us debug this: RCU used illegally from idle CPU! rcu_scheduler_active = 1, debug_locks = 0 RCU used illegally from extended quiescent state! 1 lock held by swapper/0/0: #0: (rcu_read_lock){......}, at: [] irq_find_mapping+0x4c/0x198 As this issue is fairly widespread and involves at least three different architectures, a possible solution is to add a new handle_domain_irq entry point into the generic IRQ code that the interrupt controller code can call. This new function takes an irq_domain, and calls into irq_find_domain inside the irq_{enter,exit} block. An additional "lookup" parameter is used to allow non-domain architecture code to be replaced by this as well. Interrupt controllers can then be updated to use the new mechanism. This code is sitting behind a new CONFIG_HANDLE_DOMAIN_IRQ, as not all architectures implement set_irq_regs (yes, mn10300, I'm looking at you...). Reported-by: Vladimir Murzin Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-2-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- include/linux/irqdesc.h | 19 +++++++++++++++++++ kernel/irq/Kconfig | 3 +++ kernel/irq/irqdesc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 472c021a2d4f..ff24667cd86c 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -12,6 +12,8 @@ struct irq_affinity_notify; struct proc_dir_entry; struct module; struct irq_desc; +struct irq_domain; +struct pt_regs; /** * struct irq_desc - interrupt descriptor @@ -118,6 +120,23 @@ static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *de int generic_handle_irq(unsigned int irq); +#ifdef CONFIG_HANDLE_DOMAIN_IRQ +/* + * Convert a HW interrupt number to a logical one using a IRQ domain, + * and handle the result interrupt number. Return -EINVAL if + * conversion failed. Providing a NULL domain indicates that the + * conversion has already been done. + */ +int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, + bool lookup, struct pt_regs *regs); + +static inline int handle_domain_irq(struct irq_domain *domain, + unsigned int hwirq, struct pt_regs *regs) +{ + return __handle_domain_irq(domain, hwirq, true, regs); +} +#endif + /* Test to see if a driver has successfully requested an irq */ static inline int irq_has_action(unsigned int irq) { diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index d269cecdfbf0..225086b2652e 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -55,6 +55,9 @@ config GENERIC_IRQ_CHIP config IRQ_DOMAIN bool +config HANDLE_DOMAIN_IRQ + bool + config IRQ_DOMAIN_DEBUG bool "Expose hardware/virtual IRQ mapping via debugfs" depends on IRQ_DOMAIN && DEBUG_FS diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 1487a123db5c..a1782f88f0af 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "internals.h" @@ -336,6 +337,47 @@ int generic_handle_irq(unsigned int irq) } EXPORT_SYMBOL_GPL(generic_handle_irq); +#ifdef CONFIG_HANDLE_DOMAIN_IRQ +/** + * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain + * @domain: The domain where to perform the lookup + * @hwirq: The HW irq number to convert to a logical one + * @lookup: Whether to perform the domain lookup or not + * @regs: Register file coming from the low-level handling code + * + * Returns: 0 on success, or -EINVAL if conversion has failed + */ +int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, + bool lookup, struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + unsigned int irq = hwirq; + int ret = 0; + + irq_enter(); + +#ifdef CONFIG_IRQ_DOMAIN + if (lookup) + irq = irq_find_mapping(domain, hwirq); +#endif + + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. + */ + if (unlikely(!irq || irq >= nr_irqs)) { + ack_bad_irq(irq); + ret = -EINVAL; + } else { + generic_handle_irq(irq); + } + + irq_exit(); + set_irq_regs(old_regs); + return ret; +} +#endif + /* Dynamic interrupt handling */ /** -- cgit v1.2.3 From a1ddc74a23c89ae236b163a3b0887f8c344aaa4a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:17 +0100 Subject: arm64: Convert handle_IRQ to use __handle_domain_irq In order to limit code duplication, convert the architecture specific handle_IRQ to use the generic __handle_domain_irq function. Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Link: https://lkml.kernel.org/r/1409047421-27649-3-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm64/Kconfig | 1 + arch/arm64/kernel/irq.c | 18 +----------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index fd4e81a4e1ce..1f16ed96f3f6 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -30,6 +30,7 @@ config ARM64 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL + select HANDLE_DOMAIN_IRQ select HARDIRQS_SW_RESEND select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_JUMP_LABEL diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 0f08dfd69ebc..2c0e2a744723 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -48,23 +48,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) */ void handle_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); - - /* - * Some hardware gives randomly wrong interrupts. Rather - * than crashing, do something sensible. - */ - if (unlikely(irq >= nr_irqs)) { - pr_warn_ratelimited("Bad IRQ%u\n", irq); - ack_bad_irq(irq); - } else { - generic_handle_irq(irq); - } - - irq_exit(); - set_irq_regs(old_regs); + __handle_domain_irq(NULL, irq, false, regs); } void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) -- cgit v1.2.3 From a71b092a9c68685a270ebdde7b5986ba8787e575 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:18 +0100 Subject: ARM: Convert handle_IRQ to use __handle_domain_irq In order to limit code duplication, convert the architecture specific handle_IRQ to use the generic __handle_domain_irq function. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-4-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm/Kconfig | 1 + arch/arm/kernel/irq.c | 19 +------------------ 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c49a775937db..5918d40bb12e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -24,6 +24,7 @@ config ARM select GENERIC_SMP_IDLE_THREAD select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HANDLE_DOMAIN_IRQ select HARDIRQS_SW_RESEND select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 2c4257604513..0509d07c96ab 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -65,24 +65,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) */ void handle_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); - - /* - * Some hardware gives randomly wrong interrupts. Rather - * than crashing, do something sensible. - */ - if (unlikely(irq >= nr_irqs)) { - if (printk_ratelimit()) - printk(KERN_WARNING "Bad IRQ%u\n", irq); - ack_bad_irq(irq); - } else { - generic_handle_irq(irq); - } - - irq_exit(); - set_irq_regs(old_regs); + __handle_domain_irq(NULL, irq, false, regs); } /* -- cgit v1.2.3 From d1f6f28f68507e3ae67203de3e7ab7e5b9bf0082 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:19 +0100 Subject: openrisc: Convert handle_IRQ to use __handle_domain_irq In order to limit code duplication, convert the architecture specific handle_IRQ to use the generic __handle_domain_irq function. Signed-off-by: Marc Zyngier Acked-by: Stefan Kristiansson Link: https://lkml.kernel.org/r/1409047421-27649-5-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/openrisc/Kconfig | 1 + arch/openrisc/kernel/irq.c | 9 +-------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 88e83368bbf5..e5a693b16da2 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -8,6 +8,7 @@ config OPENRISC select OF select OF_EARLY_FLATTREE select IRQ_DOMAIN + select HANDLE_DOMAIN_IRQ select HAVE_MEMBLOCK select ARCH_REQUIRE_GPIOLIB select HAVE_ARCH_TRACEHOOK diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c index 967eb1430203..e9aaf280b7d9 100644 --- a/arch/openrisc/kernel/irq.c +++ b/arch/openrisc/kernel/irq.c @@ -50,14 +50,7 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) void handle_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); - - generic_handle_irq(irq); - - irq_exit(); - set_irq_regs(old_regs); + __handle_domain_irq(NULL, irq, false, regs); } void __irq_entry do_IRQ(struct pt_regs *regs) -- cgit v1.2.3 From 60031b4ef40b62f6563cc6635f670a144f182b83 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:20 +0100 Subject: irqchip: gic: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-6-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4b959e606fe8..480bae864a87 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -270,8 +270,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) irqnr = irqstat & GICC_IAR_INT_ID_MASK; if (likely(irqnr > 15 && irqnr < 1021)) { - irqnr = irq_find_mapping(gic->domain, irqnr); - handle_IRQ(irqnr, regs); + handle_domain_irq(gic->domain, irqnr, regs); continue; } if (irqnr < 16) { -- cgit v1.2.3 From e89c6a06b876239161653da84dbb2a0e243768b8 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:21 +0100 Subject: irqchip: armada-370-xp: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-7-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 574aba0eba4e..fa75a29a0408 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -393,13 +393,15 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained) if (!(msimask & BIT(msinr))) continue; - irq = irq_find_mapping(armada_370_xp_msi_domain, - msinr - 16); - - if (is_chained) + if (is_chained) { + irq = irq_find_mapping(armada_370_xp_msi_domain, + msinr - 16); generic_handle_irq(irq); - else - handle_IRQ(irq, regs); + } else { + irq = msinr - 16; + handle_domain_irq(armada_370_xp_msi_domain, + irq, regs); + } } } #else @@ -444,9 +446,8 @@ armada_370_xp_handle_irq(struct pt_regs *regs) break; if (irqnr > 1) { - irqnr = irq_find_mapping(armada_370_xp_mpic_domain, - irqnr); - handle_IRQ(irqnr, regs); + handle_domain_irq(armada_370_xp_mpic_domain, + irqnr, regs); continue; } -- cgit v1.2.3 From a8e10cb769eb94277658d3f3bce12e10b5652b7f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:22 +0100 Subject: irqchip: clps711x: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-8-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-clps711x.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c index 33340dc97d1d..33127f131d78 100644 --- a/drivers/irqchip/irq-clps711x.c +++ b/drivers/irqchip/irq-clps711x.c @@ -76,24 +76,20 @@ static struct { static asmlinkage void __exception_irq_entry clps711x_irqh(struct pt_regs *regs) { - u32 irqnr, irqstat; + u32 irqstat; do { irqstat = readw_relaxed(clps711x_intc->intmr[0]) & readw_relaxed(clps711x_intc->intsr[0]); - if (irqstat) { - irqnr = irq_find_mapping(clps711x_intc->domain, - fls(irqstat) - 1); - handle_IRQ(irqnr, regs); - } + if (irqstat) + handle_domain_irq(clps711x_intc->domain, + fls(irqstat) - 1, regs); irqstat = readw_relaxed(clps711x_intc->intmr[1]) & readw_relaxed(clps711x_intc->intsr[1]); - if (irqstat) { - irqnr = irq_find_mapping(clps711x_intc->domain, - fls(irqstat) - 1 + 16); - handle_IRQ(irqnr, regs); - } + if (irqstat) + handle_domain_irq(clps711x_intc->domain, + fls(irqstat) - 1 + 16, regs); } while (irqstat); } -- cgit v1.2.3 From b918402c8092e9f55ad1e848c4264cc0c9ea7513 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:23 +0100 Subject: irqchip: mmp: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-9-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-mmp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index 1c3e2c9b46ba..c0da57bdb89d 100644 --- a/drivers/irqchip/irq-mmp.c +++ b/drivers/irqchip/irq-mmp.c @@ -196,26 +196,24 @@ static struct mmp_intc_conf mmp2_conf = { static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs) { - int irq, hwirq; + int hwirq; hwirq = readl_relaxed(mmp_icu_base + PJ1_INT_SEL); if (!(hwirq & SEL_INT_PENDING)) return; hwirq &= SEL_INT_NUM_MASK; - irq = irq_find_mapping(icu_data[0].domain, hwirq); - handle_IRQ(irq, regs); + handle_domain_irq(icu_data[0].domain, hwirq, regs); } static void __exception_irq_entry mmp2_handle_irq(struct pt_regs *regs) { - int irq, hwirq; + int hwirq; hwirq = readl_relaxed(mmp_icu_base + PJ4_INT_SEL); if (!(hwirq & SEL_INT_PENDING)) return; hwirq &= SEL_INT_NUM_MASK; - irq = irq_find_mapping(icu_data[0].domain, hwirq); - handle_IRQ(irq, regs); + handle_domain_irq(icu_data[0].domain, hwirq, regs); } /* MMP (ARMv5) */ -- cgit v1.2.3 From b3410e5f4b6a9611fcdff8927d7ce04757708d96 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:24 +0100 Subject: irqchip: mxs: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Shawn Guo Link: https://lkml.kernel.org/r/1409047421-27649-10-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-mxs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 4044ff287663..e4acf1e3f8e3 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -78,8 +78,7 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs) irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET); __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR); - irqnr = irq_find_mapping(icoll_domain, irqnr); - handle_IRQ(irqnr, regs); + handle_domain_irq(icoll_domain, irqnr, regs); } static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq, -- cgit v1.2.3 From f4bc9288b4a29ead48425dd7d1bf4b825a8aff58 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:25 +0100 Subject: irqchip: orion: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-11-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-orion.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index 34d18b48bb78..ad0c0f6f1d65 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c @@ -43,9 +43,8 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs) gc->mask_cache; while (stat) { u32 hwirq = __fls(stat); - u32 irq = irq_find_mapping(orion_irq_domain, - gc->irq_base + hwirq); - handle_IRQ(irq, regs); + handle_domain_irq(orion_irq_domain, + gc->irq_base + hwirq, regs); stat &= ~(1 << hwirq); } } -- cgit v1.2.3 From cf86bfdd68997b584f4a8f1da9ffd2fae852a5a9 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:26 +0100 Subject: irqchip: s3c24xx: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-12-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-s3c24xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c index 78a6accd205f..c8d373fcd823 100644 --- a/drivers/irqchip/irq-s3c24xx.c +++ b/drivers/irqchip/irq-s3c24xx.c @@ -339,7 +339,6 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, { int pnd; int offset; - int irq; pnd = __raw_readl(intc->reg_intpnd); if (!pnd) @@ -365,8 +364,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, if (!(pnd & (1 << offset))) offset = __ffs(pnd); - irq = irq_find_mapping(intc->domain, intc_offset + offset); - handle_IRQ(irq, regs); + handle_domain_irq(intc->domain, intc_offset + offset, regs); return true; } -- cgit v1.2.3 From c15018e9192bbaa1a0f68ebee0284f701491b800 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:27 +0100 Subject: irqchip: sirfsoc: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-13-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-sirfsoc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-sirfsoc.c b/drivers/irqchip/irq-sirfsoc.c index 5e54f6d71e77..a469355df352 100644 --- a/drivers/irqchip/irq-sirfsoc.c +++ b/drivers/irqchip/irq-sirfsoc.c @@ -50,12 +50,10 @@ sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) { void __iomem *base = sirfsoc_irqdomain->host_data; - u32 irqstat, irqnr; + u32 irqstat; irqstat = readl_relaxed(base + SIRFSOC_INIT_IRQ_ID); - irqnr = irq_find_mapping(sirfsoc_irqdomain, irqstat & 0xff); - - handle_IRQ(irqnr, regs); + handle_domain_irq(sirfsoc_irqdomain, irqstat & 0xff, regs); } static int __init sirfsoc_irq_init(struct device_node *np, -- cgit v1.2.3 From 21d06d91c23ddb24895bbe82ba96633864891f6e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:28 +0100 Subject: irqchip: sun4i: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-14-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-sun4i.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index 6fcef4a95a18..64155b686081 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c @@ -136,7 +136,7 @@ IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-a10-ic", sun4i_of_init); static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) { - u32 irq, hwirq; + u32 hwirq; /* * hwirq == 0 can mean one of 3 things: @@ -154,8 +154,7 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) return; do { - irq = irq_find_mapping(sun4i_irq_domain, hwirq); - handle_IRQ(irq, regs); + handle_domain_irq(sun4i_irq_domain, hwirq, regs); hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; } while (hwirq != 0); } -- cgit v1.2.3 From 84bc7399099344e41672d72864e3c34297a877d2 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:29 +0100 Subject: irqchip: versatile-fpga: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-15-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-versatile-fpga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index ccf58548b161..1ab451729a5c 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -96,7 +96,7 @@ static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs) while ((status = readl(f->base + IRQ_STATUS))) { irq = ffs(status) - 1; - handle_IRQ(irq_find_mapping(f->domain, irq), regs); + handle_domain_irq(f->domain, irq, regs); handled = 1; } -- cgit v1.2.3 From 0af83b3b00cc302388beea8b6bd48c5fcbc715a8 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:30 +0100 Subject: irqchip: vic: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-16-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-vic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 7d35287f9e90..54089debf2dc 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -219,7 +219,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { irq = ffs(stat) - 1; - handle_IRQ(irq_find_mapping(vic->domain, irq), regs); + handle_domain_irq(vic->domain, irq, regs); handled = 1; } -- cgit v1.2.3 From 0beb65041e86ea313eaceaa6a04c87f9cc01f6b1 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:31 +0100 Subject: irqchip: vt8500: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-17-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-vt8500.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c index eb6e91efdec8..b7af816f2769 100644 --- a/drivers/irqchip/irq-vt8500.c +++ b/drivers/irqchip/irq-vt8500.c @@ -181,7 +181,7 @@ static struct irq_domain_ops vt8500_irq_domain_ops = { static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) { u32 stat, i; - int irqnr, virq; + int irqnr; void __iomem *base; /* Loop through each active controller */ @@ -198,8 +198,7 @@ static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs) continue; } - virq = irq_find_mapping(intc[i].domain, irqnr); - handle_IRQ(virq, regs); + handle_domain_irq(intc[i].domain, irqnr, regs); } } -- cgit v1.2.3 From d8c0ffa56798a9b6dc6ee44d230a50f1fe0a10d4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:32 +0100 Subject: irqchip: zevio: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-18-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-zevio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c index ceb3a4318f73..e4ef74ed454a 100644 --- a/drivers/irqchip/irq-zevio.c +++ b/drivers/irqchip/irq-zevio.c @@ -56,8 +56,7 @@ static void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) while (readl(zevio_irq_io + IO_STATUS)) { irqnr = readl(zevio_irq_io + IO_CURRENT); - irqnr = irq_find_mapping(zevio_irq_domain, irqnr); - handle_IRQ(irqnr, regs); + handle_domain_irq(zevio_irq_domain, irqnr, regs); }; } -- cgit v1.2.3 From ebc6de0056e277a0283845536fd219a96806fc80 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:33 +0100 Subject: irqchip: gic-v3: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/1409047421-27649-19-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-v3.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 57eaa5a0b1e3..9e3144975696 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -274,14 +274,13 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs irqnr = gic_read_iar(); if (likely(irqnr > 15 && irqnr < 1020)) { - u64 irq = irq_find_mapping(gic_data.domain, irqnr); - if (likely(irq)) { - handle_IRQ(irq, regs); - continue; + int err; + err = handle_domain_irq(gic_data.domain, irqnr, regs); + if (err) { + WARN_ONCE(true, "Unexpected SPI received!\n"); + gic_write_eoir(irqnr); } - - WARN_ONCE(true, "Unexpected SPI received!\n"); - gic_write_eoir(irqnr); + continue; } if (irqnr < 16) { gic_write_eoir(irqnr); -- cgit v1.2.3 From 841f2aa46299b894ce146cd7d2a8fd9a1f6dbdcb Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:34 +0100 Subject: irqchip: atmel-aic: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Nicolas Ferre Acked-by: Boris Brezillon Link: https://lkml.kernel.org/r/1409047421-27649-20-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-atmel-aic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index a82869e9fb26..9a2cf3c1a3a5 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -68,12 +68,10 @@ aic_handle(struct pt_regs *regs) irqnr = irq_reg_readl(gc->reg_base + AT91_AIC_IVR); irqstat = irq_reg_readl(gc->reg_base + AT91_AIC_ISR); - irqnr = irq_find_mapping(aic_domain, irqnr); - if (!irqstat) irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR); else - handle_IRQ(irqnr, regs); + handle_domain_irq(aic_domain, irqnr, regs); } static int aic_retrigger(struct irq_data *d) -- cgit v1.2.3 From 31b7b6a86e9b86b8d97b3bc47b22585074ad115b Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:35 +0100 Subject: irqchip: atmel-aic5: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Nicolas Ferre Acked-by: Boris Brezillon Link: https://lkml.kernel.org/r/1409047421-27649-21-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-atmel-aic5.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index edb227081524..04fe2c1b5178 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -78,12 +78,10 @@ aic5_handle(struct pt_regs *regs) irqnr = irq_reg_readl(gc->reg_base + AT91_AIC5_IVR); irqstat = irq_reg_readl(gc->reg_base + AT91_AIC5_ISR); - irqnr = irq_find_mapping(aic5_domain, irqnr); - if (!irqstat) irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR); else - handle_IRQ(irqnr, regs); + handle_domain_irq(aic5_domain, irqnr, regs); } static void aic5_mask(struct irq_data *d) -- cgit v1.2.3 From b0fee1dc7883c3c4b2319d384decdd1563cf30bb Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:36 +0100 Subject: irqchip: or1k-pic: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Stefan Kristiansson Link: https://lkml.kernel.org/r/1409047421-27649-22-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-or1k-pic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c index 17ff033d9925..e93d079fe069 100644 --- a/drivers/irqchip/irq-or1k-pic.c +++ b/drivers/irqchip/irq-or1k-pic.c @@ -113,7 +113,7 @@ static inline int pic_get_irq(int first) else hwirq = hwirq + first - 1; - return irq_find_mapping(root_domain, hwirq); + return hwirq; } static void or1k_pic_handle_irq(struct pt_regs *regs) @@ -121,7 +121,7 @@ static void or1k_pic_handle_irq(struct pt_regs *regs) int irq = -1; while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) - handle_IRQ(irq, regs); + handle_domain_irq(root_domain, irq, regs); } static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) -- cgit v1.2.3 From 9705ca3dea5a7c5ae57fa65ab256f7b1b7d848c0 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:37 +0100 Subject: ARM: imx: avic: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Shawn Guo Link: https://lkml.kernel.org/r/1409047421-27649-23-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm/mach-imx/avic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 24b103c67f82..1a8932335b21 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -144,7 +144,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) if (nivector == 0xffff) break; - handle_IRQ(irq_find_mapping(domain, nivector), regs); + handle_domain_irq(domain, nivector, regs); } while (1); } -- cgit v1.2.3 From cb221761001dc6c3eaf8b1edda0901b8c5c801bd Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:38 +0100 Subject: ARM: imx: tzic: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Shawn Guo Link: https://lkml.kernel.org/r/1409047421-27649-24-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm/mach-imx/tzic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index 1d4f384ca773..4de65eeda1eb 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -141,8 +141,7 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) while (stat) { handled = 1; irqofs = fls(stat) - 1; - handle_IRQ(irq_find_mapping(domain, - irqofs + i * 32), regs); + handle_domain_irq(domain, irqofs + i * 32, regs); stat &= ~(1 << irqofs); } } -- cgit v1.2.3 From f978999f60966076f3f43ed1894b54507c8ddfc9 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:39 +0100 Subject: ARM: omap2: irq: Convert to handle_domain_irq Use the new handle_domain_irq method to handle interrupts. Signed-off-by: Marc Zyngier Acked-by: Tony Lindgren Link: https://lkml.kernel.org/r/1409047421-27649-25-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm/mach-omap2/irq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 35b8590c322e..a62ba5aebe63 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -248,8 +248,7 @@ out: irqnr &= ACTIVEIRQ_MASK; if (irqnr) { - irqnr = irq_find_mapping(domain, irqnr); - handle_IRQ(irqnr, regs); + handle_domain_irq(domain, irqnr, regs); handled_irq = 1; } } while (irqnr); -- cgit v1.2.3 From c59e1ef874e699bb37c8ed20b70113e1e8f45f52 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:40 +0100 Subject: arm64: Get rid of handle_IRQ All the arm64 irqchip drivers have been converted to handle_domain_irq, making it possible to remove the handle_IRQ stub entierely. Signed-off-by: Marc Zyngier Acked-by: Catalin Marinas Link: https://lkml.kernel.org/r/1409047421-27649-26-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/arm64/include/asm/hardirq.h | 2 -- arch/arm64/kernel/irq.c | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h index 0be67821f9ce..e8a3268a891c 100644 --- a/arch/arm64/include/asm/hardirq.h +++ b/arch/arm64/include/asm/hardirq.h @@ -47,8 +47,6 @@ static inline void ack_bad_irq(unsigned int irq) irq_err_count++; } -extern void handle_IRQ(unsigned int, struct pt_regs *); - /* * No arch-specific IRQ flags. */ diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 2c0e2a744723..67ca197277ee 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -40,17 +40,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) return 0; } -/* - * handle_IRQ handles all hardware IRQ's. Decoded IRQs should - * not come via this function. Instead, they should provide their - * own 'handler'. Used by platform code implementing C-based 1st - * level decoding. - */ -void handle_IRQ(unsigned int irq, struct pt_regs *regs) -{ - __handle_domain_irq(NULL, irq, false, regs); -} - void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) { if (handle_arch_irq) -- cgit v1.2.3 From 087fe000f086c933f831044cbd0e69b4e140f38c Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 26 Aug 2014 11:03:41 +0100 Subject: openrisc: Get rid of handle_IRQ The openrisc irqchip driver has been converted to handle_domain_irq, making it possible to remove the handle_IRQ stub entierely. Signed-off-by: Marc Zyngier Acked-by: Stefan Kristiansson Link: https://lkml.kernel.org/r/1409047421-27649-27-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper --- arch/openrisc/include/asm/irq.h | 1 - arch/openrisc/kernel/irq.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/arch/openrisc/include/asm/irq.h b/arch/openrisc/include/asm/irq.h index b84634cc95eb..d9eee0a2b7b4 100644 --- a/arch/openrisc/include/asm/irq.h +++ b/arch/openrisc/include/asm/irq.h @@ -24,7 +24,6 @@ #define NO_IRQ (-1) -void handle_IRQ(unsigned int, struct pt_regs *); extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif /* __ASM_OPENRISC_IRQ_H__ */ diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c index e9aaf280b7d9..35e478a93116 100644 --- a/arch/openrisc/kernel/irq.c +++ b/arch/openrisc/kernel/irq.c @@ -48,11 +48,6 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) handle_arch_irq = handle_irq; } -void handle_IRQ(unsigned int irq, struct pt_regs *regs) -{ - __handle_domain_irq(NULL, irq, false, regs); -} - void __irq_entry do_IRQ(struct pt_regs *regs) { handle_arch_irq(regs); -- cgit v1.2.3