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