xref: /linux/arch/powerpc/platforms/ps3/interrupt.c (revision 4d9f2ca2e37ce7fe7567761b2392748456e1ce43)
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 		return -ENOMEM;
188 	}
189 
190 	DBG("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
191 		outlet, cpu, *virq);
192 
193 	result = irq_set_chip_data(*virq, pd);
194 
195 	if (result) {
196 		FAIL("%s:%d: irq_set_chip_data failed\n",
197 			__func__, __LINE__);
198 		irq_dispose_mapping(*virq);
199 		return result;
200 	}
201 
202 	ps3_chip_mask(irq_get_irq_data(*virq));
203 
204 	return result;
205 }
206 
207 /**
208  * ps3_virq_destroy - virq related teardown.
209  * @virq: The assigned Linux virq.
210  *
211  * Clears chip data and calls irq_dispose_mapping() for the virq.
212  */
213 
214 static int ps3_virq_destroy(unsigned int virq)
215 {
216 	const struct ps3_private *pd = irq_get_chip_data(virq);
217 
218 	DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
219 		__LINE__, pd->ppe_id, pd->thread_id, virq);
220 
221 	irq_set_chip_data(virq, NULL);
222 	irq_dispose_mapping(virq);
223 
224 	DBG("%s:%d <-\n", __func__, __LINE__);
225 	return 0;
226 }
227 
228 /**
229  * ps3_irq_plug_setup - Generic outlet and virq related setup.
230  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
231  * serviced on.
232  * @outlet: The HV outlet from the various create outlet routines.
233  * @virq: The assigned Linux virq.
234  *
235  * Sets up virq and connects the irq plug.
236  */
237 
238 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
239 	unsigned int *virq)
240 {
241 	int result;
242 	struct ps3_private *pd;
243 
244 	result = ps3_virq_setup(cpu, outlet, virq);
245 
246 	if (result) {
247 		FAIL("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
248 		return result;
249 	}
250 
251 	pd = irq_get_chip_data(*virq);
252 
253 	/* Binds outlet to cpu + virq. */
254 
255 	result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
256 		outlet, 0);
257 
258 	if (result) {
259 		FAIL("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
260 		__func__, __LINE__, ps3_result(result));
261 		ps3_virq_destroy(*virq);
262 		return -EPERM;
263 	}
264 
265 	return result;
266 }
267 EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
268 
269 /**
270  * ps3_irq_plug_destroy - Generic outlet and virq related teardown.
271  * @virq: The assigned Linux virq.
272  *
273  * Disconnects the irq plug and tears down virq.
274  * Do not call for system bus event interrupts setup with
275  * ps3_sb_event_receive_port_setup().
276  */
277 
278 int ps3_irq_plug_destroy(unsigned int virq)
279 {
280 	int result;
281 	const struct ps3_private *pd = irq_get_chip_data(virq);
282 
283 	DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
284 		__LINE__, pd->ppe_id, pd->thread_id, virq);
285 
286 	ps3_chip_mask(irq_get_irq_data(virq));
287 
288 	result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
289 
290 	if (result)
291 		FAIL("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
292 		__func__, __LINE__, ps3_result(result));
293 
294 	ps3_virq_destroy(virq);
295 
296 	return result;
297 }
298 EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy);
299 
300 /**
301  * ps3_event_receive_port_setup - Setup an event receive port.
302  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
303  * serviced on.
304  * @virq: The assigned Linux virq.
305  *
306  * The virq can be used with lv1_connect_interrupt_event_receive_port() to
307  * arrange to receive interrupts from system-bus devices, or with
308  * ps3_send_event_locally() to signal events.
309  */
310 
311 int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
312 {
313 	int result;
314 	u64 outlet;
315 
316 	result = lv1_construct_event_receive_port(&outlet);
317 
318 	if (result) {
319 		FAIL("%s:%d: lv1_construct_event_receive_port failed: %s\n",
320 			__func__, __LINE__, ps3_result(result));
321 		*virq = 0;
322 		return result;
323 	}
324 
325 	result = ps3_irq_plug_setup(cpu, outlet, virq);
326 	BUG_ON(result);
327 
328 	return result;
329 }
330 EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup);
331 
332 /**
333  * ps3_event_receive_port_destroy - Destroy an event receive port.
334  * @virq: The assigned Linux virq.
335  *
336  * Since ps3_event_receive_port_destroy destroys the receive port outlet,
337  * SB devices need to call disconnect_interrupt_event_receive_port() before
338  * this.
339  */
340 
341 int ps3_event_receive_port_destroy(unsigned int virq)
342 {
343 	int result;
344 
345 	DBG(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
346 
347 	ps3_chip_mask(irq_get_irq_data(virq));
348 
349 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
350 
351 	if (result)
352 		FAIL("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
353 			__func__, __LINE__, ps3_result(result));
354 
355 	/*
356 	 * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
357 	 * calls from interrupt context (smp_call_function) when kexecing.
358 	 */
359 
360 	DBG(" <- %s:%d\n", __func__, __LINE__);
361 	return result;
362 }
363 
364 int ps3_send_event_locally(unsigned int virq)
365 {
366 	return lv1_send_event_locally(virq_to_hw(virq));
367 }
368 
369 /**
370  * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
371  * @dev: The system bus device instance.
372  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
373  * serviced on.
374  * @virq: The assigned Linux virq.
375  *
376  * An event irq represents a virtual device interrupt.  The interrupt_id
377  * coresponds to the software interrupt number.
378  */
379 
380 int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
381 	enum ps3_cpu_binding cpu, unsigned int *virq)
382 {
383 	/* this should go in system-bus.c */
384 
385 	int result;
386 
387 	result = ps3_event_receive_port_setup(cpu, virq);
388 
389 	if (result)
390 		return result;
391 
392 	result = lv1_connect_interrupt_event_receive_port(dev->bus_id,
393 		dev->dev_id, virq_to_hw(*virq), dev->interrupt_id);
394 
395 	if (result) {
396 		FAIL("%s:%d: lv1_connect_interrupt_event_receive_port"
397 			" failed: %s\n", __func__, __LINE__,
398 			ps3_result(result));
399 		ps3_event_receive_port_destroy(*virq);
400 		*virq = 0;
401 		return result;
402 	}
403 
404 	DBG("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
405 		dev->interrupt_id, *virq);
406 
407 	return 0;
408 }
409 EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
410 
411 int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
412 	unsigned int virq)
413 {
414 	/* this should go in system-bus.c */
415 
416 	int result;
417 
418 	DBG(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
419 		dev->interrupt_id, virq);
420 
421 	result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
422 		dev->dev_id, virq_to_hw(virq), dev->interrupt_id);
423 
424 	if (result)
425 		FAIL("%s:%d: lv1_disconnect_interrupt_event_receive_port"
426 			" failed: %s\n", __func__, __LINE__,
427 			ps3_result(result));
428 
429 	result = ps3_event_receive_port_destroy(virq);
430 	BUG_ON(result);
431 
432 	/*
433 	 * ps3_event_receive_port_destroy() destroys the IRQ plug,
434 	 * so don't call ps3_irq_plug_destroy() here.
435 	 */
436 
437 	result = ps3_virq_destroy(virq);
438 	BUG_ON(result);
439 
440 	DBG(" <- %s:%d\n", __func__, __LINE__);
441 	return result;
442 }
443 EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy);
444 
445 /**
446  * ps3_io_irq_setup - Setup a system bus io irq.
447  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
448  * serviced on.
449  * @interrupt_id: The device interrupt id read from the system repository.
450  * @virq: The assigned Linux virq.
451  *
452  * An io irq represents a non-virtualized device interrupt.  interrupt_id
453  * coresponds to the interrupt number of the interrupt controller.
454  */
455 
456 int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
457 	unsigned int *virq)
458 {
459 	int result;
460 	u64 outlet;
461 
462 	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
463 
464 	if (result) {
465 		FAIL("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
466 			__func__, __LINE__, ps3_result(result));
467 		return result;
468 	}
469 
470 	result = ps3_irq_plug_setup(cpu, outlet, virq);
471 	BUG_ON(result);
472 
473 	return result;
474 }
475 EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
476 
477 int ps3_io_irq_destroy(unsigned int virq)
478 {
479 	int result;
480 	unsigned long outlet = virq_to_hw(virq);
481 
482 	ps3_chip_mask(irq_get_irq_data(virq));
483 
484 	/*
485 	 * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
486 	 * so call ps3_irq_plug_destroy() first.
487 	 */
488 
489 	result = ps3_irq_plug_destroy(virq);
490 	BUG_ON(result);
491 
492 	result = lv1_destruct_io_irq_outlet(outlet);
493 
494 	if (result)
495 		FAIL("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
496 			__func__, __LINE__, ps3_result(result));
497 
498 	return result;
499 }
500 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
501 
502 /**
503  * ps3_vuart_irq_setup - Setup the system virtual uart virq.
504  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
505  * serviced on.
506  * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
507  * @virq: The assigned Linux virq.
508  *
509  * The system supports only a single virtual uart, so multiple calls without
510  * freeing the interrupt will return a wrong state error.
511  */
512 
513 int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
514 	unsigned int *virq)
515 {
516 	int result;
517 	u64 outlet;
518 	u64 lpar_addr;
519 
520 	BUG_ON(!is_kernel_addr((u64)virt_addr_bmp));
521 
522 	lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp));
523 
524 	result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet);
525 
526 	if (result) {
527 		FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
528 			__func__, __LINE__, ps3_result(result));
529 		return result;
530 	}
531 
532 	result = ps3_irq_plug_setup(cpu, outlet, virq);
533 	BUG_ON(result);
534 
535 	return result;
536 }
537 EXPORT_SYMBOL_GPL(ps3_vuart_irq_setup);
538 
539 int ps3_vuart_irq_destroy(unsigned int virq)
540 {
541 	int result;
542 
543 	ps3_chip_mask(irq_get_irq_data(virq));
544 	result = lv1_deconfigure_virtual_uart_irq();
545 
546 	if (result) {
547 		FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
548 			__func__, __LINE__, ps3_result(result));
549 		return result;
550 	}
551 
552 	result = ps3_irq_plug_destroy(virq);
553 	BUG_ON(result);
554 
555 	return result;
556 }
557 EXPORT_SYMBOL_GPL(ps3_vuart_irq_destroy);
558 
559 /**
560  * ps3_spe_irq_setup - Setup an spe virq.
561  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
562  * serviced on.
563  * @spe_id: The spe_id returned from lv1_construct_logical_spe().
564  * @class: The spe interrupt class {0,1,2}.
565  * @virq: The assigned Linux virq.
566  *
567  */
568 
569 int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
570 	unsigned int class, unsigned int *virq)
571 {
572 	int result;
573 	u64 outlet;
574 
575 	BUG_ON(class > 2);
576 
577 	result = lv1_get_spe_irq_outlet(spe_id, class, &outlet);
578 
579 	if (result) {
580 		FAIL("%s:%d: lv1_get_spe_irq_outlet failed: %s\n",
581 			__func__, __LINE__, ps3_result(result));
582 		return result;
583 	}
584 
585 	result = ps3_irq_plug_setup(cpu, outlet, virq);
586 	BUG_ON(result);
587 
588 	return result;
589 }
590 
591 int ps3_spe_irq_destroy(unsigned int virq)
592 {
593 	int result;
594 
595 	ps3_chip_mask(irq_get_irq_data(virq));
596 
597 	result = ps3_irq_plug_destroy(virq);
598 	BUG_ON(result);
599 
600 	return result;
601 }
602 
603 
604 #define PS3_INVALID_OUTLET ((irq_hw_number_t)-1)
605 #define PS3_PLUG_MAX 63
606 
607 #if defined(DEBUG)
608 static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
609 	const char* func, int line)
610 {
611 	pr_debug("%s:%d: %s %u {%04llx_%04llx_%04llx_%04llx}\n",
612 		func, line, header, cpu,
613 		*p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff,
614 		*p & 0xffff);
615 }
616 
617 static void __maybe_unused _dump_256_bmp(const char *header,
618 	const u64 *p, unsigned cpu, const char* func, int line)
619 {
620 	pr_debug("%s:%d: %s %u {%016llx:%016llx:%016llx:%016llx}\n",
621 		func, line, header, cpu, p[0], p[1], p[2], p[3]);
622 }
623 
624 #define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__)
625 static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
626 {
627 	unsigned long flags;
628 
629 	spin_lock_irqsave(&pd->bmp_lock, flags);
630 	_dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line);
631 	_dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line);
632 	spin_unlock_irqrestore(&pd->bmp_lock, flags);
633 }
634 
635 #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
636 static void __maybe_unused _dump_mask(struct ps3_private *pd,
637 	const char* func, int line)
638 {
639 	unsigned long flags;
640 
641 	spin_lock_irqsave(&pd->bmp_lock, flags);
642 	_dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line);
643 	spin_unlock_irqrestore(&pd->bmp_lock, flags);
644 }
645 #else
646 static void dump_bmp(struct ps3_private* pd) {};
647 #endif /* defined(DEBUG) */
648 
649 static int ps3_host_map(struct irq_domain *h, unsigned int virq,
650 	irq_hw_number_t hwirq)
651 {
652 	DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
653 		virq);
654 
655 	irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
656 
657 	return 0;
658 }
659 
660 static int ps3_host_match(struct irq_domain *h, struct device_node *np,
661 			  enum irq_domain_bus_token bus_token)
662 {
663 	/* Match all */
664 	return 1;
665 }
666 
667 static const struct irq_domain_ops ps3_host_ops = {
668 	.map = ps3_host_map,
669 	.match = ps3_host_match,
670 };
671 
672 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
673 {
674 	struct ps3_private *pd = &per_cpu(ps3_private, cpu);
675 
676 	set_bit(63 - virq, &pd->ipi_debug_brk_mask);
677 
678 	DBG("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__,
679 		cpu, virq, pd->ipi_debug_brk_mask);
680 }
681 
682 void __init ps3_register_ipi_irq(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_mask);
687 
688 	DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__,
689 		cpu, virq, pd->ipi_mask);
690 }
691 
692 static unsigned int ps3_get_irq(void)
693 {
694 	struct ps3_private *pd = this_cpu_ptr(&ps3_private);
695 	u64 x = (pd->bmp.status & pd->bmp.mask);
696 	unsigned int plug;
697 
698 	/* check for ipi break first to stop this cpu ASAP */
699 
700 	if (x & pd->ipi_debug_brk_mask)
701 		x &= pd->ipi_debug_brk_mask;
702 
703 	asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x));
704 	plug &= 0x3f;
705 
706 	if (unlikely(!plug)) {
707 		DBG("%s:%d: no plug found: thread_id %llu\n", __func__,
708 			__LINE__, pd->thread_id);
709 		dump_bmp(&per_cpu(ps3_private, 0));
710 		dump_bmp(&per_cpu(ps3_private, 1));
711 		return 0;
712 	}
713 
714 #if defined(DEBUG)
715 	if (unlikely(plug < NR_IRQS_LEGACY || plug > PS3_PLUG_MAX)) {
716 		dump_bmp(&per_cpu(ps3_private, 0));
717 		dump_bmp(&per_cpu(ps3_private, 1));
718 		BUG();
719 	}
720 #endif
721 
722 	/* IPIs are EOIed here. */
723 
724 	if (test_bit(63 - plug, &pd->ipi_mask))
725 		lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug);
726 
727 	return plug;
728 }
729 
730 void __init ps3_init_IRQ(void)
731 {
732 	int result;
733 	unsigned cpu;
734 	struct irq_domain *host;
735 
736 	host = irq_domain_create_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL);
737 	irq_set_default_domain(host);
738 
739 	for_each_possible_cpu(cpu) {
740 		struct ps3_private *pd = &per_cpu(ps3_private, cpu);
741 
742 		lv1_get_logical_ppe_id(&pd->ppe_id);
743 		pd->thread_id = get_hard_smp_processor_id(cpu);
744 		spin_lock_init(&pd->bmp_lock);
745 
746 		DBG("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n",
747 			__func__, __LINE__, pd->ppe_id, pd->thread_id,
748 			ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
749 
750 		result = lv1_configure_irq_state_bitmap(pd->ppe_id,
751 			pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
752 
753 		if (result)
754 			FAIL("%s:%d: lv1_configure_irq_state_bitmap failed:"
755 				" %s\n", __func__, __LINE__,
756 				ps3_result(result));
757 	}
758 
759 	ppc_md.get_irq = ps3_get_irq;
760 }
761 
762 void ps3_shutdown_IRQ(int cpu)
763 {
764 	int result;
765 	u64 ppe_id;
766 	u64 thread_id = get_hard_smp_processor_id(cpu);
767 
768 	lv1_get_logical_ppe_id(&ppe_id);
769 	result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0);
770 
771 	DBG("%s:%d: lv1_configure_irq_state_bitmap (%llu:%llu/%d) %s\n", __func__,
772 		__LINE__, ppe_id, thread_id, cpu, ps3_result(result));
773 }
774