diff options
author | Zang Roy-r61911 <tie-fei.zang@freescale.com> | 2006-08-25 00:16:30 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-08-30 00:29:42 -0400 |
commit | 7233593b7844c2db930594ee9c0c872a6900bfcc (patch) | |
tree | afd6d3011feec3d2a2b1d80afd0e4ee9ef5fa3e4 | |
parent | 3efbdd136e52ee4028b5bb5b848a6043cf61cd6e (diff) |
[POWERPC] Support for "weird" MPICs and fixup mpc7448_hpc2
This adds a new hardware information table for mpic. This enables
the mpic code to deal with mpic controllers with different register
layouts and hardware behaviours.
This introduces CONFIG_MPIC_WEIRD. For boards with non standard mpic
controllers, select CONFIG_MPIC_WEIRD and add its hardware information
in the mpic_infos[] array.
TSI108/109 PIC takes the first index of weird hardware information
table. :) The table can be extended. The Tsi108/109 PIC looks like
standard OpenPIC but, in fact, is different in register mapping and
behavior.
The patch does not affect the behavior of standard mpic. If
CONFIG_MPIC_WEIRD is not defined, the code is essentially identical to
the current code.
[benh@kernel.crashing.org:
This patch is a slightly cleaned up version of Zang Roy's support for
the TSI108 MPIC variant. It also fixes up MPC7448_hpc2 to use the new
version of the type macros and changes the way MPIC is selected in
Kconfig to better match what is done for other system devices.
]
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/Kconfig | 20 | ||||
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 223 | ||||
-rw-r--r-- | include/asm-powerpc/mpic.h | 125 |
5 files changed, 305 insertions, 66 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index abb325eb8f75..4d4b6fb156e1 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -354,6 +354,7 @@ endchoice | |||
354 | config PPC_PSERIES | 354 | config PPC_PSERIES |
355 | depends on PPC_MULTIPLATFORM && PPC64 | 355 | depends on PPC_MULTIPLATFORM && PPC64 |
356 | bool "IBM pSeries & new (POWER5-based) iSeries" | 356 | bool "IBM pSeries & new (POWER5-based) iSeries" |
357 | select MPIC | ||
357 | select PPC_I8259 | 358 | select PPC_I8259 |
358 | select PPC_RTAS | 359 | select PPC_RTAS |
359 | select RTAS_ERROR_LOGGING | 360 | select RTAS_ERROR_LOGGING |
@@ -363,6 +364,7 @@ config PPC_PSERIES | |||
363 | config PPC_CHRP | 364 | config PPC_CHRP |
364 | bool "Common Hardware Reference Platform (CHRP) based machines" | 365 | bool "Common Hardware Reference Platform (CHRP) based machines" |
365 | depends on PPC_MULTIPLATFORM && PPC32 | 366 | depends on PPC_MULTIPLATFORM && PPC32 |
367 | select MPIC | ||
366 | select PPC_I8259 | 368 | select PPC_I8259 |
367 | select PPC_INDIRECT_PCI | 369 | select PPC_INDIRECT_PCI |
368 | select PPC_RTAS | 370 | select PPC_RTAS |
@@ -373,6 +375,7 @@ config PPC_CHRP | |||
373 | config PPC_PMAC | 375 | config PPC_PMAC |
374 | bool "Apple PowerMac based machines" | 376 | bool "Apple PowerMac based machines" |
375 | depends on PPC_MULTIPLATFORM | 377 | depends on PPC_MULTIPLATFORM |
378 | select MPIC | ||
376 | select PPC_INDIRECT_PCI if PPC32 | 379 | select PPC_INDIRECT_PCI if PPC32 |
377 | select PPC_MPC106 if PPC32 | 380 | select PPC_MPC106 if PPC32 |
378 | default y | 381 | default y |
@@ -380,6 +383,7 @@ config PPC_PMAC | |||
380 | config PPC_PMAC64 | 383 | config PPC_PMAC64 |
381 | bool | 384 | bool |
382 | depends on PPC_PMAC && POWER4 | 385 | depends on PPC_PMAC && POWER4 |
386 | select MPIC | ||
383 | select U3_DART | 387 | select U3_DART |
384 | select MPIC_BROKEN_U3 | 388 | select MPIC_BROKEN_U3 |
385 | select GENERIC_TBSYNC | 389 | select GENERIC_TBSYNC |
@@ -389,6 +393,7 @@ config PPC_PMAC64 | |||
389 | config PPC_PREP | 393 | config PPC_PREP |
390 | bool "PowerPC Reference Platform (PReP) based machines" | 394 | bool "PowerPC Reference Platform (PReP) based machines" |
391 | depends on PPC_MULTIPLATFORM && PPC32 && BROKEN | 395 | depends on PPC_MULTIPLATFORM && PPC32 && BROKEN |
396 | select MPIC | ||
392 | select PPC_I8259 | 397 | select PPC_I8259 |
393 | select PPC_INDIRECT_PCI | 398 | select PPC_INDIRECT_PCI |
394 | select PPC_UDBG_16550 | 399 | select PPC_UDBG_16550 |
@@ -397,6 +402,7 @@ config PPC_PREP | |||
397 | config PPC_MAPLE | 402 | config PPC_MAPLE |
398 | depends on PPC_MULTIPLATFORM && PPC64 | 403 | depends on PPC_MULTIPLATFORM && PPC64 |
399 | bool "Maple 970FX Evaluation Board" | 404 | bool "Maple 970FX Evaluation Board" |
405 | select MPIC | ||
400 | select U3_DART | 406 | select U3_DART |
401 | select MPIC_BROKEN_U3 | 407 | select MPIC_BROKEN_U3 |
402 | select GENERIC_TBSYNC | 408 | select GENERIC_TBSYNC |
@@ -439,12 +445,6 @@ config U3_DART | |||
439 | depends on PPC_MULTIPLATFORM && PPC64 | 445 | depends on PPC_MULTIPLATFORM && PPC64 |
440 | default n | 446 | default n |
441 | 447 | ||
442 | config MPIC | ||
443 | depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \ | ||
444 | || MPC7448HPC2 | ||
445 | bool | ||
446 | default y | ||
447 | |||
448 | config PPC_RTAS | 448 | config PPC_RTAS |
449 | bool | 449 | bool |
450 | default n | 450 | default n |
@@ -812,6 +812,14 @@ config GENERIC_ISA_DMA | |||
812 | depends on PPC64 || POWER4 || 6xx && !CPM2 | 812 | depends on PPC64 || POWER4 || 6xx && !CPM2 |
813 | default y | 813 | default y |
814 | 814 | ||
815 | config MPIC | ||
816 | bool | ||
817 | default n | ||
818 | |||
819 | config MPIC_WEIRD | ||
820 | bool | ||
821 | default n | ||
822 | |||
815 | config PPC_I8259 | 823 | config PPC_I8259 |
816 | bool | 824 | bool |
817 | default n | 825 | default n |
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index ba07a9a7c039..234a861870a8 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig | |||
@@ -80,6 +80,7 @@ config MPC7448HPC2 | |||
80 | select DEFAULT_UIMAGE | 80 | select DEFAULT_UIMAGE |
81 | select PPC_UDBG_16550 | 81 | select PPC_UDBG_16550 |
82 | select MPIC | 82 | select MPIC |
83 | select MPIC_WEIRD | ||
83 | help | 84 | help |
84 | Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) | 85 | Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) |
85 | platform | 86 | platform |
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index ed00ed2455dd..5d393eb94935 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
@@ -215,7 +215,7 @@ static void __init mpc7448_hpc2_init_IRQ(void) | |||
215 | 215 | ||
216 | mpic = mpic_alloc(tsi_pic, mpic_paddr, | 216 | mpic = mpic_alloc(tsi_pic, mpic_paddr, |
217 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | 217 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | |
218 | MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108), | 218 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, |
219 | 0, /* num_sources used */ | 219 | 0, /* num_sources used */ |
220 | 0, /* num_sources used */ | 220 | 0, /* num_sources used */ |
221 | "Tsi108_PIC"); | 221 | "Tsi108_PIC"); |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 6e0281afa6c3..b604926401f5 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -54,6 +54,94 @@ static DEFINE_SPINLOCK(mpic_lock); | |||
54 | #endif | 54 | #endif |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | #ifdef CONFIG_MPIC_WEIRD | ||
58 | static u32 mpic_infos[][MPIC_IDX_END] = { | ||
59 | [0] = { /* Original OpenPIC compatible MPIC */ | ||
60 | MPIC_GREG_BASE, | ||
61 | MPIC_GREG_FEATURE_0, | ||
62 | MPIC_GREG_GLOBAL_CONF_0, | ||
63 | MPIC_GREG_VENDOR_ID, | ||
64 | MPIC_GREG_IPI_VECTOR_PRI_0, | ||
65 | MPIC_GREG_IPI_STRIDE, | ||
66 | MPIC_GREG_SPURIOUS, | ||
67 | MPIC_GREG_TIMER_FREQ, | ||
68 | |||
69 | MPIC_TIMER_BASE, | ||
70 | MPIC_TIMER_STRIDE, | ||
71 | MPIC_TIMER_CURRENT_CNT, | ||
72 | MPIC_TIMER_BASE_CNT, | ||
73 | MPIC_TIMER_VECTOR_PRI, | ||
74 | MPIC_TIMER_DESTINATION, | ||
75 | |||
76 | MPIC_CPU_BASE, | ||
77 | MPIC_CPU_STRIDE, | ||
78 | MPIC_CPU_IPI_DISPATCH_0, | ||
79 | MPIC_CPU_IPI_DISPATCH_STRIDE, | ||
80 | MPIC_CPU_CURRENT_TASK_PRI, | ||
81 | MPIC_CPU_WHOAMI, | ||
82 | MPIC_CPU_INTACK, | ||
83 | MPIC_CPU_EOI, | ||
84 | |||
85 | MPIC_IRQ_BASE, | ||
86 | MPIC_IRQ_STRIDE, | ||
87 | MPIC_IRQ_VECTOR_PRI, | ||
88 | MPIC_VECPRI_VECTOR_MASK, | ||
89 | MPIC_VECPRI_POLARITY_POSITIVE, | ||
90 | MPIC_VECPRI_POLARITY_NEGATIVE, | ||
91 | MPIC_VECPRI_SENSE_LEVEL, | ||
92 | MPIC_VECPRI_SENSE_EDGE, | ||
93 | MPIC_VECPRI_POLARITY_MASK, | ||
94 | MPIC_VECPRI_SENSE_MASK, | ||
95 | MPIC_IRQ_DESTINATION | ||
96 | }, | ||
97 | [1] = { /* Tsi108/109 PIC */ | ||
98 | TSI108_GREG_BASE, | ||
99 | TSI108_GREG_FEATURE_0, | ||
100 | TSI108_GREG_GLOBAL_CONF_0, | ||
101 | TSI108_GREG_VENDOR_ID, | ||
102 | TSI108_GREG_IPI_VECTOR_PRI_0, | ||
103 | TSI108_GREG_IPI_STRIDE, | ||
104 | TSI108_GREG_SPURIOUS, | ||
105 | TSI108_GREG_TIMER_FREQ, | ||
106 | |||
107 | TSI108_TIMER_BASE, | ||
108 | TSI108_TIMER_STRIDE, | ||
109 | TSI108_TIMER_CURRENT_CNT, | ||
110 | TSI108_TIMER_BASE_CNT, | ||
111 | TSI108_TIMER_VECTOR_PRI, | ||
112 | TSI108_TIMER_DESTINATION, | ||
113 | |||
114 | TSI108_CPU_BASE, | ||
115 | TSI108_CPU_STRIDE, | ||
116 | TSI108_CPU_IPI_DISPATCH_0, | ||
117 | TSI108_CPU_IPI_DISPATCH_STRIDE, | ||
118 | TSI108_CPU_CURRENT_TASK_PRI, | ||
119 | TSI108_CPU_WHOAMI, | ||
120 | TSI108_CPU_INTACK, | ||
121 | TSI108_CPU_EOI, | ||
122 | |||
123 | TSI108_IRQ_BASE, | ||
124 | TSI108_IRQ_STRIDE, | ||
125 | TSI108_IRQ_VECTOR_PRI, | ||
126 | TSI108_VECPRI_VECTOR_MASK, | ||
127 | TSI108_VECPRI_POLARITY_POSITIVE, | ||
128 | TSI108_VECPRI_POLARITY_NEGATIVE, | ||
129 | TSI108_VECPRI_SENSE_LEVEL, | ||
130 | TSI108_VECPRI_SENSE_EDGE, | ||
131 | TSI108_VECPRI_POLARITY_MASK, | ||
132 | TSI108_VECPRI_SENSE_MASK, | ||
133 | TSI108_IRQ_DESTINATION | ||
134 | }, | ||
135 | }; | ||
136 | |||
137 | #define MPIC_INFO(name) mpic->hw_set[MPIC_IDX_##name] | ||
138 | |||
139 | #else /* CONFIG_MPIC_WEIRD */ | ||
140 | |||
141 | #define MPIC_INFO(name) MPIC_##name | ||
142 | |||
143 | #endif /* CONFIG_MPIC_WEIRD */ | ||
144 | |||
57 | /* | 145 | /* |
58 | * Register accessor functions | 146 | * Register accessor functions |
59 | */ | 147 | */ |
@@ -80,7 +168,8 @@ static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, | |||
80 | static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) | 168 | static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) |
81 | { | 169 | { |
82 | unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; | 170 | unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; |
83 | unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); | 171 | unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + |
172 | (ipi * MPIC_INFO(GREG_IPI_STRIDE)); | ||
84 | 173 | ||
85 | if (mpic->flags & MPIC_BROKEN_IPI) | 174 | if (mpic->flags & MPIC_BROKEN_IPI) |
86 | be = !be; | 175 | be = !be; |
@@ -89,7 +178,8 @@ static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) | |||
89 | 178 | ||
90 | static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) | 179 | static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) |
91 | { | 180 | { |
92 | unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); | 181 | unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + |
182 | (ipi * MPIC_INFO(GREG_IPI_STRIDE)); | ||
93 | 183 | ||
94 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); | 184 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); |
95 | } | 185 | } |
@@ -120,7 +210,7 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne | |||
120 | unsigned int idx = src_no & mpic->isu_mask; | 210 | unsigned int idx = src_no & mpic->isu_mask; |
121 | 211 | ||
122 | return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], | 212 | return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], |
123 | reg + (idx * MPIC_IRQ_STRIDE)); | 213 | reg + (idx * MPIC_INFO(IRQ_STRIDE))); |
124 | } | 214 | } |
125 | 215 | ||
126 | static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, | 216 | static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, |
@@ -130,7 +220,7 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, | |||
130 | unsigned int idx = src_no & mpic->isu_mask; | 220 | unsigned int idx = src_no & mpic->isu_mask; |
131 | 221 | ||
132 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], | 222 | _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], |
133 | reg + (idx * MPIC_IRQ_STRIDE), value); | 223 | reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); |
134 | } | 224 | } |
135 | 225 | ||
136 | #define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) | 226 | #define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) |
@@ -156,8 +246,8 @@ static void __init mpic_test_broken_ipi(struct mpic *mpic) | |||
156 | { | 246 | { |
157 | u32 r; | 247 | u32 r; |
158 | 248 | ||
159 | mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK); | 249 | mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK); |
160 | r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0); | 250 | r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0)); |
161 | 251 | ||
162 | if (r == le32_to_cpu(MPIC_VECPRI_MASK)) { | 252 | if (r == le32_to_cpu(MPIC_VECPRI_MASK)) { |
163 | printk(KERN_INFO "mpic: Detected reversed IPI registers\n"); | 253 | printk(KERN_INFO "mpic: Detected reversed IPI registers\n"); |
@@ -394,8 +484,8 @@ static inline struct mpic * mpic_from_irq(unsigned int irq) | |||
394 | /* Send an EOI */ | 484 | /* Send an EOI */ |
395 | static inline void mpic_eoi(struct mpic *mpic) | 485 | static inline void mpic_eoi(struct mpic *mpic) |
396 | { | 486 | { |
397 | mpic_cpu_write(MPIC_CPU_EOI, 0); | 487 | mpic_cpu_write(MPIC_INFO(CPU_EOI), 0); |
398 | (void)mpic_cpu_read(MPIC_CPU_WHOAMI); | 488 | (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); |
399 | } | 489 | } |
400 | 490 | ||
401 | #ifdef CONFIG_SMP | 491 | #ifdef CONFIG_SMP |
@@ -419,8 +509,8 @@ static void mpic_unmask_irq(unsigned int irq) | |||
419 | 509 | ||
420 | DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); | 510 | DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); |
421 | 511 | ||
422 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, | 512 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), |
423 | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & | 513 | mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & |
424 | ~MPIC_VECPRI_MASK); | 514 | ~MPIC_VECPRI_MASK); |
425 | /* make sure mask gets to controller before we return to user */ | 515 | /* make sure mask gets to controller before we return to user */ |
426 | do { | 516 | do { |
@@ -428,7 +518,7 @@ static void mpic_unmask_irq(unsigned int irq) | |||
428 | printk(KERN_ERR "mpic_enable_irq timeout\n"); | 518 | printk(KERN_ERR "mpic_enable_irq timeout\n"); |
429 | break; | 519 | break; |
430 | } | 520 | } |
431 | } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); | 521 | } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK); |
432 | } | 522 | } |
433 | 523 | ||
434 | static void mpic_mask_irq(unsigned int irq) | 524 | static void mpic_mask_irq(unsigned int irq) |
@@ -439,8 +529,8 @@ static void mpic_mask_irq(unsigned int irq) | |||
439 | 529 | ||
440 | DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); | 530 | DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); |
441 | 531 | ||
442 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, | 532 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), |
443 | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | | 533 | mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) | |
444 | MPIC_VECPRI_MASK); | 534 | MPIC_VECPRI_MASK); |
445 | 535 | ||
446 | /* make sure mask gets to controller before we return to user */ | 536 | /* make sure mask gets to controller before we return to user */ |
@@ -449,7 +539,7 @@ static void mpic_mask_irq(unsigned int irq) | |||
449 | printk(KERN_ERR "mpic_enable_irq timeout\n"); | 539 | printk(KERN_ERR "mpic_enable_irq timeout\n"); |
450 | break; | 540 | break; |
451 | } | 541 | } |
452 | } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); | 542 | } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK)); |
453 | } | 543 | } |
454 | 544 | ||
455 | static void mpic_end_irq(unsigned int irq) | 545 | static void mpic_end_irq(unsigned int irq) |
@@ -560,24 +650,28 @@ static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask) | |||
560 | 650 | ||
561 | cpus_and(tmp, cpumask, cpu_online_map); | 651 | cpus_and(tmp, cpumask, cpu_online_map); |
562 | 652 | ||
563 | mpic_irq_write(src, MPIC_IRQ_DESTINATION, | 653 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), |
564 | mpic_physmask(cpus_addr(tmp)[0])); | 654 | mpic_physmask(cpus_addr(tmp)[0])); |
565 | } | 655 | } |
566 | 656 | ||
567 | static unsigned int mpic_type_to_vecpri(unsigned int type) | 657 | static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) |
568 | { | 658 | { |
569 | /* Now convert sense value */ | 659 | /* Now convert sense value */ |
570 | switch(type & IRQ_TYPE_SENSE_MASK) { | 660 | switch(type & IRQ_TYPE_SENSE_MASK) { |
571 | case IRQ_TYPE_EDGE_RISING: | 661 | case IRQ_TYPE_EDGE_RISING: |
572 | return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE; | 662 | return MPIC_INFO(VECPRI_SENSE_EDGE) | |
663 | MPIC_INFO(VECPRI_POLARITY_POSITIVE); | ||
573 | case IRQ_TYPE_EDGE_FALLING: | 664 | case IRQ_TYPE_EDGE_FALLING: |
574 | case IRQ_TYPE_EDGE_BOTH: | 665 | case IRQ_TYPE_EDGE_BOTH: |
575 | return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE; | 666 | return MPIC_INFO(VECPRI_SENSE_EDGE) | |
667 | MPIC_INFO(VECPRI_POLARITY_NEGATIVE); | ||
576 | case IRQ_TYPE_LEVEL_HIGH: | 668 | case IRQ_TYPE_LEVEL_HIGH: |
577 | return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE; | 669 | return MPIC_INFO(VECPRI_SENSE_LEVEL) | |
670 | MPIC_INFO(VECPRI_POLARITY_POSITIVE); | ||
578 | case IRQ_TYPE_LEVEL_LOW: | 671 | case IRQ_TYPE_LEVEL_LOW: |
579 | default: | 672 | default: |
580 | return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE; | 673 | return MPIC_INFO(VECPRI_SENSE_LEVEL) | |
674 | MPIC_INFO(VECPRI_POLARITY_NEGATIVE); | ||
581 | } | 675 | } |
582 | } | 676 | } |
583 | 677 | ||
@@ -609,13 +703,14 @@ static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
609 | vecpri = MPIC_VECPRI_POLARITY_POSITIVE | | 703 | vecpri = MPIC_VECPRI_POLARITY_POSITIVE | |
610 | MPIC_VECPRI_SENSE_EDGE; | 704 | MPIC_VECPRI_SENSE_EDGE; |
611 | else | 705 | else |
612 | vecpri = mpic_type_to_vecpri(flow_type); | 706 | vecpri = mpic_type_to_vecpri(mpic, flow_type); |
613 | 707 | ||
614 | vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI); | 708 | vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); |
615 | vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK); | 709 | vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | |
710 | MPIC_INFO(VECPRI_SENSE_MASK)); | ||
616 | vnew |= vecpri; | 711 | vnew |= vecpri; |
617 | if (vold != vnew) | 712 | if (vold != vnew) |
618 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew); | 713 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew); |
619 | 714 | ||
620 | return 0; | 715 | return 0; |
621 | } | 716 | } |
@@ -798,17 +893,22 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
798 | mpic->irq_count = irq_count; | 893 | mpic->irq_count = irq_count; |
799 | mpic->num_sources = 0; /* so far */ | 894 | mpic->num_sources = 0; /* so far */ |
800 | 895 | ||
896 | #ifdef CONFIG_MPIC_WEIRD | ||
897 | mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; | ||
898 | #endif | ||
899 | |||
801 | /* Map the global registers */ | 900 | /* Map the global registers */ |
802 | mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000); | 901 | mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000); |
803 | mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2); | 902 | mpic->tmregs = mpic->gregs + |
903 | ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2); | ||
804 | BUG_ON(mpic->gregs == NULL); | 904 | BUG_ON(mpic->gregs == NULL); |
805 | 905 | ||
806 | /* Reset */ | 906 | /* Reset */ |
807 | if (flags & MPIC_WANTS_RESET) { | 907 | if (flags & MPIC_WANTS_RESET) { |
808 | mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, | 908 | mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), |
809 | mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) | 909 | mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) |
810 | | MPIC_GREG_GCONF_RESET); | 910 | | MPIC_GREG_GCONF_RESET); |
811 | while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) | 911 | while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) |
812 | & MPIC_GREG_GCONF_RESET) | 912 | & MPIC_GREG_GCONF_RESET) |
813 | mb(); | 913 | mb(); |
814 | } | 914 | } |
@@ -817,7 +917,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
817 | * MPICs, num sources as well. On ISU MPICs, sources are counted | 917 | * MPICs, num sources as well. On ISU MPICs, sources are counted |
818 | * as ISUs are added | 918 | * as ISUs are added |
819 | */ | 919 | */ |
820 | reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0); | 920 | reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); |
821 | mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) | 921 | mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) |
822 | >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; | 922 | >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; |
823 | if (isu_size == 0) | 923 | if (isu_size == 0) |
@@ -826,16 +926,16 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
826 | 926 | ||
827 | /* Map the per-CPU registers */ | 927 | /* Map the per-CPU registers */ |
828 | for (i = 0; i < mpic->num_cpus; i++) { | 928 | for (i = 0; i < mpic->num_cpus; i++) { |
829 | mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE + | 929 | mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) + |
830 | i * MPIC_CPU_STRIDE, 0x1000); | 930 | i * MPIC_INFO(CPU_STRIDE), 0x1000); |
831 | BUG_ON(mpic->cpuregs[i] == NULL); | 931 | BUG_ON(mpic->cpuregs[i] == NULL); |
832 | } | 932 | } |
833 | 933 | ||
834 | /* Initialize main ISU if none provided */ | 934 | /* Initialize main ISU if none provided */ |
835 | if (mpic->isu_size == 0) { | 935 | if (mpic->isu_size == 0) { |
836 | mpic->isu_size = mpic->num_sources; | 936 | mpic->isu_size = mpic->num_sources; |
837 | mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE, | 937 | mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE), |
838 | MPIC_IRQ_STRIDE * mpic->isu_size); | 938 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); |
839 | BUG_ON(mpic->isus[0] == NULL); | 939 | BUG_ON(mpic->isus[0] == NULL); |
840 | } | 940 | } |
841 | mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); | 941 | mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); |
@@ -879,7 +979,8 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, | |||
879 | 979 | ||
880 | BUG_ON(isu_num >= MPIC_MAX_ISU); | 980 | BUG_ON(isu_num >= MPIC_MAX_ISU); |
881 | 981 | ||
882 | mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size); | 982 | mpic->isus[isu_num] = ioremap(phys_addr, |
983 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); | ||
883 | if ((isu_first + mpic->isu_size) > mpic->num_sources) | 984 | if ((isu_first + mpic->isu_size) > mpic->num_sources) |
884 | mpic->num_sources = isu_first + mpic->isu_size; | 985 | mpic->num_sources = isu_first + mpic->isu_size; |
885 | } | 986 | } |
@@ -904,14 +1005,16 @@ void __init mpic_init(struct mpic *mpic) | |||
904 | printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); | 1005 | printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); |
905 | 1006 | ||
906 | /* Set current processor priority to max */ | 1007 | /* Set current processor priority to max */ |
907 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); | 1008 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); |
908 | 1009 | ||
909 | /* Initialize timers: just disable them all */ | 1010 | /* Initialize timers: just disable them all */ |
910 | for (i = 0; i < 4; i++) { | 1011 | for (i = 0; i < 4; i++) { |
911 | mpic_write(mpic->tmregs, | 1012 | mpic_write(mpic->tmregs, |
912 | i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0); | 1013 | i * MPIC_INFO(TIMER_STRIDE) + |
1014 | MPIC_INFO(TIMER_DESTINATION), 0); | ||
913 | mpic_write(mpic->tmregs, | 1015 | mpic_write(mpic->tmregs, |
914 | i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI, | 1016 | i * MPIC_INFO(TIMER_STRIDE) + |
1017 | MPIC_INFO(TIMER_VECTOR_PRI), | ||
915 | MPIC_VECPRI_MASK | | 1018 | MPIC_VECPRI_MASK | |
916 | (MPIC_VEC_TIMER_0 + i)); | 1019 | (MPIC_VEC_TIMER_0 + i)); |
917 | } | 1020 | } |
@@ -940,21 +1043,22 @@ void __init mpic_init(struct mpic *mpic) | |||
940 | (8 << MPIC_VECPRI_PRIORITY_SHIFT); | 1043 | (8 << MPIC_VECPRI_PRIORITY_SHIFT); |
941 | 1044 | ||
942 | /* init hw */ | 1045 | /* init hw */ |
943 | mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri); | 1046 | mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); |
944 | mpic_irq_write(i, MPIC_IRQ_DESTINATION, | 1047 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), |
945 | 1 << hard_smp_processor_id()); | 1048 | 1 << hard_smp_processor_id()); |
946 | } | 1049 | } |
947 | 1050 | ||
948 | /* Init spurrious vector */ | 1051 | /* Init spurrious vector */ |
949 | mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS); | 1052 | mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS); |
950 | 1053 | ||
951 | /* Disable 8259 passthrough */ | 1054 | /* Disable 8259 passthrough, if supported */ |
952 | mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, | 1055 | if (!(mpic->flags & MPIC_NO_PTHROU_DIS)) |
953 | mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) | 1056 | mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), |
954 | | MPIC_GREG_GCONF_8259_PTHROU_DIS); | 1057 | mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) |
1058 | | MPIC_GREG_GCONF_8259_PTHROU_DIS); | ||
955 | 1059 | ||
956 | /* Set current processor priority to 0 */ | 1060 | /* Set current processor priority to 0 */ |
957 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); | 1061 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); |
958 | } | 1062 | } |
959 | 1063 | ||
960 | void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) | 1064 | void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) |
@@ -997,9 +1101,9 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) | |||
997 | mpic_ipi_write(src - MPIC_VEC_IPI_0, | 1101 | mpic_ipi_write(src - MPIC_VEC_IPI_0, |
998 | reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); | 1102 | reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); |
999 | } else { | 1103 | } else { |
1000 | reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | 1104 | reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
1001 | & ~MPIC_VECPRI_PRIORITY_MASK; | 1105 | & ~MPIC_VECPRI_PRIORITY_MASK; |
1002 | mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, | 1106 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), |
1003 | reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); | 1107 | reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); |
1004 | } | 1108 | } |
1005 | spin_unlock_irqrestore(&mpic_lock, flags); | 1109 | spin_unlock_irqrestore(&mpic_lock, flags); |
@@ -1017,7 +1121,7 @@ unsigned int mpic_irq_get_priority(unsigned int irq) | |||
1017 | if (is_ipi) | 1121 | if (is_ipi) |
1018 | reg = mpic_ipi_read(src = MPIC_VEC_IPI_0); | 1122 | reg = mpic_ipi_read(src = MPIC_VEC_IPI_0); |
1019 | else | 1123 | else |
1020 | reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI); | 1124 | reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); |
1021 | spin_unlock_irqrestore(&mpic_lock, flags); | 1125 | spin_unlock_irqrestore(&mpic_lock, flags); |
1022 | return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; | 1126 | return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; |
1023 | } | 1127 | } |
@@ -1043,12 +1147,12 @@ void mpic_setup_this_cpu(void) | |||
1043 | */ | 1147 | */ |
1044 | if (distribute_irqs) { | 1148 | if (distribute_irqs) { |
1045 | for (i = 0; i < mpic->num_sources ; i++) | 1149 | for (i = 0; i < mpic->num_sources ; i++) |
1046 | mpic_irq_write(i, MPIC_IRQ_DESTINATION, | 1150 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), |
1047 | mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk); | 1151 | mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); |
1048 | } | 1152 | } |
1049 | 1153 | ||
1050 | /* Set current processor priority to 0 */ | 1154 | /* Set current processor priority to 0 */ |
1051 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); | 1155 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); |
1052 | 1156 | ||
1053 | spin_unlock_irqrestore(&mpic_lock, flags); | 1157 | spin_unlock_irqrestore(&mpic_lock, flags); |
1054 | #endif /* CONFIG_SMP */ | 1158 | #endif /* CONFIG_SMP */ |
@@ -1058,7 +1162,7 @@ int mpic_cpu_get_priority(void) | |||
1058 | { | 1162 | { |
1059 | struct mpic *mpic = mpic_primary; | 1163 | struct mpic *mpic = mpic_primary; |
1060 | 1164 | ||
1061 | return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI); | 1165 | return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI)); |
1062 | } | 1166 | } |
1063 | 1167 | ||
1064 | void mpic_cpu_set_priority(int prio) | 1168 | void mpic_cpu_set_priority(int prio) |
@@ -1066,7 +1170,7 @@ void mpic_cpu_set_priority(int prio) | |||
1066 | struct mpic *mpic = mpic_primary; | 1170 | struct mpic *mpic = mpic_primary; |
1067 | 1171 | ||
1068 | prio &= MPIC_CPU_TASKPRI_MASK; | 1172 | prio &= MPIC_CPU_TASKPRI_MASK; |
1069 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio); | 1173 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio); |
1070 | } | 1174 | } |
1071 | 1175 | ||
1072 | /* | 1176 | /* |
@@ -1088,11 +1192,11 @@ void mpic_teardown_this_cpu(int secondary) | |||
1088 | 1192 | ||
1089 | /* let the mpic know we don't want intrs. */ | 1193 | /* let the mpic know we don't want intrs. */ |
1090 | for (i = 0; i < mpic->num_sources ; i++) | 1194 | for (i = 0; i < mpic->num_sources ; i++) |
1091 | mpic_irq_write(i, MPIC_IRQ_DESTINATION, | 1195 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), |
1092 | mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); | 1196 | mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk); |
1093 | 1197 | ||
1094 | /* Set current processor priority to max */ | 1198 | /* Set current processor priority to max */ |
1095 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); | 1199 | mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); |
1096 | 1200 | ||
1097 | spin_unlock_irqrestore(&mpic_lock, flags); | 1201 | spin_unlock_irqrestore(&mpic_lock, flags); |
1098 | } | 1202 | } |
@@ -1108,7 +1212,8 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) | |||
1108 | DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); | 1212 | DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); |
1109 | #endif | 1213 | #endif |
1110 | 1214 | ||
1111 | mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, | 1215 | mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + |
1216 | ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), | ||
1112 | mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); | 1217 | mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); |
1113 | } | 1218 | } |
1114 | 1219 | ||
@@ -1116,7 +1221,7 @@ unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) | |||
1116 | { | 1221 | { |
1117 | u32 src; | 1222 | u32 src; |
1118 | 1223 | ||
1119 | src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; | 1224 | src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK); |
1120 | #ifdef DEBUG_LOW | 1225 | #ifdef DEBUG_LOW |
1121 | DBG("%s: get_one_irq(): %d\n", mpic->name, src); | 1226 | DBG("%s: get_one_irq(): %d\n", mpic->name, src); |
1122 | #endif | 1227 | #endif |
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index eb241c99c457..a9f9604b9eff 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0 | 41 | #define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0 |
42 | #define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0 | 42 | #define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0 |
43 | #define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0 | 43 | #define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0 |
44 | #define MPIC_GREG_IPI_STRIDE 0x10 | ||
44 | #define MPIC_GREG_SPURIOUS 0x000e0 | 45 | #define MPIC_GREG_SPURIOUS 0x000e0 |
45 | #define MPIC_GREG_TIMER_FREQ 0x000f0 | 46 | #define MPIC_GREG_TIMER_FREQ 0x000f0 |
46 | 47 | ||
@@ -68,6 +69,7 @@ | |||
68 | #define MPIC_CPU_IPI_DISPATCH_1 0x00050 | 69 | #define MPIC_CPU_IPI_DISPATCH_1 0x00050 |
69 | #define MPIC_CPU_IPI_DISPATCH_2 0x00060 | 70 | #define MPIC_CPU_IPI_DISPATCH_2 0x00060 |
70 | #define MPIC_CPU_IPI_DISPATCH_3 0x00070 | 71 | #define MPIC_CPU_IPI_DISPATCH_3 0x00070 |
72 | #define MPIC_CPU_IPI_DISPATCH_STRIDE 0x00010 | ||
71 | #define MPIC_CPU_CURRENT_TASK_PRI 0x00080 | 73 | #define MPIC_CPU_CURRENT_TASK_PRI 0x00080 |
72 | #define MPIC_CPU_TASKPRI_MASK 0x0000000f | 74 | #define MPIC_CPU_TASKPRI_MASK 0x0000000f |
73 | #define MPIC_CPU_WHOAMI 0x00090 | 75 | #define MPIC_CPU_WHOAMI 0x00090 |
@@ -114,6 +116,103 @@ | |||
114 | #define MPIC_VEC_TIMER_1 248 | 116 | #define MPIC_VEC_TIMER_1 248 |
115 | #define MPIC_VEC_TIMER_0 247 | 117 | #define MPIC_VEC_TIMER_0 247 |
116 | 118 | ||
119 | /* | ||
120 | * Tsi108 implementation of MPIC has many differences from the original one | ||
121 | */ | ||
122 | |||
123 | /* | ||
124 | * Global registers | ||
125 | */ | ||
126 | |||
127 | #define TSI108_GREG_BASE 0x00000 | ||
128 | #define TSI108_GREG_FEATURE_0 0x00000 | ||
129 | #define TSI108_GREG_GLOBAL_CONF_0 0x00004 | ||
130 | #define TSI108_GREG_VENDOR_ID 0x0000c | ||
131 | #define TSI108_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */ | ||
132 | #define TSI108_GREG_IPI_STRIDE 0x0c | ||
133 | #define TSI108_GREG_SPURIOUS 0x00010 | ||
134 | #define TSI108_GREG_TIMER_FREQ 0x00014 | ||
135 | |||
136 | /* | ||
137 | * Timer registers | ||
138 | */ | ||
139 | #define TSI108_TIMER_BASE 0x0030 | ||
140 | #define TSI108_TIMER_STRIDE 0x10 | ||
141 | #define TSI108_TIMER_CURRENT_CNT 0x00000 | ||
142 | #define TSI108_TIMER_BASE_CNT 0x00004 | ||
143 | #define TSI108_TIMER_VECTOR_PRI 0x00008 | ||
144 | #define TSI108_TIMER_DESTINATION 0x0000c | ||
145 | |||
146 | /* | ||
147 | * Per-Processor registers | ||
148 | */ | ||
149 | #define TSI108_CPU_BASE 0x00300 | ||
150 | #define TSI108_CPU_STRIDE 0x00040 | ||
151 | #define TSI108_CPU_IPI_DISPATCH_0 0x00200 | ||
152 | #define TSI108_CPU_IPI_DISPATCH_STRIDE 0x00000 | ||
153 | #define TSI108_CPU_CURRENT_TASK_PRI 0x00000 | ||
154 | #define TSI108_CPU_WHOAMI 0xffffffff | ||
155 | #define TSI108_CPU_INTACK 0x00004 | ||
156 | #define TSI108_CPU_EOI 0x00008 | ||
157 | |||
158 | /* | ||
159 | * Per-source registers | ||
160 | */ | ||
161 | #define TSI108_IRQ_BASE 0x00100 | ||
162 | #define TSI108_IRQ_STRIDE 0x00008 | ||
163 | #define TSI108_IRQ_VECTOR_PRI 0x00000 | ||
164 | #define TSI108_VECPRI_VECTOR_MASK 0x000000ff | ||
165 | #define TSI108_VECPRI_POLARITY_POSITIVE 0x01000000 | ||
166 | #define TSI108_VECPRI_POLARITY_NEGATIVE 0x00000000 | ||
167 | #define TSI108_VECPRI_SENSE_LEVEL 0x02000000 | ||
168 | #define TSI108_VECPRI_SENSE_EDGE 0x00000000 | ||
169 | #define TSI108_VECPRI_POLARITY_MASK 0x01000000 | ||
170 | #define TSI108_VECPRI_SENSE_MASK 0x02000000 | ||
171 | #define TSI108_IRQ_DESTINATION 0x00004 | ||
172 | |||
173 | /* weird mpic register indices and mask bits in the HW info array */ | ||
174 | enum { | ||
175 | MPIC_IDX_GREG_BASE = 0, | ||
176 | MPIC_IDX_GREG_FEATURE_0, | ||
177 | MPIC_IDX_GREG_GLOBAL_CONF_0, | ||
178 | MPIC_IDX_GREG_VENDOR_ID, | ||
179 | MPIC_IDX_GREG_IPI_VECTOR_PRI_0, | ||
180 | MPIC_IDX_GREG_IPI_STRIDE, | ||
181 | MPIC_IDX_GREG_SPURIOUS, | ||
182 | MPIC_IDX_GREG_TIMER_FREQ, | ||
183 | |||
184 | MPIC_IDX_TIMER_BASE, | ||
185 | MPIC_IDX_TIMER_STRIDE, | ||
186 | MPIC_IDX_TIMER_CURRENT_CNT, | ||
187 | MPIC_IDX_TIMER_BASE_CNT, | ||
188 | MPIC_IDX_TIMER_VECTOR_PRI, | ||
189 | MPIC_IDX_TIMER_DESTINATION, | ||
190 | |||
191 | MPIC_IDX_CPU_BASE, | ||
192 | MPIC_IDX_CPU_STRIDE, | ||
193 | MPIC_IDX_CPU_IPI_DISPATCH_0, | ||
194 | MPIC_IDX_CPU_IPI_DISPATCH_STRIDE, | ||
195 | MPIC_IDX_CPU_CURRENT_TASK_PRI, | ||
196 | MPIC_IDX_CPU_WHOAMI, | ||
197 | MPIC_IDX_CPU_INTACK, | ||
198 | MPIC_IDX_CPU_EOI, | ||
199 | |||
200 | MPIC_IDX_IRQ_BASE, | ||
201 | MPIC_IDX_IRQ_STRIDE, | ||
202 | MPIC_IDX_IRQ_VECTOR_PRI, | ||
203 | |||
204 | MPIC_IDX_VECPRI_VECTOR_MASK, | ||
205 | MPIC_IDX_VECPRI_POLARITY_POSITIVE, | ||
206 | MPIC_IDX_VECPRI_POLARITY_NEGATIVE, | ||
207 | MPIC_IDX_VECPRI_SENSE_LEVEL, | ||
208 | MPIC_IDX_VECPRI_SENSE_EDGE, | ||
209 | MPIC_IDX_VECPRI_POLARITY_MASK, | ||
210 | MPIC_IDX_VECPRI_SENSE_MASK, | ||
211 | MPIC_IDX_IRQ_DESTINATION, | ||
212 | MPIC_IDX_END | ||
213 | }; | ||
214 | |||
215 | |||
117 | #ifdef CONFIG_MPIC_BROKEN_U3 | 216 | #ifdef CONFIG_MPIC_BROKEN_U3 |
118 | /* Fixup table entry */ | 217 | /* Fixup table entry */ |
119 | struct mpic_irq_fixup | 218 | struct mpic_irq_fixup |
@@ -171,15 +270,29 @@ struct mpic | |||
171 | volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS]; | 270 | volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS]; |
172 | volatile u32 __iomem *isus[MPIC_MAX_ISU]; | 271 | volatile u32 __iomem *isus[MPIC_MAX_ISU]; |
173 | 272 | ||
273 | #ifdef CONFIG_MPIC_WEIRD | ||
274 | /* Pointer to HW info array */ | ||
275 | u32 *hw_set; | ||
276 | #endif | ||
277 | |||
174 | /* link */ | 278 | /* link */ |
175 | struct mpic *next; | 279 | struct mpic *next; |
176 | }; | 280 | }; |
177 | 281 | ||
282 | /* | ||
283 | * MPIC flags (passed to mpic_alloc) | ||
284 | * | ||
285 | * The top 4 bits contain an MPIC bhw id that is used to index the | ||
286 | * register offsets and some masks when CONFIG_MPIC_WEIRD is set. | ||
287 | * Note setting any ID (leaving those bits to 0) means standard MPIC | ||
288 | */ | ||
289 | |||
178 | /* This is the primary controller, only that one has IPIs and | 290 | /* This is the primary controller, only that one has IPIs and |
179 | * has afinity control. A non-primary MPIC always uses CPU0 | 291 | * has afinity control. A non-primary MPIC always uses CPU0 |
180 | * registers only | 292 | * registers only |
181 | */ | 293 | */ |
182 | #define MPIC_PRIMARY 0x00000001 | 294 | #define MPIC_PRIMARY 0x00000001 |
295 | |||
183 | /* Set this for a big-endian MPIC */ | 296 | /* Set this for a big-endian MPIC */ |
184 | #define MPIC_BIG_ENDIAN 0x00000002 | 297 | #define MPIC_BIG_ENDIAN 0x00000002 |
185 | /* Broken U3 MPIC */ | 298 | /* Broken U3 MPIC */ |
@@ -188,6 +301,18 @@ struct mpic | |||
188 | #define MPIC_BROKEN_IPI 0x00000008 | 301 | #define MPIC_BROKEN_IPI 0x00000008 |
189 | /* MPIC wants a reset */ | 302 | /* MPIC wants a reset */ |
190 | #define MPIC_WANTS_RESET 0x00000010 | 303 | #define MPIC_WANTS_RESET 0x00000010 |
304 | /* Spurious vector requires EOI */ | ||
305 | #define MPIC_SPV_EOI 0x00000020 | ||
306 | /* No passthrough disable */ | ||
307 | #define MPIC_NO_PTHROU_DIS 0x00000040 | ||
308 | |||
309 | /* MPIC HW modification ID */ | ||
310 | #define MPIC_REGSET_MASK 0xf0000000 | ||
311 | #define MPIC_REGSET(val) (((val) & 0xf ) << 28) | ||
312 | #define MPIC_GET_REGSET(flags) (((flags) >> 28) & 0xf) | ||
313 | |||
314 | #define MPIC_REGSET_STANDARD MPIC_REGSET(0) /* Original MPIC */ | ||
315 | #define MPIC_REGSET_TSI108 MPIC_REGSET(1) /* Tsi108/109 PIC */ | ||
191 | 316 | ||
192 | /* Allocate the controller structure and setup the linux irq descs | 317 | /* Allocate the controller structure and setup the linux irq descs |
193 | * for the range if interrupts passed in. No HW initialization is | 318 | * for the range if interrupts passed in. No HW initialization is |