GNU Linux-libre 6.8.9-gnu
[releases.git] / arch / powerpc / platforms / ps3 / interrupt.c
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
58 struct 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
77 struct 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
86 static 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
95 static 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
116 static 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
137 static 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
151 static 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
169 static 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
206 fail_set:
207         irq_dispose_mapping(*virq);
208 fail_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
219 static 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
243 int 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
272 fail_connect:
273         ps3_virq_destroy(*virq);
274 fail_setup:
275         return result;
276 }
277 EXPORT_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
288 int 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 }
308 EXPORT_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
321 int 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 }
340 EXPORT_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
351 int 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
374 int 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
390 int 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 }
419 EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
420
421 int 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 }
453 EXPORT_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
466 int 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 }
485 EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
486
487 int 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 }
510 EXPORT_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
523 int 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 }
547 EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
548
549 int 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 }
567 EXPORT_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
579 int 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
601 int 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)
618 static 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
627 static 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__)
635 static 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__)
646 static 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
656 static void dump_bmp(struct ps3_private* pd) {};
657 #endif /* defined(DEBUG) */
658
659 static 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
670 static 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
677 static const struct irq_domain_ops ps3_host_ops = {
678         .map = ps3_host_map,
679         .match = ps3_host_match,
680 };
681
682 void __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
692 void __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
702 static 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
740 void __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
772 void 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 }