[PATCH 6/7] ARM: nuc900: use SPARSE_IRQ
Arnd Bergmann
arnd at arndb.de
Thu Jul 14 04:11:34 PDT 2016
ARCH_MULTIPLATFORM implies sparse IRQs, so in we first have to make sure that actually
works. This enables CONFIG_SPARSE_IRQ for all of mach-w90x900.
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-w90x900/include/mach/irqs.h | 5 -----
arch/arm/mach-w90x900/irq.c | 22 +++++++++++++++++++++-
drivers/irqchip/irq-nuc900.c | 2 +-
4 files changed, 23 insertions(+), 7 deletions(-)
delete mode 100644 arch/arm/mach-w90x900/include/mach/irqs.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 908694886088..160dbf993660 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -504,6 +504,7 @@ config ARCH_W90X900
select GENERIC_CLOCKEVENTS
select GPIOLIB
select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
help
Support for Nuvoton (Winbond logic dept.) ARM9 processor,
At present, the w90x900 has been renamed nuc900, regarding
diff --git a/arch/arm/mach-w90x900/include/mach/irqs.h b/arch/arm/mach-w90x900/include/mach/irqs.h
deleted file mode 100644
index 277903857030..000000000000
--- a/arch/arm/mach-w90x900/include/mach/irqs.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(CONFIG_SOC_NUC900)
-#define NR_IRQS (IRQ_ADC+1)
-#else
-#define NR_IRQS 62
-#endif
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
index 42d9af897c42..726f646c992b 100644
--- a/arch/arm/mach-w90x900/irq.c
+++ b/arch/arm/mach-w90x900/irq.c
@@ -20,6 +20,7 @@
#include <linux/ioport.h>
#include <linux/ptrace.h>
#include <linux/device.h>
+#include <linux/irqdomain.h>
#include <linux/io.h>
#include <asm/exception.h>
@@ -203,6 +204,8 @@ static struct irq_chip nuc900_irq_chip = {
.irq_unmask = nuc900_irq_unmask,
};
+static struct irq_domain *aic_domain;
+
static void __exception_irq_entry nuc900_handle_irq(struct pt_regs *regs)
{
int hwirq;
@@ -210,15 +213,32 @@ static void __exception_irq_entry nuc900_handle_irq(struct pt_regs *regs)
(void)readl(REG_AIC_IPER);
hwirq = readl(REG_AIC_ISNR);
- handle_IRQ(hwirq, regs);
+ handle_domain_irq(aic_domain, hwirq, regs);
}
+static int aic_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(virq, &nuc900_irq_chip, handle_level_irq);
+ irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
+ return 0;
+}
+
+static struct irq_domain_ops aic_irq_domain_ops = {
+ .map = aic_irq_domain_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
void __init nuc900_init_irq(void)
{
int irqno;
set_handle_irq(nuc900_handle_irq);
+ aic_domain = irq_domain_add_simple(NULL, 31, 1,
+ &aic_irq_domain_ops, NULL);
+
__raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) {
diff --git a/drivers/irqchip/irq-nuc900.c b/drivers/irqchip/irq-nuc900.c
index c4b2e39f7662..a595139f2f9c 100644
--- a/drivers/irqchip/irq-nuc900.c
+++ b/drivers/irqchip/irq-nuc900.c
@@ -129,7 +129,7 @@ static int __init aic_of_init(struct device_node *node,
writel(0xFFFFFFFC, aic_base + REG_AIC_MDCR);
writel(0xFFFFFFFF, aic_base + REG_AIC_MDCRH);
- aic_domain = irq_domain_add_linear(node, NR_IRQS,
+ aic_domain = irq_domain_add_linear(node, 64,
&aic_irq_domain_ops, NULL);
if (!aic_domain) {
--
2.9.0
More information about the linux-arm-kernel
mailing list