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 udbg_printf 34 #else 35 #define DBG pr_debug 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 * The mask is declared as unsigned long so we can use set/clear_bit on it. 65 */ 66 67 #define PS3_BMP_MINALIGN 64 68 69 struct ps3_bmp { 70 struct { 71 u64 status; 72 u64 unused_1[3]; 73 unsigned long mask; 74 u64 unused_2[3]; 75 }; 76 u64 ipi_debug_brk_mask; 77 spinlock_t lock; 78 }; 79 80 /** 81 * struct ps3_private - a per cpu data structure 82 * @bmp: ps3_bmp structure 83 * @ppe_id: HV logical_ppe_id 84 * @thread_id: HV thread_id 85 */ 86 87 struct ps3_private { 88 struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); 89 u64 ppe_id; 90 u64 thread_id; 91 }; 92 93 static DEFINE_PER_CPU(struct ps3_private, ps3_private); 94 95 /** 96 * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp. 97 * @virq: The assigned Linux virq. 98 * 99 * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask(). 100 */ 101 102 static void ps3_chip_mask(unsigned int virq) 103 { 104 struct ps3_private *pd = get_irq_chip_data(virq); 105 unsigned long flags; 106 107 pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, 108 pd->thread_id, virq); 109 110 local_irq_save(flags); 111 clear_bit(63 - virq, &pd->bmp.mask); 112 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id); 113 local_irq_restore(flags); 114 } 115 116 /** 117 * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp. 118 * @virq: The assigned Linux virq. 119 * 120 * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask(). 121 */ 122 123 static void ps3_chip_unmask(unsigned int virq) 124 { 125 struct ps3_private *pd = get_irq_chip_data(virq); 126 unsigned long flags; 127 128 pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, 129 pd->thread_id, virq); 130 131 local_irq_save(flags); 132 set_bit(63 - virq, &pd->bmp.mask); 133 lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id); 134 local_irq_restore(flags); 135 } 136 137 /** 138 * ps3_chip_eoi - HV end-of-interrupt. 139 * @virq: The assigned Linux virq. 140 * 141 * Calls lv1_end_of_interrupt_ext(). 142 */ 143 144 static void ps3_chip_eoi(unsigned int virq) 145 { 146 const struct ps3_private *pd = get_irq_chip_data(virq); 147 lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq); 148 } 149 150 /** 151 * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip. 152 */ 153 154 static struct irq_chip ps3_irq_chip = { 155 .name = "ps3", 156 .mask = ps3_chip_mask, 157 .unmask = ps3_chip_unmask, 158 .eoi = ps3_chip_eoi, 159 }; 160 161 /** 162 * ps3_virq_setup - virq related setup. 163 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 164 * serviced on. 165 * @outlet: The HV outlet from the various create outlet routines. 166 * @virq: The assigned Linux virq. 167 * 168 * Calls irq_create_mapping() to get a virq and sets the chip data to 169 * ps3_private data. 170 */ 171 172 static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, 173 unsigned int *virq) 174 { 175 int result; 176 struct ps3_private *pd; 177 178 /* This defines the default interrupt distribution policy. */ 179 180 if (cpu == PS3_BINDING_CPU_ANY) 181 cpu = 0; 182 183 pd = &per_cpu(ps3_private, cpu); 184 185 *virq = irq_create_mapping(NULL, outlet); 186 187 if (*virq == NO_IRQ) { 188 pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", 189 __func__, __LINE__, outlet); 190 result = -ENOMEM; 191 goto fail_create; 192 } 193 194 pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, 195 outlet, cpu, *virq); 196 197 result = set_irq_chip_data(*virq, pd); 198 199 if (result) { 200 pr_debug("%s:%d: set_irq_chip_data failed\n", 201 __func__, __LINE__); 202 goto fail_set; 203 } 204 205 ps3_chip_mask(*virq); 206 207 return result; 208 209 fail_set: 210 irq_dispose_mapping(*virq); 211 fail_create: 212 return result; 213 } 214 215 /** 216 * ps3_virq_destroy - virq related teardown. 217 * @virq: The assigned Linux virq. 218 * 219 * Clears chip data and calls irq_dispose_mapping() for the virq. 220 */ 221 222 static int ps3_virq_destroy(unsigned int virq) 223 { 224 const struct ps3_private *pd = get_irq_chip_data(virq); 225 226 pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, 227 __LINE__, pd->ppe_id, pd->thread_id, virq); 228 229 set_irq_chip_data(virq, NULL); 230 irq_dispose_mapping(virq); 231 232 pr_debug("%s:%d <-\n", __func__, __LINE__); 233 return 0; 234 } 235 236 /** 237 * ps3_irq_plug_setup - Generic outlet and virq related setup. 238 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 239 * serviced on. 240 * @outlet: The HV outlet from the various create outlet routines. 241 * @virq: The assigned Linux virq. 242 * 243 * Sets up virq and connects the irq plug. 244 */ 245 246 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, 247 unsigned int *virq) 248 { 249 int result; 250 struct ps3_private *pd; 251 252 result = ps3_virq_setup(cpu, outlet, virq); 253 254 if (result) { 255 pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); 256 goto fail_setup; 257 } 258 259 pd = get_irq_chip_data(*virq); 260 261 /* Binds outlet to cpu + virq. */ 262 263 result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq, 264 outlet, 0); 265 266 if (result) { 267 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", 268 __func__, __LINE__, ps3_result(result)); 269 result = -EPERM; 270 goto fail_connect; 271 } 272 273 return result; 274 275 fail_connect: 276 ps3_virq_destroy(*virq); 277 fail_setup: 278 return result; 279 } 280 EXPORT_SYMBOL_GPL(ps3_irq_plug_setup); 281 282 /** 283 * ps3_irq_plug_destroy - Generic outlet and virq related teardown. 284 * @virq: The assigned Linux virq. 285 * 286 * Disconnects the irq plug and tears down virq. 287 * Do not call for system bus event interrupts setup with 288 * ps3_sb_event_receive_port_setup(). 289 */ 290 291 int ps3_irq_plug_destroy(unsigned int virq) 292 { 293 int result; 294 const struct ps3_private *pd = get_irq_chip_data(virq); 295 296 pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, 297 __LINE__, pd->ppe_id, pd->thread_id, virq); 298 299 ps3_chip_mask(virq); 300 301 result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); 302 303 if (result) 304 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", 305 __func__, __LINE__, ps3_result(result)); 306 307 ps3_virq_destroy(virq); 308 309 return result; 310 } 311 EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy); 312 313 /** 314 * ps3_event_receive_port_setup - Setup an event receive port. 315 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 316 * serviced on. 317 * @virq: The assigned Linux virq. 318 * 319 * The virq can be used with lv1_connect_interrupt_event_receive_port() to 320 * arrange to receive interrupts from system-bus devices, or with 321 * ps3_send_event_locally() to signal events. 322 */ 323 324 int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) 325 { 326 int result; 327 u64 outlet; 328 329 result = lv1_construct_event_receive_port(&outlet); 330 331 if (result) { 332 pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", 333 __func__, __LINE__, ps3_result(result)); 334 *virq = NO_IRQ; 335 return result; 336 } 337 338 result = ps3_irq_plug_setup(cpu, outlet, virq); 339 BUG_ON(result); 340 341 return result; 342 } 343 EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup); 344 345 /** 346 * ps3_event_receive_port_destroy - Destroy an event receive port. 347 * @virq: The assigned Linux virq. 348 * 349 * Since ps3_event_receive_port_destroy destroys the receive port outlet, 350 * SB devices need to call disconnect_interrupt_event_receive_port() before 351 * this. 352 */ 353 354 int ps3_event_receive_port_destroy(unsigned int virq) 355 { 356 int result; 357 358 pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq); 359 360 ps3_chip_mask(virq); 361 362 result = lv1_destruct_event_receive_port(virq_to_hw(virq)); 363 364 if (result) 365 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", 366 __func__, __LINE__, ps3_result(result)); 367 368 /* 369 * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu() 370 * calls from interrupt context (smp_call_function) when kexecing. 371 */ 372 373 pr_debug(" <- %s:%d\n", __func__, __LINE__); 374 return result; 375 } 376 377 int ps3_send_event_locally(unsigned int virq) 378 { 379 return lv1_send_event_locally(virq_to_hw(virq)); 380 } 381 382 /** 383 * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. 384 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 385 * serviced on. 386 * @dev: The system bus device instance. 387 * @virq: The assigned Linux virq. 388 * 389 * An event irq represents a virtual device interrupt. The interrupt_id 390 * coresponds to the software interrupt number. 391 */ 392 393 int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, 394 enum ps3_cpu_binding cpu, unsigned int *virq) 395 { 396 /* this should go in system-bus.c */ 397 398 int result; 399 400 result = ps3_event_receive_port_setup(cpu, virq); 401 402 if (result) 403 return result; 404 405 result = lv1_connect_interrupt_event_receive_port(dev->bus_id, 406 dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); 407 408 if (result) { 409 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" 410 " failed: %s\n", __func__, __LINE__, 411 ps3_result(result)); 412 ps3_event_receive_port_destroy(*virq); 413 *virq = NO_IRQ; 414 return result; 415 } 416 417 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 418 dev->interrupt_id, *virq); 419 420 return 0; 421 } 422 EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); 423 424 int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, 425 unsigned int virq) 426 { 427 /* this should go in system-bus.c */ 428 429 int result; 430 431 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, 432 dev->interrupt_id, virq); 433 434 result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, 435 dev->dev_id, virq_to_hw(virq), dev->interrupt_id); 436 437 if (result) 438 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" 439 " failed: %s\n", __func__, __LINE__, 440 ps3_result(result)); 441 442 result = ps3_event_receive_port_destroy(virq); 443 BUG_ON(result); 444 445 /* 446 * ps3_event_receive_port_destroy() destroys the IRQ plug, 447 * so don't call ps3_irq_plug_destroy() here. 448 */ 449 450 result = ps3_virq_destroy(virq); 451 BUG_ON(result); 452 453 pr_debug(" <- %s:%d\n", __func__, __LINE__); 454 return result; 455 } 456 EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); 457 458 /** 459 * ps3_io_irq_setup - Setup a system bus io irq. 460 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 461 * serviced on. 462 * @interrupt_id: The device interrupt id read from the system repository. 463 * @virq: The assigned Linux virq. 464 * 465 * An io irq represents a non-virtualized device interrupt. interrupt_id 466 * coresponds to the interrupt number of the interrupt controller. 467 */ 468 469 int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, 470 unsigned int *virq) 471 { 472 int result; 473 u64 outlet; 474 475 result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); 476 477 if (result) { 478 pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", 479 __func__, __LINE__, ps3_result(result)); 480 return result; 481 } 482 483 result = ps3_irq_plug_setup(cpu, outlet, virq); 484 BUG_ON(result); 485 486 return result; 487 } 488 EXPORT_SYMBOL_GPL(ps3_io_irq_setup); 489 490 int ps3_io_irq_destroy(unsigned int virq) 491 { 492 int result; 493 unsigned long outlet = virq_to_hw(virq); 494 495 ps3_chip_mask(virq); 496 497 /* 498 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug, 499 * so call ps3_irq_plug_destroy() first. 500 */ 501 502 result = ps3_irq_plug_destroy(virq); 503 BUG_ON(result); 504 505 result = lv1_destruct_io_irq_outlet(outlet); 506 507 if (result) 508 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", 509 __func__, __LINE__, ps3_result(result)); 510 511 return result; 512 } 513 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); 514 515 /** 516 * ps3_vuart_irq_setup - Setup the system virtual uart virq. 517 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 518 * serviced on. 519 * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. 520 * @virq: The assigned Linux virq. 521 * 522 * The system supports only a single virtual uart, so multiple calls without 523 * freeing the interrupt will return a wrong state error. 524 */ 525 526 int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, 527 unsigned int *virq) 528 { 529 int result; 530 u64 outlet; 531 u64 lpar_addr; 532 533 BUG_ON(!is_kernel_addr((u64)virt_addr_bmp)); 534 535 lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp)); 536 537 result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); 538 539 if (result) { 540 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", 541 __func__, __LINE__, ps3_result(result)); 542 return result; 543 } 544 545 result = ps3_irq_plug_setup(cpu, outlet, virq); 546 BUG_ON(result); 547 548 return result; 549 } 550 EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup); 551 552 int ps3_vuart_irq_destroy(unsigned int virq) 553 { 554 int result; 555 556 ps3_chip_mask(virq); 557 result = lv1_deconfigure_virtual_uart_irq(); 558 559 if (result) { 560 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", 561 __func__, __LINE__, ps3_result(result)); 562 return result; 563 } 564 565 result = ps3_irq_plug_destroy(virq); 566 BUG_ON(result); 567 568 return result; 569 } 570 EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy); 571 572 /** 573 * ps3_spe_irq_setup - Setup an spe virq. 574 * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be 575 * serviced on. 576 * @spe_id: The spe_id returned from lv1_construct_logical_spe(). 577 * @class: The spe interrupt class {0,1,2}. 578 * @virq: The assigned Linux virq. 579 * 580 */ 581 582 int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, 583 unsigned int class, unsigned int *virq) 584 { 585 int result; 586 u64 outlet; 587 588 BUG_ON(class > 2); 589 590 result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); 591 592 if (result) { 593 pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", 594 __func__, __LINE__, ps3_result(result)); 595 return result; 596 } 597 598 result = ps3_irq_plug_setup(cpu, outlet, virq); 599 BUG_ON(result); 600 601 return result; 602 } 603 604 int ps3_spe_irq_destroy(unsigned int virq) 605 { 606 int result; 607 608 ps3_chip_mask(virq); 609 610 result = ps3_irq_plug_destroy(virq); 611 BUG_ON(result); 612 613 return result; 614 } 615 616 617 #define PS3_INVALID_OUTLET ((irq_hw_number_t)-1) 618 #define PS3_PLUG_MAX 63 619 620 #if defined(DEBUG) 621 static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, 622 const char* func, int line) 623 { 624 pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", 625 func, line, header, cpu, 626 *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, 627 *p & 0xffff); 628 } 629 630 static void __maybe_unused _dump_256_bmp(const char *header, 631 const u64 *p, unsigned cpu, const char* func, int line) 632 { 633 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", 634 func, line, header, cpu, p[0], p[1], p[2], p[3]); 635 } 636 637 #define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__) 638 static void _dump_bmp(struct ps3_private* pd, const char* func, int line) 639 { 640 unsigned long flags; 641 642 spin_lock_irqsave(&pd->bmp.lock, flags); 643 _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); 644 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); 645 spin_unlock_irqrestore(&pd->bmp.lock, flags); 646 } 647 648 #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) 649 static void __maybe_unused _dump_mask(struct ps3_private *pd, 650 const char* func, int line) 651 { 652 unsigned long flags; 653 654 spin_lock_irqsave(&pd->bmp.lock, flags); 655 _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); 656 spin_unlock_irqrestore(&pd->bmp.lock, flags); 657 } 658 #else 659 static void dump_bmp(struct ps3_private* pd) {}; 660 #endif /* defined(DEBUG) */ 661 662 static void ps3_host_unmap(struct irq_host *h, unsigned int virq) 663 { 664 set_irq_chip_data(virq, NULL); 665 } 666 667 static int ps3_host_map(struct irq_host *h, unsigned int virq, 668 irq_hw_number_t hwirq) 669 { 670 pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, 671 virq); 672 673 set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); 674 675 return 0; 676 } 677 678 static int ps3_host_match(struct irq_host *h, struct device_node *np) 679 { 680 /* Match all */ 681 return 1; 682 } 683 684 static struct irq_host_ops ps3_host_ops = { 685 .map = ps3_host_map, 686 .unmap = ps3_host_unmap, 687 .match = ps3_host_match, 688 }; 689 690 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) 691 { 692 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 693 694 pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; 695 696 pr_debug("%s:%d: cpu %u, virq %u, mask %llxh\n", __func__, __LINE__, 697 cpu, virq, pd->bmp.ipi_debug_brk_mask); 698 } 699 700 static unsigned int ps3_get_irq(void) 701 { 702 struct ps3_private *pd = &__get_cpu_var(ps3_private); 703 u64 x = (pd->bmp.status & pd->bmp.mask); 704 unsigned int plug; 705 706 /* check for ipi break first to stop this cpu ASAP */ 707 708 if (x & pd->bmp.ipi_debug_brk_mask) 709 x &= pd->bmp.ipi_debug_brk_mask; 710 711 asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); 712 plug &= 0x3f; 713 714 if (unlikely(plug == NO_IRQ)) { 715 pr_debug("%s:%d: no plug found: thread_id %llu\n", __func__, 716 __LINE__, pd->thread_id); 717 dump_bmp(&per_cpu(ps3_private, 0)); 718 dump_bmp(&per_cpu(ps3_private, 1)); 719 return NO_IRQ; 720 } 721 722 #if defined(DEBUG) 723 if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) { 724 dump_bmp(&per_cpu(ps3_private, 0)); 725 dump_bmp(&per_cpu(ps3_private, 1)); 726 BUG(); 727 } 728 #endif 729 return plug; 730 } 731 732 void __init ps3_init_IRQ(void) 733 { 734 int result; 735 unsigned cpu; 736 struct irq_host *host; 737 738 host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops, 739 PS3_INVALID_OUTLET); 740 irq_set_default_host(host); 741 irq_set_virq_count(PS3_PLUG_MAX + 1); 742 743 for_each_possible_cpu(cpu) { 744 struct ps3_private *pd = &per_cpu(ps3_private, cpu); 745 746 lv1_get_logical_ppe_id(&pd->ppe_id); 747 pd->thread_id = get_hard_smp_processor_id(cpu); 748 spin_lock_init(&pd->bmp.lock); 749 750 pr_debug("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", 751 __func__, __LINE__, pd->ppe_id, pd->thread_id, 752 ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 753 754 result = lv1_configure_irq_state_bitmap(pd->ppe_id, 755 pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); 756 757 if (result) 758 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" 759 " %s\n", __func__, __LINE__, 760 ps3_result(result)); 761 } 762 763 ppc_md.get_irq = ps3_get_irq; 764 } 765 766 void ps3_shutdown_IRQ(int cpu) 767 { 768 int result; 769 u64 ppe_id; 770 u64 thread_id = get_hard_smp_processor_id(cpu); 771 772 lv1_get_logical_ppe_id(&ppe_id); 773 result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0); 774 775 DBG("%s:%d: lv1_configure_irq_state_bitmap (%llu:%llu/%d) %s\n", __func__, 776 __LINE__, ppe_id, thread_id, cpu, ps3_result(result)); 777 } 778