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