diff options
Diffstat (limited to 'arch/mn10300/kernel/smp.c')
-rw-r--r-- | arch/mn10300/kernel/smp.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index 0dcd1c686ba8..226c826a2194 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c | |||
@@ -113,15 +113,17 @@ static void init_ipi(void); | |||
113 | */ | 113 | */ |
114 | static void mn10300_ipi_disable(unsigned int irq); | 114 | static void mn10300_ipi_disable(unsigned int irq); |
115 | static void mn10300_ipi_enable(unsigned int irq); | 115 | static void mn10300_ipi_enable(unsigned int irq); |
116 | static void mn10300_ipi_ack(unsigned int irq); | 116 | static void mn10300_ipi_chip_disable(struct irq_data *d); |
117 | static void mn10300_ipi_nop(unsigned int irq); | 117 | static void mn10300_ipi_chip_enable(struct irq_data *d); |
118 | static void mn10300_ipi_ack(struct irq_data *d); | ||
119 | static void mn10300_ipi_nop(struct irq_data *d); | ||
118 | 120 | ||
119 | static struct irq_chip mn10300_ipi_type = { | 121 | static struct irq_chip mn10300_ipi_type = { |
120 | .name = "cpu_ipi", | 122 | .name = "cpu_ipi", |
121 | .disable = mn10300_ipi_disable, | 123 | .irq_disable = mn10300_ipi_chip_disable, |
122 | .enable = mn10300_ipi_enable, | 124 | .irq_enable = mn10300_ipi_chip_enable, |
123 | .ack = mn10300_ipi_ack, | 125 | .irq_ack = mn10300_ipi_ack, |
124 | .eoi = mn10300_ipi_nop | 126 | .irq_eoi = mn10300_ipi_nop |
125 | }; | 127 | }; |
126 | 128 | ||
127 | static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id); | 129 | static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id); |
@@ -154,15 +156,15 @@ static void init_ipi(void) | |||
154 | u16 tmp16; | 156 | u16 tmp16; |
155 | 157 | ||
156 | /* set up the reschedule IPI */ | 158 | /* set up the reschedule IPI */ |
157 | set_irq_chip_and_handler(RESCHEDULE_IPI, | 159 | irq_set_chip_and_handler(RESCHEDULE_IPI, &mn10300_ipi_type, |
158 | &mn10300_ipi_type, handle_percpu_irq); | 160 | handle_percpu_irq); |
159 | setup_irq(RESCHEDULE_IPI, &reschedule_ipi); | 161 | setup_irq(RESCHEDULE_IPI, &reschedule_ipi); |
160 | set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV); | 162 | set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV); |
161 | mn10300_ipi_enable(RESCHEDULE_IPI); | 163 | mn10300_ipi_enable(RESCHEDULE_IPI); |
162 | 164 | ||
163 | /* set up the call function IPI */ | 165 | /* set up the call function IPI */ |
164 | set_irq_chip_and_handler(CALL_FUNC_SINGLE_IPI, | 166 | irq_set_chip_and_handler(CALL_FUNC_SINGLE_IPI, &mn10300_ipi_type, |
165 | &mn10300_ipi_type, handle_percpu_irq); | 167 | handle_percpu_irq); |
166 | setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi); | 168 | setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi); |
167 | set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV); | 169 | set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV); |
168 | mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI); | 170 | mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI); |
@@ -170,8 +172,8 @@ static void init_ipi(void) | |||
170 | /* set up the local timer IPI */ | 172 | /* set up the local timer IPI */ |
171 | #if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \ | 173 | #if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \ |
172 | defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) | 174 | defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) |
173 | set_irq_chip_and_handler(LOCAL_TIMER_IPI, | 175 | irq_set_chip_and_handler(LOCAL_TIMER_IPI, &mn10300_ipi_type, |
174 | &mn10300_ipi_type, handle_percpu_irq); | 176 | handle_percpu_irq); |
175 | setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi); | 177 | setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi); |
176 | set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV); | 178 | set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV); |
177 | mn10300_ipi_enable(LOCAL_TIMER_IPI); | 179 | mn10300_ipi_enable(LOCAL_TIMER_IPI); |
@@ -236,6 +238,11 @@ static void mn10300_ipi_enable(unsigned int irq) | |||
236 | arch_local_irq_restore(flags); | 238 | arch_local_irq_restore(flags); |
237 | } | 239 | } |
238 | 240 | ||
241 | static void mn10300_ipi_chip_enable(struct irq_data *d) | ||
242 | { | ||
243 | mn10300_ipi_enable(d->irq); | ||
244 | } | ||
245 | |||
239 | /** | 246 | /** |
240 | * mn10300_ipi_disable - Disable an IPI | 247 | * mn10300_ipi_disable - Disable an IPI |
241 | * @irq: The IPI to be disabled. | 248 | * @irq: The IPI to be disabled. |
@@ -254,6 +261,12 @@ static void mn10300_ipi_disable(unsigned int irq) | |||
254 | arch_local_irq_restore(flags); | 261 | arch_local_irq_restore(flags); |
255 | } | 262 | } |
256 | 263 | ||
264 | static void mn10300_ipi_chip_disable(struct irq_data *d) | ||
265 | { | ||
266 | mn10300_ipi_disable(d->irq); | ||
267 | } | ||
268 | |||
269 | |||
257 | /** | 270 | /** |
258 | * mn10300_ipi_ack - Acknowledge an IPI interrupt in the PIC | 271 | * mn10300_ipi_ack - Acknowledge an IPI interrupt in the PIC |
259 | * @irq: The IPI to be acknowledged. | 272 | * @irq: The IPI to be acknowledged. |
@@ -261,8 +274,9 @@ static void mn10300_ipi_disable(unsigned int irq) | |||
261 | * Clear the interrupt detection flag for the IPI on the appropriate interrupt | 274 | * Clear the interrupt detection flag for the IPI on the appropriate interrupt |
262 | * channel in the PIC. | 275 | * channel in the PIC. |
263 | */ | 276 | */ |
264 | static void mn10300_ipi_ack(unsigned int irq) | 277 | static void mn10300_ipi_ack(struct irq_data *d) |
265 | { | 278 | { |
279 | unsigned int irq = d->irq; | ||
266 | unsigned long flags; | 280 | unsigned long flags; |
267 | u16 tmp; | 281 | u16 tmp; |
268 | 282 | ||
@@ -276,7 +290,7 @@ static void mn10300_ipi_ack(unsigned int irq) | |||
276 | * mn10300_ipi_nop - Dummy IPI action | 290 | * mn10300_ipi_nop - Dummy IPI action |
277 | * @irq: The IPI to be acted upon. | 291 | * @irq: The IPI to be acted upon. |
278 | */ | 292 | */ |
279 | static void mn10300_ipi_nop(unsigned int irq) | 293 | static void mn10300_ipi_nop(struct irq_data *d) |
280 | { | 294 | { |
281 | } | 295 | } |
282 | 296 | ||
@@ -426,6 +440,22 @@ int smp_nmi_call_function(smp_call_func_t func, void *info, int wait) | |||
426 | } | 440 | } |
427 | 441 | ||
428 | /** | 442 | /** |
443 | * smp_jump_to_debugger - Make other CPUs enter the debugger by sending an IPI | ||
444 | * | ||
445 | * Send a non-maskable request to all other CPUs in the system, instructing | ||
446 | * them to jump into the debugger. The caller is responsible for checking that | ||
447 | * the other CPUs responded to the instruction. | ||
448 | * | ||
449 | * The caller should make sure that this CPU's debugger IPI is disabled. | ||
450 | */ | ||
451 | void smp_jump_to_debugger(void) | ||
452 | { | ||
453 | if (num_online_cpus() > 1) | ||
454 | /* Send a message to all other CPUs */ | ||
455 | send_IPI_allbutself(DEBUGGER_NMI_IPI); | ||
456 | } | ||
457 | |||
458 | /** | ||
429 | * stop_this_cpu - Callback to stop a CPU. | 459 | * stop_this_cpu - Callback to stop a CPU. |
430 | * @unused: Callback context (ignored). | 460 | * @unused: Callback context (ignored). |
431 | */ | 461 | */ |
@@ -589,7 +619,7 @@ static void __init smp_cpu_init(void) | |||
589 | /** | 619 | /** |
590 | * smp_prepare_cpu_init - Initialise CPU in startup_secondary | 620 | * smp_prepare_cpu_init - Initialise CPU in startup_secondary |
591 | * | 621 | * |
592 | * Set interrupt level 0-6 setting and init ICR of gdbstub. | 622 | * Set interrupt level 0-6 setting and init ICR of the kernel debugger. |
593 | */ | 623 | */ |
594 | void smp_prepare_cpu_init(void) | 624 | void smp_prepare_cpu_init(void) |
595 | { | 625 | { |
@@ -608,15 +638,15 @@ void smp_prepare_cpu_init(void) | |||
608 | for (loop = 0; loop < GxICR_NUM_IRQS; loop++) | 638 | for (loop = 0; loop < GxICR_NUM_IRQS; loop++) |
609 | GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT; | 639 | GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT; |
610 | 640 | ||
611 | #ifdef CONFIG_GDBSTUB | 641 | #ifdef CONFIG_KERNEL_DEBUGGER |
612 | /* initialise GDB-stub */ | 642 | /* initialise the kernel debugger interrupt */ |
613 | do { | 643 | do { |
614 | unsigned long flags; | 644 | unsigned long flags; |
615 | u16 tmp16; | 645 | u16 tmp16; |
616 | 646 | ||
617 | flags = arch_local_cli_save(); | 647 | flags = arch_local_cli_save(); |
618 | GxICR(GDB_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; | 648 | GxICR(DEBUGGER_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; |
619 | tmp16 = GxICR(GDB_NMI_IPI); | 649 | tmp16 = GxICR(DEBUGGER_NMI_IPI); |
620 | arch_local_irq_restore(flags); | 650 | arch_local_irq_restore(flags); |
621 | } while (0); | 651 | } while (0); |
622 | #endif | 652 | #endif |