1 /* 2 * PS3 interrupt routines. 3 * 4 * Copyright (C) 2006 Sony Computer Entertainment Inc. 5 * Copyright 2006 Sony Corp. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; version 2 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/irq.h> 24 25 #include <asm/machdep.h> 26 #include <asm/udbg.h> 27 #include <asm/lv1call.h> 28 29 #include "platform.h" 30 31 #if defined(DEBUG) 32 #define DBG(fmt...) udbg_printf(fmt) 33 #else 34 #define DBG(fmt...) do{if(0)printk(fmt);}while(0) 35 #endif 36 37 /** 38 * struct ps3_bmp - a per cpu irq status and mask bitmap structure 39 * @status: 256 bit status bitmap indexed by plug 40 * @unused_1: 41 * @mask: 256 bit mask bitmap indexed by plug 42 * @unused_2: 43 * @lock: 44 * @ipi_debug_brk_mask: 45 * 46 * The HV mantains per SMT thread mappings of HV outlet to HV plug on 47 * behalf of the guest. These mappings are implemented as 256 bit guest 48 * supplied bitmaps indexed by plug number. The addresses of the bitmaps 49 * are registered with the HV through lv1_configure_irq_state_bitmap(). 50 * The HV requires that the 512 bits of status + mask not cross a page 51 * boundary. PS3_BMP_MINALIGN is used to define this minimal 64 byte 52 * alignment. 53 * 54 * The HV supports 256 plugs per thread, assigned as {0..255}, for a total 55 * of 512 plugs supported on a processor. To simplify the logic this 56 * implementation equates HV plug value to Linux virq value, constrains each 57 * interrupt to have a system wide unique plug number, and limits the range 58 * of the plug values to map into the first dword of the bitmaps. This 59 * gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note 60 * that there is no constraint on how many in this set an individual thread 61 * can acquire. 62 */ 63 64 #define PS3_BMP_MINALIGN 64 65 66 struct ps3_bmp { 67 struct { 68 u64 status; 69 u64 unused_1[3]; 70 u64 mask; 71 u64 unused_2[3]; 72 }; 73 u64 ipi_debug_brk_mask; 74 spinlock_t lock; 75 }; 76 77 /** 78 * struct ps3_private - a per cpu data structure 79 * @bmp: ps3_bmp structure 80 * @node: HV logical_ppe_id 81 * @cpu: HV thread_id 82 */ 83 84 struct ps3_private { 85 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); 86 u64 node; 87 unsigned int cpu; 88 }; 89 90 static DEFINE_PER_CPU(struct ps3_private, ps3_private); 91 92 /** 93 * ps3_virq_setup - virq related setup. 94 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 95 * serviced on. 96 * @outlet: The HV outlet from the various create outlet routines. 97 * @virq: The assigned Linux virq. 98 * 99 * Calls irq_create_mapping() to get a virq and sets the chip data to 100 * ps3_private data. 101 */ 102 103 int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, 104 unsigned int *virq) 105 { 106 int result; 107 struct ps3_private *pd; 108 109 /* This defines the default interrupt distribution policy. */ 110 111 if (cpu == PS3_BINDING_CPU_ANY) 112 cpu = 0; 113 114 pd = &per_cpu(ps3_private, cpu); 115 116 *virq = irq_create_mapping(NULL, outlet); 117 118 if (*virq == NO_IRQ) { 119 pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", 120 __func__, __LINE__, outlet); 121 result = -ENOMEM; 122 goto fail_create; 123 } 124 125 pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, 126 outlet, cpu, *virq); 127 128 result = set_irq_chip_data(*virq, pd); 129 130 if (result) { 131 pr_debug("%s:%d: set_irq_chip_data failed\n", 132 __func__, __LINE__); 133 goto fail_set; 134 } 135 136 return result; 137 138 fail_set: 139 irq_dispose_mapping(*virq); 140 fail_create: 141 return result; 142 } 143 144 /** 145 * ps3_virq_destroy - virq related teardown. 146 * @virq: The assigned Linux virq. 147 * 148 * Clears chip data and calls irq_dispose_mapping() for the virq. 149 */ 150 151 int ps3_virq_destroy(unsigned int virq) 152 { 153 const struct ps3_private *pd = get_irq_chip_data(virq); 154 155 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 156 pd->node, pd->cpu, virq); 157 158 set_irq_chip_data(virq, NULL); 159 irq_dispose_mapping(virq); 160 161 pr_debug("%s:%d <-\n", __func__, __LINE__); 162 return 0; 163 } 164 165 /** 166 * ps3_irq_plug_setup - Generic outlet and virq related setup. 167 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 168 * serviced on. 169 * @outlet: The HV outlet from the various create outlet routines. 170 * @virq: The assigned Linux virq. 171 * 172 * Sets up virq and connects the irq plug. 173 */ 174 175 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, 176 unsigned int *virq) 177 { 178 int result; 179 struct ps3_private *pd; 180 181 result = ps3_virq_setup(cpu, outlet, virq); 182 183 if (result) { 184 pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); 185 goto fail_setup; 186 } 187 188 pd = get_irq_chip_data(*virq); 189 190 /* Binds outlet to cpu + virq. */ 191 192 result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); 193 194 if (result) { 195 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", 196 __func__, __LINE__, ps3_result(result)); 197 result = -EPERM; 198 goto fail_connect; 199 } 200 201 return result; 202 203 fail_connect: 204 ps3_virq_destroy(*virq); 205 fail_setup: 206 return result; 207 } 208 EXPORT_SYMBOL_GPL(ps3_irq_plug_setup); 209 210 /** 211 * ps3_irq_plug_destroy - Generic outlet and virq related teardown. 212 * @virq: The assigned Linux virq. 213 * 214 * Disconnects the irq plug and tears down virq. 215 * Do not call for system bus event interrupts setup with 216 * ps3_sb_event_receive_port_setup(). 217 */ 218 219 int ps3_irq_plug_destroy(unsigned int virq) 220 { 221 int result; 222 const struct ps3_private *pd = get_irq_chip_data(virq); 223 224 pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, 225 pd->node, pd->cpu, virq); 226 227 result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); 228 229 if (result) 230 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", 231 __func__, __LINE__, ps3_result(result)); 232 233 ps3_virq_destroy(virq); 234 235 return result; 236 } 237 EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy); 238 239 /** 240 * ps3_event_receive_port_setup - Setup an event receive port. 241 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 242 * serviced on. 243 * @virq: The assigned Linux virq. 244 * 245 * The virq can be used with lv1_connect_interrupt_event_receive_port() to 246 * arrange to receive interrupts from system-bus devices, or with 247 * ps3_send_event_locally() to signal events. 248 */ 249 250 int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) 251 { 252 int result; 253 unsigned long outlet; 254 255 result = lv1_construct_event_receive_port(&outlet); 256 257 if (result) { 258 pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", 259 __func__, __LINE__, ps3_result(result)); 260 *virq = NO_IRQ; 261 return result; 262 } 263 264 result = ps3_irq_plug_setup(cpu, outlet, virq); 265 BUG_ON(result); 266 267 return result; 268 } 269 EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup); 270 271 /** 272 * ps3_event_receive_port_destroy - Destroy an event receive port. 273 * @virq: The assigned Linux virq. 274 * 275 * Since ps3_event_receive_port_destroy destroys the receive port outlet, 276 * SB devices need to call disconnect_interrupt_event_receive_port() before 277 * this. 278 */ 279 280 int ps3_event_receive_port_destroy(unsigned int virq) 281 { 282 int result; 283 284 pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); 285 286 result = lv1_destruct_event_receive_port(virq_to_hw(virq)); 287 288 if (result) 289 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", 290 __func__, __LINE__, ps3_result(result)); 291 292 /* lv1_destruct_event_receive_port() destroys the IRQ plug, 293 * so don't call ps3_irq_plug_destroy() here. 294 */ 295 296 result = ps3_virq_destroy(virq); 297 BUG_ON(result); 298 299 pr_debug(" <- %s:%d\n", __func__, __LINE__); 300 return result; 301 } 302 EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy); 303 304 int ps3_send_event_locally(unsigned int virq) 305 { 306 return lv1_send_event_locally(virq_to_hw(virq)); 307 } 308 309 /** 310 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. 311 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 312 * serviced on. 313 * @did: The HV device identifier read from the system repository. 314 * @interrupt_id: The device interrupt id read from the system repository. 315 * @virq: The assigned Linux virq. 316 * 317 * An event irq represents a virtual device interrupt. The interrupt_id 318 * coresponds to the software interrupt number. 319 */ 320 321 int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, 322 const struct ps3_device_id *did, unsigned int interrupt_id, 323 unsigned int *virq) 324 { 325 /* this should go in system-bus.c */ 326 327 int result; 328 329 result = ps3_event_receive_port_setup(cpu, virq); 330 331 if (result) 332 return result; 333 334 result = lv1_connect_interrupt_event_receive_port(did->bus_id, 335 did->dev_id, virq_to_hw(*virq), interrupt_id); 336 337 if (result) { 338 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" 339 " failed: %s\n", __func__, __LINE__, 340 ps3_result(result)); 341 ps3_event_receive_port_destroy(*virq); 342 *virq = NO_IRQ; 343 return result; 344 } 345 346 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 347 interrupt_id, *virq); 348 349 return 0; 350 } 351 EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); 352 353 int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, 354 unsigned int interrupt_id, unsigned int virq) 355 { 356 /* this should go in system-bus.c */ 357 358 int result; 359 360 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 361 interrupt_id, virq); 362 363 result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, 364 did->dev_id, virq_to_hw(virq), interrupt_id); 365 366 if (result) 367 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" 368 " failed: %s\n", __func__, __LINE__, 369 ps3_result(result)); 370 371 result = ps3_event_receive_port_destroy(virq); 372 BUG_ON(result); 373 374 pr_debug(" <- %s:%d\n", __func__, __LINE__); 375 return result; 376 } 377 EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); 378 379 /** 380 * ps3_io_irq_setup - Setup a system bus io irq. 381 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 382 * serviced on. 383 * @interrupt_id: The device interrupt id read from the system repository. 384 * @virq: The assigned Linux virq. 385 * 386 * An io irq represents a non-virtualized device interrupt. interrupt_id 387 * coresponds to the interrupt number of the interrupt controller. 388 */ 389 390 int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, 391 unsigned int *virq) 392 { 393 int result; 394 unsigned long outlet; 395 396 result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); 397 398 if (result) { 399 pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", 400 __func__, __LINE__, ps3_result(result)); 401 return result; 402 } 403 404 result = ps3_irq_plug_setup(cpu, outlet, virq); 405 BUG_ON(result); 406 407 return result; 408 } 409 EXPORT_SYMBOL_GPL(ps3_io_irq_setup); 410 411 int ps3_io_irq_destroy(unsigned int virq) 412 { 413 int result; 414 415 result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); 416 417 if (result) 418 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", 419 __func__, __LINE__, ps3_result(result)); 420 421 result = ps3_irq_plug_destroy(virq); 422 BUG_ON(result); 423 424 return result; 425 } 426 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); 427 428 /** 429 * ps3_vuart_irq_setup - Setup the system virtual uart virq. 430 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 431 * serviced on. 432 * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. 433 * @virq: The assigned Linux virq. 434 * 435 * The system supports only a single virtual uart, so multiple calls without 436 * freeing the interrupt will return a wrong state error. 437 */ 438 439 int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, 440 unsigned int *virq) 441 { 442 int result; 443 unsigned long outlet; 444 u64 lpar_addr; 445 446 BUG_ON(!is_kernel_addr((u64)virt_addr_bmp)); 447 448 lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp)); 449 450 result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); 451 452 if (result) { 453 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", 454 __func__, __LINE__, ps3_result(result)); 455 return result; 456 } 457 458 result = ps3_irq_plug_setup(cpu, outlet, virq); 459 BUG_ON(result); 460 461 return result; 462 } 463 464 int ps3_vuart_irq_destroy(unsigned int virq) 465 { 466 int result; 467 468 result = lv1_deconfigure_virtual_uart_irq(); 469 470 if (result) { 471 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", 472 __func__, __LINE__, ps3_result(result)); 473 return result; 474 } 475 476 result = ps3_irq_plug_destroy(virq); 477 BUG_ON(result); 478 479 return result; 480 } 481 482 /** 483 * ps3_spe_irq_setup - Setup an spe virq. 484 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 485 * serviced on. 486 * @spe_id: The spe_id returned from lv1_construct_logical_spe(). 487 * @class: The spe interrupt class {0,1,2}. 488 * @virq: The assigned Linux virq. 489 * 490 */ 491 492 int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, 493 unsigned int class, unsigned int *virq) 494 { 495 int result; 496 unsigned long outlet; 497 498 BUG_ON(class > 2); 499 500 result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); 501 502 if (result) { 503 pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", 504 __func__, __LINE__, ps3_result(result)); 505 return result; 506 } 507 508 result = ps3_irq_plug_setup(cpu, outlet, virq); 509 BUG_ON(result); 510 511 return result; 512 } 513 514 int ps3_spe_irq_destroy(unsigned int virq) 515 { 516 int result = ps3_irq_plug_destroy(virq); 517 BUG_ON(result); 518 return 0; 519 } 520 521 522 #define PS3_INVALID_OUTLET ((irq_hw_number_t)-1) 523 #define PS3_PLUG_MAX 63 524 525 #if defined(DEBUG) 526 static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, 527 const char* func, int line) 528 { 529 pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", 530 func, line, header, cpu, 531 *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, 532 *p & 0xffff); 533 } 534 535 static void __attribute__ ((unused)) _dump_256_bmp(const char *header, 536 const u64 *p, unsigned cpu, const char* func, int line) 537 { 538 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", 539 func, line, header, cpu, p[0], p[1], p[2], p[3]); 540 } 541 542 #define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__) 543 static void _dump_bmp(struct ps3_private* pd, const char* func, int line) 544 { 545 unsigned long flags; 546 547 spin_lock_irqsave(&pd->bmp.lock, flags); 548 _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); 549 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 550 spin_unlock_irqrestore(&pd->bmp.lock, flags); 551 } 552 553 #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) 554 static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd, 555 const char* func, int line) 556 { 557 unsigned long flags; 558 559 spin_lock_irqsave(&pd->bmp.lock, flags); 560 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); 561 spin_unlock_irqrestore(&pd->bmp.lock, flags); 562 } 563 #else 564 static void dump_bmp(struct ps3_private* pd) {}; 565 #endif /* defined(DEBUG) */ 566 567 static void ps3_chip_mask(unsigned int virq) 568 { 569 struct ps3_private *pd = get_irq_chip_data(virq); 570 u64 bit = 0x8000000000000000UL >> virq; 571 u64 *p = &pd->bmp.mask; 572 u64 old; 573 unsigned long flags; 574 575 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); 576 577 local_irq_save(flags); 578 asm volatile( 579 "1: ldarx %0,0,%3\n" 580 "andc %0,%0,%2\n" 581 "stdcx. %0,0,%3\n" 582 "bne- 1b" 583 : "=&r" (old), "+m" (*p) 584 : "r" (bit), "r" (p) 585 : "cc" ); 586 587 lv1_did_update_interrupt_mask(pd->node, pd->cpu); 588 local_irq_restore(flags); 589 } 590 591 static void ps3_chip_unmask(unsigned int virq) 592 { 593 struct ps3_private *pd = get_irq_chip_data(virq); 594 u64 bit = 0x8000000000000000UL >> virq; 595 u64 *p = &pd->bmp.mask; 596 u64 old; 597 unsigned long flags; 598 599 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); 600 601 local_irq_save(flags); 602 asm volatile( 603 "1: ldarx %0,0,%3\n" 604 "or %0,%0,%2\n" 605 "stdcx. %0,0,%3\n" 606 "bne- 1b" 607 : "=&r" (old), "+m" (*p) 608 : "r" (bit), "r" (p) 609 : "cc" ); 610 611 lv1_did_update_interrupt_mask(pd->node, pd->cpu); 612 local_irq_restore(flags); 613 } 614 615 static void ps3_chip_eoi(unsigned int virq) 616 { 617 const struct ps3_private *pd = get_irq_chip_data(virq); 618 lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq); 619 } 620 621 static struct irq_chip irq_chip = { 622 .typename = "ps3", 623 .mask = ps3_chip_mask, 624 .unmask = ps3_chip_unmask, 625 .eoi = ps3_chip_eoi, 626 }; 627 628 static void ps3_host_unmap(struct irq_host *h, unsigned int virq) 629 { 630 set_irq_chip_data(virq, NULL); 631 } 632 633 static int ps3_host_map(struct irq_host *h, unsigned int virq, 634 irq_hw_number_t hwirq) 635 { 636 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 637 virq); 638 639 set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); 640 641 return 0; 642 } 643 644 static struct irq_host_ops ps3_host_ops = { 645 .map = ps3_host_map, 646 .unmap = ps3_host_unmap, 647 }; 648 649 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) 650 { 651 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 652 653 pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; 654 655 pr_debug("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__, 656 cpu, virq, pd->bmp.ipi_debug_brk_mask); 657 } 658 659 unsigned int ps3_get_irq(void) 660 { 661 struct ps3_private *pd = &__get_cpu_var(ps3_private); 662 u64 x = (pd->bmp.status & pd->bmp.mask); 663 unsigned int plug; 664 665 /* check for ipi break first to stop this cpu ASAP */ 666 667 if (x & pd->bmp.ipi_debug_brk_mask) 668 x &= pd->bmp.ipi_debug_brk_mask; 669 670 asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); 671 plug &= 0x3f; 672 673 if (unlikely(plug) == NO_IRQ) { 674 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, 675 pd->cpu); 676 dump_bmp(&per_cpu(ps3_private, 0)); 677 dump_bmp(&per_cpu(ps3_private, 1)); 678 return NO_IRQ; 679 } 680 681 #if defined(DEBUG) 682 if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) { 683 dump_bmp(&per_cpu(ps3_private, 0)); 684 dump_bmp(&per_cpu(ps3_private, 1)); 685 BUG(); 686 } 687 #endif 688 return plug; 689 } 690 691 void __init ps3_init_IRQ(void) 692 { 693 int result; 694 unsigned cpu; 695 struct irq_host *host; 696 697 host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops, 698 PS3_INVALID_OUTLET); 699 irq_set_default_host(host); 700 irq_set_virq_count(PS3_PLUG_MAX + 1); 701 702 for_each_possible_cpu(cpu) { 703 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 704 705 lv1_get_logical_ppe_id(&pd->node); 706 pd->cpu = get_hard_smp_processor_id(cpu); 707 spin_lock_init(&pd->bmp.lock); 708 709 pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__, 710 __LINE__, pd->node, pd->cpu, 711 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 712 713 result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu, 714 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 715 716 if (result) 717 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" 718 " %s\n", __func__, __LINE__, 719 ps3_result(result)); 720 } 721 722 ppc_md.get_irq = ps3_get_irq; 723 } 724