@@ -1,18 +1,3 @@
-config ARM_VIC
- bool
- select IRQ_DOMAIN
- select MULTI_IRQ_HANDLER
-
-config ARM_VIC_NR
- int
- default 4 if ARCH_S5PV210
- default 3 if ARCH_S5PC100
- default 2
- depends on ARM_VIC
- help
- The maximum number of VICs available in the system, for
- power management.
-
config ICST
bool
@@ -2,7 +2,6 @@
# Makefile for the linux kernel.
#
-obj-$(CONFIG_ARM_VIC) += vic.o
obj-$(CONFIG_ICST) += icst.o
obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
@@ -9,3 +9,18 @@ config ARM_GIC
config GIC_NON_BANKED
bool
+
+config ARM_VIC
+ bool
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+
+config ARM_VIC_NR
+ int
+ default 4 if ARCH_S5PV210
+ default 3 if ARCH_S5PC100
+ default 2
+ depends on ARM_VIC
+ help
+ The maximum number of VICs available in the system, for
+ power management.
@@ -2,3 +2,4 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_ARM_GIC) += irq-gic.o
+obj-$(CONFIG_ARM_VIC) += irq-vic.o
similarity index 98%
rename from arch/arm/common/vic.c
rename to drivers/irqchip/irq-vic.c
@@ -35,6 +35,8 @@
#include <asm/mach/irq.h>
#include <asm/hardware/vic.h>
+#include "irqchip.h"
+
/**
* struct vic_device - VIC PM device
* @irq: The IRQ number for the base of the VIC.
@@ -390,6 +392,40 @@ void __init __vic_init(void __iomem *base, unsigned int irq_start,
vic_register(base, irq_start, vic_sources, resume_sources, node);
}
+/*
+ * Handle each interrupt in a single VIC. Returns non-zero if we've
+ * handled at least one interrupt. This reads the status register
+ * before handling each interrupt, which is necessary given that
+ * handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
+ */
+static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
+{
+ u32 stat, irq;
+ int handled = 0;
+
+ while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
+ irq = ffs(stat) - 1;
+ handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
+ 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);
+}
+
/**
* vic_init() - initialise a vectored interrupt controller
* @base: iomem base address
@@ -422,6 +458,8 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
__vic_init(regs, irq_base, ~0, ~0, node);
+ set_handle_irq(vic_handle_irq);
+
return 0;
out_unmap:
@@ -429,38 +467,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
return -EIO;
}
-#endif /* CONFIG OF */
-
-/*
- * Handle each interrupt in a single VIC. Returns non-zero if we've
- * handled at least one interrupt. This reads the status register
- * before handling each interrupt, which is necessary given that
- * handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
- */
-static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
-{
- u32 stat, irq;
- int handled = 0;
- while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
- irq = ffs(stat) - 1;
- handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
- handled = 1;
- }
+IRQCHIP_DECLARE(versatile_vic, "arm,versatile-vic", vic_of_init);
+IRQCHIP_DECLARE(pl190_vic, "arm,pl190-vic", vic_of_init);
+IRQCHIP_DECLARE(pl192_vic, "arm,pl192-vic", vic_of_init);
- 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 OF */