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