1 /*
2  * I/O SAPIC support.
3  *
4  * Copyright (C) 1999 Intel Corp.
5  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
6  * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
7  * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
8  *	David Mosberger-Tang <davidm@hpl.hp.com>
9  * Copyright (C) 1999 VA Linux Systems
10  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
11  *
12  * 00/04/19	D. Mosberger	Rewritten to mirror more closely the x86 I/O APIC code.
13  *				In particular, we now have separate handlers for edge
14  *				and level triggered interrupts.
15  * 00/10/27	Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector allocation
16  *				PCI to vector mapping, shared PCI interrupts.
17  * 00/10/27	D. Mosberger	Document things a bit more to make them more understandable.
18  *				Clean up much of the old IOSAPIC cruft.
19  * 01/07/27	J.I. Lee	PCI irq routing, Platform/Legacy interrupts and fixes for
20  *				ACPI S5(SoftOff) support.
21  * 02/01/23	J.I. Lee	iosapic pgm fixes for PCI irq routing from _PRT
22  * 02/01/07     E. Focht        <efocht@ess.nec.de> Redirectable interrupt vectors in
23  *                              iosapic_set_affinity(), initializations for
24  *                              /proc/irq/#/smp_affinity
25  * 02/04/02	P. Diefenbaugh	Cleaned up ACPI PCI IRQ routing.
26  * 02/04/18	J.I. Lee	bug fix in iosapic_init_pci_irq
27  * 02/04/30	J.I. Lee	bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping error
28  * 02/07/29	T. Kochi	Allocate interrupt vectors dynamically
29  * 02/08/04	T. Kochi	Cleaned up terminology (irq, global system interrupt, vector, etc.)
30  * 02/08/13	B. Helgaas	Support PCI segments
31  * 03/02/19	B. Helgaas	Make pcat_compat system-wide, not per-IOSAPIC.
32  *				Remove iosapic_address & gsi_base from external interfaces.
33  *				Rationalize __init/__devinit attributes.
34  */
35 /*
36  * Here is what the interrupt logic between a PCI device and the CPU looks like:
37  *
38  * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD).  The
39  *     device is uniquely identified by its segment--, bus--, and slot-number (the function
40  *     number does not matter here because all functions share the same interrupt
41  *     lines).
42  *
43  * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller.
44  *     Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level
45  *     triggered and use the same polarity).  Each interrupt line has a unique Global
46  *     System Interrupt (GSI) number which can be calculated as the sum of the controller's
47  *     base GSI number and the IOSAPIC pin number to which the line connects.
48  *
49  * (3) The IOSAPIC uses internal routing table entries (RTEs) to map the IOSAPIC pin
50  *     to the IA-64 interrupt vector.  This interrupt vector is then sent to the CPU.
51  *
52  * (4) The kernel recognizes an interrupt as an IRQ.  The IRQ interface
53  *     is an architecture-independent interrupt handling mechanism in
54  *     Linux.  An IRQ is a number, so we need a mapping between IRQ
55  *     numbers and IA-64 vectors.  The platform_irq_to_vector(irq) and
56  *     platform_local_vector_to_irq(vector) APIs can define platform-
57  *     specific mappings.
58  *
59  * To sum up, there are three levels of mappings involved:
60  *
61  *	PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
62  *
63  * Note: The term "IRQ" is loosely used everywhere in the Linux kernel
64  * to describe interrupts.  In this module, "IRQ" refers only to Linux
65  * IRQ numbers ("isa_irq" is an exception to this rule).
66  */
67 #include <linux/config.h>
68 
69 #include <linux/acpi.h>
70 #include <linux/init.h>
71 #include <linux/irq.h>
72 #include <linux/kernel.h>
73 #include <linux/pci.h>
74 #include <linux/smp.h>
75 #include <linux/smp_lock.h>
76 #include <linux/string.h>
77 
78 #include <asm/delay.h>
79 #include <asm/hw_irq.h>
80 #include <asm/io.h>
81 #include <asm/iosapic.h>
82 #include <asm/machvec.h>
83 #include <asm/processor.h>
84 #include <asm/ptrace.h>
85 #include <asm/system.h>
86 
87 
88 #undef DEBUG_INTERRUPT_ROUTING
89 
90 #ifdef DEBUG_INTERRUPT_ROUTING
91 #define DBG(fmt...)	printk(fmt)
92 #else
93 #define DBG(fmt...)
94 #endif
95 
96 static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
97 
98 /* PCI pin to GSI routing information.  This info typically comes from ACPI. */
99 
100 static struct {
101 	int num_routes;
102 	struct pci_vector_struct *route;
103 } pci_irq;
104 
105 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
106 
107 static struct iosapic_intr_info {
108 	char		*addr;		/* base address of IOSAPIC */
109 	unsigned int	gsi_base;	/* first GSI assigned to this IOSAPIC */
110 	char		rte_index;	/* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */
111 	unsigned char	dmode	: 3;	/* delivery mode (see iosapic.h) */
112 	unsigned char 	polarity: 1;	/* interrupt polarity (see iosapic.h) */
113 	unsigned char	trigger	: 1;	/* trigger mode (see iosapic.h) */
114 } iosapic_intr_info[IA64_NUM_VECTORS];
115 
116 static struct iosapic {
117 	char		*addr;		/* base address of IOSAPIC */
118 	unsigned int 	gsi_base;	/* first GSI assigned to this IOSAPIC */
119 	unsigned short 	num_rte;	/* number of RTE in this IOSAPIC */
120 } iosapic_lists[256];
121 
122 static int num_iosapic;
123 
124 static unsigned char pcat_compat __initdata;	/* 8259 compatibility flag */
125 
126 
127 /*
128  * Find an IOSAPIC associated with a GSI
129  */
130 static inline int
find_iosapic(unsigned int gsi)131 find_iosapic (unsigned int gsi)
132 {
133 	int i;
134 
135 	for (i = 0; i < num_iosapic; i++) {
136 		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
137 			return i;
138 	}
139 
140 	return -1;
141 }
142 
143 /*
144  * Translate GSI number to the corresponding IA-64 interrupt vector.  If no
145  * entry exists, return -1.
146  */
147 int
gsi_to_vector(unsigned int gsi)148 gsi_to_vector (unsigned int gsi)
149 {
150 	int vector;
151 
152 	for (vector = 0; vector < IA64_NUM_VECTORS; vector++)
153 		if (iosapic_intr_info[vector].gsi_base + iosapic_intr_info[vector].rte_index == gsi)
154 			return vector;
155 	return -1;
156 }
157 
158 static void
set_rte(unsigned int vector,unsigned int dest)159 set_rte (unsigned int vector, unsigned int dest)
160 {
161 	unsigned long pol, trigger, dmode;
162 	u32 low32, high32;
163 	char *addr;
164 	int rte_index;
165 	char redir;
166 
167 	DBG(KERN_DEBUG "IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
168 
169 	rte_index = iosapic_intr_info[vector].rte_index;
170 	if (rte_index < 0)
171 		return;		/* not an IOSAPIC interrupt */
172 
173 	addr    = iosapic_intr_info[vector].addr;
174 	pol     = iosapic_intr_info[vector].polarity;
175 	trigger = iosapic_intr_info[vector].trigger;
176 	dmode   = iosapic_intr_info[vector].dmode;
177 
178 	redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
179 #ifdef CONFIG_SMP
180 	{
181 		unsigned int irq;
182 
183 		for (irq = 0; irq < NR_IRQS; ++irq)
184 			if (irq_to_vector(irq) == vector) {
185 				set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
186 				break;
187 			}
188 	}
189 #endif
190 
191 	low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
192 		 (trigger << IOSAPIC_TRIGGER_SHIFT) |
193 		 (dmode << IOSAPIC_DELIVERY_SHIFT) |
194 		 vector);
195 
196 	/* dest contains both id and eid */
197 	high32 = (dest << IOSAPIC_DEST_SHIFT);
198 
199 	writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
200 	writel(high32, addr + IOSAPIC_WINDOW);
201 	writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
202 	writel(low32, addr + IOSAPIC_WINDOW);
203 }
204 
205 static void
nop(unsigned int vector)206 nop (unsigned int vector)
207 {
208 	/* do nothing... */
209 }
210 
211 static void
mask_irq(unsigned int irq)212 mask_irq (unsigned int irq)
213 {
214 	unsigned long flags;
215 	char *addr;
216 	u32 low32;
217 	int rte_index;
218 	ia64_vector vec = irq_to_vector(irq);
219 
220 	addr = iosapic_intr_info[vec].addr;
221 	rte_index = iosapic_intr_info[vec].rte_index;
222 
223 	if (rte_index < 0)
224 		return;			/* not an IOSAPIC interrupt! */
225 
226 	spin_lock_irqsave(&iosapic_lock, flags);
227 	{
228 		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
229 		low32 = readl(addr + IOSAPIC_WINDOW);
230 
231 		low32 |= (1 << IOSAPIC_MASK_SHIFT);    /* set only the mask bit */
232 		writel(low32, addr + IOSAPIC_WINDOW);
233 	}
234 	spin_unlock_irqrestore(&iosapic_lock, flags);
235 }
236 
237 static void
unmask_irq(unsigned int irq)238 unmask_irq (unsigned int irq)
239 {
240 	unsigned long flags;
241 	char *addr;
242 	u32 low32;
243 	int rte_index;
244 	ia64_vector vec = irq_to_vector(irq);
245 
246 	addr = iosapic_intr_info[vec].addr;
247 	rte_index = iosapic_intr_info[vec].rte_index;
248 	if (rte_index < 0)
249 		return;			/* not an IOSAPIC interrupt! */
250 
251 	spin_lock_irqsave(&iosapic_lock, flags);
252 	{
253 		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
254 		low32 = readl(addr + IOSAPIC_WINDOW);
255 
256 		low32 &= ~(1 << IOSAPIC_MASK_SHIFT);    /* clear only the mask bit */
257 		writel(low32, addr + IOSAPIC_WINDOW);
258 	}
259 	spin_unlock_irqrestore(&iosapic_lock, flags);
260 }
261 
262 
263 static void
iosapic_set_affinity(unsigned int irq,unsigned long mask)264 iosapic_set_affinity (unsigned int irq, unsigned long mask)
265 {
266 #ifdef CONFIG_SMP
267 	unsigned long flags;
268 	u32 high32, low32;
269 	int dest, rte_index;
270 	char *addr;
271 	int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
272 	ia64_vector vec;
273 
274 	irq &= (~IA64_IRQ_REDIRECTED);
275 	vec = irq_to_vector(irq);
276 
277 	mask &= (1UL << smp_num_cpus) - 1;
278 
279 	if (!mask || vec >= IA64_NUM_VECTORS)
280 		return;
281 
282 	dest = cpu_physical_id(ffz(~mask));
283 
284 	rte_index = iosapic_intr_info[vec].rte_index;
285 	addr = iosapic_intr_info[vec].addr;
286 
287 	if (rte_index < 0)
288 		return;			/* not an IOSAPIC interrupt */
289 
290 	set_irq_affinity_info(irq, dest, redir);
291 
292 	/* dest contains both id and eid */
293 	high32 = dest << IOSAPIC_DEST_SHIFT;
294 
295 	spin_lock_irqsave(&iosapic_lock, flags);
296 	{
297 		/* get current delivery mode by reading the low32 */
298 		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
299 		low32 = readl(addr + IOSAPIC_WINDOW);
300 
301 		low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT);
302 		if (redir)
303 		        /* change delivery mode to lowest priority */
304 			low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
305 		else
306 		        /* change delivery mode to fixed */
307 			low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
308 
309 		writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
310 		writel(high32, addr + IOSAPIC_WINDOW);
311 		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
312 		writel(low32, addr + IOSAPIC_WINDOW);
313 	}
314 	spin_unlock_irqrestore(&iosapic_lock, flags);
315 #endif
316 }
317 
318 /*
319  * Handlers for level-triggered interrupts.
320  */
321 
322 static unsigned int
iosapic_startup_level_irq(unsigned int irq)323 iosapic_startup_level_irq (unsigned int irq)
324 {
325 	unmask_irq(irq);
326 	return 0;
327 }
328 
329 static void
iosapic_end_level_irq(unsigned int irq)330 iosapic_end_level_irq (unsigned int irq)
331 {
332 	ia64_vector vec = irq_to_vector(irq);
333 
334 	writel(vec, iosapic_intr_info[vec].addr + IOSAPIC_EOI);
335 }
336 
337 #define iosapic_shutdown_level_irq	mask_irq
338 #define iosapic_enable_level_irq	unmask_irq
339 #define iosapic_disable_level_irq	mask_irq
340 #define iosapic_ack_level_irq		nop
341 
342 struct hw_interrupt_type irq_type_iosapic_level = {
343 	.typename =	"IO-SAPIC-level",
344 	.startup =	iosapic_startup_level_irq,
345 	.shutdown =	iosapic_shutdown_level_irq,
346 	.enable =	iosapic_enable_level_irq,
347 	.disable =	iosapic_disable_level_irq,
348 	.ack =		iosapic_ack_level_irq,
349 	.end =		iosapic_end_level_irq,
350 	.set_affinity =	iosapic_set_affinity
351 };
352 
353 /*
354  * Handlers for edge-triggered interrupts.
355  */
356 
357 static unsigned int
iosapic_startup_edge_irq(unsigned int irq)358 iosapic_startup_edge_irq (unsigned int irq)
359 {
360 	unmask_irq(irq);
361 	/*
362 	 * IOSAPIC simply drops interrupts pended while the
363 	 * corresponding pin was masked, so we can't know if an
364 	 * interrupt is pending already.  Let's hope not...
365 	 */
366 	return 0;
367 }
368 
369 static void
iosapic_ack_edge_irq(unsigned int irq)370 iosapic_ack_edge_irq (unsigned int irq)
371 {
372 	irq_desc_t *idesc = irq_desc(irq);
373 	/*
374 	 * Once we have recorded IRQ_PENDING already, we can mask the
375 	 * interrupt for real. This prevents IRQ storms from unhandled
376 	 * devices.
377 	 */
378 	if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED))
379 		mask_irq(irq);
380 }
381 
382 #define iosapic_enable_edge_irq		unmask_irq
383 #define iosapic_disable_edge_irq	nop
384 #define iosapic_end_edge_irq		nop
385 
386 struct hw_interrupt_type irq_type_iosapic_edge = {
387 	.typename =	"IO-SAPIC-edge",
388 	.startup =	iosapic_startup_edge_irq,
389 	.shutdown =	iosapic_disable_edge_irq,
390 	.enable =	iosapic_enable_edge_irq,
391 	.disable =	iosapic_disable_edge_irq,
392 	.ack =		iosapic_ack_edge_irq,
393 	.end =		iosapic_end_edge_irq,
394 	.set_affinity =	iosapic_set_affinity
395 };
396 
397 unsigned int
iosapic_version(char * addr)398 iosapic_version (char *addr)
399 {
400 	/*
401 	 * IOSAPIC Version Register return 32 bit structure like:
402 	 * {
403 	 *	unsigned int version   : 8;
404 	 *	unsigned int reserved1 : 8;
405 	 *	unsigned int max_redir : 8;
406 	 *	unsigned int reserved2 : 8;
407 	 * }
408 	 */
409 	writel(IOSAPIC_VERSION, addr + IOSAPIC_REG_SELECT);
410 	return readl(IOSAPIC_WINDOW + addr);
411 }
412 
413 /*
414  * if the given vector is already owned by other,
415  *  assign a new vector for the other and make the vector available
416  */
417 static void __init
iosapic_reassign_vector(int vector)418 iosapic_reassign_vector (int vector)
419 {
420 	int new_vector;
421 
422 	if (iosapic_intr_info[vector].rte_index >= 0 || iosapic_intr_info[vector].addr
423 	    || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode
424 	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger)
425 	{
426 		new_vector = ia64_alloc_vector();
427 		printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
428 		memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
429 		       sizeof(struct iosapic_intr_info));
430 		memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
431 		iosapic_intr_info[vector].rte_index = -1;
432 	}
433 }
434 
435 static void
register_intr(unsigned int gsi,int vector,unsigned char delivery,unsigned long polarity,unsigned long trigger)436 register_intr (unsigned int gsi, int vector, unsigned char delivery,
437 	       unsigned long polarity, unsigned long trigger)
438 {
439 	irq_desc_t *idesc;
440 	struct hw_interrupt_type *irq_type;
441 	int rte_index;
442 	int index;
443 	unsigned long gsi_base;
444 	char *iosapic_address;
445 
446 	index = find_iosapic(gsi);
447 	if (index < 0) {
448 		printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi);
449 		return;
450 	}
451 
452 	iosapic_address = iosapic_lists[index].addr;
453 	gsi_base = iosapic_lists[index].gsi_base;
454 
455 	rte_index = gsi - gsi_base;
456 	iosapic_intr_info[vector].rte_index = rte_index;
457 	iosapic_intr_info[vector].polarity = polarity;
458 	iosapic_intr_info[vector].dmode    = delivery;
459 	iosapic_intr_info[vector].addr     = iosapic_address;
460 	iosapic_intr_info[vector].gsi_base = gsi_base;
461 	iosapic_intr_info[vector].trigger  = trigger;
462 
463 	if (trigger == IOSAPIC_EDGE)
464 		irq_type = &irq_type_iosapic_edge;
465 	else
466 		irq_type = &irq_type_iosapic_level;
467 
468 	idesc = irq_desc(vector);
469 	if (idesc->handler != irq_type) {
470 		if (idesc->handler != &no_irq_type)
471 			printk(KERN_WARNING "%s: changing vector %d from %s to %s\n",
472 			       __FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
473 		idesc->handler = irq_type;
474 	}
475 }
476 
477 /*
478  * ACPI can describe IOSAPIC interrupts via static tables and namespace
479  * methods.  This provides an interface to register those interrupts and
480  * program the IOSAPIC RTE.
481  */
482 int
iosapic_register_intr(unsigned int gsi,unsigned long polarity,unsigned long trigger)483 iosapic_register_intr (unsigned int gsi,
484 		       unsigned long polarity, unsigned long trigger)
485 {
486 	int vector;
487 	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
488 
489 	vector = gsi_to_vector(gsi);
490 	if (vector < 0)
491 		vector = ia64_alloc_vector();
492 
493 	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
494 		      polarity, trigger);
495 
496 	printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
497 	       gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
498 	       (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
499 
500 	/* program the IOSAPIC routing table */
501 	set_rte(vector, dest);
502 	return vector;
503 }
504 
505 /*
506  * ACPI calls this when it finds an entry for a platform interrupt.
507  * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
508  */
509 int __init
iosapic_register_platform_intr(u32 int_type,unsigned int gsi,int iosapic_vector,u16 eid,u16 id,unsigned long polarity,unsigned long trigger)510 iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
511 				int iosapic_vector, u16 eid, u16 id,
512 				unsigned long polarity, unsigned long trigger)
513 {
514 	unsigned char delivery;
515 	int vector;
516 	unsigned int dest = ((id << 8) | eid) & 0xffff;
517 
518 	switch (int_type) {
519 	      case ACPI_INTERRUPT_PMI:
520 		vector = iosapic_vector;
521 		/*
522 		 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
523 		 * we need to make sure the vector is available
524 		 */
525 		iosapic_reassign_vector(vector);
526 		delivery = IOSAPIC_PMI;
527 		break;
528 	      case ACPI_INTERRUPT_INIT:
529 		vector = ia64_alloc_vector();
530 		delivery = IOSAPIC_INIT;
531 		break;
532 	      case ACPI_INTERRUPT_CPEI:
533 		vector = IA64_CPE_VECTOR;
534 		delivery = IOSAPIC_LOWEST_PRIORITY;
535 		break;
536 	      default:
537 		printk(KERN_ERR "%s: invalid interrupt type (%d)\n", __FUNCTION__,
538 			int_type);
539 		return -1;
540 	}
541 
542 	register_intr(gsi, vector, delivery, polarity, trigger);
543 
544 	printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
545 	       int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
546 	       (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
547 
548 	/* program the IOSAPIC routing table */
549 	set_rte(vector, dest);
550 	return vector;
551 }
552 
553 
554 /*
555  * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
556  * Note that the gsi_base and IOSAPIC address must be set in iosapic_init().
557  */
558 void __init
iosapic_override_isa_irq(unsigned int isa_irq,unsigned int gsi,unsigned long polarity,unsigned long trigger)559 iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
560 			  unsigned long polarity, unsigned long trigger)
561 {
562 	int vector;
563 	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
564 
565 	vector = isa_irq_to_vector(isa_irq);
566 
567 	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
568 
569 	DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
570 	    isa_irq, gsi,
571 	    polarity == IOSAPIC_POL_HIGH ? "high" : "low", trigger == IOSAPIC_EDGE ? "edge" : "level",
572 	    dest, vector);
573 
574 	/* program the IOSAPIC routing table */
575 	set_rte(vector, dest);
576 }
577 
578 /*
579  * Map PCI pin to the corresponding GSI.
580  * If no such mapping exists, return -1.
581  */
582 static int
pci_pin_to_gsi(int segment,int bus,int slot,int pci_pin,unsigned int * gsi)583 pci_pin_to_gsi (int segment, int bus, int slot, int pci_pin, unsigned int *gsi)
584 {
585 	struct pci_vector_struct *r;
586 
587 	for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; r++)
588 		if (r->segment == segment && r->bus == bus &&
589 		    (r->pci_id >> 16) == slot && r->pin == pci_pin) {
590 			*gsi = r->irq;
591 			return 0;
592 		}
593 
594 	return -1;
595 }
596 
597 /*
598  * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
599  * try to allocate a new vector.  If it fails, return -1.
600  */
601 static int
pci_pin_to_vector(int segment,int bus,int slot,int pci_pin)602 pci_pin_to_vector (int segment, int bus, int slot, int pci_pin)
603 {
604 	int vector;
605 	unsigned int gsi;
606 
607 	if (pci_pin_to_gsi(segment, bus, slot, pci_pin, &gsi) < 0) {
608 		printk(KERN_ERR "PCI: no interrupt route for %02x:%02x:%02x pin %c\n",
609 			segment, bus, slot, 'A' + pci_pin);
610 		return -1;
611 	}
612 
613 	vector = gsi_to_vector(gsi);
614 
615 	if (vector < 0) {
616 		/* allocate a vector for this interrupt line */
617 		if (pcat_compat && (gsi < 16))
618 			vector = isa_irq_to_vector(gsi);
619 		else {
620 			/* new GSI; allocate a vector for it */
621 			vector = ia64_alloc_vector();
622 		}
623 
624 		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
625 
626 		DBG("PCI: (%02x:%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n",
627 		    segment, bus, slot, 'A' + pci_pin, gsi, vector);
628 	}
629 
630 	return vector;
631 }
632 
633 void __init
iosapic_system_init(int system_pcat_compat)634 iosapic_system_init (int system_pcat_compat)
635 {
636 	int vector;
637 
638 	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
639 		iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
640 
641 	pcat_compat = system_pcat_compat;
642 	if (pcat_compat) {
643 		/*
644 		 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
645 		 * enabled.
646 		 */
647 		printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
648 		outb(0xff, 0xA1);
649 		outb(0xff, 0x21);
650 	}
651 }
652 
653 void __init
iosapic_init(unsigned long phys_addr,unsigned int gsi_base)654 iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
655 {
656 	int num_rte;
657 	unsigned int isa_irq, ver;
658 	char *addr;
659 
660 	addr = ioremap(phys_addr, 0);
661 	ver = iosapic_version(addr);
662 
663 	/*
664 	 * The MAX_REDIR register holds the highest input pin
665 	 * number (starting from 0).
666 	 * We add 1 so that we can use it for number of pins (= RTEs)
667 	 */
668 	num_rte = ((ver >> 16) & 0xff) + 1;
669 
670 	iosapic_lists[num_iosapic].addr = addr;
671 	iosapic_lists[num_iosapic].gsi_base = gsi_base;
672 	iosapic_lists[num_iosapic].num_rte = num_rte;
673 	num_iosapic++;
674 
675 	printk(KERN_INFO "  IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
676 	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1);
677 
678 	if ((gsi_base == 0) && pcat_compat) {
679 
680 		/*
681 		 * Map the legacy ISA devices into the IOSAPIC data.  Some of these may
682 		 * get reprogrammed later on with data from the ACPI Interrupt Source
683 		 * Override table.
684 		 */
685 		for (isa_irq = 0; isa_irq < 16; ++isa_irq)
686 			iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
687 	}
688 }
689 
690 
691 /*
692  * Set allocated interrupt vector to dev->irq and
693  * program IOSAPIC to deliver interrupts
694  */
695 void
iosapic_fixup_pci_interrupt(struct pci_dev * dev)696 iosapic_fixup_pci_interrupt (struct pci_dev *dev)
697 {
698 	int segment;
699 	unsigned char pci_pin;
700 	int vector;
701 	unsigned int dest;
702 	struct hw_interrupt_type *irq_type;
703 	irq_desc_t *idesc;
704 
705 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pci_pin);
706 	if (pci_pin) {
707 		pci_pin--; /* interrupt pins are numberd starting from 1 */
708 
709 		segment = PCI_SEGMENT(dev);
710 		vector = pci_pin_to_vector(segment, dev->bus->number, PCI_SLOT(dev->devfn), pci_pin);
711 
712 		if (vector < 0 && dev->bus->parent) {
713 			/* go back to the bridge */
714 			struct pci_dev *bridge = dev->bus->self;
715 
716 			if (bridge) {
717 				/* allow for multiple bridges on an adapter */
718 				do {
719 					/* do the bridge swizzle... */
720 					pci_pin = (pci_pin + PCI_SLOT(dev->devfn)) % 4;
721 					vector = pci_pin_to_vector(segment,
722 								   bridge->bus->number,
723 								   PCI_SLOT(bridge->devfn),
724 								   pci_pin);
725 				} while (vector < 0 && (bridge = bridge->bus->self));
726 			}
727 			if (vector >= 0)
728 				printk(KERN_WARNING
729 				       "PCI: using PPB (%s INT%c) to get vector %d\n",
730 				       dev->slot_name, 'A' + pci_pin,
731 				       vector);
732 			else
733 				printk(KERN_WARNING
734 				       "PCI: Couldn't map irq for (%s INT%c)\n",
735 				       dev->slot_name, 'A' + pci_pin);
736 		}
737 
738 		if (vector >= 0) {
739 			dev->irq = vector;
740 
741 			irq_type = &irq_type_iosapic_level;
742 			idesc = irq_desc(vector);
743 			if (idesc->handler != irq_type) {
744 				if (idesc->handler != &no_irq_type)
745 					printk(KERN_INFO "%s: changing vector %d from %s to %s\n",
746 					       __FUNCTION__, vector,
747 					       idesc->handler->typename,
748 					       irq_type->typename);
749 				idesc->handler = irq_type;
750 			}
751 #ifdef CONFIG_SMP
752 			/*
753 			 * For platforms that do not support interrupt redirect
754 			 * via the XTP interface, we can round-robin the PCI
755 			 * device interrupts to the processors
756 			 */
757 			if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
758 				static int cpu_index = 0;
759 
760 				dest = cpu_physical_id(cpu_index) & 0xffff;
761 
762 				cpu_index++;
763 				if (cpu_index >= smp_num_cpus)
764 					cpu_index = 0;
765 			} else {
766 				/*
767 				 * Direct the interrupt vector to the current cpu,
768 				 * platform redirection will distribute them.
769 				 */
770 				dest = (ia64_get_lid() >> 16) & 0xffff;
771 			}
772 #else
773 			/* direct the interrupt vector to the running cpu id */
774 			dest = (ia64_get_lid() >> 16) & 0xffff;
775 #endif
776 
777 			printk(KERN_INFO "PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
778 			       dev->slot_name, 'A' + pci_pin, dest, vector);
779 			set_rte(vector, dest);
780 		}
781 	}
782 }
783 
784 
785 void
iosapic_pci_fixup(int phase)786 iosapic_pci_fixup (int phase)
787 {
788 	struct	pci_dev	*dev;
789 
790 	if (phase == 0) {
791 		if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) {
792 			printk(KERN_ERR "%s: acpi_get_prt failed\n", __FUNCTION__);
793 		}
794 		return;
795 	}
796 
797 	if (phase != 1)
798 		return;
799 
800 	pci_for_each_dev(dev) {
801 		/* fixup dev->irq and program IOSAPIC */
802 		iosapic_fixup_pci_interrupt(dev);
803 
804 		/*
805 		 * Nothing to fixup
806 		 * Fix out-of-range IRQ numbers
807 		 */
808 		if (dev->irq >= IA64_NUM_VECTORS)
809 			dev->irq = 15;	/* Spurious interrupts */
810 	}
811 }
812