Commit 863cb9bad8f992a9c171e90552045eac77808e84
1 parent
25f12b339c
Exists in
master
and in
7 other branches
MIPS: GIC: Remove dependencies from Malta files.
This prevents the GIC code from being reusable sanely. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Showing 4 changed files with 5 additions and 5 deletions Inline Diff
arch/mips/include/asm/gic.h
1 | /* | 1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 2000, 07 MIPS Technologies, Inc. | 6 | * Copyright (C) 2000, 07 MIPS Technologies, Inc. |
7 | * | 7 | * |
8 | * GIC Register Definitions | 8 | * GIC Register Definitions |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | #ifndef _ASM_GICREGS_H | 11 | #ifndef _ASM_GICREGS_H |
12 | #define _ASM_GICREGS_H | 12 | #define _ASM_GICREGS_H |
13 | 13 | ||
14 | #undef GICISBYTELITTLEENDIAN | 14 | #undef GICISBYTELITTLEENDIAN |
15 | 15 | ||
16 | /* Constants */ | 16 | /* Constants */ |
17 | #define GIC_POL_POS 1 | 17 | #define GIC_POL_POS 1 |
18 | #define GIC_POL_NEG 0 | 18 | #define GIC_POL_NEG 0 |
19 | #define GIC_TRIG_EDGE 1 | 19 | #define GIC_TRIG_EDGE 1 |
20 | #define GIC_TRIG_LEVEL 0 | 20 | #define GIC_TRIG_LEVEL 0 |
21 | 21 | ||
22 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | 22 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) |
23 | 23 | ||
24 | #define MSK(n) ((1 << (n)) - 1) | 24 | #define MSK(n) ((1 << (n)) - 1) |
25 | #define REG32(addr) (*(volatile unsigned int *) (addr)) | 25 | #define REG32(addr) (*(volatile unsigned int *) (addr)) |
26 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) | 26 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) |
27 | #define REGP(base, phys) REG32((unsigned long)(base) + (phys)) | 27 | #define REGP(base, phys) REG32((unsigned long)(base) + (phys)) |
28 | 28 | ||
29 | /* Accessors */ | 29 | /* Accessors */ |
30 | #define GIC_REG(segment, offset) \ | 30 | #define GIC_REG(segment, offset) \ |
31 | REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | 31 | REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS) |
32 | #define GIC_REG_ADDR(segment, offset) \ | 32 | #define GIC_REG_ADDR(segment, offset) \ |
33 | REG32(_gic_base + segment##_##SECTION_OFS + offset) | 33 | REG32(_gic_base + segment##_##SECTION_OFS + offset) |
34 | 34 | ||
35 | #define GIC_ABS_REG(segment, offset) \ | 35 | #define GIC_ABS_REG(segment, offset) \ |
36 | (_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | 36 | (_gic_base + segment##_##SECTION_OFS + offset##_##OFS) |
37 | #define GIC_REG_ABS_ADDR(segment, offset) \ | 37 | #define GIC_REG_ABS_ADDR(segment, offset) \ |
38 | (_gic_base + segment##_##SECTION_OFS + offset) | 38 | (_gic_base + segment##_##SECTION_OFS + offset) |
39 | 39 | ||
40 | #ifdef GICISBYTELITTLEENDIAN | 40 | #ifdef GICISBYTELITTLEENDIAN |
41 | #define GICREAD(reg, data) (data) = (reg), (data) = le32_to_cpu(data) | 41 | #define GICREAD(reg, data) (data) = (reg), (data) = le32_to_cpu(data) |
42 | #define GICWRITE(reg, data) (reg) = cpu_to_le32(data) | 42 | #define GICWRITE(reg, data) (reg) = cpu_to_le32(data) |
43 | #define GICBIS(reg, bits) \ | 43 | #define GICBIS(reg, bits) \ |
44 | ({unsigned int data; \ | 44 | ({unsigned int data; \ |
45 | GICREAD(reg, data); \ | 45 | GICREAD(reg, data); \ |
46 | data |= bits; \ | 46 | data |= bits; \ |
47 | GICWRITE(reg, data); \ | 47 | GICWRITE(reg, data); \ |
48 | }) | 48 | }) |
49 | 49 | ||
50 | #else | 50 | #else |
51 | #define GICREAD(reg, data) (data) = (reg) | 51 | #define GICREAD(reg, data) (data) = (reg) |
52 | #define GICWRITE(reg, data) (reg) = (data) | 52 | #define GICWRITE(reg, data) (reg) = (data) |
53 | #define GICBIS(reg, bits) (reg) |= (bits) | 53 | #define GICBIS(reg, bits) (reg) |= (bits) |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | 56 | ||
57 | /* GIC Address Space */ | 57 | /* GIC Address Space */ |
58 | #define SHARED_SECTION_OFS 0x0000 | 58 | #define SHARED_SECTION_OFS 0x0000 |
59 | #define SHARED_SECTION_SIZE 0x8000 | 59 | #define SHARED_SECTION_SIZE 0x8000 |
60 | #define VPE_LOCAL_SECTION_OFS 0x8000 | 60 | #define VPE_LOCAL_SECTION_OFS 0x8000 |
61 | #define VPE_LOCAL_SECTION_SIZE 0x4000 | 61 | #define VPE_LOCAL_SECTION_SIZE 0x4000 |
62 | #define VPE_OTHER_SECTION_OFS 0xc000 | 62 | #define VPE_OTHER_SECTION_OFS 0xc000 |
63 | #define VPE_OTHER_SECTION_SIZE 0x4000 | 63 | #define VPE_OTHER_SECTION_SIZE 0x4000 |
64 | #define USM_VISIBLE_SECTION_OFS 0x10000 | 64 | #define USM_VISIBLE_SECTION_OFS 0x10000 |
65 | #define USM_VISIBLE_SECTION_SIZE 0x10000 | 65 | #define USM_VISIBLE_SECTION_SIZE 0x10000 |
66 | 66 | ||
67 | /* Register Map for Shared Section */ | 67 | /* Register Map for Shared Section */ |
68 | 68 | ||
69 | #define GIC_SH_CONFIG_OFS 0x0000 | 69 | #define GIC_SH_CONFIG_OFS 0x0000 |
70 | 70 | ||
71 | /* Shared Global Counter */ | 71 | /* Shared Global Counter */ |
72 | #define GIC_SH_COUNTER_31_00_OFS 0x0010 | 72 | #define GIC_SH_COUNTER_31_00_OFS 0x0010 |
73 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 | 73 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 |
74 | #define GIC_SH_REVISIONID_OFS 0x0020 | 74 | #define GIC_SH_REVISIONID_OFS 0x0020 |
75 | 75 | ||
76 | /* Interrupt Polarity */ | 76 | /* Interrupt Polarity */ |
77 | #define GIC_SH_POL_31_0_OFS 0x0100 | 77 | #define GIC_SH_POL_31_0_OFS 0x0100 |
78 | #define GIC_SH_POL_63_32_OFS 0x0104 | 78 | #define GIC_SH_POL_63_32_OFS 0x0104 |
79 | #define GIC_SH_POL_95_64_OFS 0x0108 | 79 | #define GIC_SH_POL_95_64_OFS 0x0108 |
80 | #define GIC_SH_POL_127_96_OFS 0x010c | 80 | #define GIC_SH_POL_127_96_OFS 0x010c |
81 | #define GIC_SH_POL_159_128_OFS 0x0110 | 81 | #define GIC_SH_POL_159_128_OFS 0x0110 |
82 | #define GIC_SH_POL_191_160_OFS 0x0114 | 82 | #define GIC_SH_POL_191_160_OFS 0x0114 |
83 | #define GIC_SH_POL_223_192_OFS 0x0118 | 83 | #define GIC_SH_POL_223_192_OFS 0x0118 |
84 | #define GIC_SH_POL_255_224_OFS 0x011c | 84 | #define GIC_SH_POL_255_224_OFS 0x011c |
85 | 85 | ||
86 | /* Edge/Level Triggering */ | 86 | /* Edge/Level Triggering */ |
87 | #define GIC_SH_TRIG_31_0_OFS 0x0180 | 87 | #define GIC_SH_TRIG_31_0_OFS 0x0180 |
88 | #define GIC_SH_TRIG_63_32_OFS 0x0184 | 88 | #define GIC_SH_TRIG_63_32_OFS 0x0184 |
89 | #define GIC_SH_TRIG_95_64_OFS 0x0188 | 89 | #define GIC_SH_TRIG_95_64_OFS 0x0188 |
90 | #define GIC_SH_TRIG_127_96_OFS 0x018c | 90 | #define GIC_SH_TRIG_127_96_OFS 0x018c |
91 | #define GIC_SH_TRIG_159_128_OFS 0x0190 | 91 | #define GIC_SH_TRIG_159_128_OFS 0x0190 |
92 | #define GIC_SH_TRIG_191_160_OFS 0x0194 | 92 | #define GIC_SH_TRIG_191_160_OFS 0x0194 |
93 | #define GIC_SH_TRIG_223_192_OFS 0x0198 | 93 | #define GIC_SH_TRIG_223_192_OFS 0x0198 |
94 | #define GIC_SH_TRIG_255_224_OFS 0x019c | 94 | #define GIC_SH_TRIG_255_224_OFS 0x019c |
95 | 95 | ||
96 | /* Dual Edge Triggering */ | 96 | /* Dual Edge Triggering */ |
97 | #define GIC_SH_DUAL_31_0_OFS 0x0200 | 97 | #define GIC_SH_DUAL_31_0_OFS 0x0200 |
98 | #define GIC_SH_DUAL_63_32_OFS 0x0204 | 98 | #define GIC_SH_DUAL_63_32_OFS 0x0204 |
99 | #define GIC_SH_DUAL_95_64_OFS 0x0208 | 99 | #define GIC_SH_DUAL_95_64_OFS 0x0208 |
100 | #define GIC_SH_DUAL_127_96_OFS 0x020c | 100 | #define GIC_SH_DUAL_127_96_OFS 0x020c |
101 | #define GIC_SH_DUAL_159_128_OFS 0x0210 | 101 | #define GIC_SH_DUAL_159_128_OFS 0x0210 |
102 | #define GIC_SH_DUAL_191_160_OFS 0x0214 | 102 | #define GIC_SH_DUAL_191_160_OFS 0x0214 |
103 | #define GIC_SH_DUAL_223_192_OFS 0x0218 | 103 | #define GIC_SH_DUAL_223_192_OFS 0x0218 |
104 | #define GIC_SH_DUAL_255_224_OFS 0x021c | 104 | #define GIC_SH_DUAL_255_224_OFS 0x021c |
105 | 105 | ||
106 | /* Set/Clear corresponding bit in Edge Detect Register */ | 106 | /* Set/Clear corresponding bit in Edge Detect Register */ |
107 | #define GIC_SH_WEDGE_OFS 0x0280 | 107 | #define GIC_SH_WEDGE_OFS 0x0280 |
108 | 108 | ||
109 | /* Reset Mask - Disables Interrupt */ | 109 | /* Reset Mask - Disables Interrupt */ |
110 | #define GIC_SH_RMASK_31_0_OFS 0x0300 | 110 | #define GIC_SH_RMASK_31_0_OFS 0x0300 |
111 | #define GIC_SH_RMASK_63_32_OFS 0x0304 | 111 | #define GIC_SH_RMASK_63_32_OFS 0x0304 |
112 | #define GIC_SH_RMASK_95_64_OFS 0x0308 | 112 | #define GIC_SH_RMASK_95_64_OFS 0x0308 |
113 | #define GIC_SH_RMASK_127_96_OFS 0x030c | 113 | #define GIC_SH_RMASK_127_96_OFS 0x030c |
114 | #define GIC_SH_RMASK_159_128_OFS 0x0310 | 114 | #define GIC_SH_RMASK_159_128_OFS 0x0310 |
115 | #define GIC_SH_RMASK_191_160_OFS 0x0314 | 115 | #define GIC_SH_RMASK_191_160_OFS 0x0314 |
116 | #define GIC_SH_RMASK_223_192_OFS 0x0318 | 116 | #define GIC_SH_RMASK_223_192_OFS 0x0318 |
117 | #define GIC_SH_RMASK_255_224_OFS 0x031c | 117 | #define GIC_SH_RMASK_255_224_OFS 0x031c |
118 | 118 | ||
119 | /* Set Mask (WO) - Enables Interrupt */ | 119 | /* Set Mask (WO) - Enables Interrupt */ |
120 | #define GIC_SH_SMASK_31_0_OFS 0x0380 | 120 | #define GIC_SH_SMASK_31_0_OFS 0x0380 |
121 | #define GIC_SH_SMASK_63_32_OFS 0x0384 | 121 | #define GIC_SH_SMASK_63_32_OFS 0x0384 |
122 | #define GIC_SH_SMASK_95_64_OFS 0x0388 | 122 | #define GIC_SH_SMASK_95_64_OFS 0x0388 |
123 | #define GIC_SH_SMASK_127_96_OFS 0x038c | 123 | #define GIC_SH_SMASK_127_96_OFS 0x038c |
124 | #define GIC_SH_SMASK_159_128_OFS 0x0390 | 124 | #define GIC_SH_SMASK_159_128_OFS 0x0390 |
125 | #define GIC_SH_SMASK_191_160_OFS 0x0394 | 125 | #define GIC_SH_SMASK_191_160_OFS 0x0394 |
126 | #define GIC_SH_SMASK_223_192_OFS 0x0398 | 126 | #define GIC_SH_SMASK_223_192_OFS 0x0398 |
127 | #define GIC_SH_SMASK_255_224_OFS 0x039c | 127 | #define GIC_SH_SMASK_255_224_OFS 0x039c |
128 | 128 | ||
129 | /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ | 129 | /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ |
130 | #define GIC_SH_MASK_31_0_OFS 0x0400 | 130 | #define GIC_SH_MASK_31_0_OFS 0x0400 |
131 | #define GIC_SH_MASK_63_32_OFS 0x0404 | 131 | #define GIC_SH_MASK_63_32_OFS 0x0404 |
132 | #define GIC_SH_MASK_95_64_OFS 0x0408 | 132 | #define GIC_SH_MASK_95_64_OFS 0x0408 |
133 | #define GIC_SH_MASK_127_96_OFS 0x040c | 133 | #define GIC_SH_MASK_127_96_OFS 0x040c |
134 | #define GIC_SH_MASK_159_128_OFS 0x0410 | 134 | #define GIC_SH_MASK_159_128_OFS 0x0410 |
135 | #define GIC_SH_MASK_191_160_OFS 0x0414 | 135 | #define GIC_SH_MASK_191_160_OFS 0x0414 |
136 | #define GIC_SH_MASK_223_192_OFS 0x0418 | 136 | #define GIC_SH_MASK_223_192_OFS 0x0418 |
137 | #define GIC_SH_MASK_255_224_OFS 0x041c | 137 | #define GIC_SH_MASK_255_224_OFS 0x041c |
138 | 138 | ||
139 | /* Pending Global Interrupts (RO) */ | 139 | /* Pending Global Interrupts (RO) */ |
140 | #define GIC_SH_PEND_31_0_OFS 0x0480 | 140 | #define GIC_SH_PEND_31_0_OFS 0x0480 |
141 | #define GIC_SH_PEND_63_32_OFS 0x0484 | 141 | #define GIC_SH_PEND_63_32_OFS 0x0484 |
142 | #define GIC_SH_PEND_95_64_OFS 0x0488 | 142 | #define GIC_SH_PEND_95_64_OFS 0x0488 |
143 | #define GIC_SH_PEND_127_96_OFS 0x048c | 143 | #define GIC_SH_PEND_127_96_OFS 0x048c |
144 | #define GIC_SH_PEND_159_128_OFS 0x0490 | 144 | #define GIC_SH_PEND_159_128_OFS 0x0490 |
145 | #define GIC_SH_PEND_191_160_OFS 0x0494 | 145 | #define GIC_SH_PEND_191_160_OFS 0x0494 |
146 | #define GIC_SH_PEND_223_192_OFS 0x0498 | 146 | #define GIC_SH_PEND_223_192_OFS 0x0498 |
147 | #define GIC_SH_PEND_255_224_OFS 0x049c | 147 | #define GIC_SH_PEND_255_224_OFS 0x049c |
148 | 148 | ||
149 | #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 | 149 | #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 |
150 | 150 | ||
151 | /* Maps Interrupt X to a Pin */ | 151 | /* Maps Interrupt X to a Pin */ |
152 | #define GIC_SH_MAP_TO_PIN(intr) \ | 152 | #define GIC_SH_MAP_TO_PIN(intr) \ |
153 | (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) | 153 | (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) |
154 | 154 | ||
155 | #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 | 155 | #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 |
156 | 156 | ||
157 | /* Maps Interrupt X to a VPE */ | 157 | /* Maps Interrupt X to a VPE */ |
158 | #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ | 158 | #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ |
159 | (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) | 159 | (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) |
160 | #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) | 160 | #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) |
161 | 161 | ||
162 | /* Convert an interrupt number to a byte offset/bit for multi-word registers */ | 162 | /* Convert an interrupt number to a byte offset/bit for multi-word registers */ |
163 | #define GIC_INTR_OFS(intr) (((intr) / 32)*4) | 163 | #define GIC_INTR_OFS(intr) (((intr) / 32)*4) |
164 | #define GIC_INTR_BIT(intr) ((intr) % 32) | 164 | #define GIC_INTR_BIT(intr) ((intr) % 32) |
165 | 165 | ||
166 | /* Polarity : Reset Value is always 0 */ | 166 | /* Polarity : Reset Value is always 0 */ |
167 | #define GIC_SH_SET_POLARITY_OFS 0x0100 | 167 | #define GIC_SH_SET_POLARITY_OFS 0x0100 |
168 | #define GIC_SET_POLARITY(intr, pol) \ | 168 | #define GIC_SET_POLARITY(intr, pol) \ |
169 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ | 169 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ |
170 | GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr)) | 170 | GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr)) |
171 | 171 | ||
172 | /* Triggering : Reset Value is always 0 */ | 172 | /* Triggering : Reset Value is always 0 */ |
173 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 | 173 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 |
174 | #define GIC_SET_TRIGGER(intr, trig) \ | 174 | #define GIC_SET_TRIGGER(intr, trig) \ |
175 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ | 175 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ |
176 | GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr)) | 176 | GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr)) |
177 | 177 | ||
178 | /* Mask manipulation */ | 178 | /* Mask manipulation */ |
179 | #define GIC_SH_SMASK_OFS 0x0380 | 179 | #define GIC_SH_SMASK_OFS 0x0380 |
180 | #define GIC_SET_INTR_MASK(intr) \ | 180 | #define GIC_SET_INTR_MASK(intr) \ |
181 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ | 181 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ |
182 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | 182 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) |
183 | #define GIC_SH_RMASK_OFS 0x0300 | 183 | #define GIC_SH_RMASK_OFS 0x0300 |
184 | #define GIC_CLR_INTR_MASK(intr) \ | 184 | #define GIC_CLR_INTR_MASK(intr) \ |
185 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ | 185 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ |
186 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | 186 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) |
187 | 187 | ||
188 | /* Register Map for Local Section */ | 188 | /* Register Map for Local Section */ |
189 | #define GIC_VPE_CTL_OFS 0x0000 | 189 | #define GIC_VPE_CTL_OFS 0x0000 |
190 | #define GIC_VPE_PEND_OFS 0x0004 | 190 | #define GIC_VPE_PEND_OFS 0x0004 |
191 | #define GIC_VPE_MASK_OFS 0x0008 | 191 | #define GIC_VPE_MASK_OFS 0x0008 |
192 | #define GIC_VPE_RMASK_OFS 0x000c | 192 | #define GIC_VPE_RMASK_OFS 0x000c |
193 | #define GIC_VPE_SMASK_OFS 0x0010 | 193 | #define GIC_VPE_SMASK_OFS 0x0010 |
194 | #define GIC_VPE_WD_MAP_OFS 0x0040 | 194 | #define GIC_VPE_WD_MAP_OFS 0x0040 |
195 | #define GIC_VPE_COMPARE_MAP_OFS 0x0044 | 195 | #define GIC_VPE_COMPARE_MAP_OFS 0x0044 |
196 | #define GIC_VPE_TIMER_MAP_OFS 0x0048 | 196 | #define GIC_VPE_TIMER_MAP_OFS 0x0048 |
197 | #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 | 197 | #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 |
198 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 | 198 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 |
199 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 | 199 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 |
200 | #define GIC_VPE_OTHER_ADDR_OFS 0x0080 | 200 | #define GIC_VPE_OTHER_ADDR_OFS 0x0080 |
201 | #define GIC_VPE_WD_CONFIG0_OFS 0x0090 | 201 | #define GIC_VPE_WD_CONFIG0_OFS 0x0090 |
202 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 | 202 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 |
203 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 | 203 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 |
204 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 | 204 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 |
205 | #define GIC_VPE_COMPARE_HI 0x00a4 | 205 | #define GIC_VPE_COMPARE_HI 0x00a4 |
206 | 206 | ||
207 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | 207 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 |
208 | #define GIC_VPE_EIC_SS(intr) \ | 208 | #define GIC_VPE_EIC_SS(intr) \ |
209 | (GIC_EIC_SHADOW_SET_BASE + (4 * intr)) | 209 | (GIC_EIC_SHADOW_SET_BASE + (4 * intr)) |
210 | 210 | ||
211 | #define GIC_VPE_EIC_VEC_BASE 0x0800 | 211 | #define GIC_VPE_EIC_VEC_BASE 0x0800 |
212 | #define GIC_VPE_EIC_VEC(intr) \ | 212 | #define GIC_VPE_EIC_VEC(intr) \ |
213 | (GIC_VPE_EIC_VEC_BASE + (4 * intr)) | 213 | (GIC_VPE_EIC_VEC_BASE + (4 * intr)) |
214 | 214 | ||
215 | #define GIC_VPE_TENABLE_NMI_OFS 0x1000 | 215 | #define GIC_VPE_TENABLE_NMI_OFS 0x1000 |
216 | #define GIC_VPE_TENABLE_YQ_OFS 0x1004 | 216 | #define GIC_VPE_TENABLE_YQ_OFS 0x1004 |
217 | #define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 | 217 | #define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 |
218 | #define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 | 218 | #define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 |
219 | 219 | ||
220 | /* User Mode Visible Section Register Map */ | 220 | /* User Mode Visible Section Register Map */ |
221 | #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 | 221 | #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 |
222 | #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 | 222 | #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 |
223 | 223 | ||
224 | /* Masks */ | 224 | /* Masks */ |
225 | #define GIC_SH_CONFIG_COUNTSTOP_SHF 28 | 225 | #define GIC_SH_CONFIG_COUNTSTOP_SHF 28 |
226 | #define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) | 226 | #define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) |
227 | 227 | ||
228 | #define GIC_SH_CONFIG_COUNTBITS_SHF 24 | 228 | #define GIC_SH_CONFIG_COUNTBITS_SHF 24 |
229 | #define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF) | 229 | #define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF) |
230 | 230 | ||
231 | #define GIC_SH_CONFIG_NUMINTRS_SHF 16 | 231 | #define GIC_SH_CONFIG_NUMINTRS_SHF 16 |
232 | #define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF) | 232 | #define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF) |
233 | 233 | ||
234 | #define GIC_SH_CONFIG_NUMVPES_SHF 0 | 234 | #define GIC_SH_CONFIG_NUMVPES_SHF 0 |
235 | #define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) | 235 | #define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) |
236 | 236 | ||
237 | #define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31)) | 237 | #define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31)) |
238 | #define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31)) | 238 | #define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31)) |
239 | 239 | ||
240 | #define GIC_MAP_TO_PIN_SHF 31 | 240 | #define GIC_MAP_TO_PIN_SHF 31 |
241 | #define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) | 241 | #define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) |
242 | #define GIC_MAP_TO_NMI_SHF 30 | 242 | #define GIC_MAP_TO_NMI_SHF 30 |
243 | #define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF) | 243 | #define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF) |
244 | #define GIC_MAP_TO_YQ_SHF 29 | 244 | #define GIC_MAP_TO_YQ_SHF 29 |
245 | #define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF) | 245 | #define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF) |
246 | #define GIC_MAP_SHF 0 | 246 | #define GIC_MAP_SHF 0 |
247 | #define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) | 247 | #define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) |
248 | 248 | ||
249 | /* GIC_VPE_CTL Masks */ | 249 | /* GIC_VPE_CTL Masks */ |
250 | #define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 | 250 | #define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 |
251 | #define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) | 251 | #define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) |
252 | #define GIC_VPE_CTL_TIMER_RTBL_SHF 1 | 252 | #define GIC_VPE_CTL_TIMER_RTBL_SHF 1 |
253 | #define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF) | 253 | #define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF) |
254 | #define GIC_VPE_CTL_EIC_MODE_SHF 0 | 254 | #define GIC_VPE_CTL_EIC_MODE_SHF 0 |
255 | #define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF) | 255 | #define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF) |
256 | 256 | ||
257 | /* GIC_VPE_PEND Masks */ | 257 | /* GIC_VPE_PEND Masks */ |
258 | #define GIC_VPE_PEND_WD_SHF 0 | 258 | #define GIC_VPE_PEND_WD_SHF 0 |
259 | #define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF) | 259 | #define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF) |
260 | #define GIC_VPE_PEND_CMP_SHF 1 | 260 | #define GIC_VPE_PEND_CMP_SHF 1 |
261 | #define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF) | 261 | #define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF) |
262 | #define GIC_VPE_PEND_TIMER_SHF 2 | 262 | #define GIC_VPE_PEND_TIMER_SHF 2 |
263 | #define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF) | 263 | #define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF) |
264 | #define GIC_VPE_PEND_PERFCOUNT_SHF 3 | 264 | #define GIC_VPE_PEND_PERFCOUNT_SHF 3 |
265 | #define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF) | 265 | #define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF) |
266 | #define GIC_VPE_PEND_SWINT0_SHF 4 | 266 | #define GIC_VPE_PEND_SWINT0_SHF 4 |
267 | #define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF) | 267 | #define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF) |
268 | #define GIC_VPE_PEND_SWINT1_SHF 5 | 268 | #define GIC_VPE_PEND_SWINT1_SHF 5 |
269 | #define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF) | 269 | #define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF) |
270 | 270 | ||
271 | /* GIC_VPE_RMASK Masks */ | 271 | /* GIC_VPE_RMASK Masks */ |
272 | #define GIC_VPE_RMASK_WD_SHF 0 | 272 | #define GIC_VPE_RMASK_WD_SHF 0 |
273 | #define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF) | 273 | #define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF) |
274 | #define GIC_VPE_RMASK_CMP_SHF 1 | 274 | #define GIC_VPE_RMASK_CMP_SHF 1 |
275 | #define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF) | 275 | #define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF) |
276 | #define GIC_VPE_RMASK_TIMER_SHF 2 | 276 | #define GIC_VPE_RMASK_TIMER_SHF 2 |
277 | #define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF) | 277 | #define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF) |
278 | #define GIC_VPE_RMASK_PERFCNT_SHF 3 | 278 | #define GIC_VPE_RMASK_PERFCNT_SHF 3 |
279 | #define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF) | 279 | #define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF) |
280 | #define GIC_VPE_RMASK_SWINT0_SHF 4 | 280 | #define GIC_VPE_RMASK_SWINT0_SHF 4 |
281 | #define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF) | 281 | #define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF) |
282 | #define GIC_VPE_RMASK_SWINT1_SHF 5 | 282 | #define GIC_VPE_RMASK_SWINT1_SHF 5 |
283 | #define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF) | 283 | #define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF) |
284 | 284 | ||
285 | /* GIC_VPE_SMASK Masks */ | 285 | /* GIC_VPE_SMASK Masks */ |
286 | #define GIC_VPE_SMASK_WD_SHF 0 | 286 | #define GIC_VPE_SMASK_WD_SHF 0 |
287 | #define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF) | 287 | #define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF) |
288 | #define GIC_VPE_SMASK_CMP_SHF 1 | 288 | #define GIC_VPE_SMASK_CMP_SHF 1 |
289 | #define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF) | 289 | #define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF) |
290 | #define GIC_VPE_SMASK_TIMER_SHF 2 | 290 | #define GIC_VPE_SMASK_TIMER_SHF 2 |
291 | #define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF) | 291 | #define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF) |
292 | #define GIC_VPE_SMASK_PERFCNT_SHF 3 | 292 | #define GIC_VPE_SMASK_PERFCNT_SHF 3 |
293 | #define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF) | 293 | #define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF) |
294 | #define GIC_VPE_SMASK_SWINT0_SHF 4 | 294 | #define GIC_VPE_SMASK_SWINT0_SHF 4 |
295 | #define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF) | 295 | #define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF) |
296 | #define GIC_VPE_SMASK_SWINT1_SHF 5 | 296 | #define GIC_VPE_SMASK_SWINT1_SHF 5 |
297 | #define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) | 297 | #define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * Set the Mapping of Interrupt X to a VPE. | 300 | * Set the Mapping of Interrupt X to a VPE. |
301 | */ | 301 | */ |
302 | #define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \ | 302 | #define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \ |
303 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ | 303 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ |
304 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) | 304 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) |
305 | 305 | ||
306 | struct gic_pcpu_mask { | 306 | struct gic_pcpu_mask { |
307 | DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | 307 | DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); |
308 | }; | 308 | }; |
309 | 309 | ||
310 | struct gic_pending_regs { | 310 | struct gic_pending_regs { |
311 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | 311 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); |
312 | }; | 312 | }; |
313 | 313 | ||
314 | struct gic_intrmask_regs { | 314 | struct gic_intrmask_regs { |
315 | DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | 315 | DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); |
316 | }; | 316 | }; |
317 | 317 | ||
318 | /* | 318 | /* |
319 | * Interrupt Meta-data specification. The ipiflag helps | 319 | * Interrupt Meta-data specification. The ipiflag helps |
320 | * in building ipi_map. | 320 | * in building ipi_map. |
321 | */ | 321 | */ |
322 | struct gic_intr_map { | 322 | struct gic_intr_map { |
323 | unsigned int cpunum; /* Directed to this CPU */ | 323 | unsigned int cpunum; /* Directed to this CPU */ |
324 | #define GIC_UNUSED 0xdead /* Dummy data */ | ||
324 | unsigned int pin; /* Directed to this Pin */ | 325 | unsigned int pin; /* Directed to this Pin */ |
325 | unsigned int polarity; /* Polarity : +/- */ | 326 | unsigned int polarity; /* Polarity : +/- */ |
326 | unsigned int trigtype; /* Trigger : Edge/Levl */ | 327 | unsigned int trigtype; /* Trigger : Edge/Levl */ |
327 | unsigned int flags; /* Misc flags */ | 328 | unsigned int flags; /* Misc flags */ |
328 | #define GIC_FLAG_IPI 0x01 | 329 | #define GIC_FLAG_IPI 0x01 |
329 | #define GIC_FLAG_TRANSPARENT 0x02 | 330 | #define GIC_FLAG_TRANSPARENT 0x02 |
330 | }; | 331 | }; |
331 | 332 | ||
332 | extern void gic_init(unsigned long gic_base_addr, | 333 | extern void gic_init(unsigned long gic_base_addr, |
333 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, | 334 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, |
334 | unsigned int intrmap_size, unsigned int irqbase); | 335 | unsigned int intrmap_size, unsigned int irqbase); |
335 | 336 | ||
336 | extern unsigned int gic_get_int(void); | 337 | extern unsigned int gic_get_int(void); |
337 | extern void gic_send_ipi(unsigned int intr); | 338 | extern void gic_send_ipi(unsigned int intr); |
338 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | 339 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); |
339 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 340 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
340 | 341 | ||
341 | #endif /* _ASM_GICREGS_H */ | 342 | #endif /* _ASM_GICREGS_H */ |
342 | 343 |
arch/mips/include/asm/mips-boards/maltaint.h
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * Carsten Langgaard, carstenl@mips.com |
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | 3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * ######################################################################## | 5 | * ######################################################################## |
6 | * | 6 | * |
7 | * This program is free software; you can distribute it and/or modify it | 7 | * This program is free software; you can distribute it and/or modify it |
8 | * under the terms of the GNU General Public License (Version 2) as | 8 | * under the terms of the GNU General Public License (Version 2) as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | 10 | * |
11 | * This program is distributed in the hope it will be useful, but WITHOUT | 11 | * This program is distributed in the hope it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * for more details. | 14 | * for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License along | 16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; if not, write to the Free Software Foundation, Inc., | 17 | * with this program; if not, write to the Free Software Foundation, Inc., |
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
19 | * | 19 | * |
20 | * ######################################################################## | 20 | * ######################################################################## |
21 | * | 21 | * |
22 | * Defines for the Malta interrupt controller. | 22 | * Defines for the Malta interrupt controller. |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | #ifndef _MIPS_MALTAINT_H | 25 | #ifndef _MIPS_MALTAINT_H |
26 | #define _MIPS_MALTAINT_H | 26 | #define _MIPS_MALTAINT_H |
27 | 27 | ||
28 | #include <irq.h> | 28 | #include <irq.h> |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * Interrupts 0..15 are used for Malta ISA compatible interrupts | 31 | * Interrupts 0..15 are used for Malta ISA compatible interrupts |
32 | */ | 32 | */ |
33 | #define MALTA_INT_BASE 0 | 33 | #define MALTA_INT_BASE 0 |
34 | 34 | ||
35 | /* CPU interrupt offsets */ | 35 | /* CPU interrupt offsets */ |
36 | #define MIPSCPU_INT_SW0 0 | 36 | #define MIPSCPU_INT_SW0 0 |
37 | #define MIPSCPU_INT_SW1 1 | 37 | #define MIPSCPU_INT_SW1 1 |
38 | #define MIPSCPU_INT_MB0 2 | 38 | #define MIPSCPU_INT_MB0 2 |
39 | #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 | 39 | #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 |
40 | #define MIPSCPU_INT_MB1 3 | 40 | #define MIPSCPU_INT_MB1 3 |
41 | #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 | 41 | #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 |
42 | #define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */ | 42 | #define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */ |
43 | #define MIPSCPU_INT_MB2 4 | 43 | #define MIPSCPU_INT_MB2 4 |
44 | #define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */ | 44 | #define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */ |
45 | #define MIPSCPU_INT_MB3 5 | 45 | #define MIPSCPU_INT_MB3 5 |
46 | #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 | 46 | #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 |
47 | #define MIPSCPU_INT_MB4 6 | 47 | #define MIPSCPU_INT_MB4 6 |
48 | #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 | 48 | #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Interrupts 64..127 are used for Soc-it Classic interrupts | 51 | * Interrupts 64..127 are used for Soc-it Classic interrupts |
52 | */ | 52 | */ |
53 | #define MSC01C_INT_BASE 64 | 53 | #define MSC01C_INT_BASE 64 |
54 | 54 | ||
55 | /* SOC-it Classic interrupt offsets */ | 55 | /* SOC-it Classic interrupt offsets */ |
56 | #define MSC01C_INT_TMR 0 | 56 | #define MSC01C_INT_TMR 0 |
57 | #define MSC01C_INT_PCI 1 | 57 | #define MSC01C_INT_PCI 1 |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Interrupts 64..127 are used for Soc-it EIC interrupts | 60 | * Interrupts 64..127 are used for Soc-it EIC interrupts |
61 | */ | 61 | */ |
62 | #define MSC01E_INT_BASE 64 | 62 | #define MSC01E_INT_BASE 64 |
63 | 63 | ||
64 | /* SOC-it EIC interrupt offsets */ | 64 | /* SOC-it EIC interrupt offsets */ |
65 | #define MSC01E_INT_SW0 1 | 65 | #define MSC01E_INT_SW0 1 |
66 | #define MSC01E_INT_SW1 2 | 66 | #define MSC01E_INT_SW1 2 |
67 | #define MSC01E_INT_MB0 3 | 67 | #define MSC01E_INT_MB0 3 |
68 | #define MSC01E_INT_I8259A MSC01E_INT_MB0 | 68 | #define MSC01E_INT_I8259A MSC01E_INT_MB0 |
69 | #define MSC01E_INT_MB1 4 | 69 | #define MSC01E_INT_MB1 4 |
70 | #define MSC01E_INT_SMI MSC01E_INT_MB1 | 70 | #define MSC01E_INT_SMI MSC01E_INT_MB1 |
71 | #define MSC01E_INT_MB2 5 | 71 | #define MSC01E_INT_MB2 5 |
72 | #define MSC01E_INT_MB3 6 | 72 | #define MSC01E_INT_MB3 6 |
73 | #define MSC01E_INT_COREHI MSC01E_INT_MB3 | 73 | #define MSC01E_INT_COREHI MSC01E_INT_MB3 |
74 | #define MSC01E_INT_MB4 7 | 74 | #define MSC01E_INT_MB4 7 |
75 | #define MSC01E_INT_CORELO MSC01E_INT_MB4 | 75 | #define MSC01E_INT_CORELO MSC01E_INT_MB4 |
76 | #define MSC01E_INT_TMR 8 | 76 | #define MSC01E_INT_TMR 8 |
77 | #define MSC01E_INT_PCI 9 | 77 | #define MSC01E_INT_PCI 9 |
78 | #define MSC01E_INT_PERFCTR 10 | 78 | #define MSC01E_INT_PERFCTR 10 |
79 | #define MSC01E_INT_CPUCTR 11 | 79 | #define MSC01E_INT_CPUCTR 11 |
80 | 80 | ||
81 | /* GIC's Nomenclature for Core Interrupt Pins on the Malta */ | 81 | /* GIC's Nomenclature for Core Interrupt Pins on the Malta */ |
82 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | 82 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ |
83 | #define GIC_CPU_INT1 1 /* . */ | 83 | #define GIC_CPU_INT1 1 /* . */ |
84 | #define GIC_CPU_INT2 2 /* . */ | 84 | #define GIC_CPU_INT2 2 /* . */ |
85 | #define GIC_CPU_INT3 3 /* . */ | 85 | #define GIC_CPU_INT3 3 /* . */ |
86 | #define GIC_CPU_INT4 4 /* . */ | 86 | #define GIC_CPU_INT4 4 /* . */ |
87 | #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ | 87 | #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ |
88 | 88 | ||
89 | #define GIC_EXT_INTR(x) x | 89 | #define GIC_EXT_INTR(x) x |
90 | 90 | ||
91 | /* Dummy data */ | ||
92 | #define X 0xdead | ||
93 | |||
94 | /* External Interrupts used for IPI */ | 91 | /* External Interrupts used for IPI */ |
95 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 | 92 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 |
96 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 | 93 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 |
97 | #define GIC_IPI_EXT_INTR_RESCHED_VPE1 18 | 94 | #define GIC_IPI_EXT_INTR_RESCHED_VPE1 18 |
98 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19 | 95 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19 |
99 | #define GIC_IPI_EXT_INTR_RESCHED_VPE2 20 | 96 | #define GIC_IPI_EXT_INTR_RESCHED_VPE2 20 |
100 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21 | 97 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21 |
101 | #define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 | 98 | #define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 |
102 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 | 99 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 |
103 | 100 | ||
104 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | 101 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) |
105 | 102 | ||
106 | #ifndef __ASSEMBLY__ | 103 | #ifndef __ASSEMBLY__ |
107 | extern void maltaint_init(void); | 104 | extern void maltaint_init(void); |
108 | #endif | 105 | #endif |
109 | 106 | ||
110 | #endif /* !(_MIPS_MALTAINT_H) */ | 107 | #endif /* !(_MIPS_MALTAINT_H) */ |
111 | 108 |
arch/mips/kernel/irq-gic.c
1 | #undef DEBUG | 1 | #undef DEBUG |
2 | 2 | ||
3 | #include <linux/bitmap.h> | 3 | #include <linux/bitmap.h> |
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/smp.h> | 5 | #include <linux/smp.h> |
6 | 6 | ||
7 | #include <asm/io.h> | 7 | #include <asm/io.h> |
8 | #include <asm/gic.h> | 8 | #include <asm/gic.h> |
9 | #include <asm/gcmpregs.h> | 9 | #include <asm/gcmpregs.h> |
10 | #include <asm/mips-boards/maltaint.h> | ||
11 | #include <asm/irq.h> | 10 | #include <asm/irq.h> |
12 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
13 | #include <asm-generic/bitops/find.h> | 12 | #include <asm-generic/bitops/find.h> |
14 | 13 | ||
15 | 14 | ||
16 | static unsigned long _gic_base; | 15 | static unsigned long _gic_base; |
17 | static unsigned int _irqbase; | 16 | static unsigned int _irqbase; |
18 | static unsigned int gic_irq_flags[GIC_NUM_INTRS]; | 17 | static unsigned int gic_irq_flags[GIC_NUM_INTRS]; |
19 | #define GIC_IRQ_FLAG_EDGE 0x0001 | 18 | #define GIC_IRQ_FLAG_EDGE 0x0001 |
20 | 19 | ||
21 | struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | 20 | struct gic_pcpu_mask pcpu_masks[NR_CPUS]; |
22 | static struct gic_pending_regs pending_regs[NR_CPUS]; | 21 | static struct gic_pending_regs pending_regs[NR_CPUS]; |
23 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | 22 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; |
24 | 23 | ||
25 | void gic_send_ipi(unsigned int intr) | 24 | void gic_send_ipi(unsigned int intr) |
26 | { | 25 | { |
27 | pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, | 26 | pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, |
28 | read_c0_status()); | 27 | read_c0_status()); |
29 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); | 28 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); |
30 | } | 29 | } |
31 | 30 | ||
32 | /* This is Malta specific and needs to be exported */ | 31 | /* This is Malta specific and needs to be exported */ |
33 | static void __init vpe_local_setup(unsigned int numvpes) | 32 | static void __init vpe_local_setup(unsigned int numvpes) |
34 | { | 33 | { |
35 | int i; | 34 | int i; |
36 | unsigned long timer_interrupt = 5, perf_interrupt = 5; | 35 | unsigned long timer_interrupt = 5, perf_interrupt = 5; |
37 | unsigned int vpe_ctl; | 36 | unsigned int vpe_ctl; |
38 | 37 | ||
39 | /* | 38 | /* |
40 | * Setup the default performance counter timer interrupts | 39 | * Setup the default performance counter timer interrupts |
41 | * for all VPEs | 40 | * for all VPEs |
42 | */ | 41 | */ |
43 | for (i = 0; i < numvpes; i++) { | 42 | for (i = 0; i < numvpes; i++) { |
44 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | 43 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); |
45 | 44 | ||
46 | /* Are Interrupts locally routable? */ | 45 | /* Are Interrupts locally routable? */ |
47 | GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl); | 46 | GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl); |
48 | if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK) | 47 | if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK) |
49 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), | 48 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), |
50 | GIC_MAP_TO_PIN_MSK | timer_interrupt); | 49 | GIC_MAP_TO_PIN_MSK | timer_interrupt); |
51 | 50 | ||
52 | if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) | 51 | if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) |
53 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), | 52 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), |
54 | GIC_MAP_TO_PIN_MSK | perf_interrupt); | 53 | GIC_MAP_TO_PIN_MSK | perf_interrupt); |
55 | } | 54 | } |
56 | } | 55 | } |
57 | 56 | ||
58 | unsigned int gic_get_int(void) | 57 | unsigned int gic_get_int(void) |
59 | { | 58 | { |
60 | unsigned int i; | 59 | unsigned int i; |
61 | unsigned long *pending, *intrmask, *pcpu_mask; | 60 | unsigned long *pending, *intrmask, *pcpu_mask; |
62 | unsigned long *pending_abs, *intrmask_abs; | 61 | unsigned long *pending_abs, *intrmask_abs; |
63 | 62 | ||
64 | /* Get per-cpu bitmaps */ | 63 | /* Get per-cpu bitmaps */ |
65 | pending = pending_regs[smp_processor_id()].pending; | 64 | pending = pending_regs[smp_processor_id()].pending; |
66 | intrmask = intrmask_regs[smp_processor_id()].intrmask; | 65 | intrmask = intrmask_regs[smp_processor_id()].intrmask; |
67 | pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; | 66 | pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; |
68 | 67 | ||
69 | pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | 68 | pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, |
70 | GIC_SH_PEND_31_0_OFS); | 69 | GIC_SH_PEND_31_0_OFS); |
71 | intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | 70 | intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, |
72 | GIC_SH_MASK_31_0_OFS); | 71 | GIC_SH_MASK_31_0_OFS); |
73 | 72 | ||
74 | for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) { | 73 | for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) { |
75 | GICREAD(*pending_abs, pending[i]); | 74 | GICREAD(*pending_abs, pending[i]); |
76 | GICREAD(*intrmask_abs, intrmask[i]); | 75 | GICREAD(*intrmask_abs, intrmask[i]); |
77 | pending_abs++; | 76 | pending_abs++; |
78 | intrmask_abs++; | 77 | intrmask_abs++; |
79 | } | 78 | } |
80 | 79 | ||
81 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); | 80 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); |
82 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); | 81 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); |
83 | 82 | ||
84 | i = find_first_bit(pending, GIC_NUM_INTRS); | 83 | i = find_first_bit(pending, GIC_NUM_INTRS); |
85 | 84 | ||
86 | pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i); | 85 | pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i); |
87 | 86 | ||
88 | return i; | 87 | return i; |
89 | } | 88 | } |
90 | 89 | ||
91 | static unsigned int gic_irq_startup(unsigned int irq) | 90 | static unsigned int gic_irq_startup(unsigned int irq) |
92 | { | 91 | { |
93 | irq -= _irqbase; | 92 | irq -= _irqbase; |
94 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 93 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
95 | GIC_SET_INTR_MASK(irq); | 94 | GIC_SET_INTR_MASK(irq); |
96 | return 0; | 95 | return 0; |
97 | } | 96 | } |
98 | 97 | ||
99 | static void gic_irq_ack(unsigned int irq) | 98 | static void gic_irq_ack(unsigned int irq) |
100 | { | 99 | { |
101 | irq -= _irqbase; | 100 | irq -= _irqbase; |
102 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 101 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
103 | GIC_CLR_INTR_MASK(irq); | 102 | GIC_CLR_INTR_MASK(irq); |
104 | 103 | ||
105 | if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE) | 104 | if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE) |
106 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | 105 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); |
107 | } | 106 | } |
108 | 107 | ||
109 | static void gic_mask_irq(unsigned int irq) | 108 | static void gic_mask_irq(unsigned int irq) |
110 | { | 109 | { |
111 | irq -= _irqbase; | 110 | irq -= _irqbase; |
112 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 111 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
113 | GIC_CLR_INTR_MASK(irq); | 112 | GIC_CLR_INTR_MASK(irq); |
114 | } | 113 | } |
115 | 114 | ||
116 | static void gic_unmask_irq(unsigned int irq) | 115 | static void gic_unmask_irq(unsigned int irq) |
117 | { | 116 | { |
118 | irq -= _irqbase; | 117 | irq -= _irqbase; |
119 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 118 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
120 | GIC_SET_INTR_MASK(irq); | 119 | GIC_SET_INTR_MASK(irq); |
121 | } | 120 | } |
122 | 121 | ||
123 | #ifdef CONFIG_SMP | 122 | #ifdef CONFIG_SMP |
124 | 123 | ||
125 | static DEFINE_SPINLOCK(gic_lock); | 124 | static DEFINE_SPINLOCK(gic_lock); |
126 | 125 | ||
127 | static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | 126 | static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) |
128 | { | 127 | { |
129 | cpumask_t tmp = CPU_MASK_NONE; | 128 | cpumask_t tmp = CPU_MASK_NONE; |
130 | unsigned long flags; | 129 | unsigned long flags; |
131 | int i; | 130 | int i; |
132 | 131 | ||
133 | irq -= _irqbase; | 132 | irq -= _irqbase; |
134 | pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); | 133 | pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); |
135 | cpumask_and(&tmp, cpumask, cpu_online_mask); | 134 | cpumask_and(&tmp, cpumask, cpu_online_mask); |
136 | if (cpus_empty(tmp)) | 135 | if (cpus_empty(tmp)) |
137 | return -1; | 136 | return -1; |
138 | 137 | ||
139 | /* Assumption : cpumask refers to a single CPU */ | 138 | /* Assumption : cpumask refers to a single CPU */ |
140 | spin_lock_irqsave(&gic_lock, flags); | 139 | spin_lock_irqsave(&gic_lock, flags); |
141 | for (;;) { | 140 | for (;;) { |
142 | /* Re-route this IRQ */ | 141 | /* Re-route this IRQ */ |
143 | GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); | 142 | GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); |
144 | 143 | ||
145 | /* Update the pcpu_masks */ | 144 | /* Update the pcpu_masks */ |
146 | for (i = 0; i < NR_CPUS; i++) | 145 | for (i = 0; i < NR_CPUS; i++) |
147 | clear_bit(irq, pcpu_masks[i].pcpu_mask); | 146 | clear_bit(irq, pcpu_masks[i].pcpu_mask); |
148 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); | 147 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); |
149 | 148 | ||
150 | } | 149 | } |
151 | cpumask_copy(irq_desc[irq].affinity, cpumask); | 150 | cpumask_copy(irq_desc[irq].affinity, cpumask); |
152 | spin_unlock_irqrestore(&gic_lock, flags); | 151 | spin_unlock_irqrestore(&gic_lock, flags); |
153 | 152 | ||
154 | return 0; | 153 | return 0; |
155 | } | 154 | } |
156 | #endif | 155 | #endif |
157 | 156 | ||
158 | static struct irq_chip gic_irq_controller = { | 157 | static struct irq_chip gic_irq_controller = { |
159 | .name = "MIPS GIC", | 158 | .name = "MIPS GIC", |
160 | .startup = gic_irq_startup, | 159 | .startup = gic_irq_startup, |
161 | .ack = gic_irq_ack, | 160 | .ack = gic_irq_ack, |
162 | .mask = gic_mask_irq, | 161 | .mask = gic_mask_irq, |
163 | .mask_ack = gic_mask_irq, | 162 | .mask_ack = gic_mask_irq, |
164 | .unmask = gic_unmask_irq, | 163 | .unmask = gic_unmask_irq, |
165 | .eoi = gic_unmask_irq, | 164 | .eoi = gic_unmask_irq, |
166 | #ifdef CONFIG_SMP | 165 | #ifdef CONFIG_SMP |
167 | .set_affinity = gic_set_affinity, | 166 | .set_affinity = gic_set_affinity, |
168 | #endif | 167 | #endif |
169 | }; | 168 | }; |
170 | 169 | ||
171 | static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | 170 | static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, |
172 | unsigned int pin, unsigned int polarity, unsigned int trigtype, | 171 | unsigned int pin, unsigned int polarity, unsigned int trigtype, |
173 | unsigned int flags) | 172 | unsigned int flags) |
174 | { | 173 | { |
175 | /* Setup Intr to Pin mapping */ | 174 | /* Setup Intr to Pin mapping */ |
176 | if (pin & GIC_MAP_TO_NMI_MSK) { | 175 | if (pin & GIC_MAP_TO_NMI_MSK) { |
177 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); | 176 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); |
178 | /* FIXME: hack to route NMI to all cpu's */ | 177 | /* FIXME: hack to route NMI to all cpu's */ |
179 | for (cpu = 0; cpu < NR_CPUS; cpu += 32) { | 178 | for (cpu = 0; cpu < NR_CPUS; cpu += 32) { |
180 | GICWRITE(GIC_REG_ADDR(SHARED, | 179 | GICWRITE(GIC_REG_ADDR(SHARED, |
181 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)), | 180 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)), |
182 | 0xffffffff); | 181 | 0xffffffff); |
183 | } | 182 | } |
184 | } else { | 183 | } else { |
185 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), | 184 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), |
186 | GIC_MAP_TO_PIN_MSK | pin); | 185 | GIC_MAP_TO_PIN_MSK | pin); |
187 | /* Setup Intr to CPU mapping */ | 186 | /* Setup Intr to CPU mapping */ |
188 | GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); | 187 | GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); |
189 | } | 188 | } |
190 | 189 | ||
191 | /* Setup Intr Polarity */ | 190 | /* Setup Intr Polarity */ |
192 | GIC_SET_POLARITY(intr, polarity); | 191 | GIC_SET_POLARITY(intr, polarity); |
193 | 192 | ||
194 | /* Setup Intr Trigger Type */ | 193 | /* Setup Intr Trigger Type */ |
195 | GIC_SET_TRIGGER(intr, trigtype); | 194 | GIC_SET_TRIGGER(intr, trigtype); |
196 | 195 | ||
197 | /* Init Intr Masks */ | 196 | /* Init Intr Masks */ |
198 | GIC_CLR_INTR_MASK(intr); | 197 | GIC_CLR_INTR_MASK(intr); |
199 | /* Initialise per-cpu Interrupt software masks */ | 198 | /* Initialise per-cpu Interrupt software masks */ |
200 | if (flags & GIC_FLAG_IPI) | 199 | if (flags & GIC_FLAG_IPI) |
201 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); | 200 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); |
202 | if (flags & GIC_FLAG_TRANSPARENT) | 201 | if (flags & GIC_FLAG_TRANSPARENT) |
203 | GIC_SET_INTR_MASK(intr); | 202 | GIC_SET_INTR_MASK(intr); |
204 | if (trigtype == GIC_TRIG_EDGE) | 203 | if (trigtype == GIC_TRIG_EDGE) |
205 | gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE; | 204 | gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE; |
206 | } | 205 | } |
207 | 206 | ||
208 | static void __init gic_basic_init(int numintrs, int numvpes, | 207 | static void __init gic_basic_init(int numintrs, int numvpes, |
209 | struct gic_intr_map *intrmap, int mapsize) | 208 | struct gic_intr_map *intrmap, int mapsize) |
210 | { | 209 | { |
211 | unsigned int i, cpu; | 210 | unsigned int i, cpu; |
212 | 211 | ||
213 | /* Setup defaults */ | 212 | /* Setup defaults */ |
214 | for (i = 0; i < numintrs; i++) { | 213 | for (i = 0; i < numintrs; i++) { |
215 | GIC_SET_POLARITY(i, GIC_POL_POS); | 214 | GIC_SET_POLARITY(i, GIC_POL_POS); |
216 | GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); | 215 | GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); |
217 | GIC_CLR_INTR_MASK(i); | 216 | GIC_CLR_INTR_MASK(i); |
218 | if (i < GIC_NUM_INTRS) | 217 | if (i < GIC_NUM_INTRS) |
219 | gic_irq_flags[i] = 0; | 218 | gic_irq_flags[i] = 0; |
220 | } | 219 | } |
221 | 220 | ||
222 | /* Setup specifics */ | 221 | /* Setup specifics */ |
223 | for (i = 0; i < mapsize; i++) { | 222 | for (i = 0; i < mapsize; i++) { |
224 | cpu = intrmap[i].cpunum; | 223 | cpu = intrmap[i].cpunum; |
225 | if (cpu == X) | 224 | if (cpu == GIC_UNUSED) |
226 | continue; | 225 | continue; |
227 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) | 226 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) |
228 | continue; | 227 | continue; |
229 | gic_setup_intr(i, | 228 | gic_setup_intr(i, |
230 | intrmap[i].cpunum, | 229 | intrmap[i].cpunum, |
231 | intrmap[i].pin, | 230 | intrmap[i].pin, |
232 | intrmap[i].polarity, | 231 | intrmap[i].polarity, |
233 | intrmap[i].trigtype, | 232 | intrmap[i].trigtype, |
234 | intrmap[i].flags); | 233 | intrmap[i].flags); |
235 | } | 234 | } |
236 | 235 | ||
237 | vpe_local_setup(numvpes); | 236 | vpe_local_setup(numvpes); |
238 | 237 | ||
239 | for (i = _irqbase; i < (_irqbase + numintrs); i++) | 238 | for (i = _irqbase; i < (_irqbase + numintrs); i++) |
240 | set_irq_chip(i, &gic_irq_controller); | 239 | set_irq_chip(i, &gic_irq_controller); |
241 | } | 240 | } |
242 | 241 | ||
243 | void __init gic_init(unsigned long gic_base_addr, | 242 | void __init gic_init(unsigned long gic_base_addr, |
244 | unsigned long gic_addrspace_size, | 243 | unsigned long gic_addrspace_size, |
245 | struct gic_intr_map *intr_map, unsigned int intr_map_size, | 244 | struct gic_intr_map *intr_map, unsigned int intr_map_size, |
246 | unsigned int irqbase) | 245 | unsigned int irqbase) |
247 | { | 246 | { |
248 | unsigned int gicconfig; | 247 | unsigned int gicconfig; |
249 | int numvpes, numintrs; | 248 | int numvpes, numintrs; |
250 | 249 | ||
251 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, | 250 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, |
252 | gic_addrspace_size); | 251 | gic_addrspace_size); |
253 | _irqbase = irqbase; | 252 | _irqbase = irqbase; |
254 | 253 | ||
255 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | 254 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); |
256 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | 255 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> |
257 | GIC_SH_CONFIG_NUMINTRS_SHF; | 256 | GIC_SH_CONFIG_NUMINTRS_SHF; |
258 | numintrs = ((numintrs + 1) * 8); | 257 | numintrs = ((numintrs + 1) * 8); |
259 | 258 | ||
260 | numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> | 259 | numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> |
261 | GIC_SH_CONFIG_NUMVPES_SHF; | 260 | GIC_SH_CONFIG_NUMVPES_SHF; |
262 | 261 | ||
263 | pr_debug("%s called\n", __func__); | 262 | pr_debug("%s called\n", __func__); |
264 | 263 | ||
265 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); | 264 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); |
266 | } | 265 | } |
267 | 266 |
arch/mips/mti-malta/malta-int.c
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * Carsten Langgaard, carstenl@mips.com |
3 | * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. | 3 | * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. |
4 | * Copyright (C) 2001 Ralf Baechle | 4 | * Copyright (C) 2001 Ralf Baechle |
5 | * | 5 | * |
6 | * This program is free software; you can distribute it and/or modify it | 6 | * This program is free software; you can distribute it and/or modify it |
7 | * under the terms of the GNU General Public License (Version 2) as | 7 | * under the terms of the GNU General Public License (Version 2) as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | 10 | * This program is distributed in the hope it will be useful, but WITHOUT |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
13 | * for more details. | 13 | * for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License along | 15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | 16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
18 | * | 18 | * |
19 | * Routines for generic manipulation of the interrupts found on the MIPS | 19 | * Routines for generic manipulation of the interrupts found on the MIPS |
20 | * Malta board. | 20 | * Malta board. |
21 | * The interrupt controller is located in the South Bridge a PIIX4 device | 21 | * The interrupt controller is located in the South Bridge a PIIX4 device |
22 | * with two internal 82C95 interrupt controllers. | 22 | * with two internal 82C95 interrupt controllers. |
23 | */ | 23 | */ |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | #include <linux/kernel_stat.h> | 30 | #include <linux/kernel_stat.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/random.h> | 32 | #include <linux/random.h> |
33 | 33 | ||
34 | #include <asm/traps.h> | 34 | #include <asm/traps.h> |
35 | #include <asm/i8259.h> | 35 | #include <asm/i8259.h> |
36 | #include <asm/irq_cpu.h> | 36 | #include <asm/irq_cpu.h> |
37 | #include <asm/irq_regs.h> | 37 | #include <asm/irq_regs.h> |
38 | #include <asm/mips-boards/malta.h> | 38 | #include <asm/mips-boards/malta.h> |
39 | #include <asm/mips-boards/maltaint.h> | 39 | #include <asm/mips-boards/maltaint.h> |
40 | #include <asm/mips-boards/piix4.h> | 40 | #include <asm/mips-boards/piix4.h> |
41 | #include <asm/gt64120.h> | 41 | #include <asm/gt64120.h> |
42 | #include <asm/mips-boards/generic.h> | 42 | #include <asm/mips-boards/generic.h> |
43 | #include <asm/mips-boards/msc01_pci.h> | 43 | #include <asm/mips-boards/msc01_pci.h> |
44 | #include <asm/msc01_ic.h> | 44 | #include <asm/msc01_ic.h> |
45 | #include <asm/gic.h> | 45 | #include <asm/gic.h> |
46 | #include <asm/gcmpregs.h> | 46 | #include <asm/gcmpregs.h> |
47 | 47 | ||
48 | int gcmp_present = -1; | 48 | int gcmp_present = -1; |
49 | int gic_present; | 49 | int gic_present; |
50 | static unsigned long _msc01_biu_base; | 50 | static unsigned long _msc01_biu_base; |
51 | static unsigned long _gcmp_base; | 51 | static unsigned long _gcmp_base; |
52 | static unsigned int ipi_map[NR_CPUS]; | 52 | static unsigned int ipi_map[NR_CPUS]; |
53 | 53 | ||
54 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); | 54 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); |
55 | 55 | ||
56 | static inline int mips_pcibios_iack(void) | 56 | static inline int mips_pcibios_iack(void) |
57 | { | 57 | { |
58 | int irq; | 58 | int irq; |
59 | u32 dummy; | 59 | u32 dummy; |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * Determine highest priority pending interrupt by performing | 62 | * Determine highest priority pending interrupt by performing |
63 | * a PCI Interrupt Acknowledge cycle. | 63 | * a PCI Interrupt Acknowledge cycle. |
64 | */ | 64 | */ |
65 | switch (mips_revision_sconid) { | 65 | switch (mips_revision_sconid) { |
66 | case MIPS_REVISION_SCON_SOCIT: | 66 | case MIPS_REVISION_SCON_SOCIT: |
67 | case MIPS_REVISION_SCON_ROCIT: | 67 | case MIPS_REVISION_SCON_ROCIT: |
68 | case MIPS_REVISION_SCON_SOCITSC: | 68 | case MIPS_REVISION_SCON_SOCITSC: |
69 | case MIPS_REVISION_SCON_SOCITSCP: | 69 | case MIPS_REVISION_SCON_SOCITSCP: |
70 | MSC_READ(MSC01_PCI_IACK, irq); | 70 | MSC_READ(MSC01_PCI_IACK, irq); |
71 | irq &= 0xff; | 71 | irq &= 0xff; |
72 | break; | 72 | break; |
73 | case MIPS_REVISION_SCON_GT64120: | 73 | case MIPS_REVISION_SCON_GT64120: |
74 | irq = GT_READ(GT_PCI0_IACK_OFS); | 74 | irq = GT_READ(GT_PCI0_IACK_OFS); |
75 | irq &= 0xff; | 75 | irq &= 0xff; |
76 | break; | 76 | break; |
77 | case MIPS_REVISION_SCON_BONITO: | 77 | case MIPS_REVISION_SCON_BONITO: |
78 | /* The following will generate a PCI IACK cycle on the | 78 | /* The following will generate a PCI IACK cycle on the |
79 | * Bonito controller. It's a little bit kludgy, but it | 79 | * Bonito controller. It's a little bit kludgy, but it |
80 | * was the easiest way to implement it in hardware at | 80 | * was the easiest way to implement it in hardware at |
81 | * the given time. | 81 | * the given time. |
82 | */ | 82 | */ |
83 | BONITO_PCIMAP_CFG = 0x20000; | 83 | BONITO_PCIMAP_CFG = 0x20000; |
84 | 84 | ||
85 | /* Flush Bonito register block */ | 85 | /* Flush Bonito register block */ |
86 | dummy = BONITO_PCIMAP_CFG; | 86 | dummy = BONITO_PCIMAP_CFG; |
87 | iob(); /* sync */ | 87 | iob(); /* sync */ |
88 | 88 | ||
89 | irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); | 89 | irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); |
90 | iob(); /* sync */ | 90 | iob(); /* sync */ |
91 | irq &= 0xff; | 91 | irq &= 0xff; |
92 | BONITO_PCIMAP_CFG = 0; | 92 | BONITO_PCIMAP_CFG = 0; |
93 | break; | 93 | break; |
94 | default: | 94 | default: |
95 | printk(KERN_WARNING "Unknown system controller.\n"); | 95 | printk(KERN_WARNING "Unknown system controller.\n"); |
96 | return -1; | 96 | return -1; |
97 | } | 97 | } |
98 | return irq; | 98 | return irq; |
99 | } | 99 | } |
100 | 100 | ||
101 | static inline int get_int(void) | 101 | static inline int get_int(void) |
102 | { | 102 | { |
103 | unsigned long flags; | 103 | unsigned long flags; |
104 | int irq; | 104 | int irq; |
105 | raw_spin_lock_irqsave(&mips_irq_lock, flags); | 105 | raw_spin_lock_irqsave(&mips_irq_lock, flags); |
106 | 106 | ||
107 | irq = mips_pcibios_iack(); | 107 | irq = mips_pcibios_iack(); |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * The only way we can decide if an interrupt is spurious | 110 | * The only way we can decide if an interrupt is spurious |
111 | * is by checking the 8259 registers. This needs a spinlock | 111 | * is by checking the 8259 registers. This needs a spinlock |
112 | * on an SMP system, so leave it up to the generic code... | 112 | * on an SMP system, so leave it up to the generic code... |
113 | */ | 113 | */ |
114 | 114 | ||
115 | raw_spin_unlock_irqrestore(&mips_irq_lock, flags); | 115 | raw_spin_unlock_irqrestore(&mips_irq_lock, flags); |
116 | 116 | ||
117 | return irq; | 117 | return irq; |
118 | } | 118 | } |
119 | 119 | ||
120 | static void malta_hw0_irqdispatch(void) | 120 | static void malta_hw0_irqdispatch(void) |
121 | { | 121 | { |
122 | int irq; | 122 | int irq; |
123 | 123 | ||
124 | irq = get_int(); | 124 | irq = get_int(); |
125 | if (irq < 0) { | 125 | if (irq < 0) { |
126 | /* interrupt has already been cleared */ | 126 | /* interrupt has already been cleared */ |
127 | return; | 127 | return; |
128 | } | 128 | } |
129 | 129 | ||
130 | do_IRQ(MALTA_INT_BASE + irq); | 130 | do_IRQ(MALTA_INT_BASE + irq); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void malta_ipi_irqdispatch(void) | 133 | static void malta_ipi_irqdispatch(void) |
134 | { | 134 | { |
135 | int irq; | 135 | int irq; |
136 | 136 | ||
137 | irq = gic_get_int(); | 137 | irq = gic_get_int(); |
138 | if (irq < 0) | 138 | if (irq < 0) |
139 | return; /* interrupt has already been cleared */ | 139 | return; /* interrupt has already been cleared */ |
140 | 140 | ||
141 | do_IRQ(MIPS_GIC_IRQ_BASE + irq); | 141 | do_IRQ(MIPS_GIC_IRQ_BASE + irq); |
142 | } | 142 | } |
143 | 143 | ||
144 | static void corehi_irqdispatch(void) | 144 | static void corehi_irqdispatch(void) |
145 | { | 145 | { |
146 | unsigned int intedge, intsteer, pcicmd, pcibadaddr; | 146 | unsigned int intedge, intsteer, pcicmd, pcibadaddr; |
147 | unsigned int pcimstat, intisr, inten, intpol; | 147 | unsigned int pcimstat, intisr, inten, intpol; |
148 | unsigned int intrcause, datalo, datahi; | 148 | unsigned int intrcause, datalo, datahi; |
149 | struct pt_regs *regs = get_irq_regs(); | 149 | struct pt_regs *regs = get_irq_regs(); |
150 | 150 | ||
151 | printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n"); | 151 | printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n"); |
152 | printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n" | 152 | printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n" |
153 | "Cause : %08lx\nbadVaddr : %08lx\n", | 153 | "Cause : %08lx\nbadVaddr : %08lx\n", |
154 | regs->cp0_epc, regs->cp0_status, | 154 | regs->cp0_epc, regs->cp0_status, |
155 | regs->cp0_cause, regs->cp0_badvaddr); | 155 | regs->cp0_cause, regs->cp0_badvaddr); |
156 | 156 | ||
157 | /* Read all the registers and then print them as there is a | 157 | /* Read all the registers and then print them as there is a |
158 | problem with interspersed printk's upsetting the Bonito controller. | 158 | problem with interspersed printk's upsetting the Bonito controller. |
159 | Do it for the others too. | 159 | Do it for the others too. |
160 | */ | 160 | */ |
161 | 161 | ||
162 | switch (mips_revision_sconid) { | 162 | switch (mips_revision_sconid) { |
163 | case MIPS_REVISION_SCON_SOCIT: | 163 | case MIPS_REVISION_SCON_SOCIT: |
164 | case MIPS_REVISION_SCON_ROCIT: | 164 | case MIPS_REVISION_SCON_ROCIT: |
165 | case MIPS_REVISION_SCON_SOCITSC: | 165 | case MIPS_REVISION_SCON_SOCITSC: |
166 | case MIPS_REVISION_SCON_SOCITSCP: | 166 | case MIPS_REVISION_SCON_SOCITSCP: |
167 | ll_msc_irq(); | 167 | ll_msc_irq(); |
168 | break; | 168 | break; |
169 | case MIPS_REVISION_SCON_GT64120: | 169 | case MIPS_REVISION_SCON_GT64120: |
170 | intrcause = GT_READ(GT_INTRCAUSE_OFS); | 170 | intrcause = GT_READ(GT_INTRCAUSE_OFS); |
171 | datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); | 171 | datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); |
172 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); | 172 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); |
173 | printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause); | 173 | printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause); |
174 | printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n", | 174 | printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n", |
175 | datahi, datalo); | 175 | datahi, datalo); |
176 | break; | 176 | break; |
177 | case MIPS_REVISION_SCON_BONITO: | 177 | case MIPS_REVISION_SCON_BONITO: |
178 | pcibadaddr = BONITO_PCIBADADDR; | 178 | pcibadaddr = BONITO_PCIBADADDR; |
179 | pcimstat = BONITO_PCIMSTAT; | 179 | pcimstat = BONITO_PCIMSTAT; |
180 | intisr = BONITO_INTISR; | 180 | intisr = BONITO_INTISR; |
181 | inten = BONITO_INTEN; | 181 | inten = BONITO_INTEN; |
182 | intpol = BONITO_INTPOL; | 182 | intpol = BONITO_INTPOL; |
183 | intedge = BONITO_INTEDGE; | 183 | intedge = BONITO_INTEDGE; |
184 | intsteer = BONITO_INTSTEER; | 184 | intsteer = BONITO_INTSTEER; |
185 | pcicmd = BONITO_PCICMD; | 185 | pcicmd = BONITO_PCICMD; |
186 | printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr); | 186 | printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr); |
187 | printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten); | 187 | printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten); |
188 | printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol); | 188 | printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol); |
189 | printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge); | 189 | printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge); |
190 | printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer); | 190 | printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer); |
191 | printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd); | 191 | printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd); |
192 | printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr); | 192 | printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr); |
193 | printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat); | 193 | printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat); |
194 | break; | 194 | break; |
195 | } | 195 | } |
196 | 196 | ||
197 | die("CoreHi interrupt", regs); | 197 | die("CoreHi interrupt", regs); |
198 | } | 198 | } |
199 | 199 | ||
200 | static inline int clz(unsigned long x) | 200 | static inline int clz(unsigned long x) |
201 | { | 201 | { |
202 | __asm__( | 202 | __asm__( |
203 | " .set push \n" | 203 | " .set push \n" |
204 | " .set mips32 \n" | 204 | " .set mips32 \n" |
205 | " clz %0, %1 \n" | 205 | " clz %0, %1 \n" |
206 | " .set pop \n" | 206 | " .set pop \n" |
207 | : "=r" (x) | 207 | : "=r" (x) |
208 | : "r" (x)); | 208 | : "r" (x)); |
209 | 209 | ||
210 | return x; | 210 | return x; |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Version of ffs that only looks at bits 12..15. | 214 | * Version of ffs that only looks at bits 12..15. |
215 | */ | 215 | */ |
216 | static inline unsigned int irq_ffs(unsigned int pending) | 216 | static inline unsigned int irq_ffs(unsigned int pending) |
217 | { | 217 | { |
218 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | 218 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) |
219 | return -clz(pending) + 31 - CAUSEB_IP; | 219 | return -clz(pending) + 31 - CAUSEB_IP; |
220 | #else | 220 | #else |
221 | unsigned int a0 = 7; | 221 | unsigned int a0 = 7; |
222 | unsigned int t0; | 222 | unsigned int t0; |
223 | 223 | ||
224 | t0 = pending & 0xf000; | 224 | t0 = pending & 0xf000; |
225 | t0 = t0 < 1; | 225 | t0 = t0 < 1; |
226 | t0 = t0 << 2; | 226 | t0 = t0 << 2; |
227 | a0 = a0 - t0; | 227 | a0 = a0 - t0; |
228 | pending = pending << t0; | 228 | pending = pending << t0; |
229 | 229 | ||
230 | t0 = pending & 0xc000; | 230 | t0 = pending & 0xc000; |
231 | t0 = t0 < 1; | 231 | t0 = t0 < 1; |
232 | t0 = t0 << 1; | 232 | t0 = t0 << 1; |
233 | a0 = a0 - t0; | 233 | a0 = a0 - t0; |
234 | pending = pending << t0; | 234 | pending = pending << t0; |
235 | 235 | ||
236 | t0 = pending & 0x8000; | 236 | t0 = pending & 0x8000; |
237 | t0 = t0 < 1; | 237 | t0 = t0 < 1; |
238 | /* t0 = t0 << 2; */ | 238 | /* t0 = t0 << 2; */ |
239 | a0 = a0 - t0; | 239 | a0 = a0 - t0; |
240 | /* pending = pending << t0; */ | 240 | /* pending = pending << t0; */ |
241 | 241 | ||
242 | return a0; | 242 | return a0; |
243 | #endif | 243 | #endif |
244 | } | 244 | } |
245 | 245 | ||
246 | /* | 246 | /* |
247 | * IRQs on the Malta board look basically (barring software IRQs which we | 247 | * IRQs on the Malta board look basically (barring software IRQs which we |
248 | * don't use at all and all external interrupt sources are combined together | 248 | * don't use at all and all external interrupt sources are combined together |
249 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | 249 | * on hardware interrupt 0 (MIPS IRQ 2)) like: |
250 | * | 250 | * |
251 | * MIPS IRQ Source | 251 | * MIPS IRQ Source |
252 | * -------- ------ | 252 | * -------- ------ |
253 | * 0 Software (ignored) | 253 | * 0 Software (ignored) |
254 | * 1 Software (ignored) | 254 | * 1 Software (ignored) |
255 | * 2 Combined hardware interrupt (hw0) | 255 | * 2 Combined hardware interrupt (hw0) |
256 | * 3 Hardware (ignored) | 256 | * 3 Hardware (ignored) |
257 | * 4 Hardware (ignored) | 257 | * 4 Hardware (ignored) |
258 | * 5 Hardware (ignored) | 258 | * 5 Hardware (ignored) |
259 | * 6 Hardware (ignored) | 259 | * 6 Hardware (ignored) |
260 | * 7 R4k timer (what we use) | 260 | * 7 R4k timer (what we use) |
261 | * | 261 | * |
262 | * We handle the IRQ according to _our_ priority which is: | 262 | * We handle the IRQ according to _our_ priority which is: |
263 | * | 263 | * |
264 | * Highest ---- R4k Timer | 264 | * Highest ---- R4k Timer |
265 | * Lowest ---- Combined hardware interrupt | 265 | * Lowest ---- Combined hardware interrupt |
266 | * | 266 | * |
267 | * then we just return, if multiple IRQs are pending then we will just take | 267 | * then we just return, if multiple IRQs are pending then we will just take |
268 | * another exception, big deal. | 268 | * another exception, big deal. |
269 | */ | 269 | */ |
270 | 270 | ||
271 | asmlinkage void plat_irq_dispatch(void) | 271 | asmlinkage void plat_irq_dispatch(void) |
272 | { | 272 | { |
273 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | 273 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; |
274 | int irq; | 274 | int irq; |
275 | 275 | ||
276 | irq = irq_ffs(pending); | 276 | irq = irq_ffs(pending); |
277 | 277 | ||
278 | if (irq == MIPSCPU_INT_I8259A) | 278 | if (irq == MIPSCPU_INT_I8259A) |
279 | malta_hw0_irqdispatch(); | 279 | malta_hw0_irqdispatch(); |
280 | else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) | 280 | else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) |
281 | malta_ipi_irqdispatch(); | 281 | malta_ipi_irqdispatch(); |
282 | else if (irq >= 0) | 282 | else if (irq >= 0) |
283 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | 283 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); |
284 | else | 284 | else |
285 | spurious_interrupt(); | 285 | spurious_interrupt(); |
286 | } | 286 | } |
287 | 287 | ||
288 | #ifdef CONFIG_MIPS_MT_SMP | 288 | #ifdef CONFIG_MIPS_MT_SMP |
289 | 289 | ||
290 | 290 | ||
291 | #define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 | 291 | #define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 |
292 | #define GIC_MIPS_CPU_IPI_CALL_IRQ 4 | 292 | #define GIC_MIPS_CPU_IPI_CALL_IRQ 4 |
293 | 293 | ||
294 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ | 294 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ |
295 | #define C_RESCHED C_SW0 | 295 | #define C_RESCHED C_SW0 |
296 | #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ | 296 | #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ |
297 | #define C_CALL C_SW1 | 297 | #define C_CALL C_SW1 |
298 | static int cpu_ipi_resched_irq, cpu_ipi_call_irq; | 298 | static int cpu_ipi_resched_irq, cpu_ipi_call_irq; |
299 | 299 | ||
300 | static void ipi_resched_dispatch(void) | 300 | static void ipi_resched_dispatch(void) |
301 | { | 301 | { |
302 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); | 302 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); |
303 | } | 303 | } |
304 | 304 | ||
305 | static void ipi_call_dispatch(void) | 305 | static void ipi_call_dispatch(void) |
306 | { | 306 | { |
307 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); | 307 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); |
308 | } | 308 | } |
309 | 309 | ||
310 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | 310 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) |
311 | { | 311 | { |
312 | return IRQ_HANDLED; | 312 | return IRQ_HANDLED; |
313 | } | 313 | } |
314 | 314 | ||
315 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | 315 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) |
316 | { | 316 | { |
317 | smp_call_function_interrupt(); | 317 | smp_call_function_interrupt(); |
318 | 318 | ||
319 | return IRQ_HANDLED; | 319 | return IRQ_HANDLED; |
320 | } | 320 | } |
321 | 321 | ||
322 | static struct irqaction irq_resched = { | 322 | static struct irqaction irq_resched = { |
323 | .handler = ipi_resched_interrupt, | 323 | .handler = ipi_resched_interrupt, |
324 | .flags = IRQF_DISABLED|IRQF_PERCPU, | 324 | .flags = IRQF_DISABLED|IRQF_PERCPU, |
325 | .name = "IPI_resched" | 325 | .name = "IPI_resched" |
326 | }; | 326 | }; |
327 | 327 | ||
328 | static struct irqaction irq_call = { | 328 | static struct irqaction irq_call = { |
329 | .handler = ipi_call_interrupt, | 329 | .handler = ipi_call_interrupt, |
330 | .flags = IRQF_DISABLED|IRQF_PERCPU, | 330 | .flags = IRQF_DISABLED|IRQF_PERCPU, |
331 | .name = "IPI_call" | 331 | .name = "IPI_call" |
332 | }; | 332 | }; |
333 | #endif /* CONFIG_MIPS_MT_SMP */ | 333 | #endif /* CONFIG_MIPS_MT_SMP */ |
334 | 334 | ||
335 | static int gic_resched_int_base; | 335 | static int gic_resched_int_base; |
336 | static int gic_call_int_base; | 336 | static int gic_call_int_base; |
337 | #define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) | 337 | #define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) |
338 | #define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) | 338 | #define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) |
339 | 339 | ||
340 | unsigned int plat_ipi_call_int_xlate(unsigned int cpu) | 340 | unsigned int plat_ipi_call_int_xlate(unsigned int cpu) |
341 | { | 341 | { |
342 | return GIC_CALL_INT(cpu); | 342 | return GIC_CALL_INT(cpu); |
343 | } | 343 | } |
344 | 344 | ||
345 | unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) | 345 | unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) |
346 | { | 346 | { |
347 | return GIC_RESCHED_INT(cpu); | 347 | return GIC_RESCHED_INT(cpu); |
348 | } | 348 | } |
349 | 349 | ||
350 | static struct irqaction i8259irq = { | 350 | static struct irqaction i8259irq = { |
351 | .handler = no_action, | 351 | .handler = no_action, |
352 | .name = "XT-PIC cascade" | 352 | .name = "XT-PIC cascade" |
353 | }; | 353 | }; |
354 | 354 | ||
355 | static struct irqaction corehi_irqaction = { | 355 | static struct irqaction corehi_irqaction = { |
356 | .handler = no_action, | 356 | .handler = no_action, |
357 | .name = "CoreHi" | 357 | .name = "CoreHi" |
358 | }; | 358 | }; |
359 | 359 | ||
360 | static msc_irqmap_t __initdata msc_irqmap[] = { | 360 | static msc_irqmap_t __initdata msc_irqmap[] = { |
361 | {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, | 361 | {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, |
362 | {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, | 362 | {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, |
363 | }; | 363 | }; |
364 | static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap); | 364 | static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap); |
365 | 365 | ||
366 | static msc_irqmap_t __initdata msc_eicirqmap[] = { | 366 | static msc_irqmap_t __initdata msc_eicirqmap[] = { |
367 | {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, | 367 | {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, |
368 | {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, | 368 | {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, |
369 | {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, | 369 | {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, |
370 | {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, | 370 | {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, |
371 | {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, | 371 | {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, |
372 | {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, | 372 | {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, |
373 | {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, | 373 | {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, |
374 | {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, | 374 | {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, |
375 | {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, | 375 | {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, |
376 | {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} | 376 | {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); | 379 | static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); |
380 | 380 | ||
381 | /* | 381 | /* |
382 | * This GIC specific tabular array defines the association between External | 382 | * This GIC specific tabular array defines the association between External |
383 | * Interrupts and CPUs/Core Interrupts. The nature of the External | 383 | * Interrupts and CPUs/Core Interrupts. The nature of the External |
384 | * Interrupts is also defined here - polarity/trigger. | 384 | * Interrupts is also defined here - polarity/trigger. |
385 | */ | 385 | */ |
386 | 386 | ||
387 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | 387 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK |
388 | #define X GIC_UNUSED | ||
389 | |||
388 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | 390 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { |
389 | { X, X, X, X, 0 }, | 391 | { X, X, X, X, 0 }, |
390 | { X, X, X, X, 0 }, | 392 | { X, X, X, X, 0 }, |
391 | { X, X, X, X, 0 }, | 393 | { X, X, X, X, 0 }, |
392 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 394 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
393 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 395 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
394 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 396 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
395 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 397 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
396 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 398 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
397 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 399 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
398 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 400 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
399 | { X, X, X, X, 0 }, | 401 | { X, X, X, X, 0 }, |
400 | { X, X, X, X, 0 }, | 402 | { X, X, X, X, 0 }, |
401 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 403 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
402 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 404 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
403 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | 405 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
404 | { X, X, X, X, 0 }, | 406 | { X, X, X, X, 0 }, |
405 | /* The remainder of this table is initialised by fill_ipi_map */ | 407 | /* The remainder of this table is initialised by fill_ipi_map */ |
406 | }; | 408 | }; |
409 | #undef X | ||
407 | 410 | ||
408 | /* | 411 | /* |
409 | * GCMP needs to be detected before any SMP initialisation | 412 | * GCMP needs to be detected before any SMP initialisation |
410 | */ | 413 | */ |
411 | int __init gcmp_probe(unsigned long addr, unsigned long size) | 414 | int __init gcmp_probe(unsigned long addr, unsigned long size) |
412 | { | 415 | { |
413 | if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) { | 416 | if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) { |
414 | gcmp_present = 0; | 417 | gcmp_present = 0; |
415 | return gcmp_present; | 418 | return gcmp_present; |
416 | } | 419 | } |
417 | 420 | ||
418 | if (gcmp_present >= 0) | 421 | if (gcmp_present >= 0) |
419 | return gcmp_present; | 422 | return gcmp_present; |
420 | 423 | ||
421 | _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); | 424 | _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); |
422 | _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); | 425 | _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); |
423 | gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; | 426 | gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; |
424 | 427 | ||
425 | if (gcmp_present) | 428 | if (gcmp_present) |
426 | pr_debug("GCMP present\n"); | 429 | pr_debug("GCMP present\n"); |
427 | return gcmp_present; | 430 | return gcmp_present; |
428 | } | 431 | } |
429 | 432 | ||
430 | /* Return the number of IOCU's present */ | 433 | /* Return the number of IOCU's present */ |
431 | int __init gcmp_niocu(void) | 434 | int __init gcmp_niocu(void) |
432 | { | 435 | { |
433 | return gcmp_present ? | 436 | return gcmp_present ? |
434 | (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF : | 437 | (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF : |
435 | 0; | 438 | 0; |
436 | } | 439 | } |
437 | 440 | ||
438 | /* Set GCMP region attributes */ | 441 | /* Set GCMP region attributes */ |
439 | void __init gcmp_setregion(int region, unsigned long base, | 442 | void __init gcmp_setregion(int region, unsigned long base, |
440 | unsigned long mask, int type) | 443 | unsigned long mask, int type) |
441 | { | 444 | { |
442 | GCMPGCBn(CMxBASE, region) = base; | 445 | GCMPGCBn(CMxBASE, region) = base; |
443 | GCMPGCBn(CMxMASK, region) = mask | type; | 446 | GCMPGCBn(CMxMASK, region) = mask | type; |
444 | } | 447 | } |
445 | 448 | ||
446 | #if defined(CONFIG_MIPS_MT_SMP) | 449 | #if defined(CONFIG_MIPS_MT_SMP) |
447 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) | 450 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) |
448 | { | 451 | { |
449 | int intr = baseintr + cpu; | 452 | int intr = baseintr + cpu; |
450 | gic_intr_map[intr].cpunum = cpu; | 453 | gic_intr_map[intr].cpunum = cpu; |
451 | gic_intr_map[intr].pin = cpupin; | 454 | gic_intr_map[intr].pin = cpupin; |
452 | gic_intr_map[intr].polarity = GIC_POL_POS; | 455 | gic_intr_map[intr].polarity = GIC_POL_POS; |
453 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; | 456 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; |
454 | gic_intr_map[intr].flags = GIC_FLAG_IPI; | 457 | gic_intr_map[intr].flags = GIC_FLAG_IPI; |
455 | ipi_map[cpu] |= (1 << (cpupin + 2)); | 458 | ipi_map[cpu] |= (1 << (cpupin + 2)); |
456 | } | 459 | } |
457 | 460 | ||
458 | static void __init fill_ipi_map(void) | 461 | static void __init fill_ipi_map(void) |
459 | { | 462 | { |
460 | int cpu; | 463 | int cpu; |
461 | 464 | ||
462 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 465 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
463 | fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); | 466 | fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); |
464 | fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); | 467 | fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); |
465 | } | 468 | } |
466 | } | 469 | } |
467 | #endif | 470 | #endif |
468 | 471 | ||
469 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | 472 | void __init arch_init_ipiirq(int irq, struct irqaction *action) |
470 | { | 473 | { |
471 | setup_irq(irq, action); | 474 | setup_irq(irq, action); |
472 | set_irq_handler(irq, handle_percpu_irq); | 475 | set_irq_handler(irq, handle_percpu_irq); |
473 | } | 476 | } |
474 | 477 | ||
475 | void __init arch_init_irq(void) | 478 | void __init arch_init_irq(void) |
476 | { | 479 | { |
477 | init_i8259_irqs(); | 480 | init_i8259_irqs(); |
478 | 481 | ||
479 | if (!cpu_has_veic) | 482 | if (!cpu_has_veic) |
480 | mips_cpu_irq_init(); | 483 | mips_cpu_irq_init(); |
481 | 484 | ||
482 | if (gcmp_present) { | 485 | if (gcmp_present) { |
483 | GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; | 486 | GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; |
484 | gic_present = 1; | 487 | gic_present = 1; |
485 | } else { | 488 | } else { |
486 | if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { | 489 | if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { |
487 | _msc01_biu_base = (unsigned long) | 490 | _msc01_biu_base = (unsigned long) |
488 | ioremap_nocache(MSC01_BIU_REG_BASE, | 491 | ioremap_nocache(MSC01_BIU_REG_BASE, |
489 | MSC01_BIU_ADDRSPACE_SZ); | 492 | MSC01_BIU_ADDRSPACE_SZ); |
490 | gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & | 493 | gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & |
491 | MSC01_SC_CFG_GICPRES_MSK) >> | 494 | MSC01_SC_CFG_GICPRES_MSK) >> |
492 | MSC01_SC_CFG_GICPRES_SHF; | 495 | MSC01_SC_CFG_GICPRES_SHF; |
493 | } | 496 | } |
494 | } | 497 | } |
495 | if (gic_present) | 498 | if (gic_present) |
496 | pr_debug("GIC present\n"); | 499 | pr_debug("GIC present\n"); |
497 | 500 | ||
498 | switch (mips_revision_sconid) { | 501 | switch (mips_revision_sconid) { |
499 | case MIPS_REVISION_SCON_SOCIT: | 502 | case MIPS_REVISION_SCON_SOCIT: |
500 | case MIPS_REVISION_SCON_ROCIT: | 503 | case MIPS_REVISION_SCON_ROCIT: |
501 | if (cpu_has_veic) | 504 | if (cpu_has_veic) |
502 | init_msc_irqs(MIPS_MSC01_IC_REG_BASE, | 505 | init_msc_irqs(MIPS_MSC01_IC_REG_BASE, |
503 | MSC01E_INT_BASE, msc_eicirqmap, | 506 | MSC01E_INT_BASE, msc_eicirqmap, |
504 | msc_nr_eicirqs); | 507 | msc_nr_eicirqs); |
505 | else | 508 | else |
506 | init_msc_irqs(MIPS_MSC01_IC_REG_BASE, | 509 | init_msc_irqs(MIPS_MSC01_IC_REG_BASE, |
507 | MSC01C_INT_BASE, msc_irqmap, | 510 | MSC01C_INT_BASE, msc_irqmap, |
508 | msc_nr_irqs); | 511 | msc_nr_irqs); |
509 | break; | 512 | break; |
510 | 513 | ||
511 | case MIPS_REVISION_SCON_SOCITSC: | 514 | case MIPS_REVISION_SCON_SOCITSC: |
512 | case MIPS_REVISION_SCON_SOCITSCP: | 515 | case MIPS_REVISION_SCON_SOCITSCP: |
513 | if (cpu_has_veic) | 516 | if (cpu_has_veic) |
514 | init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, | 517 | init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, |
515 | MSC01E_INT_BASE, msc_eicirqmap, | 518 | MSC01E_INT_BASE, msc_eicirqmap, |
516 | msc_nr_eicirqs); | 519 | msc_nr_eicirqs); |
517 | else | 520 | else |
518 | init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, | 521 | init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, |
519 | MSC01C_INT_BASE, msc_irqmap, | 522 | MSC01C_INT_BASE, msc_irqmap, |
520 | msc_nr_irqs); | 523 | msc_nr_irqs); |
521 | } | 524 | } |
522 | 525 | ||
523 | if (cpu_has_veic) { | 526 | if (cpu_has_veic) { |
524 | set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); | 527 | set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); |
525 | set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); | 528 | set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); |
526 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); | 529 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); |
527 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); | 530 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); |
528 | } else if (cpu_has_vint) { | 531 | } else if (cpu_has_vint) { |
529 | set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); | 532 | set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); |
530 | set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); | 533 | set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); |
531 | #ifdef CONFIG_MIPS_MT_SMTC | 534 | #ifdef CONFIG_MIPS_MT_SMTC |
532 | setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq, | 535 | setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq, |
533 | (0x100 << MIPSCPU_INT_I8259A)); | 536 | (0x100 << MIPSCPU_INT_I8259A)); |
534 | setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | 537 | setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, |
535 | &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); | 538 | &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); |
536 | /* | 539 | /* |
537 | * Temporary hack to ensure that the subsidiary device | 540 | * Temporary hack to ensure that the subsidiary device |
538 | * interrupts coing in via the i8259A, but associated | 541 | * interrupts coing in via the i8259A, but associated |
539 | * with low IRQ numbers, will restore the Status.IM | 542 | * with low IRQ numbers, will restore the Status.IM |
540 | * value associated with the i8259A. | 543 | * value associated with the i8259A. |
541 | */ | 544 | */ |
542 | { | 545 | { |
543 | int i; | 546 | int i; |
544 | 547 | ||
545 | for (i = 0; i < 16; i++) | 548 | for (i = 0; i < 16; i++) |
546 | irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A); | 549 | irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A); |
547 | } | 550 | } |
548 | #else /* Not SMTC */ | 551 | #else /* Not SMTC */ |
549 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); | 552 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); |
550 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | 553 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, |
551 | &corehi_irqaction); | 554 | &corehi_irqaction); |
552 | #endif /* CONFIG_MIPS_MT_SMTC */ | 555 | #endif /* CONFIG_MIPS_MT_SMTC */ |
553 | } else { | 556 | } else { |
554 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); | 557 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); |
555 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | 558 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, |
556 | &corehi_irqaction); | 559 | &corehi_irqaction); |
557 | } | 560 | } |
558 | 561 | ||
559 | if (gic_present) { | 562 | if (gic_present) { |
560 | /* FIXME */ | 563 | /* FIXME */ |
561 | int i; | 564 | int i; |
562 | #if defined(CONFIG_MIPS_MT_SMP) | 565 | #if defined(CONFIG_MIPS_MT_SMP) |
563 | gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; | 566 | gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; |
564 | gic_resched_int_base = gic_call_int_base - NR_CPUS; | 567 | gic_resched_int_base = gic_call_int_base - NR_CPUS; |
565 | fill_ipi_map(); | 568 | fill_ipi_map(); |
566 | #endif | 569 | #endif |
567 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, | 570 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, |
568 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | 571 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); |
569 | if (!gcmp_present) { | 572 | if (!gcmp_present) { |
570 | /* Enable the GIC */ | 573 | /* Enable the GIC */ |
571 | i = REG(_msc01_biu_base, MSC01_SC_CFG); | 574 | i = REG(_msc01_biu_base, MSC01_SC_CFG); |
572 | REG(_msc01_biu_base, MSC01_SC_CFG) = | 575 | REG(_msc01_biu_base, MSC01_SC_CFG) = |
573 | (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); | 576 | (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); |
574 | pr_debug("GIC Enabled\n"); | 577 | pr_debug("GIC Enabled\n"); |
575 | } | 578 | } |
576 | #if defined(CONFIG_MIPS_MT_SMP) | 579 | #if defined(CONFIG_MIPS_MT_SMP) |
577 | /* set up ipi interrupts */ | 580 | /* set up ipi interrupts */ |
578 | if (cpu_has_vint) { | 581 | if (cpu_has_vint) { |
579 | set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); | 582 | set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); |
580 | set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); | 583 | set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); |
581 | } | 584 | } |
582 | /* Argh.. this really needs sorting out.. */ | 585 | /* Argh.. this really needs sorting out.. */ |
583 | printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status()); | 586 | printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status()); |
584 | write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); | 587 | write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); |
585 | printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); | 588 | printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); |
586 | write_c0_status(0x1100dc00); | 589 | write_c0_status(0x1100dc00); |
587 | printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); | 590 | printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); |
588 | for (i = 0; i < NR_CPUS; i++) { | 591 | for (i = 0; i < NR_CPUS; i++) { |
589 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + | 592 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + |
590 | GIC_RESCHED_INT(i), &irq_resched); | 593 | GIC_RESCHED_INT(i), &irq_resched); |
591 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + | 594 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + |
592 | GIC_CALL_INT(i), &irq_call); | 595 | GIC_CALL_INT(i), &irq_call); |
593 | } | 596 | } |
594 | #endif | 597 | #endif |
595 | } else { | 598 | } else { |
596 | #if defined(CONFIG_MIPS_MT_SMP) | 599 | #if defined(CONFIG_MIPS_MT_SMP) |
597 | /* set up ipi interrupts */ | 600 | /* set up ipi interrupts */ |
598 | if (cpu_has_veic) { | 601 | if (cpu_has_veic) { |
599 | set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); | 602 | set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); |
600 | set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); | 603 | set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); |
601 | cpu_ipi_resched_irq = MSC01E_INT_SW0; | 604 | cpu_ipi_resched_irq = MSC01E_INT_SW0; |
602 | cpu_ipi_call_irq = MSC01E_INT_SW1; | 605 | cpu_ipi_call_irq = MSC01E_INT_SW1; |
603 | } else { | 606 | } else { |
604 | if (cpu_has_vint) { | 607 | if (cpu_has_vint) { |
605 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); | 608 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); |
606 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); | 609 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); |
607 | } | 610 | } |
608 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; | 611 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; |
609 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; | 612 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; |
610 | } | 613 | } |
611 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); | 614 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); |
612 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); | 615 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); |
613 | #endif | 616 | #endif |
614 | } | 617 | } |
615 | } | 618 | } |
616 | 619 | ||
617 | void malta_be_init(void) | 620 | void malta_be_init(void) |
618 | { | 621 | { |
619 | if (gcmp_present) { | 622 | if (gcmp_present) { |
620 | /* Could change CM error mask register */ | 623 | /* Could change CM error mask register */ |
621 | } | 624 | } |
622 | } | 625 | } |
623 | 626 | ||
624 | 627 | ||
625 | static char *tr[8] = { | 628 | static char *tr[8] = { |
626 | "mem", "gcr", "gic", "mmio", | 629 | "mem", "gcr", "gic", "mmio", |
627 | "0x04", "0x05", "0x06", "0x07" | 630 | "0x04", "0x05", "0x06", "0x07" |
628 | }; | 631 | }; |
629 | 632 | ||
630 | static char *mcmd[32] = { | 633 | static char *mcmd[32] = { |
631 | [0x00] = "0x00", | 634 | [0x00] = "0x00", |
632 | [0x01] = "Legacy Write", | 635 | [0x01] = "Legacy Write", |
633 | [0x02] = "Legacy Read", | 636 | [0x02] = "Legacy Read", |
634 | [0x03] = "0x03", | 637 | [0x03] = "0x03", |
635 | [0x04] = "0x04", | 638 | [0x04] = "0x04", |
636 | [0x05] = "0x05", | 639 | [0x05] = "0x05", |
637 | [0x06] = "0x06", | 640 | [0x06] = "0x06", |
638 | [0x07] = "0x07", | 641 | [0x07] = "0x07", |
639 | [0x08] = "Coherent Read Own", | 642 | [0x08] = "Coherent Read Own", |
640 | [0x09] = "Coherent Read Share", | 643 | [0x09] = "Coherent Read Share", |
641 | [0x0a] = "Coherent Read Discard", | 644 | [0x0a] = "Coherent Read Discard", |
642 | [0x0b] = "Coherent Ready Share Always", | 645 | [0x0b] = "Coherent Ready Share Always", |
643 | [0x0c] = "Coherent Upgrade", | 646 | [0x0c] = "Coherent Upgrade", |
644 | [0x0d] = "Coherent Writeback", | 647 | [0x0d] = "Coherent Writeback", |
645 | [0x0e] = "0x0e", | 648 | [0x0e] = "0x0e", |
646 | [0x0f] = "0x0f", | 649 | [0x0f] = "0x0f", |
647 | [0x10] = "Coherent Copyback", | 650 | [0x10] = "Coherent Copyback", |
648 | [0x11] = "Coherent Copyback Invalidate", | 651 | [0x11] = "Coherent Copyback Invalidate", |
649 | [0x12] = "Coherent Invalidate", | 652 | [0x12] = "Coherent Invalidate", |
650 | [0x13] = "Coherent Write Invalidate", | 653 | [0x13] = "Coherent Write Invalidate", |
651 | [0x14] = "Coherent Completion Sync", | 654 | [0x14] = "Coherent Completion Sync", |
652 | [0x15] = "0x15", | 655 | [0x15] = "0x15", |
653 | [0x16] = "0x16", | 656 | [0x16] = "0x16", |
654 | [0x17] = "0x17", | 657 | [0x17] = "0x17", |
655 | [0x18] = "0x18", | 658 | [0x18] = "0x18", |
656 | [0x19] = "0x19", | 659 | [0x19] = "0x19", |
657 | [0x1a] = "0x1a", | 660 | [0x1a] = "0x1a", |
658 | [0x1b] = "0x1b", | 661 | [0x1b] = "0x1b", |
659 | [0x1c] = "0x1c", | 662 | [0x1c] = "0x1c", |
660 | [0x1d] = "0x1d", | 663 | [0x1d] = "0x1d", |
661 | [0x1e] = "0x1e", | 664 | [0x1e] = "0x1e", |
662 | [0x1f] = "0x1f" | 665 | [0x1f] = "0x1f" |
663 | }; | 666 | }; |
664 | 667 | ||
665 | static char *core[8] = { | 668 | static char *core[8] = { |
666 | "Invalid/OK", "Invalid/Data", | 669 | "Invalid/OK", "Invalid/Data", |
667 | "Shared/OK", "Shared/Data", | 670 | "Shared/OK", "Shared/Data", |
668 | "Modified/OK", "Modified/Data", | 671 | "Modified/OK", "Modified/Data", |
669 | "Exclusive/OK", "Exclusive/Data" | 672 | "Exclusive/OK", "Exclusive/Data" |
670 | }; | 673 | }; |
671 | 674 | ||
672 | static char *causes[32] = { | 675 | static char *causes[32] = { |
673 | "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR", | 676 | "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR", |
674 | "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", | 677 | "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", |
675 | "0x08", "0x09", "0x0a", "0x0b", | 678 | "0x08", "0x09", "0x0a", "0x0b", |
676 | "0x0c", "0x0d", "0x0e", "0x0f", | 679 | "0x0c", "0x0d", "0x0e", "0x0f", |
677 | "0x10", "0x11", "0x12", "0x13", | 680 | "0x10", "0x11", "0x12", "0x13", |
678 | "0x14", "0x15", "0x16", "INTVN_WR_ERR", | 681 | "0x14", "0x15", "0x16", "INTVN_WR_ERR", |
679 | "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", | 682 | "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", |
680 | "0x1c", "0x1d", "0x1e", "0x1f" | 683 | "0x1c", "0x1d", "0x1e", "0x1f" |
681 | }; | 684 | }; |
682 | 685 | ||
683 | int malta_be_handler(struct pt_regs *regs, int is_fixup) | 686 | int malta_be_handler(struct pt_regs *regs, int is_fixup) |
684 | { | 687 | { |
685 | /* This duplicates the handling in do_be which seems wrong */ | 688 | /* This duplicates the handling in do_be which seems wrong */ |
686 | int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; | 689 | int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; |
687 | 690 | ||
688 | if (gcmp_present) { | 691 | if (gcmp_present) { |
689 | unsigned long cm_error = GCMPGCB(GCMEC); | 692 | unsigned long cm_error = GCMPGCB(GCMEC); |
690 | unsigned long cm_addr = GCMPGCB(GCMEA); | 693 | unsigned long cm_addr = GCMPGCB(GCMEA); |
691 | unsigned long cm_other = GCMPGCB(GCMEO); | 694 | unsigned long cm_other = GCMPGCB(GCMEO); |
692 | unsigned long cause, ocause; | 695 | unsigned long cause, ocause; |
693 | char buf[256]; | 696 | char buf[256]; |
694 | 697 | ||
695 | cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK); | 698 | cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK); |
696 | if (cause != 0) { | 699 | if (cause != 0) { |
697 | cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF; | 700 | cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF; |
698 | if (cause < 16) { | 701 | if (cause < 16) { |
699 | unsigned long cca_bits = (cm_error >> 15) & 7; | 702 | unsigned long cca_bits = (cm_error >> 15) & 7; |
700 | unsigned long tr_bits = (cm_error >> 12) & 7; | 703 | unsigned long tr_bits = (cm_error >> 12) & 7; |
701 | unsigned long mcmd_bits = (cm_error >> 7) & 0x1f; | 704 | unsigned long mcmd_bits = (cm_error >> 7) & 0x1f; |
702 | unsigned long stag_bits = (cm_error >> 3) & 15; | 705 | unsigned long stag_bits = (cm_error >> 3) & 15; |
703 | unsigned long sport_bits = (cm_error >> 0) & 7; | 706 | unsigned long sport_bits = (cm_error >> 0) & 7; |
704 | 707 | ||
705 | snprintf(buf, sizeof(buf), | 708 | snprintf(buf, sizeof(buf), |
706 | "CCA=%lu TR=%s MCmd=%s STag=%lu " | 709 | "CCA=%lu TR=%s MCmd=%s STag=%lu " |
707 | "SPort=%lu\n", | 710 | "SPort=%lu\n", |
708 | cca_bits, tr[tr_bits], mcmd[mcmd_bits], | 711 | cca_bits, tr[tr_bits], mcmd[mcmd_bits], |
709 | stag_bits, sport_bits); | 712 | stag_bits, sport_bits); |
710 | } else { | 713 | } else { |
711 | /* glob state & sresp together */ | 714 | /* glob state & sresp together */ |
712 | unsigned long c3_bits = (cm_error >> 18) & 7; | 715 | unsigned long c3_bits = (cm_error >> 18) & 7; |
713 | unsigned long c2_bits = (cm_error >> 15) & 7; | 716 | unsigned long c2_bits = (cm_error >> 15) & 7; |
714 | unsigned long c1_bits = (cm_error >> 12) & 7; | 717 | unsigned long c1_bits = (cm_error >> 12) & 7; |
715 | unsigned long c0_bits = (cm_error >> 9) & 7; | 718 | unsigned long c0_bits = (cm_error >> 9) & 7; |
716 | unsigned long sc_bit = (cm_error >> 8) & 1; | 719 | unsigned long sc_bit = (cm_error >> 8) & 1; |
717 | unsigned long mcmd_bits = (cm_error >> 3) & 0x1f; | 720 | unsigned long mcmd_bits = (cm_error >> 3) & 0x1f; |
718 | unsigned long sport_bits = (cm_error >> 0) & 7; | 721 | unsigned long sport_bits = (cm_error >> 0) & 7; |
719 | snprintf(buf, sizeof(buf), | 722 | snprintf(buf, sizeof(buf), |
720 | "C3=%s C2=%s C1=%s C0=%s SC=%s " | 723 | "C3=%s C2=%s C1=%s C0=%s SC=%s " |
721 | "MCmd=%s SPort=%lu\n", | 724 | "MCmd=%s SPort=%lu\n", |
722 | core[c3_bits], core[c2_bits], | 725 | core[c3_bits], core[c2_bits], |
723 | core[c1_bits], core[c0_bits], | 726 | core[c1_bits], core[c0_bits], |
724 | sc_bit ? "True" : "False", | 727 | sc_bit ? "True" : "False", |
725 | mcmd[mcmd_bits], sport_bits); | 728 | mcmd[mcmd_bits], sport_bits); |
726 | } | 729 | } |
727 | 730 | ||
728 | ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >> | 731 | ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >> |
729 | GCMP_GCB_GMEO_ERROR_2ND_SHF; | 732 | GCMP_GCB_GMEO_ERROR_2ND_SHF; |
730 | 733 | ||
731 | printk("CM_ERROR=%08lx %s <%s>\n", cm_error, | 734 | printk("CM_ERROR=%08lx %s <%s>\n", cm_error, |
732 | causes[cause], buf); | 735 | causes[cause], buf); |
733 | printk("CM_ADDR =%08lx\n", cm_addr); | 736 | printk("CM_ADDR =%08lx\n", cm_addr); |
734 | printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]); | 737 | printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]); |
735 | 738 | ||
736 | /* reprime cause register */ | 739 | /* reprime cause register */ |
737 | GCMPGCB(GCMEC) = 0; | 740 | GCMPGCB(GCMEC) = 0; |
738 | } | 741 | } |
739 | } | 742 | } |
740 | 743 | ||
741 | return retval; | 744 | return retval; |
742 | } | 745 | } |
743 | 746 |