xref: /linux/arch/sparc/kernel/prom_irqtrans.c (revision be239684b18e1cdcafcf8c7face4a2f562c745ad)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/string.h>
4 #include <linux/init.h>
5 #include <linux/of.h>
6 #include <linux/of_platform.h>
7 #include <linux/platform_device.h>
8 
9 #include <asm/oplib.h>
10 #include <asm/prom.h>
11 #include <asm/irq.h>
12 #include <asm/upa.h>
13 
14 #include "prom.h"
15 
16 #ifdef CONFIG_PCI
17 /* PSYCHO interrupt mapping support. */
18 #define PSYCHO_IMAP_A_SLOT0	0x0c00UL
19 #define PSYCHO_IMAP_B_SLOT0	0x0c20UL
20 static unsigned long psycho_pcislot_imap_offset(unsigned long ino)
21 {
22 	unsigned int bus =  (ino & 0x10) >> 4;
23 	unsigned int slot = (ino & 0x0c) >> 2;
24 
25 	if (bus == 0)
26 		return PSYCHO_IMAP_A_SLOT0 + (slot * 8);
27 	else
28 		return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
29 }
30 
31 #define PSYCHO_OBIO_IMAP_BASE	0x1000UL
32 
33 #define PSYCHO_ONBOARD_IRQ_BASE		0x20
34 #define psycho_onboard_imap_offset(__ino) \
35 	(PSYCHO_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
36 
37 #define PSYCHO_ICLR_A_SLOT0	0x1400UL
38 #define PSYCHO_ICLR_SCSI	0x1800UL
39 
40 #define psycho_iclr_offset(ino)					      \
41 	((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
42 			(PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
43 
44 static unsigned int psycho_irq_build(struct device_node *dp,
45 				     unsigned int ino,
46 				     void *_data)
47 {
48 	unsigned long controller_regs = (unsigned long) _data;
49 	unsigned long imap, iclr;
50 	unsigned long imap_off, iclr_off;
51 	int inofixup = 0;
52 
53 	ino &= 0x3f;
54 	if (ino < PSYCHO_ONBOARD_IRQ_BASE) {
55 		/* PCI slot */
56 		imap_off = psycho_pcislot_imap_offset(ino);
57 	} else {
58 		/* Onboard device */
59 		imap_off = psycho_onboard_imap_offset(ino);
60 	}
61 
62 	/* Now build the IRQ bucket. */
63 	imap = controller_regs + imap_off;
64 
65 	iclr_off = psycho_iclr_offset(ino);
66 	iclr = controller_regs + iclr_off;
67 
68 	if ((ino & 0x20) == 0)
69 		inofixup = ino & 0x03;
70 
71 	return build_irq(inofixup, iclr, imap);
72 }
73 
74 static void __init psycho_irq_trans_init(struct device_node *dp)
75 {
76 	const struct linux_prom64_registers *regs;
77 
78 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
79 	dp->irq_trans->irq_build = psycho_irq_build;
80 
81 	regs = of_get_property(dp, "reg", NULL);
82 	dp->irq_trans->data = (void *) regs[2].phys_addr;
83 }
84 
85 #define sabre_read(__reg) \
86 ({	u64 __ret; \
87 	__asm__ __volatile__("ldxa [%1] %2, %0" \
88 			     : "=r" (__ret) \
89 			     : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
90 			     : "memory"); \
91 	__ret; \
92 })
93 
94 struct sabre_irq_data {
95 	unsigned long controller_regs;
96 	unsigned int pci_first_busno;
97 };
98 #define SABRE_CONFIGSPACE	0x001000000UL
99 #define SABRE_WRSYNC		0x1c20UL
100 
101 #define SABRE_CONFIG_BASE(CONFIG_SPACE)	\
102 	(CONFIG_SPACE | (1UL << 24))
103 #define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG)	\
104 	(((unsigned long)(BUS)   << 16) |	\
105 	 ((unsigned long)(DEVFN) << 8)  |	\
106 	 ((unsigned long)(REG)))
107 
108 /* When a device lives behind a bridge deeper in the PCI bus topology
109  * than APB, a special sequence must run to make sure all pending DMA
110  * transfers at the time of IRQ delivery are visible in the coherency
111  * domain by the cpu.  This sequence is to perform a read on the far
112  * side of the non-APB bridge, then perform a read of Sabre's DMA
113  * write-sync register.
114  */
115 static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
116 {
117 	unsigned int phys_hi = (unsigned int) (unsigned long) _arg1;
118 	struct sabre_irq_data *irq_data = _arg2;
119 	unsigned long controller_regs = irq_data->controller_regs;
120 	unsigned long sync_reg = controller_regs + SABRE_WRSYNC;
121 	unsigned long config_space = controller_regs + SABRE_CONFIGSPACE;
122 	unsigned int bus, devfn;
123 	u16 _unused;
124 
125 	config_space = SABRE_CONFIG_BASE(config_space);
126 
127 	bus = (phys_hi >> 16) & 0xff;
128 	devfn = (phys_hi >> 8) & 0xff;
129 
130 	config_space |= SABRE_CONFIG_ENCODE(bus, devfn, 0x00);
131 
132 	__asm__ __volatile__("membar #Sync\n\t"
133 			     "lduha [%1] %2, %0\n\t"
134 			     "membar #Sync"
135 			     : "=r" (_unused)
136 			     : "r" ((u16 *) config_space),
137 			       "i" (ASI_PHYS_BYPASS_EC_E_L)
138 			     : "memory");
139 
140 	sabre_read(sync_reg);
141 }
142 
143 #define SABRE_IMAP_A_SLOT0	0x0c00UL
144 #define SABRE_IMAP_B_SLOT0	0x0c20UL
145 #define SABRE_ICLR_A_SLOT0	0x1400UL
146 #define SABRE_ICLR_B_SLOT0	0x1480UL
147 #define SABRE_ICLR_SCSI		0x1800UL
148 #define SABRE_ICLR_ETH		0x1808UL
149 #define SABRE_ICLR_BPP		0x1810UL
150 #define SABRE_ICLR_AU_REC	0x1818UL
151 #define SABRE_ICLR_AU_PLAY	0x1820UL
152 #define SABRE_ICLR_PFAIL	0x1828UL
153 #define SABRE_ICLR_KMS		0x1830UL
154 #define SABRE_ICLR_FLPY		0x1838UL
155 #define SABRE_ICLR_SHW		0x1840UL
156 #define SABRE_ICLR_KBD		0x1848UL
157 #define SABRE_ICLR_MS		0x1850UL
158 #define SABRE_ICLR_SER		0x1858UL
159 #define SABRE_ICLR_UE		0x1870UL
160 #define SABRE_ICLR_CE		0x1878UL
161 #define SABRE_ICLR_PCIERR	0x1880UL
162 
163 static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
164 {
165 	unsigned int bus =  (ino & 0x10) >> 4;
166 	unsigned int slot = (ino & 0x0c) >> 2;
167 
168 	if (bus == 0)
169 		return SABRE_IMAP_A_SLOT0 + (slot * 8);
170 	else
171 		return SABRE_IMAP_B_SLOT0 + (slot * 8);
172 }
173 
174 #define SABRE_OBIO_IMAP_BASE	0x1000UL
175 #define SABRE_ONBOARD_IRQ_BASE	0x20
176 #define sabre_onboard_imap_offset(__ino) \
177 	(SABRE_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
178 
179 #define sabre_iclr_offset(ino)					      \
180 	((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
181 			(SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
182 
183 static int sabre_device_needs_wsync(struct device_node *dp)
184 {
185 	struct device_node *parent = dp->parent;
186 	const char *parent_model, *parent_compat;
187 
188 	/* This traversal up towards the root is meant to
189 	 * handle two cases:
190 	 *
191 	 * 1) non-PCI bus sitting under PCI, such as 'ebus'
192 	 * 2) the PCI controller interrupts themselves, which
193 	 *    will use the sabre_irq_build but do not need
194 	 *    the DMA synchronization handling
195 	 */
196 	while (parent) {
197 		if (of_node_is_type(parent, "pci"))
198 			break;
199 		parent = parent->parent;
200 	}
201 
202 	if (!parent)
203 		return 0;
204 
205 	parent_model = of_get_property(parent,
206 				       "model", NULL);
207 	if (parent_model &&
208 	    (!strcmp(parent_model, "SUNW,sabre") ||
209 	     !strcmp(parent_model, "SUNW,simba")))
210 		return 0;
211 
212 	parent_compat = of_get_property(parent,
213 					"compatible", NULL);
214 	if (parent_compat &&
215 	    (!strcmp(parent_compat, "pci108e,a000") ||
216 	     !strcmp(parent_compat, "pci108e,a001")))
217 		return 0;
218 
219 	return 1;
220 }
221 
222 static unsigned int sabre_irq_build(struct device_node *dp,
223 				    unsigned int ino,
224 				    void *_data)
225 {
226 	struct sabre_irq_data *irq_data = _data;
227 	unsigned long controller_regs = irq_data->controller_regs;
228 	const struct linux_prom_pci_registers *regs;
229 	unsigned long imap, iclr;
230 	unsigned long imap_off, iclr_off;
231 	int inofixup = 0;
232 	int irq;
233 
234 	ino &= 0x3f;
235 	if (ino < SABRE_ONBOARD_IRQ_BASE) {
236 		/* PCI slot */
237 		imap_off = sabre_pcislot_imap_offset(ino);
238 	} else {
239 		/* onboard device */
240 		imap_off = sabre_onboard_imap_offset(ino);
241 	}
242 
243 	/* Now build the IRQ bucket. */
244 	imap = controller_regs + imap_off;
245 
246 	iclr_off = sabre_iclr_offset(ino);
247 	iclr = controller_regs + iclr_off;
248 
249 	if ((ino & 0x20) == 0)
250 		inofixup = ino & 0x03;
251 
252 	irq = build_irq(inofixup, iclr, imap);
253 
254 	/* If the parent device is a PCI<->PCI bridge other than
255 	 * APB, we have to install a pre-handler to ensure that
256 	 * all pending DMA is drained before the interrupt handler
257 	 * is run.
258 	 */
259 	regs = of_get_property(dp, "reg", NULL);
260 	if (regs && sabre_device_needs_wsync(dp)) {
261 		irq_install_pre_handler(irq,
262 					sabre_wsync_handler,
263 					(void *) (long) regs->phys_hi,
264 					(void *) irq_data);
265 	}
266 
267 	return irq;
268 }
269 
270 static void __init sabre_irq_trans_init(struct device_node *dp)
271 {
272 	const struct linux_prom64_registers *regs;
273 	struct sabre_irq_data *irq_data;
274 	const u32 *busrange;
275 
276 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
277 	dp->irq_trans->irq_build = sabre_irq_build;
278 
279 	irq_data = prom_early_alloc(sizeof(struct sabre_irq_data));
280 
281 	regs = of_get_property(dp, "reg", NULL);
282 	irq_data->controller_regs = regs[0].phys_addr;
283 
284 	busrange = of_get_property(dp, "bus-range", NULL);
285 	irq_data->pci_first_busno = busrange[0];
286 
287 	dp->irq_trans->data = irq_data;
288 }
289 
290 /* SCHIZO interrupt mapping support.  Unlike Psycho, for this controller the
291  * imap/iclr registers are per-PBM.
292  */
293 #define SCHIZO_IMAP_BASE	0x1000UL
294 #define SCHIZO_ICLR_BASE	0x1400UL
295 
296 static unsigned long schizo_imap_offset(unsigned long ino)
297 {
298 	return SCHIZO_IMAP_BASE + (ino * 8UL);
299 }
300 
301 static unsigned long schizo_iclr_offset(unsigned long ino)
302 {
303 	return SCHIZO_ICLR_BASE + (ino * 8UL);
304 }
305 
306 static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs,
307 					unsigned int ino)
308 {
309 
310 	return pbm_regs + schizo_iclr_offset(ino);
311 }
312 
313 static unsigned long schizo_ino_to_imap(unsigned long pbm_regs,
314 					unsigned int ino)
315 {
316 	return pbm_regs + schizo_imap_offset(ino);
317 }
318 
319 #define schizo_read(__reg) \
320 ({	u64 __ret; \
321 	__asm__ __volatile__("ldxa [%1] %2, %0" \
322 			     : "=r" (__ret) \
323 			     : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
324 			     : "memory"); \
325 	__ret; \
326 })
327 #define schizo_write(__reg, __val) \
328 	__asm__ __volatile__("stxa %0, [%1] %2" \
329 			     : /* no outputs */ \
330 			     : "r" (__val), "r" (__reg), \
331 			       "i" (ASI_PHYS_BYPASS_EC_E) \
332 			     : "memory")
333 
334 static void tomatillo_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
335 {
336 	unsigned long sync_reg = (unsigned long) _arg2;
337 	u64 mask = 1UL << (ino & IMAP_INO);
338 	u64 val;
339 	int limit;
340 
341 	schizo_write(sync_reg, mask);
342 
343 	limit = 100000;
344 	val = 0;
345 	while (--limit) {
346 		val = schizo_read(sync_reg);
347 		if (!(val & mask))
348 			break;
349 	}
350 	if (limit <= 0) {
351 		printk("tomatillo_wsync_handler: DMA won't sync [%llx:%llx]\n",
352 		       val, mask);
353 	}
354 
355 	if (_arg1) {
356 		static unsigned char cacheline[64]
357 			__attribute__ ((aligned (64)));
358 
359 		__asm__ __volatile__("rd %%fprs, %0\n\t"
360 				     "or %0, %4, %1\n\t"
361 				     "wr %1, 0x0, %%fprs\n\t"
362 				     "stda %%f0, [%5] %6\n\t"
363 				     "wr %0, 0x0, %%fprs\n\t"
364 				     "membar #Sync"
365 				     : "=&r" (mask), "=&r" (val)
366 				     : "0" (mask), "1" (val),
367 				     "i" (FPRS_FEF), "r" (&cacheline[0]),
368 				     "i" (ASI_BLK_COMMIT_P));
369 	}
370 }
371 
372 struct schizo_irq_data {
373 	unsigned long pbm_regs;
374 	unsigned long sync_reg;
375 	u32 portid;
376 	int chip_version;
377 };
378 
379 static unsigned int schizo_irq_build(struct device_node *dp,
380 				     unsigned int ino,
381 				     void *_data)
382 {
383 	struct schizo_irq_data *irq_data = _data;
384 	unsigned long pbm_regs = irq_data->pbm_regs;
385 	unsigned long imap, iclr;
386 	int ign_fixup;
387 	int irq;
388 	int is_tomatillo;
389 
390 	ino &= 0x3f;
391 
392 	/* Now build the IRQ bucket. */
393 	imap = schizo_ino_to_imap(pbm_regs, ino);
394 	iclr = schizo_ino_to_iclr(pbm_regs, ino);
395 
396 	/* On Schizo, no inofixup occurs.  This is because each
397 	 * INO has it's own IMAP register.  On Psycho and Sabre
398 	 * there is only one IMAP register for each PCI slot even
399 	 * though four different INOs can be generated by each
400 	 * PCI slot.
401 	 *
402 	 * But, for JBUS variants (essentially, Tomatillo), we have
403 	 * to fixup the lowest bit of the interrupt group number.
404 	 */
405 	ign_fixup = 0;
406 
407 	is_tomatillo = (irq_data->sync_reg != 0UL);
408 
409 	if (is_tomatillo) {
410 		if (irq_data->portid & 1)
411 			ign_fixup = (1 << 6);
412 	}
413 
414 	irq = build_irq(ign_fixup, iclr, imap);
415 
416 	if (is_tomatillo) {
417 		irq_install_pre_handler(irq,
418 					tomatillo_wsync_handler,
419 					((irq_data->chip_version <= 4) ?
420 					 (void *) 1 : (void *) 0),
421 					(void *) irq_data->sync_reg);
422 	}
423 
424 	return irq;
425 }
426 
427 static void __init __schizo_irq_trans_init(struct device_node *dp,
428 					   int is_tomatillo)
429 {
430 	const struct linux_prom64_registers *regs;
431 	struct schizo_irq_data *irq_data;
432 
433 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
434 	dp->irq_trans->irq_build = schizo_irq_build;
435 
436 	irq_data = prom_early_alloc(sizeof(struct schizo_irq_data));
437 
438 	regs = of_get_property(dp, "reg", NULL);
439 	dp->irq_trans->data = irq_data;
440 
441 	irq_data->pbm_regs = regs[0].phys_addr;
442 	if (is_tomatillo)
443 		irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
444 	else
445 		irq_data->sync_reg = 0UL;
446 	irq_data->portid = of_getintprop_default(dp, "portid", 0);
447 	irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
448 }
449 
450 static void __init schizo_irq_trans_init(struct device_node *dp)
451 {
452 	__schizo_irq_trans_init(dp, 0);
453 }
454 
455 static void __init tomatillo_irq_trans_init(struct device_node *dp)
456 {
457 	__schizo_irq_trans_init(dp, 1);
458 }
459 
460 static unsigned int pci_sun4v_irq_build(struct device_node *dp,
461 					unsigned int devino,
462 					void *_data)
463 {
464 	u32 devhandle = (u32) (unsigned long) _data;
465 
466 	return sun4v_build_irq(devhandle, devino);
467 }
468 
469 static void __init pci_sun4v_irq_trans_init(struct device_node *dp)
470 {
471 	const struct linux_prom64_registers *regs;
472 
473 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
474 	dp->irq_trans->irq_build = pci_sun4v_irq_build;
475 
476 	regs = of_get_property(dp, "reg", NULL);
477 	dp->irq_trans->data = (void *) (unsigned long)
478 		((regs->phys_addr >> 32UL) & 0x0fffffff);
479 }
480 
481 struct fire_irq_data {
482 	unsigned long pbm_regs;
483 	u32 portid;
484 };
485 
486 #define FIRE_IMAP_BASE	0x001000
487 #define FIRE_ICLR_BASE	0x001400
488 
489 static unsigned long fire_imap_offset(unsigned long ino)
490 {
491 	return FIRE_IMAP_BASE + (ino * 8UL);
492 }
493 
494 static unsigned long fire_iclr_offset(unsigned long ino)
495 {
496 	return FIRE_ICLR_BASE + (ino * 8UL);
497 }
498 
499 static unsigned long fire_ino_to_iclr(unsigned long pbm_regs,
500 					    unsigned int ino)
501 {
502 	return pbm_regs + fire_iclr_offset(ino);
503 }
504 
505 static unsigned long fire_ino_to_imap(unsigned long pbm_regs,
506 					    unsigned int ino)
507 {
508 	return pbm_regs + fire_imap_offset(ino);
509 }
510 
511 static unsigned int fire_irq_build(struct device_node *dp,
512 					 unsigned int ino,
513 					 void *_data)
514 {
515 	struct fire_irq_data *irq_data = _data;
516 	unsigned long pbm_regs = irq_data->pbm_regs;
517 	unsigned long imap, iclr;
518 	unsigned long int_ctrlr;
519 
520 	ino &= 0x3f;
521 
522 	/* Now build the IRQ bucket. */
523 	imap = fire_ino_to_imap(pbm_regs, ino);
524 	iclr = fire_ino_to_iclr(pbm_regs, ino);
525 
526 	/* Set the interrupt controller number.  */
527 	int_ctrlr = 1 << 6;
528 	upa_writeq(int_ctrlr, imap);
529 
530 	/* The interrupt map registers do not have an INO field
531 	 * like other chips do.  They return zero in the INO
532 	 * field, and the interrupt controller number is controlled
533 	 * in bits 6 to 9.  So in order for build_irq() to get
534 	 * the INO right we pass it in as part of the fixup
535 	 * which will get added to the map register zero value
536 	 * read by build_irq().
537 	 */
538 	ino |= (irq_data->portid << 6);
539 	ino -= int_ctrlr;
540 	return build_irq(ino, iclr, imap);
541 }
542 
543 static void __init fire_irq_trans_init(struct device_node *dp)
544 {
545 	const struct linux_prom64_registers *regs;
546 	struct fire_irq_data *irq_data;
547 
548 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
549 	dp->irq_trans->irq_build = fire_irq_build;
550 
551 	irq_data = prom_early_alloc(sizeof(struct fire_irq_data));
552 
553 	regs = of_get_property(dp, "reg", NULL);
554 	dp->irq_trans->data = irq_data;
555 
556 	irq_data->pbm_regs = regs[0].phys_addr;
557 	irq_data->portid = of_getintprop_default(dp, "portid", 0);
558 }
559 #endif /* CONFIG_PCI */
560 
561 #ifdef CONFIG_SBUS
562 /* INO number to IMAP register offset for SYSIO external IRQ's.
563  * This should conform to both Sunfire/Wildfire server and Fusion
564  * desktop designs.
565  */
566 #define SYSIO_IMAP_SLOT0	0x2c00UL
567 #define SYSIO_IMAP_SLOT1	0x2c08UL
568 #define SYSIO_IMAP_SLOT2	0x2c10UL
569 #define SYSIO_IMAP_SLOT3	0x2c18UL
570 #define SYSIO_IMAP_SCSI		0x3000UL
571 #define SYSIO_IMAP_ETH		0x3008UL
572 #define SYSIO_IMAP_BPP		0x3010UL
573 #define SYSIO_IMAP_AUDIO	0x3018UL
574 #define SYSIO_IMAP_PFAIL	0x3020UL
575 #define SYSIO_IMAP_KMS		0x3028UL
576 #define SYSIO_IMAP_FLPY		0x3030UL
577 #define SYSIO_IMAP_SHW		0x3038UL
578 #define SYSIO_IMAP_KBD		0x3040UL
579 #define SYSIO_IMAP_MS		0x3048UL
580 #define SYSIO_IMAP_SER		0x3050UL
581 #define SYSIO_IMAP_TIM0		0x3060UL
582 #define SYSIO_IMAP_TIM1		0x3068UL
583 #define SYSIO_IMAP_UE		0x3070UL
584 #define SYSIO_IMAP_CE		0x3078UL
585 #define SYSIO_IMAP_SBERR	0x3080UL
586 #define SYSIO_IMAP_PMGMT	0x3088UL
587 #define SYSIO_IMAP_GFX		0x3090UL
588 #define SYSIO_IMAP_EUPA		0x3098UL
589 
590 #define bogon     ((unsigned long) -1)
591 static unsigned long sysio_irq_offsets[] = {
592 	/* SBUS Slot 0 --> 3, level 1 --> 7 */
593 	SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
594 	SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
595 	SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
596 	SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
597 	SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
598 	SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
599 	SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
600 	SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
601 
602 	/* Onboard devices (not relevant/used on SunFire). */
603 	SYSIO_IMAP_SCSI,
604 	SYSIO_IMAP_ETH,
605 	SYSIO_IMAP_BPP,
606 	bogon,
607 	SYSIO_IMAP_AUDIO,
608 	SYSIO_IMAP_PFAIL,
609 	bogon,
610 	bogon,
611 	SYSIO_IMAP_KMS,
612 	SYSIO_IMAP_FLPY,
613 	SYSIO_IMAP_SHW,
614 	SYSIO_IMAP_KBD,
615 	SYSIO_IMAP_MS,
616 	SYSIO_IMAP_SER,
617 	bogon,
618 	bogon,
619 	SYSIO_IMAP_TIM0,
620 	SYSIO_IMAP_TIM1,
621 	bogon,
622 	bogon,
623 	SYSIO_IMAP_UE,
624 	SYSIO_IMAP_CE,
625 	SYSIO_IMAP_SBERR,
626 	SYSIO_IMAP_PMGMT,
627 	SYSIO_IMAP_GFX,
628 	SYSIO_IMAP_EUPA,
629 };
630 
631 #undef bogon
632 
633 #define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
634 
635 /* Convert Interrupt Mapping register pointer to associated
636  * Interrupt Clear register pointer, SYSIO specific version.
637  */
638 #define SYSIO_ICLR_UNUSED0	0x3400UL
639 #define SYSIO_ICLR_SLOT0	0x3408UL
640 #define SYSIO_ICLR_SLOT1	0x3448UL
641 #define SYSIO_ICLR_SLOT2	0x3488UL
642 #define SYSIO_ICLR_SLOT3	0x34c8UL
643 static unsigned long sysio_imap_to_iclr(unsigned long imap)
644 {
645 	unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
646 	return imap + diff;
647 }
648 
649 static unsigned int sbus_of_build_irq(struct device_node *dp,
650 				      unsigned int ino,
651 				      void *_data)
652 {
653 	unsigned long reg_base = (unsigned long) _data;
654 	const struct linux_prom_registers *regs;
655 	unsigned long imap, iclr;
656 	int sbus_slot = 0;
657 	int sbus_level = 0;
658 
659 	ino &= 0x3f;
660 
661 	regs = of_get_property(dp, "reg", NULL);
662 	if (regs)
663 		sbus_slot = regs->which_io;
664 
665 	if (ino < 0x20)
666 		ino += (sbus_slot * 8);
667 
668 	imap = sysio_irq_offsets[ino];
669 	if (imap == ((unsigned long)-1)) {
670 		prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n",
671 			    ino);
672 		prom_halt();
673 	}
674 	imap += reg_base;
675 
676 	/* SYSIO inconsistency.  For external SLOTS, we have to select
677 	 * the right ICLR register based upon the lower SBUS irq level
678 	 * bits.
679 	 */
680 	if (ino >= 0x20) {
681 		iclr = sysio_imap_to_iclr(imap);
682 	} else {
683 		sbus_level = ino & 0x7;
684 
685 		switch(sbus_slot) {
686 		case 0:
687 			iclr = reg_base + SYSIO_ICLR_SLOT0;
688 			break;
689 		case 1:
690 			iclr = reg_base + SYSIO_ICLR_SLOT1;
691 			break;
692 		case 2:
693 			iclr = reg_base + SYSIO_ICLR_SLOT2;
694 			break;
695 		default:
696 		case 3:
697 			iclr = reg_base + SYSIO_ICLR_SLOT3;
698 			break;
699 		}
700 
701 		iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
702 	}
703 	return build_irq(sbus_level, iclr, imap);
704 }
705 
706 static void __init sbus_irq_trans_init(struct device_node *dp)
707 {
708 	const struct linux_prom64_registers *regs;
709 
710 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
711 	dp->irq_trans->irq_build = sbus_of_build_irq;
712 
713 	regs = of_get_property(dp, "reg", NULL);
714 	dp->irq_trans->data = (void *) (unsigned long) regs->phys_addr;
715 }
716 #endif /* CONFIG_SBUS */
717 
718 
719 static unsigned int central_build_irq(struct device_node *dp,
720 				      unsigned int ino,
721 				      void *_data)
722 {
723 	struct device_node *central_dp = _data;
724 	struct platform_device *central_op = of_find_device_by_node(central_dp);
725 	struct resource *res;
726 	unsigned long imap, iclr;
727 	u32 tmp;
728 
729 	if (of_node_name_eq(dp, "eeprom")) {
730 		res = &central_op->resource[5];
731 	} else if (of_node_name_eq(dp, "zs")) {
732 		res = &central_op->resource[4];
733 	} else if (of_node_name_eq(dp, "clock-board")) {
734 		res = &central_op->resource[3];
735 	} else {
736 		return ino;
737 	}
738 
739 	imap = res->start + 0x00UL;
740 	iclr = res->start + 0x10UL;
741 
742 	/* Set the INO state to idle, and disable.  */
743 	upa_writel(0, iclr);
744 	upa_readl(iclr);
745 
746 	tmp = upa_readl(imap);
747 	tmp &= ~0x80000000;
748 	upa_writel(tmp, imap);
749 
750 	return build_irq(0, iclr, imap);
751 }
752 
753 static void __init central_irq_trans_init(struct device_node *dp)
754 {
755 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
756 	dp->irq_trans->irq_build = central_build_irq;
757 
758 	dp->irq_trans->data = dp;
759 }
760 
761 struct irq_trans {
762 	const char *name;
763 	void (*init)(struct device_node *);
764 };
765 
766 #ifdef CONFIG_PCI
767 static struct irq_trans __initdata pci_irq_trans_table[] = {
768 	{ "SUNW,sabre", sabre_irq_trans_init },
769 	{ "pci108e,a000", sabre_irq_trans_init },
770 	{ "pci108e,a001", sabre_irq_trans_init },
771 	{ "SUNW,psycho", psycho_irq_trans_init },
772 	{ "pci108e,8000", psycho_irq_trans_init },
773 	{ "SUNW,schizo", schizo_irq_trans_init },
774 	{ "pci108e,8001", schizo_irq_trans_init },
775 	{ "SUNW,schizo+", schizo_irq_trans_init },
776 	{ "pci108e,8002", schizo_irq_trans_init },
777 	{ "SUNW,tomatillo", tomatillo_irq_trans_init },
778 	{ "pci108e,a801", tomatillo_irq_trans_init },
779 	{ "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
780 	{ "pciex108e,80f0", fire_irq_trans_init },
781 };
782 #endif
783 
784 static unsigned int sun4v_vdev_irq_build(struct device_node *dp,
785 					 unsigned int devino,
786 					 void *_data)
787 {
788 	u32 devhandle = (u32) (unsigned long) _data;
789 
790 	return sun4v_build_irq(devhandle, devino);
791 }
792 
793 static void __init sun4v_vdev_irq_trans_init(struct device_node *dp)
794 {
795 	const struct linux_prom64_registers *regs;
796 
797 	dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
798 	dp->irq_trans->irq_build = sun4v_vdev_irq_build;
799 
800 	regs = of_get_property(dp, "reg", NULL);
801 	dp->irq_trans->data = (void *) (unsigned long)
802 		((regs->phys_addr >> 32UL) & 0x0fffffff);
803 }
804 
805 void __init irq_trans_init(struct device_node *dp)
806 {
807 #ifdef CONFIG_PCI
808 	const char *model;
809 	int i;
810 #endif
811 
812 #ifdef CONFIG_PCI
813 	model = of_get_property(dp, "model", NULL);
814 	if (!model)
815 		model = of_get_property(dp, "compatible", NULL);
816 	if (model) {
817 		for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
818 			struct irq_trans *t = &pci_irq_trans_table[i];
819 
820 			if (!strcmp(model, t->name)) {
821 				t->init(dp);
822 				return;
823 			}
824 		}
825 	}
826 #endif
827 #ifdef CONFIG_SBUS
828 	if (of_node_name_eq(dp, "sbus") ||
829 	    of_node_name_eq(dp, "sbi")) {
830 		sbus_irq_trans_init(dp);
831 		return;
832 	}
833 #endif
834 	if (of_node_name_eq(dp, "fhc") &&
835 	    of_node_name_eq(dp->parent, "central")) {
836 		central_irq_trans_init(dp);
837 		return;
838 	}
839 	if (of_node_name_eq(dp, "virtual-devices") ||
840 	    of_node_name_eq(dp, "niu")) {
841 		sun4v_vdev_irq_trans_init(dp);
842 		return;
843 	}
844 }
845