aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-01-13 16:30:48 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-13 16:30:48 -0500
commitfa0fe48fcca9ea7f8c13e21d2646bbaa1747d183 (patch)
tree803a155f42d989ad15d3dc74389dfa6277a78895 /arch/arm
parent5ff3fd27161127cc464fc04548d58672a6a8272a (diff)
[ARM] Separate VIC (vectored interrupt controller) support from Versatile
Other machines may wish to make use of the VIC support code, so move it to arch/arm/common. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/common/Kconfig7
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/vic.c92
-rw-r--r--arch/arm/mach-versatile/core.c58
5 files changed, 104 insertions, 55 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 50b9afa8ae6d..c4d585e2de7a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -180,6 +180,7 @@ config ARCH_OMAP
180config ARCH_VERSATILE 180config ARCH_VERSATILE
181 bool "Versatile" 181 bool "Versatile"
182 select ARM_AMBA 182 select ARM_AMBA
183 select ARM_VIC
183 select ICST307 184 select ICST307
184 help 185 help
185 This enables support for ARM Ltd Versatile board. 186 This enables support for ARM Ltd Versatile board.
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index d7509c7a3c5e..5e34ca6d38b6 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -1,7 +1,10 @@
1config ICST525 1config ARM_GIC
2 bool 2 bool
3 3
4config ARM_GIC 4config ARM_VIC
5 bool
6
7config ICST525
5 bool 8 bool
6 9
7config ICST307 10config ICST307
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index ec8d17c96906..c81a2ff6b5be 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-y += rtctime.o 5obj-y += rtctime.o
6obj-$(CONFIG_ARM_GIC) += gic.o 6obj-$(CONFIG_ARM_GIC) += gic.o
7obj-$(CONFIG_ARM_VIC) += vic.o
7obj-$(CONFIG_ICST525) += icst525.o 8obj-$(CONFIG_ICST525) += icst525.o
8obj-$(CONFIG_ICST307) += icst307.o 9obj-$(CONFIG_ICST307) += icst307.o
9obj-$(CONFIG_SA1111) += sa1111.o 10obj-$(CONFIG_SA1111) += sa1111.o
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
new file mode 100644
index 000000000000..a45ed1687a59
--- /dev/null
+++ b/arch/arm/common/vic.c
@@ -0,0 +1,92 @@
1/*
2 * linux/arch/arm/common/vic.c
3 *
4 * Copyright (C) 1999 - 2003 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/init.h>
22#include <linux/list.h>
23
24#include <asm/io.h>
25#include <asm/irq.h>
26#include <asm/mach/irq.h>
27#include <asm/hardware/vic.h>
28
29static void __iomem *vic_base;
30
31static void vic_mask_irq(unsigned int irq)
32{
33 irq -= IRQ_VIC_START;
34 writel(1 << irq, vic_base + VIC_INT_ENABLE_CLEAR);
35}
36
37static void vic_unmask_irq(unsigned int irq)
38{
39 irq -= IRQ_VIC_START;
40 writel(1 << irq, vic_base + VIC_INT_ENABLE);
41}
42
43static struct irqchip vic_chip = {
44 .ack = vic_mask_irq,
45 .mask = vic_mask_irq,
46 .unmask = vic_unmask_irq,
47};
48
49void __init vic_init(void __iomem *base, u32 vic_sources)
50{
51 unsigned int i;
52
53 vic_base = base;
54
55 /* Disable all interrupts initially. */
56
57 writel(0, vic_base + VIC_INT_SELECT);
58 writel(0, vic_base + VIC_INT_ENABLE);
59 writel(~0, vic_base + VIC_INT_ENABLE_CLEAR);
60 writel(0, vic_base + VIC_IRQ_STATUS);
61 writel(0, vic_base + VIC_ITCR);
62 writel(~0, vic_base + VIC_INT_SOFT_CLEAR);
63
64 /*
65 * Make sure we clear all existing interrupts
66 */
67 writel(0, vic_base + VIC_VECT_ADDR);
68 for (i = 0; i < 19; i++) {
69 unsigned int value;
70
71 value = readl(vic_base + VIC_VECT_ADDR);
72 writel(value, vic_base + VIC_VECT_ADDR);
73 }
74
75 for (i = 0; i < 16; i++) {
76 void __iomem *reg = vic_base + VIC_VECT_CNTL0 + (i * 4);
77 writel(VIC_VECT_CNTL_ENABLE | i, reg);
78 }
79
80 writel(32, vic_base + VIC_DEF_VECT_ADDR);
81
82 for (i = 0; i < 32; i++) {
83 unsigned int irq = IRQ_VIC_START + i;
84
85 set_irq_chip(irq, &vic_chip);
86
87 if (vic_sources & (1 << i)) {
88 set_irq_handler(irq, do_level_IRQ);
89 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
90 }
91 }
92}
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 90023745b23a..9ebbe808b41d 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -35,6 +35,7 @@
35#include <asm/leds.h> 35#include <asm/leds.h>
36#include <asm/hardware/arm_timer.h> 36#include <asm/hardware/arm_timer.h>
37#include <asm/hardware/icst307.h> 37#include <asm/hardware/icst307.h>
38#include <asm/hardware/vic.h>
38 39
39#include <asm/mach/arch.h> 40#include <asm/mach/arch.h>
40#include <asm/mach/flash.h> 41#include <asm/mach/flash.h>
@@ -56,24 +57,6 @@
56#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) 57#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
57#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) 58#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
58 59
59static void vic_mask_irq(unsigned int irq)
60{
61 irq -= IRQ_VIC_START;
62 writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
63}
64
65static void vic_unmask_irq(unsigned int irq)
66{
67 irq -= IRQ_VIC_START;
68 writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE);
69}
70
71static struct irqchip vic_chip = {
72 .ack = vic_mask_irq,
73 .mask = vic_mask_irq,
74 .unmask = vic_unmask_irq,
75};
76
77static void sic_mask_irq(unsigned int irq) 60static void sic_mask_irq(unsigned int irq)
78{ 61{
79 irq -= IRQ_SIC_START; 62 irq -= IRQ_SIC_START;
@@ -127,43 +110,12 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
127 110
128void __init versatile_init_irq(void) 111void __init versatile_init_irq(void)
129{ 112{
130 unsigned int i, value; 113 unsigned int i;
131
132 /* Disable all interrupts initially. */
133 114
134 writel(0, VA_VIC_BASE + VIC_INT_SELECT); 115 vic_init(VA_VIC_BASE, ~(1 << 31));
135 writel(0, VA_VIC_BASE + VIC_IRQ_ENABLE);
136 writel(~0, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
137 writel(0, VA_VIC_BASE + VIC_IRQ_STATUS);
138 writel(0, VA_VIC_BASE + VIC_ITCR);
139 writel(~0, VA_VIC_BASE + VIC_IRQ_SOFT_CLEAR);
140
141 /*
142 * Make sure we clear all existing interrupts
143 */
144 writel(0, VA_VIC_BASE + VIC_VECT_ADDR);
145 for (i = 0; i < 19; i++) {
146 value = readl(VA_VIC_BASE + VIC_VECT_ADDR);
147 writel(value, VA_VIC_BASE + VIC_VECT_ADDR);
148 }
149
150 for (i = 0; i < 16; i++) {
151 value = readl(VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
152 writel(value | VICVectCntl_Enable | i, VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
153 }
154
155 writel(32, VA_VIC_BASE + VIC_DEF_VECT_ADDR);
156
157 for (i = IRQ_VIC_START; i <= IRQ_VIC_END; i++) {
158 if (i != IRQ_VICSOURCE31) {
159 set_irq_chip(i, &vic_chip);
160 set_irq_handler(i, do_level_IRQ);
161 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
162 }
163 }
164 116
165 set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq); 117 set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
166 vic_unmask_irq(IRQ_VICSOURCE31); 118 enable_irq(IRQ_VICSOURCE31);
167 119
168 /* Do second interrupt controller */ 120 /* Do second interrupt controller */
169 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); 121 writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
@@ -877,7 +829,7 @@ static unsigned long versatile_gettimeoffset(void)
877 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; 829 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
878 do { 830 do {
879 ticks1 = ticks2; 831 ticks1 = ticks2;
880 status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); 832 status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS);
881 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; 833 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
882 } while (ticks2 > ticks1); 834 } while (ticks2 > ticks1);
883 835