linux/arch/powerpc/platforms/ps3/interrupt.c
<<
>>
Prefs
   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 maintains 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
  69struct 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
  87struct ps3_private {
  88        struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
  89        u64 ppe_id;
  90        u64 thread_id;
  91};
  92
  93static 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
 102static void ps3_chip_mask(struct irq_data *d)
 103{
 104        struct ps3_private *pd = irq_data_get_irq_chip_data(d);
 105        unsigned long flags;
 106
 107        pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
 108                pd->thread_id, d->irq);
 109
 110        local_irq_save(flags);
 111        clear_bit(63 - d->irq, &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
 123static void ps3_chip_unmask(struct irq_data *d)
 124{
 125        struct ps3_private *pd = irq_data_get_irq_chip_data(d);
 126        unsigned long flags;
 127
 128        pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
 129                pd->thread_id, d->irq);
 130
 131        local_irq_save(flags);
 132        set_bit(63 - d->irq, &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
 144static void ps3_chip_eoi(struct irq_data *d)
 145{
 146        const struct ps3_private *pd = irq_data_get_irq_chip_data(d);
 147        lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
 148}
 149
 150/**
 151 * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
 152 */
 153
 154static struct irq_chip ps3_irq_chip = {
 155        .name = "ps3",
 156        .irq_mask = ps3_chip_mask,
 157        .irq_unmask = ps3_chip_unmask,
 158        .irq_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
 172static 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 = irq_set_chip_data(*virq, pd);
 198
 199        if (result) {
 200                pr_debug("%s:%d: irq_set_chip_data failed\n",
 201                        __func__, __LINE__);
 202                goto fail_set;
 203        }
 204
 205        ps3_chip_mask(irq_get_irq_data(*virq));
 206
 207        return result;
 208
 209fail_set:
 210        irq_dispose_mapping(*virq);
 211fail_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
 222static int ps3_virq_destroy(unsigned int virq)
 223{
 224        const struct ps3_private *pd = irq_get_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        irq_set_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
 246int 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 = irq_get_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
 275fail_connect:
 276        ps3_virq_destroy(*virq);
 277fail_setup:
 278        return result;
 279}
 280EXPORT_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
 291int ps3_irq_plug_destroy(unsigned int virq)
 292{
 293        int result;
 294        const struct ps3_private *pd = irq_get_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(irq_get_irq_data(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}
 311EXPORT_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
 324int 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}
 343EXPORT_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
 354int 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(irq_get_irq_data(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
 377int 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
 393int 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}
 422EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
 423
 424int 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}
 456EXPORT_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
 469int 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}
 488EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
 489
 490int ps3_io_irq_destroy(unsigned int virq)
 491{
 492        int result;
 493        unsigned long outlet = virq_to_hw(virq);
 494
 495        ps3_chip_mask(irq_get_irq_data(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}
 513EXPORT_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
 526int 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}
 550EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
 551
 552int ps3_vuart_irq_destroy(unsigned int virq)
 553{
 554        int result;
 555
 556        ps3_chip_mask(irq_get_irq_data(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}
 570EXPORT_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
 582int 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
 604int ps3_spe_irq_destroy(unsigned int virq)
 605{
 606        int result;
 607
 608        ps3_chip_mask(irq_get_irq_data(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)
 621static 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
 630static 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__)
 638static 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__)
 649static 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
 659static void dump_bmp(struct ps3_private* pd) {};
 660#endif /* defined(DEBUG) */
 661
 662static int ps3_host_map(struct irq_host *h, unsigned int virq,
 663        irq_hw_number_t hwirq)
 664{
 665        pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
 666                virq);
 667
 668        irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
 669
 670        return 0;
 671}
 672
 673static int ps3_host_match(struct irq_host *h, struct device_node *np)
 674{
 675        /* Match all */
 676        return 1;
 677}
 678
 679static struct irq_host_ops ps3_host_ops = {
 680        .map = ps3_host_map,
 681        .match = ps3_host_match,
 682};
 683
 684void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
 685{
 686        struct ps3_private *pd = &per_cpu(ps3_private, cpu);
 687
 688        pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq;
 689
 690        pr_debug("%s:%d: cpu %u, virq %u, mask %llxh\n", __func__, __LINE__,
 691                cpu, virq, pd->bmp.ipi_debug_brk_mask);
 692}
 693
 694static unsigned int ps3_get_irq(void)
 695{
 696        struct ps3_private *pd = &__get_cpu_var(ps3_private);
 697        u64 x = (pd->bmp.status & pd->bmp.mask);
 698        unsigned int plug;
 699
 700        /* check for ipi break first to stop this cpu ASAP */
 701
 702        if (x & pd->bmp.ipi_debug_brk_mask)
 703                x &= pd->bmp.ipi_debug_brk_mask;
 704
 705        asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x));
 706        plug &= 0x3f;
 707
 708        if (unlikely(plug == NO_IRQ)) {
 709                pr_debug("%s:%d: no plug found: thread_id %llu\n", __func__,
 710                        __LINE__, pd->thread_id);
 711                dump_bmp(&per_cpu(ps3_private, 0));
 712                dump_bmp(&per_cpu(ps3_private, 1));
 713                return NO_IRQ;
 714        }
 715
 716#if defined(DEBUG)
 717        if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) {
 718                dump_bmp(&per_cpu(ps3_private, 0));
 719                dump_bmp(&per_cpu(ps3_private, 1));
 720                BUG();
 721        }
 722#endif
 723        return plug;
 724}
 725
 726void __init ps3_init_IRQ(void)
 727{
 728        int result;
 729        unsigned cpu;
 730        struct irq_host *host;
 731
 732        host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
 733                PS3_INVALID_OUTLET);
 734        irq_set_default_host(host);
 735        irq_set_virq_count(PS3_PLUG_MAX + 1);
 736
 737        for_each_possible_cpu(cpu) {
 738                struct ps3_private *pd = &per_cpu(ps3_private, cpu);
 739
 740                lv1_get_logical_ppe_id(&pd->ppe_id);
 741                pd->thread_id = get_hard_smp_processor_id(cpu);
 742                spin_lock_init(&pd->bmp.lock);
 743
 744                pr_debug("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n",
 745                        __func__, __LINE__, pd->ppe_id, pd->thread_id,
 746                        ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
 747
 748                result = lv1_configure_irq_state_bitmap(pd->ppe_id,
 749                        pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
 750
 751                if (result)
 752                        pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
 753                                " %s\n", __func__, __LINE__,
 754                                ps3_result(result));
 755        }
 756
 757        ppc_md.get_irq = ps3_get_irq;
 758}
 759
 760void ps3_shutdown_IRQ(int cpu)
 761{
 762        int result;
 763        u64 ppe_id;
 764        u64 thread_id = get_hard_smp_processor_id(cpu);
 765
 766        lv1_get_logical_ppe_id(&ppe_id);
 767        result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0);
 768
 769        DBG("%s:%d: lv1_configure_irq_state_bitmap (%llu:%llu/%d) %s\n", __func__,
 770                __LINE__, ppe_id, thread_id, cpu, ps3_result(result));
 771}
 772