diff options
| author | Chris Dearman <chris@mips.com> | 2009-07-10 04:54:09 -0400 |
|---|---|---|
| committer | Ralf Baechle <ralf@linux-mips.org> | 2009-11-02 06:00:06 -0500 |
| commit | 7098f748283b4c056cca9c284c476b03f004ca12 (patch) | |
| tree | 51d3f09abeabfe27dff3351a212b8c8a976ebba4 | |
| parent | 2ee0a42961c942c6a2fb70700ef4e25c0acf5fca (diff) | |
MIPS: GIC: Random fixes and enhancements.
Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
| -rw-r--r-- | arch/mips/include/asm/gcmpregs.h | 18 | ||||
| -rw-r--r-- | arch/mips/include/asm/gic.h | 188 | ||||
| -rw-r--r-- | arch/mips/kernel/irq-gic.c | 114 | ||||
| -rw-r--r-- | arch/mips/mti-malta/malta-int.c | 101 | ||||
| -rw-r--r-- | arch/mips/mti-malta/malta-pci.c | 14 |
5 files changed, 142 insertions, 293 deletions
diff --git a/arch/mips/include/asm/gcmpregs.h b/arch/mips/include/asm/gcmpregs.h index 36fd969d64d6..c0cf76a2ca89 100644 --- a/arch/mips/include/asm/gcmpregs.h +++ b/arch/mips/include/asm/gcmpregs.h | |||
| @@ -19,15 +19,20 @@ | |||
| 19 | #define GCMP_GDB_OFS 0x8000 /* Global Debug Block */ | 19 | #define GCMP_GDB_OFS 0x8000 /* Global Debug Block */ |
| 20 | 20 | ||
| 21 | /* Offsets to individual GCMP registers from GCMP base */ | 21 | /* Offsets to individual GCMP registers from GCMP base */ |
| 22 | #define GCMPOFS(block, tag, reg) (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS) | 22 | #define GCMPOFS(block, tag, reg) \ |
| 23 | (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS) | ||
| 24 | #define GCMPOFSn(block, tag, reg, n) \ | ||
| 25 | (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS(n)) | ||
| 23 | 26 | ||
| 24 | #define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg) | 27 | #define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg) |
| 28 | #define GCMPGCBOFSn(reg, n) GCMPOFSn(GCB, GCB, reg, n) | ||
| 25 | #define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg) | 29 | #define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg) |
| 26 | #define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg) | 30 | #define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg) |
| 27 | #define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg) | 31 | #define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg) |
| 28 | 32 | ||
| 29 | /* GCMP register access */ | 33 | /* GCMP register access */ |
| 30 | #define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg)) | 34 | #define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg)) |
| 35 | #define GCMPGCBn(reg, n) REGP(_gcmp_base, GCMPGCBOFSn(reg, n)) | ||
| 31 | #define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg)) | 36 | #define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg)) |
| 32 | #define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg)) | 37 | #define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg)) |
| 33 | #define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg)) | 38 | #define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg)) |
| @@ -49,10 +54,10 @@ | |||
| 49 | #define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17) | 54 | #define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17) |
| 50 | #define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0 | 55 | #define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0 |
| 51 | #define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2) | 56 | #define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2) |
| 52 | #define GCMP_GCB_GCMPB_CMDEFTGT_MEM 0 | 57 | #define GCMP_GCB_GCMPB_CMDEFTGT_DISABLED 0 |
| 53 | #define GCMP_GCB_GCMPB_CMDEFTGT_MEM1 1 | 58 | #define GCMP_GCB_GCMPB_CMDEFTGT_MEM 1 |
| 54 | #define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2 | 59 | #define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2 |
| 55 | #define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3 | 60 | #define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3 |
| 56 | #define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */ | 61 | #define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */ |
| 57 | #define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */ | 62 | #define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */ |
| 58 | #define GCMP_GCB_GCSRAP_CMACCESS_SHF 0 | 63 | #define GCMP_GCB_GCSRAP_CMACCESS_SHF 0 |
| @@ -115,5 +120,6 @@ | |||
| 115 | #define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */ | 120 | #define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */ |
| 116 | 121 | ||
| 117 | extern int __init gcmp_probe(unsigned long, unsigned long); | 122 | extern int __init gcmp_probe(unsigned long, unsigned long); |
| 118 | 123 | extern int __init gcmp_niocu(void); | |
| 124 | extern void __init gcmp_setregion(int, unsigned long, unsigned long, int); | ||
| 119 | #endif /* _ASM_GCMPREGS_H */ | 125 | #endif /* _ASM_GCMPREGS_H */ |
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index a8f57341f123..9b9436a4d816 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #define _ASM_GICREGS_H | 12 | #define _ASM_GICREGS_H |
| 13 | 13 | ||
| 14 | #undef GICISBYTELITTLEENDIAN | 14 | #undef GICISBYTELITTLEENDIAN |
| 15 | #define GICISWORDLITTLEENDIAN | ||
| 16 | 15 | ||
| 17 | /* Constants */ | 16 | /* Constants */ |
| 18 | #define GIC_POL_POS 1 | 17 | #define GIC_POL_POS 1 |
| @@ -20,11 +19,7 @@ | |||
| 20 | #define GIC_TRIG_EDGE 1 | 19 | #define GIC_TRIG_EDGE 1 |
| 21 | #define GIC_TRIG_LEVEL 0 | 20 | #define GIC_TRIG_LEVEL 0 |
| 22 | 21 | ||
| 23 | #ifdef CONFIG_SMP | ||
| 24 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | 22 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) |
| 25 | #else | ||
| 26 | #define GIC_NUM_INTRS 32 | ||
| 27 | #endif | ||
| 28 | 23 | ||
| 29 | #define MSK(n) ((1 << (n)) - 1) | 24 | #define MSK(n) ((1 << (n)) - 1) |
| 30 | #define REG32(addr) (*(volatile unsigned int *) (addr)) | 25 | #define REG32(addr) (*(volatile unsigned int *) (addr)) |
| @@ -70,13 +65,13 @@ | |||
| 70 | #define USM_VISIBLE_SECTION_SIZE 0x10000 | 65 | #define USM_VISIBLE_SECTION_SIZE 0x10000 |
| 71 | 66 | ||
| 72 | /* Register Map for Shared Section */ | 67 | /* Register Map for Shared Section */ |
| 73 | #if defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(GICISWORDLITTLEENDIAN) | ||
| 74 | 68 | ||
| 75 | #define GIC_SH_CONFIG_OFS 0x0000 | 69 | #define GIC_SH_CONFIG_OFS 0x0000 |
| 76 | 70 | ||
| 77 | /* Shared Global Counter */ | 71 | /* Shared Global Counter */ |
| 78 | #define GIC_SH_COUNTER_31_00_OFS 0x0010 | 72 | #define GIC_SH_COUNTER_31_00_OFS 0x0010 |
| 79 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 | 73 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 |
| 74 | #define GIC_SH_REVISIONID_OFS 0x0020 | ||
| 80 | 75 | ||
| 81 | /* Interrupt Polarity */ | 76 | /* Interrupt Polarity */ |
| 82 | #define GIC_SH_POL_31_0_OFS 0x0100 | 77 | #define GIC_SH_POL_31_0_OFS 0x0100 |
| @@ -164,24 +159,31 @@ | |||
| 164 | (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)) |
| 165 | #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)) |
| 166 | 161 | ||
| 162 | /* Convert an interrupt number to a byte offset/bit for multi-word registers */ | ||
| 163 | #define GIC_INTR_OFS(intr) (((intr) / 32)*4) | ||
| 164 | #define GIC_INTR_BIT(intr) ((intr) % 32) | ||
| 165 | |||
| 167 | /* Polarity : Reset Value is always 0 */ | 166 | /* Polarity : Reset Value is always 0 */ |
| 168 | #define GIC_SH_SET_POLARITY_OFS 0x0100 | 167 | #define GIC_SH_SET_POLARITY_OFS 0x0100 |
| 169 | #define GIC_SET_POLARITY(intr, pol) \ | 168 | #define GIC_SET_POLARITY(intr, pol) \ |
| 170 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + (((intr) / 32) * 4)), (pol) << ((intr) % 32)) | 169 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ |
| 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 + (((intr) / 32) * 4)), (trig) << ((intr) % 32)) | 175 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ |
| 176 | GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr)) | ||
| 176 | 177 | ||
| 177 | /* Mask manipulation */ | 178 | /* Mask manipulation */ |
| 178 | #define GIC_SH_SMASK_OFS 0x0380 | 179 | #define GIC_SH_SMASK_OFS 0x0380 |
| 179 | #define GIC_SET_INTR_MASK(intr, val) \ | 180 | #define GIC_SET_INTR_MASK(intr) \ |
| 180 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32))) | 181 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ |
| 181 | 182 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | |
| 182 | #define GIC_SH_RMASK_OFS 0x0300 | 183 | #define GIC_SH_RMASK_OFS 0x0300 |
| 183 | #define GIC_CLR_INTR_MASK(intr, val) \ | 184 | #define GIC_CLR_INTR_MASK(intr) \ |
| 184 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32))) | 185 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ |
| 186 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | ||
| 185 | 187 | ||
| 186 | /* Register Map for Local Section */ | 188 | /* Register Map for Local Section */ |
| 187 | #define GIC_VPE_CTL_OFS 0x0000 | 189 | #define GIC_VPE_CTL_OFS 0x0000 |
| @@ -219,161 +221,6 @@ | |||
| 219 | #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 | 221 | #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 |
| 220 | #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 | 222 | #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 |
| 221 | 223 | ||
| 222 | #else /* CONFIG_CPU_BIG_ENDIAN */ | ||
| 223 | |||
| 224 | #define GIC_SH_CONFIG_OFS 0x0000 | ||
| 225 | |||
| 226 | /* Shared Global Counter */ | ||
| 227 | #define GIC_SH_COUNTER_31_00_OFS 0x0014 | ||
| 228 | #define GIC_SH_COUNTER_63_32_OFS 0x0010 | ||
| 229 | |||
| 230 | /* Interrupt Polarity */ | ||
| 231 | #define GIC_SH_POL_31_0_OFS 0x0104 | ||
| 232 | #define GIC_SH_POL_63_32_OFS 0x0100 | ||
| 233 | #define GIC_SH_POL_95_64_OFS 0x010c | ||
| 234 | #define GIC_SH_POL_127_96_OFS 0x0108 | ||
| 235 | #define GIC_SH_POL_159_128_OFS 0x0114 | ||
| 236 | #define GIC_SH_POL_191_160_OFS 0x0110 | ||
| 237 | #define GIC_SH_POL_223_192_OFS 0x011c | ||
| 238 | #define GIC_SH_POL_255_224_OFS 0x0118 | ||
| 239 | |||
| 240 | /* Edge/Level Triggering */ | ||
| 241 | #define GIC_SH_TRIG_31_0_OFS 0x0184 | ||
| 242 | #define GIC_SH_TRIG_63_32_OFS 0x0180 | ||
| 243 | #define GIC_SH_TRIG_95_64_OFS 0x018c | ||
| 244 | #define GIC_SH_TRIG_127_96_OFS 0x0188 | ||
| 245 | #define GIC_SH_TRIG_159_128_OFS 0x0194 | ||
| 246 | #define GIC_SH_TRIG_191_160_OFS 0x0190 | ||
| 247 | #define GIC_SH_TRIG_223_192_OFS 0x019c | ||
| 248 | #define GIC_SH_TRIG_255_224_OFS 0x0198 | ||
| 249 | |||
| 250 | /* Dual Edge Triggering */ | ||
| 251 | #define GIC_SH_DUAL_31_0_OFS 0x0204 | ||
| 252 | #define GIC_SH_DUAL_63_32_OFS 0x0200 | ||
| 253 | #define GIC_SH_DUAL_95_64_OFS 0x020c | ||
| 254 | #define GIC_SH_DUAL_127_96_OFS 0x0208 | ||
| 255 | #define GIC_SH_DUAL_159_128_OFS 0x0214 | ||
| 256 | #define GIC_SH_DUAL_191_160_OFS 0x0210 | ||
| 257 | #define GIC_SH_DUAL_223_192_OFS 0x021c | ||
| 258 | #define GIC_SH_DUAL_255_224_OFS 0x0218 | ||
| 259 | |||
| 260 | /* Set/Clear corresponding bit in Edge Detect Register */ | ||
| 261 | #define GIC_SH_WEDGE_OFS 0x0280 | ||
| 262 | |||
| 263 | /* Reset Mask - Disables Interrupt */ | ||
| 264 | #define GIC_SH_RMASK_31_0_OFS 0x0304 | ||
| 265 | #define GIC_SH_RMASK_63_32_OFS 0x0300 | ||
| 266 | #define GIC_SH_RMASK_95_64_OFS 0x030c | ||
| 267 | #define GIC_SH_RMASK_127_96_OFS 0x0308 | ||
| 268 | #define GIC_SH_RMASK_159_128_OFS 0x0314 | ||
| 269 | #define GIC_SH_RMASK_191_160_OFS 0x0310 | ||
| 270 | #define GIC_SH_RMASK_223_192_OFS 0x031c | ||
| 271 | #define GIC_SH_RMASK_255_224_OFS 0x0318 | ||
| 272 | |||
| 273 | /* Set Mask (WO) - Enables Interrupt */ | ||
| 274 | #define GIC_SH_SMASK_31_0_OFS 0x0384 | ||
| 275 | #define GIC_SH_SMASK_63_32_OFS 0x0380 | ||
| 276 | #define GIC_SH_SMASK_95_64_OFS 0x038c | ||
| 277 | #define GIC_SH_SMASK_127_96_OFS 0x0388 | ||
| 278 | #define GIC_SH_SMASK_159_128_OFS 0x0394 | ||
| 279 | #define GIC_SH_SMASK_191_160_OFS 0x0390 | ||
| 280 | #define GIC_SH_SMASK_223_192_OFS 0x039c | ||
| 281 | #define GIC_SH_SMASK_255_224_OFS 0x0398 | ||
| 282 | |||
| 283 | /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ | ||
| 284 | #define GIC_SH_MASK_31_0_OFS 0x0404 | ||
| 285 | #define GIC_SH_MASK_63_32_OFS 0x0400 | ||
| 286 | #define GIC_SH_MASK_95_64_OFS 0x040c | ||
| 287 | #define GIC_SH_MASK_127_96_OFS 0x0408 | ||
| 288 | #define GIC_SH_MASK_159_128_OFS 0x0414 | ||
| 289 | #define GIC_SH_MASK_191_160_OFS 0x0410 | ||
| 290 | #define GIC_SH_MASK_223_192_OFS 0x041c | ||
| 291 | #define GIC_SH_MASK_255_224_OFS 0x0418 | ||
| 292 | |||
| 293 | /* Pending Global Interrupts (RO) */ | ||
| 294 | #define GIC_SH_PEND_31_0_OFS 0x0484 | ||
| 295 | #define GIC_SH_PEND_63_32_OFS 0x0480 | ||
| 296 | #define GIC_SH_PEND_95_64_OFS 0x048c | ||
| 297 | #define GIC_SH_PEND_127_96_OFS 0x0488 | ||
| 298 | #define GIC_SH_PEND_159_128_OFS 0x0494 | ||
| 299 | #define GIC_SH_PEND_191_160_OFS 0x0490 | ||
| 300 | #define GIC_SH_PEND_223_192_OFS 0x049c | ||
| 301 | #define GIC_SH_PEND_255_224_OFS 0x0498 | ||
| 302 | |||
| 303 | #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 | ||
| 304 | |||
| 305 | /* Maps Interrupt X to a Pin */ | ||
| 306 | #define GIC_SH_MAP_TO_PIN(intr) \ | ||
| 307 | (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) | ||
| 308 | |||
| 309 | #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2004 | ||
| 310 | |||
| 311 | /* | ||
| 312 | * Maps Interrupt X to a VPE. This is more complex than the LE case, as | ||
| 313 | * odd and even registers need to be transposed. It does work - trust me! | ||
| 314 | */ | ||
| 315 | #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ | ||
| 316 | (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + \ | ||
| 317 | (((((vpe) / 32) ^ 1) - 1) * 4)) | ||
| 318 | #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) | ||
| 319 | |||
| 320 | /* Polarity */ | ||
| 321 | #define GIC_SH_SET_POLARITY_OFS 0x0100 | ||
| 322 | #define GIC_SET_POLARITY(intr, pol) \ | ||
| 323 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (pol) << ((intr) % 32)) | ||
| 324 | |||
| 325 | /* Triggering */ | ||
| 326 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 | ||
| 327 | #define GIC_SET_TRIGGER(intr, trig) \ | ||
| 328 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (trig) << ((intr) % 32)) | ||
| 329 | |||
| 330 | /* Mask manipulation */ | ||
| 331 | #define GIC_SH_SMASK_OFS 0x0380 | ||
| 332 | #define GIC_SET_INTR_MASK(intr, val) \ | ||
| 333 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32))) | ||
| 334 | |||
| 335 | #define GIC_SH_RMASK_OFS 0x0300 | ||
| 336 | #define GIC_CLR_INTR_MASK(intr, val) \ | ||
| 337 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32))) | ||
| 338 | |||
| 339 | /* Register Map for Local Section */ | ||
| 340 | #define GIC_VPE_CTL_OFS 0x0000 | ||
| 341 | #define GIC_VPE_PEND_OFS 0x0004 | ||
| 342 | #define GIC_VPE_MASK_OFS 0x0008 | ||
| 343 | #define GIC_VPE_RMASK_OFS 0x000c | ||
| 344 | #define GIC_VPE_SMASK_OFS 0x0010 | ||
| 345 | #define GIC_VPE_WD_MAP_OFS 0x0040 | ||
| 346 | #define GIC_VPE_COMPARE_MAP_OFS 0x0044 | ||
| 347 | #define GIC_VPE_TIMER_MAP_OFS 0x0048 | ||
| 348 | #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 | ||
| 349 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 | ||
| 350 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 | ||
| 351 | #define GIC_VPE_OTHER_ADDR_OFS 0x0080 | ||
| 352 | #define GIC_VPE_WD_CONFIG0_OFS 0x0090 | ||
| 353 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 | ||
| 354 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 | ||
| 355 | #define GIC_VPE_COMPARE_LO_OFS 0x00a4 | ||
| 356 | #define GIC_VPE_COMPARE_HI_OFS 0x00a0 | ||
| 357 | |||
| 358 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | ||
| 359 | #define GIC_VPE_EIC_SS(intr) \ | ||
| 360 | (GIC_EIC_SHADOW_SET_BASE + (4 * intr)) | ||
| 361 | |||
| 362 | #define GIC_VPE_EIC_VEC_BASE 0x0800 | ||
| 363 | #define GIC_VPE_EIC_VEC(intr) \ | ||
| 364 | (GIC_VPE_EIC_VEC_BASE + (4 * intr)) | ||
| 365 | |||
| 366 | #define GIC_VPE_TENABLE_NMI_OFS 0x1000 | ||
| 367 | #define GIC_VPE_TENABLE_YQ_OFS 0x1004 | ||
| 368 | #define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 | ||
| 369 | #define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 | ||
| 370 | |||
| 371 | /* User Mode Visible Section Register Map */ | ||
| 372 | #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0004 | ||
| 373 | #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0000 | ||
| 374 | |||
| 375 | #endif /* !LE */ | ||
| 376 | |||
| 377 | /* Masks */ | 224 | /* Masks */ |
| 378 | #define GIC_SH_CONFIG_COUNTSTOP_SHF 28 | 225 | #define GIC_SH_CONFIG_COUNTSTOP_SHF 28 |
| 379 | #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) |
| @@ -473,12 +320,13 @@ struct gic_intrmask_regs { | |||
| 473 | * in building ipi_map. | 320 | * in building ipi_map. |
| 474 | */ | 321 | */ |
| 475 | struct gic_intr_map { | 322 | struct gic_intr_map { |
| 476 | unsigned int intrnum; /* Ext Intr Num */ | ||
| 477 | unsigned int cpunum; /* Directed to this CPU */ | 323 | unsigned int cpunum; /* Directed to this CPU */ |
| 478 | unsigned int pin; /* Directed to this Pin */ | 324 | unsigned int pin; /* Directed to this Pin */ |
| 479 | unsigned int polarity; /* Polarity : +/- */ | 325 | unsigned int polarity; /* Polarity : +/- */ |
| 480 | unsigned int trigtype; /* Trigger : Edge/Levl */ | 326 | unsigned int trigtype; /* Trigger : Edge/Levl */ |
| 481 | unsigned int ipiflag; /* Is used for IPI ? */ | 327 | unsigned int flags; /* Misc flags */ |
| 328 | #define GIC_FLAG_IPI 0x01 | ||
| 329 | #define GIC_FLAG_TRANSPARENT 0x02 | ||
| 482 | }; | 330 | }; |
| 483 | 331 | ||
| 484 | extern void gic_init(unsigned long gic_base_addr, | 332 | extern void gic_init(unsigned long gic_base_addr, |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index d2072cd38592..b181f2f0ea8e 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
| @@ -14,38 +14,23 @@ | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | static unsigned long _gic_base; | 16 | static unsigned long _gic_base; |
| 17 | static unsigned int _irqbase, _mapsize, numvpes, numintrs; | 17 | static unsigned int _irqbase; |
| 18 | static struct gic_intr_map *_intrmap; | 18 | static unsigned int gic_irq_flags[GIC_NUM_INTRS]; |
| 19 | #define GIC_IRQ_FLAG_EDGE 0x0001 | ||
| 19 | 20 | ||
| 20 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | 21 | struct gic_pcpu_mask pcpu_masks[NR_CPUS]; |
| 21 | static struct gic_pending_regs pending_regs[NR_CPUS]; | 22 | static struct gic_pending_regs pending_regs[NR_CPUS]; |
| 22 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | 23 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; |
| 23 | 24 | ||
| 24 | #define gic_wedgeb2bok 0 /* | ||
| 25 | * Can GIC handle b2b writes to wedge register? | ||
| 26 | */ | ||
| 27 | #if gic_wedgeb2bok == 0 | ||
| 28 | static DEFINE_SPINLOCK(gic_wedgeb2b_lock); | ||
| 29 | #endif | ||
| 30 | |||
| 31 | void gic_send_ipi(unsigned int intr) | 25 | void gic_send_ipi(unsigned int intr) |
| 32 | { | 26 | { |
| 33 | #if gic_wedgeb2bok == 0 | ||
| 34 | unsigned long flags; | ||
| 35 | #endif | ||
| 36 | pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, | 27 | pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, |
| 37 | read_c0_status()); | 28 | read_c0_status()); |
| 38 | if (!gic_wedgeb2bok) | ||
| 39 | spin_lock_irqsave(&gic_wedgeb2b_lock, flags); | ||
| 40 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); | 29 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); |
| 41 | if (!gic_wedgeb2bok) { | ||
| 42 | (void) GIC_REG(SHARED, GIC_SH_CONFIG); | ||
| 43 | spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags); | ||
| 44 | } | ||
| 45 | } | 30 | } |
| 46 | 31 | ||
| 47 | /* This is Malta specific and needs to be exported */ | 32 | /* This is Malta specific and needs to be exported */ |
| 48 | static void vpe_local_setup(unsigned int numvpes) | 33 | static void __init vpe_local_setup(unsigned int numvpes) |
| 49 | { | 34 | { |
| 50 | int i; | 35 | int i; |
| 51 | unsigned long timer_interrupt = 5, perf_interrupt = 5; | 36 | unsigned long timer_interrupt = 5, perf_interrupt = 5; |
| @@ -105,44 +90,34 @@ unsigned int gic_get_int(void) | |||
| 105 | 90 | ||
| 106 | static unsigned int gic_irq_startup(unsigned int irq) | 91 | static unsigned int gic_irq_startup(unsigned int irq) |
| 107 | { | 92 | { |
| 108 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | ||
| 109 | irq -= _irqbase; | 93 | irq -= _irqbase; |
| 110 | GIC_SET_INTR_MASK(irq, 1); | 94 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
| 95 | GIC_SET_INTR_MASK(irq); | ||
| 111 | return 0; | 96 | return 0; |
| 112 | } | 97 | } |
| 113 | 98 | ||
| 114 | static void gic_irq_ack(unsigned int irq) | 99 | static void gic_irq_ack(unsigned int irq) |
| 115 | { | 100 | { |
| 116 | #if gic_wedgeb2bok == 0 | ||
| 117 | unsigned long flags; | ||
| 118 | #endif | ||
| 119 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | ||
| 120 | irq -= _irqbase; | 101 | irq -= _irqbase; |
| 121 | GIC_CLR_INTR_MASK(irq, 1); | 102 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
| 103 | GIC_CLR_INTR_MASK(irq); | ||
| 122 | 104 | ||
| 123 | if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { | 105 | if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE) |
| 124 | if (!gic_wedgeb2bok) | ||
| 125 | spin_lock_irqsave(&gic_wedgeb2b_lock, flags); | ||
| 126 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | 106 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); |
| 127 | if (!gic_wedgeb2bok) { | ||
| 128 | (void) GIC_REG(SHARED, GIC_SH_CONFIG); | ||
| 129 | spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | 107 | } |
| 133 | 108 | ||
| 134 | static void gic_mask_irq(unsigned int irq) | 109 | static void gic_mask_irq(unsigned int irq) |
| 135 | { | 110 | { |
| 136 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | ||
| 137 | irq -= _irqbase; | 111 | irq -= _irqbase; |
| 138 | GIC_CLR_INTR_MASK(irq, 1); | 112 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
| 113 | GIC_CLR_INTR_MASK(irq); | ||
| 139 | } | 114 | } |
| 140 | 115 | ||
| 141 | static void gic_unmask_irq(unsigned int irq) | 116 | static void gic_unmask_irq(unsigned int irq) |
| 142 | { | 117 | { |
| 143 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | ||
| 144 | irq -= _irqbase; | 118 | irq -= _irqbase; |
| 145 | GIC_SET_INTR_MASK(irq, 1); | 119 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
| 120 | GIC_SET_INTR_MASK(irq); | ||
| 146 | } | 121 | } |
| 147 | 122 | ||
| 148 | #ifdef CONFIG_SMP | 123 | #ifdef CONFIG_SMP |
| @@ -155,9 +130,8 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
| 155 | unsigned long flags; | 130 | unsigned long flags; |
| 156 | int i; | 131 | int i; |
| 157 | 132 | ||
| 158 | pr_debug(KERN_DEBUG "%s called\n", __func__); | ||
| 159 | irq -= _irqbase; | 133 | irq -= _irqbase; |
| 160 | 134 | pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); | |
| 161 | cpumask_and(&tmp, cpumask, cpu_online_mask); | 135 | cpumask_and(&tmp, cpumask, cpu_online_mask); |
| 162 | if (cpus_empty(tmp)) | 136 | if (cpus_empty(tmp)) |
| 163 | return -1; | 137 | return -1; |
| @@ -168,13 +142,6 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
| 168 | /* Re-route this IRQ */ | 142 | /* Re-route this IRQ */ |
| 169 | GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); | 143 | GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); |
| 170 | 144 | ||
| 171 | /* | ||
| 172 | * FIXME: assumption that _intrmap is ordered and has no holes | ||
| 173 | */ | ||
| 174 | |||
| 175 | /* Update the intr_map */ | ||
| 176 | _intrmap[irq].cpunum = first_cpu(tmp); | ||
| 177 | |||
| 178 | /* Update the pcpu_masks */ | 145 | /* Update the pcpu_masks */ |
| 179 | for (i = 0; i < NR_CPUS; i++) | 146 | for (i = 0; i < NR_CPUS; i++) |
| 180 | clear_bit(irq, pcpu_masks[i].pcpu_mask); | 147 | clear_bit(irq, pcpu_masks[i].pcpu_mask); |
| @@ -201,8 +168,9 @@ static struct irq_chip gic_irq_controller = { | |||
| 201 | #endif | 168 | #endif |
| 202 | }; | 169 | }; |
| 203 | 170 | ||
| 204 | static void __init setup_intr(unsigned int intr, unsigned int cpu, | 171 | static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, |
| 205 | unsigned int pin, unsigned int polarity, unsigned int trigtype) | 172 | unsigned int pin, unsigned int polarity, unsigned int trigtype, |
| 173 | unsigned int flags) | ||
| 206 | { | 174 | { |
| 207 | /* Setup Intr to Pin mapping */ | 175 | /* Setup Intr to Pin mapping */ |
| 208 | if (pin & GIC_MAP_TO_NMI_MSK) { | 176 | if (pin & GIC_MAP_TO_NMI_MSK) { |
| @@ -227,38 +195,43 @@ static void __init setup_intr(unsigned int intr, unsigned int cpu, | |||
| 227 | GIC_SET_TRIGGER(intr, trigtype); | 195 | GIC_SET_TRIGGER(intr, trigtype); |
| 228 | 196 | ||
| 229 | /* Init Intr Masks */ | 197 | /* Init Intr Masks */ |
| 230 | GIC_SET_INTR_MASK(intr, 0); | 198 | GIC_CLR_INTR_MASK(intr); |
| 199 | /* Initialise per-cpu Interrupt software masks */ | ||
| 200 | if (flags & GIC_FLAG_IPI) | ||
| 201 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); | ||
| 202 | if (flags & GIC_FLAG_TRANSPARENT) | ||
| 203 | GIC_SET_INTR_MASK(intr); | ||
| 204 | if (trigtype == GIC_TRIG_EDGE) | ||
| 205 | gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE; | ||
| 231 | } | 206 | } |
| 232 | 207 | ||
| 233 | static void __init gic_basic_init(void) | 208 | static void __init gic_basic_init(int numintrs, int numvpes, |
| 209 | struct gic_intr_map *intrmap, int mapsize) | ||
| 234 | { | 210 | { |
| 235 | unsigned int i, cpu; | 211 | unsigned int i, cpu; |
| 236 | 212 | ||
| 237 | /* Setup defaults */ | 213 | /* Setup defaults */ |
| 238 | for (i = 0; i < GIC_NUM_INTRS; i++) { | 214 | for (i = 0; i < numintrs; i++) { |
| 239 | GIC_SET_POLARITY(i, GIC_POL_POS); | 215 | GIC_SET_POLARITY(i, GIC_POL_POS); |
| 240 | GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); | 216 | GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); |
| 241 | GIC_SET_INTR_MASK(i, 0); | 217 | GIC_CLR_INTR_MASK(i); |
| 218 | if (i < GIC_NUM_INTRS) | ||
| 219 | gic_irq_flags[i] = 0; | ||
| 242 | } | 220 | } |
| 243 | 221 | ||
| 244 | /* Setup specifics */ | 222 | /* Setup specifics */ |
| 245 | for (i = 0; i < _mapsize; i++) { | 223 | for (i = 0; i < mapsize; i++) { |
| 246 | cpu = _intrmap[i].cpunum; | 224 | cpu = intrmap[i].cpunum; |
| 247 | if (cpu == X) | 225 | if (cpu == X) |
| 248 | continue; | 226 | continue; |
| 249 | 227 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) | |
| 250 | if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 && | ||
| 251 | _intrmap[i].ipiflag == 0) | ||
| 252 | continue; | 228 | continue; |
| 253 | 229 | gic_setup_intr(i, | |
| 254 | setup_intr(_intrmap[i].intrnum, | 230 | intrmap[i].cpunum, |
| 255 | _intrmap[i].cpunum, | 231 | intrmap[i].pin, |
| 256 | _intrmap[i].pin, | 232 | intrmap[i].polarity, |
| 257 | _intrmap[i].polarity, | 233 | intrmap[i].trigtype, |
| 258 | _intrmap[i].trigtype); | 234 | intrmap[i].flags); |
| 259 | /* Initialise per-cpu Interrupt software masks */ | ||
| 260 | if (_intrmap[i].ipiflag) | ||
| 261 | set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask); | ||
| 262 | } | 235 | } |
| 263 | 236 | ||
| 264 | vpe_local_setup(numvpes); | 237 | vpe_local_setup(numvpes); |
| @@ -273,12 +246,11 @@ void __init gic_init(unsigned long gic_base_addr, | |||
| 273 | unsigned int irqbase) | 246 | unsigned int irqbase) |
| 274 | { | 247 | { |
| 275 | unsigned int gicconfig; | 248 | unsigned int gicconfig; |
| 249 | int numvpes, numintrs; | ||
| 276 | 250 | ||
| 277 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, | 251 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, |
| 278 | gic_addrspace_size); | 252 | gic_addrspace_size); |
| 279 | _irqbase = irqbase; | 253 | _irqbase = irqbase; |
| 280 | _intrmap = intr_map; | ||
| 281 | _mapsize = intr_map_size; | ||
| 282 | 254 | ||
| 283 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | 255 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); |
| 284 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | 256 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> |
| @@ -290,5 +262,5 @@ void __init gic_init(unsigned long gic_base_addr, | |||
| 290 | 262 | ||
| 291 | pr_debug("%s called\n", __func__); | 263 | pr_debug("%s called\n", __func__); |
| 292 | 264 | ||
| 293 | gic_basic_init(); | 265 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); |
| 294 | } | 266 | } |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index e568d0da060e..377a925e8cc6 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
| @@ -379,32 +379,32 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = { | |||
| 379 | 379 | ||
| 380 | static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); | 380 | static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); |
| 381 | 381 | ||
| 382 | #if defined(CONFIG_MIPS_MT_SMP) | ||
| 383 | /* | 382 | /* |
| 384 | * This GIC specific tabular array defines the association between External | 383 | * This GIC specific tabular array defines the association between External |
| 385 | * Interrupts and CPUs/Core Interrupts. The nature of the External | 384 | * Interrupts and CPUs/Core Interrupts. The nature of the External |
| 386 | * Interrupts is also defined here - polarity/trigger. | 385 | * Interrupts is also defined here - polarity/trigger. |
| 387 | */ | 386 | */ |
| 387 | |||
| 388 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | ||
| 388 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | 389 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { |
| 389 | { GIC_EXT_INTR(0), X, X, X, X, 0 }, | 390 | { X, X, X, X, 0 }, |
| 390 | { GIC_EXT_INTR(1), X, X, X, X, 0 }, | 391 | { X, X, X, X, 0 }, |
| 391 | { GIC_EXT_INTR(2), X, X, X, X, 0 }, | 392 | { X, X, X, X, 0 }, |
| 392 | { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 393 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 393 | { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 394 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 394 | { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 395 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 395 | { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 396 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 396 | { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 397 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 397 | { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 398 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 398 | { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 399 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 399 | { GIC_EXT_INTR(10), X, X, X, X, 0 }, | 400 | { X, X, X, X, 0 }, |
| 400 | { GIC_EXT_INTR(11), X, X, X, X, 0 }, | 401 | { X, X, X, X, 0 }, |
| 401 | { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 402 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 402 | { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 403 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 403 | { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, | 404 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, |
| 404 | { GIC_EXT_INTR(15), X, X, X, X, 0 }, | 405 | { X, X, X, X, 0 }, |
| 405 | /* This is the end of the general interrupts now we do IPI ones */ | 406 | /* The remainder of this table is initialised by fill_ipi_map */ |
| 406 | }; | 407 | }; |
| 407 | #endif | ||
| 408 | 408 | ||
| 409 | /* | 409 | /* |
| 410 | * GCMP needs to be detected before any SMP initialisation | 410 | * GCMP needs to be detected before any SMP initialisation |
| @@ -419,20 +419,35 @@ int __init gcmp_probe(unsigned long addr, unsigned long size) | |||
| 419 | gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; | 419 | gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; |
| 420 | 420 | ||
| 421 | if (gcmp_present) | 421 | if (gcmp_present) |
| 422 | printk(KERN_DEBUG "GCMP present\n"); | 422 | pr_debug("GCMP present\n"); |
| 423 | return gcmp_present; | 423 | return gcmp_present; |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | /* Return the number of IOCU's present */ | ||
| 427 | int __init gcmp_niocu(void) | ||
| 428 | { | ||
| 429 | return gcmp_present ? | ||
| 430 | (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF : | ||
| 431 | 0; | ||
| 432 | } | ||
| 433 | |||
| 434 | /* Set GCMP region attributes */ | ||
| 435 | void __init gcmp_setregion(int region, unsigned long base, | ||
| 436 | unsigned long mask, int type) | ||
| 437 | { | ||
| 438 | GCMPGCBn(CMxBASE, region) = base; | ||
| 439 | GCMPGCBn(CMxMASK, region) = mask | type; | ||
| 440 | } | ||
| 441 | |||
| 426 | #if defined(CONFIG_MIPS_MT_SMP) | 442 | #if defined(CONFIG_MIPS_MT_SMP) |
| 427 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) | 443 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) |
| 428 | { | 444 | { |
| 429 | int intr = baseintr + cpu; | 445 | int intr = baseintr + cpu; |
| 430 | gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr); | ||
| 431 | gic_intr_map[intr].cpunum = cpu; | 446 | gic_intr_map[intr].cpunum = cpu; |
| 432 | gic_intr_map[intr].pin = cpupin; | 447 | gic_intr_map[intr].pin = cpupin; |
| 433 | gic_intr_map[intr].polarity = GIC_POL_POS; | 448 | gic_intr_map[intr].polarity = GIC_POL_POS; |
| 434 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; | 449 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; |
| 435 | gic_intr_map[intr].ipiflag = 1; | 450 | gic_intr_map[intr].flags = GIC_FLAG_IPI; |
| 436 | ipi_map[cpu] |= (1 << (cpupin + 2)); | 451 | ipi_map[cpu] |= (1 << (cpupin + 2)); |
| 437 | } | 452 | } |
| 438 | 453 | ||
| @@ -447,6 +462,12 @@ static void __init fill_ipi_map(void) | |||
| 447 | } | 462 | } |
| 448 | #endif | 463 | #endif |
| 449 | 464 | ||
| 465 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | ||
| 466 | { | ||
| 467 | setup_irq(irq, action); | ||
| 468 | set_irq_handler(irq, handle_percpu_irq); | ||
| 469 | } | ||
| 470 | |||
| 450 | void __init arch_init_irq(void) | 471 | void __init arch_init_irq(void) |
| 451 | { | 472 | { |
| 452 | init_i8259_irqs(); | 473 | init_i8259_irqs(); |
| @@ -463,7 +484,7 @@ void __init arch_init_irq(void) | |||
| 463 | MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; | 484 | MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; |
| 464 | } | 485 | } |
| 465 | if (gic_present) | 486 | if (gic_present) |
| 466 | printk(KERN_DEBUG "GIC present\n"); | 487 | pr_debug("GIC present\n"); |
| 467 | 488 | ||
| 468 | switch (mips_revision_sconid) { | 489 | switch (mips_revision_sconid) { |
| 469 | case MIPS_REVISION_SCON_SOCIT: | 490 | case MIPS_REVISION_SCON_SOCIT: |
| @@ -526,16 +547,16 @@ void __init arch_init_irq(void) | |||
| 526 | &corehi_irqaction); | 547 | &corehi_irqaction); |
| 527 | } | 548 | } |
| 528 | 549 | ||
| 529 | #if defined(CONFIG_MIPS_MT_SMP) | ||
| 530 | if (gic_present) { | 550 | if (gic_present) { |
| 531 | /* FIXME */ | 551 | /* FIXME */ |
| 532 | int i; | 552 | int i; |
| 533 | 553 | #if defined(CONFIG_MIPS_MT_SMP) | |
| 534 | gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; | 554 | gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; |
| 535 | gic_resched_int_base = gic_call_int_base - NR_CPUS; | 555 | gic_resched_int_base = gic_call_int_base - NR_CPUS; |
| 536 | |||
| 537 | fill_ipi_map(); | 556 | fill_ipi_map(); |
| 538 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | 557 | #endif |
| 558 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, | ||
| 559 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | ||
| 539 | if (!gcmp_present) { | 560 | if (!gcmp_present) { |
| 540 | /* Enable the GIC */ | 561 | /* Enable the GIC */ |
| 541 | i = REG(_msc01_biu_base, MSC01_SC_CFG); | 562 | i = REG(_msc01_biu_base, MSC01_SC_CFG); |
| @@ -543,7 +564,7 @@ void __init arch_init_irq(void) | |||
| 543 | (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); | 564 | (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); |
| 544 | pr_debug("GIC Enabled\n"); | 565 | pr_debug("GIC Enabled\n"); |
| 545 | } | 566 | } |
| 546 | 567 | #if defined(CONFIG_MIPS_MT_SMP) | |
| 547 | /* set up ipi interrupts */ | 568 | /* set up ipi interrupts */ |
| 548 | if (cpu_has_vint) { | 569 | if (cpu_has_vint) { |
| 549 | set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); | 570 | set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); |
| @@ -556,16 +577,14 @@ void __init arch_init_irq(void) | |||
| 556 | write_c0_status(0x1100dc00); | 577 | write_c0_status(0x1100dc00); |
| 557 | printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); | 578 | printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); |
| 558 | for (i = 0; i < NR_CPUS; i++) { | 579 | for (i = 0; i < NR_CPUS; i++) { |
| 559 | setup_irq(MIPS_GIC_IRQ_BASE + | 580 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + |
| 560 | GIC_RESCHED_INT(i), &irq_resched); | 581 | GIC_RESCHED_INT(i), &irq_resched); |
| 561 | setup_irq(MIPS_GIC_IRQ_BASE + | 582 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + |
| 562 | GIC_CALL_INT(i), &irq_call); | 583 | GIC_CALL_INT(i), &irq_call); |
| 563 | set_irq_handler(MIPS_GIC_IRQ_BASE + | ||
| 564 | GIC_RESCHED_INT(i), handle_percpu_irq); | ||
| 565 | set_irq_handler(MIPS_GIC_IRQ_BASE + | ||
| 566 | GIC_CALL_INT(i), handle_percpu_irq); | ||
| 567 | } | 584 | } |
| 585 | #endif | ||
| 568 | } else { | 586 | } else { |
| 587 | #if defined(CONFIG_MIPS_MT_SMP) | ||
| 569 | /* set up ipi interrupts */ | 588 | /* set up ipi interrupts */ |
| 570 | if (cpu_has_veic) { | 589 | if (cpu_has_veic) { |
| 571 | set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); | 590 | set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); |
| @@ -580,14 +599,10 @@ void __init arch_init_irq(void) | |||
| 580 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; | 599 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; |
| 581 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; | 600 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; |
| 582 | } | 601 | } |
| 583 | 602 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); | |
| 584 | setup_irq(cpu_ipi_resched_irq, &irq_resched); | 603 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); |
| 585 | setup_irq(cpu_ipi_call_irq, &irq_call); | ||
| 586 | |||
| 587 | set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); | ||
| 588 | set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); | ||
| 589 | } | ||
| 590 | #endif | 604 | #endif |
| 605 | } | ||
| 591 | } | 606 | } |
| 592 | 607 | ||
| 593 | void malta_be_init(void) | 608 | void malta_be_init(void) |
diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c index efdb4f66ffcf..2fbfa1a8c3a9 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/mti-malta/malta-pci.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | 28 | ||
| 29 | #include <asm/gt64120.h> | 29 | #include <asm/gt64120.h> |
| 30 | 30 | #include <asm/gcmpregs.h> | |
| 31 | #include <asm/mips-boards/generic.h> | 31 | #include <asm/mips-boards/generic.h> |
| 32 | #include <asm/mips-boards/bonito64.h> | 32 | #include <asm/mips-boards/bonito64.h> |
| 33 | #include <asm/mips-boards/msc01_pci.h> | 33 | #include <asm/mips-boards/msc01_pci.h> |
| @@ -201,7 +201,11 @@ void __init mips_pcibios_init(void) | |||
| 201 | msc_mem_resource.start = start & mask; | 201 | msc_mem_resource.start = start & mask; |
| 202 | msc_mem_resource.end = (start & mask) | ~mask; | 202 | msc_mem_resource.end = (start & mask) | ~mask; |
| 203 | msc_controller.mem_offset = (start & mask) - (map & mask); | 203 | msc_controller.mem_offset = (start & mask) - (map & mask); |
| 204 | 204 | #ifdef CONFIG_MIPS_CMP | |
| 205 | if (gcmp_niocu()) | ||
| 206 | gcmp_setregion(0, start, mask, | ||
| 207 | GCMP_GCB_GCMPB_CMDEFTGT_IOCU1); | ||
| 208 | #endif | ||
| 205 | MSC_READ(MSC01_PCI_SC2PIOBASL, start); | 209 | MSC_READ(MSC01_PCI_SC2PIOBASL, start); |
| 206 | MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); | 210 | MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); |
| 207 | MSC_READ(MSC01_PCI_SC2PIOMAPL, map); | 211 | MSC_READ(MSC01_PCI_SC2PIOMAPL, map); |
| @@ -209,7 +213,11 @@ void __init mips_pcibios_init(void) | |||
| 209 | msc_io_resource.end = (map & mask) | ~mask; | 213 | msc_io_resource.end = (map & mask) | ~mask; |
| 210 | msc_controller.io_offset = 0; | 214 | msc_controller.io_offset = 0; |
| 211 | ioport_resource.end = ~mask; | 215 | ioport_resource.end = ~mask; |
| 212 | 216 | #ifdef CONFIG_MIPS_CMP | |
| 217 | if (gcmp_niocu()) | ||
| 218 | gcmp_setregion(1, start, mask, | ||
| 219 | GCMP_GCB_GCMPB_CMDEFTGT_IOCU1); | ||
| 220 | #endif | ||
| 213 | /* If ranges overlap I/O takes precedence. */ | 221 | /* If ranges overlap I/O takes precedence. */ |
| 214 | start = start & mask; | 222 | start = start & mask; |
| 215 | end = start | ~mask; | 223 | end = start | ~mask; |
