aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/ps3/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/ps3/interrupt.c')
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c272
1 files changed, 158 insertions, 114 deletions
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index ec9030dbb5f1..67e32ec9b37e 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -30,9 +30,9 @@
30#include "platform.h" 30#include "platform.h"
31 31
32#if defined(DEBUG) 32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt) 33#define DBG udbg_printf
34#else 34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35#define DBG pr_debug
36#endif 36#endif
37 37
38/** 38/**
@@ -78,19 +78,85 @@ struct ps3_bmp {
78/** 78/**
79 * struct ps3_private - a per cpu data structure 79 * struct ps3_private - a per cpu data structure
80 * @bmp: ps3_bmp structure 80 * @bmp: ps3_bmp structure
81 * @node: HV logical_ppe_id 81 * @ppe_id: HV logical_ppe_id
82 * @cpu: HV thread_id 82 * @thread_id: HV thread_id
83 */ 83 */
84 84
85struct ps3_private { 85struct ps3_private {
86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); 86 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
87 u64 node; 87 u64 ppe_id;
88 unsigned int cpu; 88 u64 thread_id;
89}; 89};
90 90
91static DEFINE_PER_CPU(struct ps3_private, ps3_private); 91static DEFINE_PER_CPU(struct ps3_private, ps3_private);
92 92
93/** 93/**
94 * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
95 * @virq: The assigned Linux virq.
96 *
97 * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
98 */
99
100static void ps3_chip_mask(unsigned int virq)
101{
102 struct ps3_private *pd = get_irq_chip_data(virq);
103 unsigned long flags;
104
105 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
106 pd->thread_id, virq);
107
108 local_irq_save(flags);
109 clear_bit(63 - virq, &pd->bmp.mask);
110 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
111 local_irq_restore(flags);
112}
113
114/**
115 * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
116 * @virq: The assigned Linux virq.
117 *
118 * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
119 */
120
121static void ps3_chip_unmask(unsigned int virq)
122{
123 struct ps3_private *pd = get_irq_chip_data(virq);
124 unsigned long flags;
125
126 pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
127 pd->thread_id, virq);
128
129 local_irq_save(flags);
130 set_bit(63 - virq, &pd->bmp.mask);
131 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
132 local_irq_restore(flags);
133}
134
135/**
136 * ps3_chip_eoi - HV end-of-interrupt.
137 * @virq: The assigned Linux virq.
138 *
139 * Calls lv1_end_of_interrupt_ext().
140 */
141
142static void ps3_chip_eoi(unsigned int virq)
143{
144 const struct ps3_private *pd = get_irq_chip_data(virq);
145 lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
146}
147
148/**
149 * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
150 */
151
152static struct irq_chip ps3_irq_chip = {
153 .typename = "ps3",
154 .mask = ps3_chip_mask,
155 .unmask = ps3_chip_unmask,
156 .eoi = ps3_chip_eoi,
157};
158
159/**
94 * ps3_virq_setup - virq related setup. 160 * ps3_virq_setup - virq related setup.
95 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 161 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
96 * serviced on. 162 * serviced on.
@@ -134,6 +200,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
134 goto fail_set; 200 goto fail_set;
135 } 201 }
136 202
203 ps3_chip_mask(*virq);
204
137 return result; 205 return result;
138 206
139fail_set: 207fail_set:
@@ -153,8 +221,8 @@ int ps3_virq_destroy(unsigned int virq)
153{ 221{
154 const struct ps3_private *pd = get_irq_chip_data(virq); 222 const struct ps3_private *pd = get_irq_chip_data(virq);
155 223
156 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 224 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
157 pd->node, pd->cpu, virq); 225 __LINE__, pd->ppe_id, pd->thread_id, virq);
158 226
159 set_irq_chip_data(virq, NULL); 227 set_irq_chip_data(virq, NULL);
160 irq_dispose_mapping(virq); 228 irq_dispose_mapping(virq);
@@ -190,7 +258,8 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
190 258
191 /* Binds outlet to cpu + virq. */ 259 /* Binds outlet to cpu + virq. */
192 260
193 result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); 261 result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
262 outlet, 0);
194 263
195 if (result) { 264 if (result) {
196 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", 265 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
@@ -222,10 +291,12 @@ int ps3_irq_plug_destroy(unsigned int virq)
222 int result; 291 int result;
223 const struct ps3_private *pd = get_irq_chip_data(virq); 292 const struct ps3_private *pd = get_irq_chip_data(virq);
224 293
225 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 294 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
226 pd->node, pd->cpu, virq); 295 __LINE__, pd->ppe_id, pd->thread_id, virq);
296
297 ps3_chip_mask(virq);
227 298
228 result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); 299 result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
229 300
230 if (result) 301 if (result)
231 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", 302 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
@@ -282,7 +353,9 @@ int ps3_event_receive_port_destroy(unsigned int virq)
282{ 353{
283 int result; 354 int result;
284 355
285 pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); 356 pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
357
358 ps3_chip_mask(virq);
286 359
287 result = lv1_destruct_event_receive_port(virq_to_hw(virq)); 360 result = lv1_destruct_event_receive_port(virq_to_hw(virq));
288 361
@@ -290,17 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq)
290 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", 363 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
291 __func__, __LINE__, ps3_result(result)); 364 __func__, __LINE__, ps3_result(result));
292 365
293 /* lv1_destruct_event_receive_port() destroys the IRQ plug, 366 /*
294 * so don't call ps3_irq_plug_destroy() here. 367 * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
368 * calls from interrupt context (smp_call_function) when kexecing.
295 */ 369 */
296 370
297 result = ps3_virq_destroy(virq);
298 BUG_ON(result);
299
300 pr_debug(" <- %s:%d\n", __func__, __LINE__); 371 pr_debug(" <- %s:%d\n", __func__, __LINE__);
301 return result; 372 return result;
302} 373}
303EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
304 374
305int ps3_send_event_locally(unsigned int virq) 375int ps3_send_event_locally(unsigned int virq)
306{ 376{
@@ -311,17 +381,15 @@ int ps3_send_event_locally(unsigned int virq)
311 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. 381 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
312 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 382 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
313 * serviced on. 383 * serviced on.
314 * @did: The HV device identifier read from the system repository. 384 * @dev: The system bus device instance.
315 * @interrupt_id: The device interrupt id read from the system repository.
316 * @virq: The assigned Linux virq. 385 * @virq: The assigned Linux virq.
317 * 386 *
318 * An event irq represents a virtual device interrupt. The interrupt_id 387 * An event irq represents a virtual device interrupt. The interrupt_id
319 * coresponds to the software interrupt number. 388 * coresponds to the software interrupt number.
320 */ 389 */
321 390
322int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, 391int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
323 const struct ps3_device_id *did, unsigned int interrupt_id, 392 enum ps3_cpu_binding cpu, unsigned int *virq)
324 unsigned int *virq)
325{ 393{
326 /* this should go in system-bus.c */ 394 /* this should go in system-bus.c */
327 395
@@ -332,8 +400,8 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
332 if (result) 400 if (result)
333 return result; 401 return result;
334 402
335 result = lv1_connect_interrupt_event_receive_port(did->bus_id, 403 result = lv1_connect_interrupt_event_receive_port(dev->bus_id,
336 did->dev_id, virq_to_hw(*virq), interrupt_id); 404 dev->dev_id, virq_to_hw(*virq), dev->interrupt_id);
337 405
338 if (result) { 406 if (result) {
339 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" 407 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
@@ -345,24 +413,24 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
345 } 413 }
346 414
347 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 415 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
348 interrupt_id, *virq); 416 dev->interrupt_id, *virq);
349 417
350 return 0; 418 return 0;
351} 419}
352EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); 420EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
353 421
354int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, 422int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
355 unsigned int interrupt_id, unsigned int virq) 423 unsigned int virq)
356{ 424{
357 /* this should go in system-bus.c */ 425 /* this should go in system-bus.c */
358 426
359 int result; 427 int result;
360 428
361 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 429 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
362 interrupt_id, virq); 430 dev->interrupt_id, virq);
363 431
364 result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, 432 result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
365 did->dev_id, virq_to_hw(virq), interrupt_id); 433 dev->dev_id, virq_to_hw(virq), dev->interrupt_id);
366 434
367 if (result) 435 if (result)
368 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" 436 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
@@ -372,6 +440,14 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
372 result = ps3_event_receive_port_destroy(virq); 440 result = ps3_event_receive_port_destroy(virq);
373 BUG_ON(result); 441 BUG_ON(result);
374 442
443 /*
444 * ps3_event_receive_port_destroy() destroys the IRQ plug,
445 * so don't call ps3_irq_plug_destroy() here.
446 */
447
448 result = ps3_virq_destroy(virq);
449 BUG_ON(result);
450
375 pr_debug(" <- %s:%d\n", __func__, __LINE__); 451 pr_debug(" <- %s:%d\n", __func__, __LINE__);
376 return result; 452 return result;
377} 453}
@@ -412,16 +488,24 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
412int ps3_io_irq_destroy(unsigned int virq) 488int ps3_io_irq_destroy(unsigned int virq)
413{ 489{
414 int result; 490 int result;
491 unsigned long outlet = virq_to_hw(virq);
415 492
416 result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); 493 ps3_chip_mask(virq);
417 494
418 if (result) 495 /*
419 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", 496 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
420 __func__, __LINE__, ps3_result(result)); 497 * so call ps3_irq_plug_destroy() first.
498 */
421 499
422 result = ps3_irq_plug_destroy(virq); 500 result = ps3_irq_plug_destroy(virq);
423 BUG_ON(result); 501 BUG_ON(result);
424 502
503 result = lv1_destruct_io_irq_outlet(outlet);
504
505 if (result)
506 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
507 __func__, __LINE__, ps3_result(result));
508
425 return result; 509 return result;
426} 510}
427EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); 511EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -461,11 +545,13 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
461 545
462 return result; 546 return result;
463} 547}
548EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
464 549
465int ps3_vuart_irq_destroy(unsigned int virq) 550int ps3_vuart_irq_destroy(unsigned int virq)
466{ 551{
467 int result; 552 int result;
468 553
554 ps3_chip_mask(virq);
469 result = lv1_deconfigure_virtual_uart_irq(); 555 result = lv1_deconfigure_virtual_uart_irq();
470 556
471 if (result) { 557 if (result) {
@@ -479,6 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
479 565
480 return result; 566 return result;
481} 567}
568EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
482 569
483/** 570/**
484 * ps3_spe_irq_setup - Setup an spe virq. 571 * ps3_spe_irq_setup - Setup an spe virq.
@@ -514,9 +601,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
514 601
515int ps3_spe_irq_destroy(unsigned int virq) 602int ps3_spe_irq_destroy(unsigned int virq)
516{ 603{
517 int result = ps3_irq_plug_destroy(virq); 604 int result;
605
606 ps3_chip_mask(virq);
607
608 result = ps3_irq_plug_destroy(virq);
518 BUG_ON(result); 609 BUG_ON(result);
519 return 0; 610
611 return result;
520} 612}
521 613
522 614
@@ -533,7 +625,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
533 *p & 0xffff); 625 *p & 0xffff);
534} 626}
535 627
536static void __attribute__ ((unused)) _dump_256_bmp(const char *header, 628static void __maybe_unused _dump_256_bmp(const char *header,
537 const u64 *p, unsigned cpu, const char* func, int line) 629 const u64 *p, unsigned cpu, const char* func, int line)
538{ 630{
539 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", 631 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
@@ -546,86 +638,25 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
546 unsigned long flags; 638 unsigned long flags;
547 639
548 spin_lock_irqsave(&pd->bmp.lock, flags); 640 spin_lock_irqsave(&pd->bmp.lock, flags);
549 _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); 641 _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line);
550 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 642 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
551 spin_unlock_irqrestore(&pd->bmp.lock, flags); 643 spin_unlock_irqrestore(&pd->bmp.lock, flags);
552} 644}
553 645
554#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) 646#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
555static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, 647static void __maybe_unused _dump_mask(struct ps3_private *pd,
556 const char* func, int line) 648 const char* func, int line)
557{ 649{
558 unsigned long flags; 650 unsigned long flags;
559 651
560 spin_lock_irqsave(&pd->bmp.lock, flags); 652 spin_lock_irqsave(&pd->bmp.lock, flags);
561 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 653 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
562 spin_unlock_irqrestore(&pd->bmp.lock, flags); 654 spin_unlock_irqrestore(&pd->bmp.lock, flags);
563} 655}
564#else 656#else
565static void dump_bmp(struct ps3_private* pd) {}; 657static void dump_bmp(struct ps3_private* pd) {};
566#endif /* defined(DEBUG) */ 658#endif /* defined(DEBUG) */
567 659
568static void ps3_chip_mask(unsigned int virq)
569{
570 struct ps3_private *pd = get_irq_chip_data(virq);
571 u64 bit = 0x8000000000000000UL >> virq;
572 u64 *p = &pd->bmp.mask;
573 u64 old;
574 unsigned long flags;
575
576 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
577
578 local_irq_save(flags);
579 asm volatile(
580 "1: ldarx %0,0,%3\n"
581 "andc %0,%0,%2\n"
582 "stdcx. %0,0,%3\n"
583 "bne- 1b"
584 : "=&r" (old), "+m" (*p)
585 : "r" (bit), "r" (p)
586 : "cc" );
587
588 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
589 local_irq_restore(flags);
590}
591
592static void ps3_chip_unmask(unsigned int virq)
593{
594 struct ps3_private *pd = get_irq_chip_data(virq);
595 u64 bit = 0x8000000000000000UL >> virq;
596 u64 *p = &pd->bmp.mask;
597 u64 old;
598 unsigned long flags;
599
600 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
601
602 local_irq_save(flags);
603 asm volatile(
604 "1: ldarx %0,0,%3\n"
605 "or %0,%0,%2\n"
606 "stdcx. %0,0,%3\n"
607 "bne- 1b"
608 : "=&r" (old), "+m" (*p)
609 : "r" (bit), "r" (p)
610 : "cc" );
611
612 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
613 local_irq_restore(flags);
614}
615
616static void ps3_chip_eoi(unsigned int virq)
617{
618 const struct ps3_private *pd = get_irq_chip_data(virq);
619 lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
620}
621
622static struct irq_chip irq_chip = {
623 .typename = "ps3",
624 .mask = ps3_chip_mask,
625 .unmask = ps3_chip_unmask,
626 .eoi = ps3_chip_eoi,
627};
628
629static void ps3_host_unmap(struct irq_host *h, unsigned int virq) 660static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
630{ 661{
631 set_irq_chip_data(virq, NULL); 662 set_irq_chip_data(virq, NULL);
@@ -637,7 +668,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
637 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 668 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
638 virq); 669 virq);
639 670
640 set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); 671 set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
641 672
642 return 0; 673 return 0;
643} 674}
@@ -657,7 +688,7 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
657 cpu, virq, pd->bmp.ipi_debug_brk_mask); 688 cpu, virq, pd->bmp.ipi_debug_brk_mask);
658} 689}
659 690
660unsigned int ps3_get_irq(void) 691static unsigned int ps3_get_irq(void)
661{ 692{
662 struct ps3_private *pd = &__get_cpu_var(ps3_private); 693 struct ps3_private *pd = &__get_cpu_var(ps3_private);
663 u64 x = (pd->bmp.status & pd->bmp.mask); 694 u64 x = (pd->bmp.status & pd->bmp.mask);
@@ -672,8 +703,8 @@ unsigned int ps3_get_irq(void)
672 plug &= 0x3f; 703 plug &= 0x3f;
673 704
674 if (unlikely(plug) == NO_IRQ) { 705 if (unlikely(plug) == NO_IRQ) {
675 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, 706 pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__,
676 pd->cpu); 707 __LINE__, pd->thread_id);
677 dump_bmp(&per_cpu(ps3_private, 0)); 708 dump_bmp(&per_cpu(ps3_private, 0));
678 dump_bmp(&per_cpu(ps3_private, 1)); 709 dump_bmp(&per_cpu(ps3_private, 1));
679 return NO_IRQ; 710 return NO_IRQ;
@@ -703,16 +734,16 @@ void __init ps3_init_IRQ(void)
703 for_each_possible_cpu(cpu) { 734 for_each_possible_cpu(cpu) {
704 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 735 struct ps3_private *pd = &per_cpu(ps3_private, cpu);
705 736
706 lv1_get_logical_ppe_id(&pd->node); 737 lv1_get_logical_ppe_id(&pd->ppe_id);
707 pd->cpu = get_hard_smp_processor_id(cpu); 738 pd->thread_id = get_hard_smp_processor_id(cpu);
708 spin_lock_init(&pd->bmp.lock); 739 spin_lock_init(&pd->bmp.lock);
709 740
710 pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, 741 pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n",
711 __LINE__, pd->node, pd->cpu, 742 __func__, __LINE__, pd->ppe_id, pd->thread_id,
712 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 743 ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
713 744
714 result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, 745 result = lv1_configure_irq_state_bitmap(pd->ppe_id,
715 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 746 pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
716 747
717 if (result) 748 if (result)
718 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" 749 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
@@ -722,3 +753,16 @@ void __init ps3_init_IRQ(void)
722 753
723 ppc_md.get_irq = ps3_get_irq; 754 ppc_md.get_irq = ps3_get_irq;
724} 755}
756
757void ps3_shutdown_IRQ(int cpu)
758{
759 int result;
760 u64 ppe_id;
761 u64 thread_id = get_hard_smp_processor_id(cpu);
762
763 lv1_get_logical_ppe_id(&ppe_id);
764 result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0);
765
766 DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__,
767 __LINE__, ppe_id, thread_id, cpu, ps3_result(result));
768}