diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-15 19:14:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-15 19:14:08 -0400 |
commit | 4ff4275b24fdcca189b33f9a73fe7abef1dc84bc (patch) | |
tree | d78f65e793d80e3a4c454d37e710f182de4bf34e | |
parent | e00eea42f24550beb9940e641402450f695c888a (diff) | |
parent | 7b4f4ec21038ac13c63d130357d1c3015ec3f3e8 (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
[MIPS] Fix builds where MSC01E_xxx is undefined.
[MIPS] Separate performance counter interrupts
[MIPS] Malta: Fix for SOCitSC based Maltas
-rw-r--r-- | arch/mips/kernel/smp-mt.c | 12 | ||||
-rw-r--r-- | arch/mips/kernel/time.c | 44 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/init.c | 62 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/pci.c | 20 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/time.c | 115 | ||||
-rw-r--r-- | arch/mips/mips-boards/malta/malta_int.c | 42 | ||||
-rw-r--r-- | arch/mips/mips-boards/malta/malta_setup.c | 4 | ||||
-rw-r--r-- | arch/mips/oprofile/op_model_mipsxx.c | 7 | ||||
-rw-r--r-- | include/asm-mips/mips-boards/generic.h | 22 | ||||
-rw-r--r-- | include/asm-mips/mips-boards/msc01_pci.h | 1 |
10 files changed, 222 insertions, 107 deletions
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 64b62bdfb4f6..b8fa7ddd78f6 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -129,13 +129,13 @@ static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | |||
129 | 129 | ||
130 | static struct irqaction irq_resched = { | 130 | static struct irqaction irq_resched = { |
131 | .handler = ipi_resched_interrupt, | 131 | .handler = ipi_resched_interrupt, |
132 | .flags = IRQF_DISABLED, | 132 | .flags = IRQF_DISABLED|IRQF_PERCPU, |
133 | .name = "IPI_resched" | 133 | .name = "IPI_resched" |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static struct irqaction irq_call = { | 136 | static struct irqaction irq_call = { |
137 | .handler = ipi_call_interrupt, | 137 | .handler = ipi_call_interrupt, |
138 | .flags = IRQF_DISABLED, | 138 | .flags = IRQF_DISABLED|IRQF_PERCPU, |
139 | .name = "IPI_call" | 139 | .name = "IPI_call" |
140 | }; | 140 | }; |
141 | 141 | ||
@@ -275,10 +275,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) | |||
275 | setup_irq(cpu_ipi_resched_irq, &irq_resched); | 275 | setup_irq(cpu_ipi_resched_irq, &irq_resched); |
276 | setup_irq(cpu_ipi_call_irq, &irq_call); | 276 | setup_irq(cpu_ipi_call_irq, &irq_call); |
277 | 277 | ||
278 | /* need to mark IPI's as IRQ_PER_CPU */ | ||
279 | irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU; | ||
280 | set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); | 278 | set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); |
281 | irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU; | ||
282 | set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); | 279 | set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); |
283 | } | 280 | } |
284 | 281 | ||
@@ -326,8 +323,11 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) | |||
326 | 323 | ||
327 | void prom_init_secondary(void) | 324 | void prom_init_secondary(void) |
328 | { | 325 | { |
326 | /* Enable per-cpu interrupts */ | ||
327 | |||
328 | /* This is Malta specific: IPI,performance and timer inetrrupts */ | ||
329 | write_c0_status((read_c0_status() & ~ST0_IM ) | | 329 | write_c0_status((read_c0_status() & ~ST0_IM ) | |
330 | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7)); | 330 | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); |
331 | } | 331 | } |
332 | 332 | ||
333 | void prom_smp_finish(void) | 333 | void prom_smp_finish(void) |
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 751b4a18b133..7def1ff3da94 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -199,6 +199,30 @@ int (*perf_irq)(void) = null_perf_irq; | |||
199 | EXPORT_SYMBOL(null_perf_irq); | 199 | EXPORT_SYMBOL(null_perf_irq); |
200 | EXPORT_SYMBOL(perf_irq); | 200 | EXPORT_SYMBOL(perf_irq); |
201 | 201 | ||
202 | /* | ||
203 | * Performance counter IRQ or -1 if shared with timer | ||
204 | */ | ||
205 | int mipsxx_perfcount_irq; | ||
206 | EXPORT_SYMBOL(mipsxx_perfcount_irq); | ||
207 | |||
208 | /* | ||
209 | * Possibly handle a performance counter interrupt. | ||
210 | * Return true if the timer interrupt should not be checked | ||
211 | */ | ||
212 | static inline int handle_perf_irq (int r2) | ||
213 | { | ||
214 | /* | ||
215 | * The performance counter overflow interrupt may be shared with the | ||
216 | * timer interrupt (mipsxx_perfcount_irq < 0). If it is and a | ||
217 | * performance counter has overflowed (perf_irq() == IRQ_HANDLED) | ||
218 | * and we can't reliably determine if a counter interrupt has also | ||
219 | * happened (!r2) then don't check for a timer interrupt. | ||
220 | */ | ||
221 | return (mipsxx_perfcount_irq < 0) && | ||
222 | perf_irq() == IRQ_HANDLED && | ||
223 | !r2; | ||
224 | } | ||
225 | |||
202 | asmlinkage void ll_timer_interrupt(int irq) | 226 | asmlinkage void ll_timer_interrupt(int irq) |
203 | { | 227 | { |
204 | int r2 = cpu_has_mips_r2; | 228 | int r2 = cpu_has_mips_r2; |
@@ -206,19 +230,13 @@ asmlinkage void ll_timer_interrupt(int irq) | |||
206 | irq_enter(); | 230 | irq_enter(); |
207 | kstat_this_cpu.irqs[irq]++; | 231 | kstat_this_cpu.irqs[irq]++; |
208 | 232 | ||
209 | /* | 233 | if (handle_perf_irq(r2)) |
210 | * Suckage alert: | 234 | goto out; |
211 | * Before R2 of the architecture there was no way to see if a | ||
212 | * performance counter interrupt was pending, so we have to run the | ||
213 | * performance counter interrupt handler anyway. | ||
214 | */ | ||
215 | if (!r2 || (read_c0_cause() & (1 << 26))) | ||
216 | if (perf_irq()) | ||
217 | goto out; | ||
218 | 235 | ||
219 | /* we keep interrupt disabled all the time */ | 236 | if (r2 && ((read_c0_cause() & (1 << 30)) == 0)) |
220 | if (!r2 || (read_c0_cause() & (1 << 30))) | 237 | goto out; |
221 | timer_interrupt(irq, NULL); | 238 | |
239 | timer_interrupt(irq, NULL); | ||
222 | 240 | ||
223 | out: | 241 | out: |
224 | irq_exit(); | 242 | irq_exit(); |
@@ -258,7 +276,7 @@ unsigned int mips_hpt_frequency; | |||
258 | 276 | ||
259 | static struct irqaction timer_irqaction = { | 277 | static struct irqaction timer_irqaction = { |
260 | .handler = timer_interrupt, | 278 | .handler = timer_interrupt, |
261 | .flags = IRQF_DISABLED, | 279 | .flags = IRQF_DISABLED | IRQF_PERCPU, |
262 | .name = "timer", | 280 | .name = "timer", |
263 | }; | 281 | }; |
264 | 282 | ||
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index 88e9c2a7a2f9..4eabc1eadd23 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -57,7 +57,8 @@ int *_prom_argv, *_prom_envp; | |||
57 | 57 | ||
58 | int init_debug = 0; | 58 | int init_debug = 0; |
59 | 59 | ||
60 | unsigned int mips_revision_corid; | 60 | int mips_revision_corid; |
61 | int mips_revision_sconid; | ||
61 | 62 | ||
62 | /* Bonito64 system controller register base. */ | 63 | /* Bonito64 system controller register base. */ |
63 | unsigned long _pcictrl_bonito; | 64 | unsigned long _pcictrl_bonito; |
@@ -275,13 +276,38 @@ void __init prom_init(void) | |||
275 | else | 276 | else |
276 | mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; | 277 | mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; |
277 | } | 278 | } |
278 | switch(mips_revision_corid) { | 279 | |
280 | mips_revision_sconid = MIPS_REVISION_SCONID; | ||
281 | if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) { | ||
282 | switch (mips_revision_corid) { | ||
283 | case MIPS_REVISION_CORID_QED_RM5261: | ||
284 | case MIPS_REVISION_CORID_CORE_LV: | ||
285 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
286 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
287 | mips_revision_sconid = MIPS_REVISION_SCON_GT64120; | ||
288 | break; | ||
289 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
290 | case MIPS_REVISION_CORID_BONITO64: | ||
291 | case MIPS_REVISION_CORID_CORE_20K: | ||
292 | mips_revision_sconid = MIPS_REVISION_SCON_BONITO; | ||
293 | break; | ||
294 | case MIPS_REVISION_CORID_CORE_MSC: | ||
295 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
296 | case MIPS_REVISION_CORID_CORE_FPGA3: | ||
297 | case MIPS_REVISION_CORID_CORE_24K: | ||
298 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
299 | mips_revision_sconid = MIPS_REVISION_SCON_SOCIT; | ||
300 | break; | ||
301 | default: | ||
302 | mips_display_message("CC Error"); | ||
303 | while (1); /* We die here... */ | ||
304 | } | ||
305 | } | ||
306 | |||
307 | switch (mips_revision_sconid) { | ||
279 | u32 start, map, mask, data; | 308 | u32 start, map, mask, data; |
280 | 309 | ||
281 | case MIPS_REVISION_CORID_QED_RM5261: | 310 | case MIPS_REVISION_SCON_GT64120: |
282 | case MIPS_REVISION_CORID_CORE_LV: | ||
283 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
284 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
285 | /* | 311 | /* |
286 | * Setup the North bridge to do Master byte-lane swapping | 312 | * Setup the North bridge to do Master byte-lane swapping |
287 | * when running in bigendian. | 313 | * when running in bigendian. |
@@ -305,9 +331,7 @@ void __init prom_init(void) | |||
305 | set_io_port_base(MALTA_GT_PORT_BASE); | 331 | set_io_port_base(MALTA_GT_PORT_BASE); |
306 | break; | 332 | break; |
307 | 333 | ||
308 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | 334 | case MIPS_REVISION_SCON_BONITO: |
309 | case MIPS_REVISION_CORID_BONITO64: | ||
310 | case MIPS_REVISION_CORID_CORE_20K: | ||
311 | _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); | 335 | _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); |
312 | 336 | ||
313 | /* | 337 | /* |
@@ -334,13 +358,10 @@ void __init prom_init(void) | |||
334 | set_io_port_base(MALTA_BONITO_PORT_BASE); | 358 | set_io_port_base(MALTA_BONITO_PORT_BASE); |
335 | break; | 359 | break; |
336 | 360 | ||
337 | case MIPS_REVISION_CORID_CORE_MSC: | 361 | case MIPS_REVISION_SCON_SOCIT: |
338 | case MIPS_REVISION_CORID_CORE_FPGA2: | 362 | case MIPS_REVISION_SCON_ROCIT: |
339 | case MIPS_REVISION_CORID_CORE_FPGA3: | ||
340 | case MIPS_REVISION_CORID_CORE_24K: | ||
341 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
342 | _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); | 363 | _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); |
343 | 364 | mips_pci_controller: | |
344 | mb(); | 365 | mb(); |
345 | MSC_READ(MSC01_PCI_CFG, data); | 366 | MSC_READ(MSC01_PCI_CFG, data); |
346 | MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); | 367 | MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); |
@@ -374,10 +395,15 @@ void __init prom_init(void) | |||
374 | set_io_port_base(MALTA_MSC_PORT_BASE); | 395 | set_io_port_base(MALTA_MSC_PORT_BASE); |
375 | break; | 396 | break; |
376 | 397 | ||
398 | case MIPS_REVISION_SCON_SOCITSC: | ||
399 | case MIPS_REVISION_SCON_SOCITSCP: | ||
400 | _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000); | ||
401 | goto mips_pci_controller; | ||
402 | |||
377 | default: | 403 | default: |
378 | /* Unknown Core card */ | 404 | /* Unknown system controller */ |
379 | mips_display_message("CC Error"); | 405 | mips_display_message("SC Error"); |
380 | while(1); /* We die here... */ | 406 | while (1); /* We die here... */ |
381 | } | 407 | } |
382 | #endif | 408 | #endif |
383 | board_nmi_handler_setup = mips_nmi_setup; | 409 | board_nmi_handler_setup = mips_nmi_setup; |
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c index f98d60f78658..c9852206890a 100644 --- a/arch/mips/mips-boards/generic/pci.c +++ b/arch/mips/mips-boards/generic/pci.c | |||
@@ -92,11 +92,8 @@ void __init mips_pcibios_init(void) | |||
92 | struct pci_controller *controller; | 92 | struct pci_controller *controller; |
93 | resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; | 93 | resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; |
94 | 94 | ||
95 | switch (mips_revision_corid) { | 95 | switch (mips_revision_sconid) { |
96 | case MIPS_REVISION_CORID_QED_RM5261: | 96 | case MIPS_REVISION_SCON_GT64120: |
97 | case MIPS_REVISION_CORID_CORE_LV: | ||
98 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
99 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
100 | /* | 97 | /* |
101 | * Due to a bug in the Galileo system controller, we need | 98 | * Due to a bug in the Galileo system controller, we need |
102 | * to setup the PCI BAR for the Galileo internal registers. | 99 | * to setup the PCI BAR for the Galileo internal registers. |
@@ -161,9 +158,7 @@ void __init mips_pcibios_init(void) | |||
161 | controller = >64120_controller; | 158 | controller = >64120_controller; |
162 | break; | 159 | break; |
163 | 160 | ||
164 | case MIPS_REVISION_CORID_BONITO64: | 161 | case MIPS_REVISION_SCON_BONITO: |
165 | case MIPS_REVISION_CORID_CORE_20K: | ||
166 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
167 | /* Set up resource ranges from the controller's registers. */ | 162 | /* Set up resource ranges from the controller's registers. */ |
168 | map = BONITO_PCIMAP; | 163 | map = BONITO_PCIMAP; |
169 | map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >> | 164 | map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >> |
@@ -195,11 +190,10 @@ void __init mips_pcibios_init(void) | |||
195 | controller = &bonito64_controller; | 190 | controller = &bonito64_controller; |
196 | break; | 191 | break; |
197 | 192 | ||
198 | case MIPS_REVISION_CORID_CORE_MSC: | 193 | case MIPS_REVISION_SCON_SOCIT: |
199 | case MIPS_REVISION_CORID_CORE_FPGA2: | 194 | case MIPS_REVISION_SCON_ROCIT: |
200 | case MIPS_REVISION_CORID_CORE_FPGA3: | 195 | case MIPS_REVISION_SCON_SOCITSC: |
201 | case MIPS_REVISION_CORID_CORE_24K: | 196 | case MIPS_REVISION_SCON_SOCITSCP: |
202 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
203 | /* Set up resource ranges from the controller's registers. */ | 197 | /* Set up resource ranges from the controller's registers. */ |
204 | MSC_READ(MSC01_PCI_SC2PMBASL, start); | 198 | MSC_READ(MSC01_PCI_SC2PMBASL, start); |
205 | MSC_READ(MSC01_PCI_SC2PMMSKL, mask); | 199 | MSC_READ(MSC01_PCI_SC2PMMSKL, mask); |
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index b41db9e7ab1f..8f1000f51b3d 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -53,9 +53,8 @@ | |||
53 | 53 | ||
54 | unsigned long cpu_khz; | 54 | unsigned long cpu_khz; |
55 | 55 | ||
56 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) | ||
57 | |||
58 | static int mips_cpu_timer_irq; | 56 | static int mips_cpu_timer_irq; |
57 | extern int mipsxx_perfcount_irq; | ||
59 | extern void smtc_timer_broadcast(int); | 58 | extern void smtc_timer_broadcast(int); |
60 | 59 | ||
61 | static void mips_timer_dispatch(void) | 60 | static void mips_timer_dispatch(void) |
@@ -63,6 +62,11 @@ static void mips_timer_dispatch(void) | |||
63 | do_IRQ(mips_cpu_timer_irq); | 62 | do_IRQ(mips_cpu_timer_irq); |
64 | } | 63 | } |
65 | 64 | ||
65 | static void mips_perf_dispatch(void) | ||
66 | { | ||
67 | do_IRQ(mipsxx_perfcount_irq); | ||
68 | } | ||
69 | |||
66 | /* | 70 | /* |
67 | * Redeclare until I get around mopping the timer code insanity on MIPS. | 71 | * Redeclare until I get around mopping the timer code insanity on MIPS. |
68 | */ | 72 | */ |
@@ -70,6 +74,24 @@ extern int null_perf_irq(void); | |||
70 | 74 | ||
71 | extern int (*perf_irq)(void); | 75 | extern int (*perf_irq)(void); |
72 | 76 | ||
77 | /* | ||
78 | * Possibly handle a performance counter interrupt. | ||
79 | * Return true if the timer interrupt should not be checked | ||
80 | */ | ||
81 | static inline int handle_perf_irq (int r2) | ||
82 | { | ||
83 | /* | ||
84 | * The performance counter overflow interrupt may be shared with the | ||
85 | * timer interrupt (mipsxx_perfcount_irq < 0). If it is and a | ||
86 | * performance counter has overflowed (perf_irq() == IRQ_HANDLED) | ||
87 | * and we can't reliably determine if a counter interrupt has also | ||
88 | * happened (!r2) then don't check for a timer interrupt. | ||
89 | */ | ||
90 | return (mipsxx_perfcount_irq < 0) && | ||
91 | perf_irq() == IRQ_HANDLED && | ||
92 | !r2; | ||
93 | } | ||
94 | |||
73 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | 95 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id) |
74 | { | 96 | { |
75 | int cpu = smp_processor_id(); | 97 | int cpu = smp_processor_id(); |
@@ -92,8 +114,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
92 | * We could be here due to timer interrupt, | 114 | * We could be here due to timer interrupt, |
93 | * perf counter overflow, or both. | 115 | * perf counter overflow, or both. |
94 | */ | 116 | */ |
95 | if (read_c0_cause() & (1 << 26)) | 117 | (void) handle_perf_irq(1); |
96 | perf_irq(); | ||
97 | 118 | ||
98 | if (read_c0_cause() & (1 << 30)) { | 119 | if (read_c0_cause() & (1 << 30)) { |
99 | /* | 120 | /* |
@@ -115,19 +136,19 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
115 | #else /* CONFIG_MIPS_MT_SMTC */ | 136 | #else /* CONFIG_MIPS_MT_SMTC */ |
116 | int r2 = cpu_has_mips_r2; | 137 | int r2 = cpu_has_mips_r2; |
117 | 138 | ||
139 | if (handle_perf_irq(r2)) | ||
140 | goto out; | ||
141 | |||
142 | if (r2 && ((read_c0_cause() & (1 << 30)) == 0)) | ||
143 | goto out; | ||
144 | |||
118 | if (cpu == 0) { | 145 | if (cpu == 0) { |
119 | /* | 146 | /* |
120 | * CPU 0 handles the global timer interrupt job and process | 147 | * CPU 0 handles the global timer interrupt job and process |
121 | * accounting resets count/compare registers to trigger next | 148 | * accounting resets count/compare registers to trigger next |
122 | * timer int. | 149 | * timer int. |
123 | */ | 150 | */ |
124 | if (!r2 || (read_c0_cause() & (1 << 26))) | 151 | timer_interrupt(irq, NULL); |
125 | if (perf_irq()) | ||
126 | goto out; | ||
127 | |||
128 | /* we keep interrupt disabled all the time */ | ||
129 | if (!r2 || (read_c0_cause() & (1 << 30))) | ||
130 | timer_interrupt(irq, NULL); | ||
131 | } else { | 152 | } else { |
132 | /* Everyone else needs to reset the timer int here as | 153 | /* Everyone else needs to reset the timer int here as |
133 | ll_local_timer_interrupt doesn't */ | 154 | ll_local_timer_interrupt doesn't */ |
@@ -225,35 +246,85 @@ void __init mips_time_init(void) | |||
225 | mips_scroll_message(); | 246 | mips_scroll_message(); |
226 | } | 247 | } |
227 | 248 | ||
249 | irqreturn_t mips_perf_interrupt(int irq, void *dev_id) | ||
250 | { | ||
251 | return perf_irq(); | ||
252 | } | ||
253 | |||
254 | static struct irqaction perf_irqaction = { | ||
255 | .handler = mips_perf_interrupt, | ||
256 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
257 | .name = "performance", | ||
258 | }; | ||
259 | |||
260 | void __init plat_perf_setup(struct irqaction *irq) | ||
261 | { | ||
262 | int hwint = 0; | ||
263 | mipsxx_perfcount_irq = -1; | ||
264 | |||
265 | #ifdef MSC01E_INT_BASE | ||
266 | if (cpu_has_veic) { | ||
267 | set_vi_handler (MSC01E_INT_PERFCTR, mips_perf_dispatch); | ||
268 | mipsxx_perfcount_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; | ||
269 | } else | ||
270 | #endif | ||
271 | if (cpu_has_mips_r2) { | ||
272 | /* | ||
273 | * Read IntCtl.IPPCI to determine the performance | ||
274 | * counter interrupt | ||
275 | */ | ||
276 | hwint = (read_c0_intctl () >> 26) & 7; | ||
277 | if (hwint != MIPSCPU_INT_CPUCTR) { | ||
278 | if (cpu_has_vint) | ||
279 | set_vi_handler (hwint, mips_perf_dispatch); | ||
280 | mipsxx_perfcount_irq = MIPSCPU_INT_BASE + hwint; | ||
281 | } | ||
282 | } | ||
283 | if (mipsxx_perfcount_irq >= 0) { | ||
284 | #ifdef CONFIG_MIPS_MT_SMTC | ||
285 | setup_irq_smtc(mipsxx_perfcount_irq, irq, 0x100 << hwint); | ||
286 | #else | ||
287 | setup_irq(mipsxx_perfcount_irq, irq); | ||
288 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
289 | #ifdef CONFIG_SMP | ||
290 | set_irq_handler(mipsxx_perfcount_irq, handle_percpu_irq); | ||
291 | #endif | ||
292 | } | ||
293 | } | ||
294 | |||
228 | void __init plat_timer_setup(struct irqaction *irq) | 295 | void __init plat_timer_setup(struct irqaction *irq) |
229 | { | 296 | { |
297 | int hwint = 0; | ||
230 | #ifdef MSC01E_INT_BASE | 298 | #ifdef MSC01E_INT_BASE |
231 | if (cpu_has_veic) { | 299 | if (cpu_has_veic) { |
232 | set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch); | 300 | set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch); |
233 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | 301 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; |
234 | } else | 302 | } |
303 | else | ||
235 | #endif | 304 | #endif |
236 | { | 305 | { |
306 | if (cpu_has_mips_r2) | ||
307 | /* | ||
308 | * Read IntCtl.IPTI to determine the timer interrupt | ||
309 | */ | ||
310 | hwint = (read_c0_intctl () >> 29) & 7; | ||
311 | else | ||
312 | hwint = MIPSCPU_INT_CPUCTR; | ||
237 | if (cpu_has_vint) | 313 | if (cpu_has_vint) |
238 | set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch); | 314 | set_vi_handler (hwint, mips_timer_dispatch); |
239 | mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR; | 315 | mips_cpu_timer_irq = MIPSCPU_INT_BASE + hwint; |
240 | } | 316 | } |
241 | 317 | ||
242 | |||
243 | /* we are using the cpu counter for timer interrupts */ | 318 | /* we are using the cpu counter for timer interrupts */ |
244 | irq->handler = mips_timer_interrupt; /* we use our own handler */ | 319 | irq->handler = mips_timer_interrupt; /* we use our own handler */ |
245 | #ifdef CONFIG_MIPS_MT_SMTC | 320 | #ifdef CONFIG_MIPS_MT_SMTC |
246 | setup_irq_smtc(mips_cpu_timer_irq, irq, CPUCTR_IMASKBIT); | 321 | setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << hwint); |
247 | #else | 322 | #else |
248 | setup_irq(mips_cpu_timer_irq, irq); | 323 | setup_irq(mips_cpu_timer_irq, irq); |
249 | #endif /* CONFIG_MIPS_MT_SMTC */ | 324 | #endif /* CONFIG_MIPS_MT_SMTC */ |
250 | |||
251 | #ifdef CONFIG_SMP | 325 | #ifdef CONFIG_SMP |
252 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps | ||
253 | on seperate cpu's the first one tries to handle the second interrupt. | ||
254 | The effect is that the int remains disabled on the second cpu. | ||
255 | Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ | ||
256 | irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; | ||
257 | set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); | 326 | set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); |
258 | #endif | 327 | #endif |
328 | |||
329 | plat_perf_setup(&perf_irqaction); | ||
259 | } | 330 | } |
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 1cd830e3d933..1668cc21d5b5 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c | |||
@@ -53,25 +53,19 @@ static inline int mips_pcibios_iack(void) | |||
53 | * Determine highest priority pending interrupt by performing | 53 | * Determine highest priority pending interrupt by performing |
54 | * a PCI Interrupt Acknowledge cycle. | 54 | * a PCI Interrupt Acknowledge cycle. |
55 | */ | 55 | */ |
56 | switch(mips_revision_corid) { | 56 | switch (mips_revision_sconid) { |
57 | case MIPS_REVISION_CORID_CORE_MSC: | 57 | case MIPS_REVISION_SCON_SOCIT: |
58 | case MIPS_REVISION_CORID_CORE_FPGA2: | 58 | case MIPS_REVISION_SCON_ROCIT: |
59 | case MIPS_REVISION_CORID_CORE_FPGA3: | 59 | case MIPS_REVISION_SCON_SOCITSC: |
60 | case MIPS_REVISION_CORID_CORE_24K: | 60 | case MIPS_REVISION_SCON_SOCITSCP: |
61 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
62 | MSC_READ(MSC01_PCI_IACK, irq); | 61 | MSC_READ(MSC01_PCI_IACK, irq); |
63 | irq &= 0xff; | 62 | irq &= 0xff; |
64 | break; | 63 | break; |
65 | case MIPS_REVISION_CORID_QED_RM5261: | 64 | case MIPS_REVISION_SCON_GT64120: |
66 | case MIPS_REVISION_CORID_CORE_LV: | ||
67 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
68 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
69 | irq = GT_READ(GT_PCI0_IACK_OFS); | 65 | irq = GT_READ(GT_PCI0_IACK_OFS); |
70 | irq &= 0xff; | 66 | irq &= 0xff; |
71 | break; | 67 | break; |
72 | case MIPS_REVISION_CORID_BONITO64: | 68 | case MIPS_REVISION_SCON_BONITO: |
73 | case MIPS_REVISION_CORID_CORE_20K: | ||
74 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
75 | /* The following will generate a PCI IACK cycle on the | 69 | /* The following will generate a PCI IACK cycle on the |
76 | * Bonito controller. It's a little bit kludgy, but it | 70 | * Bonito controller. It's a little bit kludgy, but it |
77 | * was the easiest way to implement it in hardware at | 71 | * was the easiest way to implement it in hardware at |
@@ -89,7 +83,7 @@ static inline int mips_pcibios_iack(void) | |||
89 | BONITO_PCIMAP_CFG = 0; | 83 | BONITO_PCIMAP_CFG = 0; |
90 | break; | 84 | break; |
91 | default: | 85 | default: |
92 | printk("Unknown Core card, don't know the system controller.\n"); | 86 | printk("Unknown system controller.\n"); |
93 | return -1; | 87 | return -1; |
94 | } | 88 | } |
95 | return irq; | 89 | return irq; |
@@ -144,27 +138,21 @@ static void corehi_irqdispatch(void) | |||
144 | Do it for the others too. | 138 | Do it for the others too. |
145 | */ | 139 | */ |
146 | 140 | ||
147 | switch(mips_revision_corid) { | 141 | switch (mips_revision_sconid) { |
148 | case MIPS_REVISION_CORID_CORE_MSC: | 142 | case MIPS_REVISION_SCON_SOCIT: |
149 | case MIPS_REVISION_CORID_CORE_FPGA2: | 143 | case MIPS_REVISION_SCON_ROCIT: |
150 | case MIPS_REVISION_CORID_CORE_FPGA3: | 144 | case MIPS_REVISION_SCON_SOCITSC: |
151 | case MIPS_REVISION_CORID_CORE_24K: | 145 | case MIPS_REVISION_SCON_SOCITSCP: |
152 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
153 | ll_msc_irq(); | 146 | ll_msc_irq(); |
154 | break; | 147 | break; |
155 | case MIPS_REVISION_CORID_QED_RM5261: | 148 | case MIPS_REVISION_SCON_GT64120: |
156 | case MIPS_REVISION_CORID_CORE_LV: | ||
157 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
158 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
159 | intrcause = GT_READ(GT_INTRCAUSE_OFS); | 149 | intrcause = GT_READ(GT_INTRCAUSE_OFS); |
160 | datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); | 150 | datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); |
161 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); | 151 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); |
162 | printk("GT_INTRCAUSE = %08x\n", intrcause); | 152 | printk("GT_INTRCAUSE = %08x\n", intrcause); |
163 | printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); | 153 | printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); |
164 | break; | 154 | break; |
165 | case MIPS_REVISION_CORID_BONITO64: | 155 | case MIPS_REVISION_SCON_BONITO: |
166 | case MIPS_REVISION_CORID_CORE_20K: | ||
167 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
168 | pcibadaddr = BONITO_PCIBADADDR; | 156 | pcibadaddr = BONITO_PCIBADADDR; |
169 | pcimstat = BONITO_PCIMSTAT; | 157 | pcimstat = BONITO_PCIMSTAT; |
170 | intisr = BONITO_INTISR; | 158 | intisr = BONITO_INTISR; |
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index c14b7bf89950..8f1b78dfd89f 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c | |||
@@ -103,9 +103,7 @@ void __init plat_mem_setup(void) | |||
103 | kgdb_config (); | 103 | kgdb_config (); |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | if ((mips_revision_corid == MIPS_REVISION_CORID_BONITO64) || | 106 | if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) { |
107 | (mips_revision_corid == MIPS_REVISION_CORID_CORE_20K) || | ||
108 | (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL_BON)) { | ||
109 | char *argptr; | 107 | char *argptr; |
110 | 108 | ||
111 | argptr = prom_getcmdline(); | 109 | argptr = prom_getcmdline(); |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 4f94fa261aae..1ea5c9c1010b 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -177,7 +177,10 @@ static int mipsxx_perfcount_handler(void) | |||
177 | unsigned int counters = op_model_mipsxx_ops.num_counters; | 177 | unsigned int counters = op_model_mipsxx_ops.num_counters; |
178 | unsigned int control; | 178 | unsigned int control; |
179 | unsigned int counter; | 179 | unsigned int counter; |
180 | int handled = 0; | 180 | int handled = IRQ_NONE; |
181 | |||
182 | if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26))) | ||
183 | return handled; | ||
181 | 184 | ||
182 | switch (counters) { | 185 | switch (counters) { |
183 | #define HANDLE_COUNTER(n) \ | 186 | #define HANDLE_COUNTER(n) \ |
@@ -188,7 +191,7 @@ static int mipsxx_perfcount_handler(void) | |||
188 | (counter & M_COUNTER_OVERFLOW)) { \ | 191 | (counter & M_COUNTER_OVERFLOW)) { \ |
189 | oprofile_add_sample(get_irq_regs(), n); \ | 192 | oprofile_add_sample(get_irq_regs(), n); \ |
190 | w_c0_perfcntr ## n(reg.counter[n]); \ | 193 | w_c0_perfcntr ## n(reg.counter[n]); \ |
191 | handled = 1; \ | 194 | handled = IRQ_HANDLED; \ |
192 | } | 195 | } |
193 | HANDLE_COUNTER(3) | 196 | HANDLE_COUNTER(3) |
194 | HANDLE_COUNTER(2) | 197 | HANDLE_COUNTER(2) |
diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h index b98f1658cfd0..c8ebcc3e1267 100644 --- a/include/asm-mips/mips-boards/generic.h +++ b/include/asm-mips/mips-boards/generic.h | |||
@@ -73,12 +73,28 @@ | |||
73 | * CoreEMUL with Bonito System Controller is treated like a Core20K | 73 | * CoreEMUL with Bonito System Controller is treated like a Core20K |
74 | * CoreEMUL with SOC-it 101 System Controller is treated like a CoreMSC | 74 | * CoreEMUL with SOC-it 101 System Controller is treated like a CoreMSC |
75 | */ | 75 | */ |
76 | #define MIPS_REVISION_CORID_CORE_EMUL_BON 0x63 | 76 | #define MIPS_REVISION_CORID_CORE_EMUL_BON -1 |
77 | #define MIPS_REVISION_CORID_CORE_EMUL_MSC 0x65 | 77 | #define MIPS_REVISION_CORID_CORE_EMUL_MSC -2 |
78 | 78 | ||
79 | #define MIPS_REVISION_CORID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 10) & 0x3f) | 79 | #define MIPS_REVISION_CORID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 10) & 0x3f) |
80 | 80 | ||
81 | extern unsigned int mips_revision_corid; | 81 | extern int mips_revision_corid; |
82 | |||
83 | #define MIPS_REVISION_SCON_OTHER 0 | ||
84 | #define MIPS_REVISION_SCON_SOCITSC 1 | ||
85 | #define MIPS_REVISION_SCON_SOCITSCP 2 | ||
86 | |||
87 | /* Artificial SCON defines for MIPS_REVISION_SCON_OTHER */ | ||
88 | #define MIPS_REVISION_SCON_UNKNOWN -1 | ||
89 | #define MIPS_REVISION_SCON_GT64120 -2 | ||
90 | #define MIPS_REVISION_SCON_BONITO -3 | ||
91 | #define MIPS_REVISION_SCON_BRTL -4 | ||
92 | #define MIPS_REVISION_SCON_SOCIT -5 | ||
93 | #define MIPS_REVISION_SCON_ROCIT -6 | ||
94 | |||
95 | #define MIPS_REVISION_SCONID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 24) & 0xff) | ||
96 | |||
97 | extern int mips_revision_sconid; | ||
82 | 98 | ||
83 | #ifdef CONFIG_PCI | 99 | #ifdef CONFIG_PCI |
84 | extern void mips_pcibios_init(void); | 100 | extern void mips_pcibios_init(void); |
diff --git a/include/asm-mips/mips-boards/msc01_pci.h b/include/asm-mips/mips-boards/msc01_pci.h index 8eaefb837b9d..e036b7dd6deb 100644 --- a/include/asm-mips/mips-boards/msc01_pci.h +++ b/include/asm-mips/mips-boards/msc01_pci.h | |||
@@ -208,6 +208,7 @@ | |||
208 | * latter, they should be moved elsewhere. | 208 | * latter, they should be moved elsewhere. |
209 | */ | 209 | */ |
210 | #define MIPS_MSC01_PCI_REG_BASE 0x1bd00000 | 210 | #define MIPS_MSC01_PCI_REG_BASE 0x1bd00000 |
211 | #define MIPS_SOCITSC_PCI_REG_BASE 0x1ff10000 | ||
211 | 212 | ||
212 | extern unsigned long _pcictrl_msc; | 213 | extern unsigned long _pcictrl_msc; |
213 | 214 | ||