2 ** I/O Sapic Driver - PCI interrupt line support
4 ** (c) Copyright 1999 Grant Grundler
5 ** (c) Copyright 1999 Hewlett-Packard Company
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; either version 2 of the License, or
10 ** (at your option) any later version.
12 ** The I/O sapic driver manages the Interrupt Redirection Table which is
13 ** the control logic to convert PCI line based interrupts into a Message
14 ** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
18 ** HPA Hard Physical Address (aka MMIO address)
19 ** IRQ Interrupt ReQuest. Implies Line based interrupt.
20 ** IRT Interrupt Routing Table (provided by PAT firmware)
21 ** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
22 ** table which is implemented in I/O SAPIC.
23 ** ISR Interrupt Service Routine. aka Interrupt handler.
24 ** MSI Message Signaled Interrupt. PCI 2.2 functionality.
25 ** aka Transaction Based Interrupt (or TBI).
26 ** PA Precision Architecture. HP's RISC architecture.
27 ** RISC Reduced Instruction Set Computer.
30 ** What's a Message Signalled Interrupt?
31 ** -------------------------------------
32 ** MSI is a write transaction which targets a processor and is similar
33 ** to a processor write to memory or MMIO. MSIs can be generated by I/O
34 ** devices as well as processors and require *architecture* to work.
36 ** PA only supports MSI. So I/O subsystems must either natively generate
37 ** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
38 ** (e.g. PCI and EISA). IA64 supports MSIs via a "local SAPIC" which
39 ** acts on behalf of a processor.
41 ** MSI allows any I/O device to interrupt any processor. This makes
42 ** load balancing of the interrupt processing possible on an SMP platform.
43 ** Interrupts are also ordered WRT to DMA data. It's possible on I/O
44 ** coherent systems to completely eliminate PIO reads from the interrupt
45 ** path. The device and driver must be designed and implemented to
46 ** guarantee all DMA has been issued (issues about atomicity here)
47 ** before the MSI is issued. I/O status can then safely be read from
48 ** DMA'd data by the ISR.
53 ** PA-RISC platforms have two fundementally different types of firmware.
54 ** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
55 ** and BARs similar to a traditional PC BIOS.
56 ** The newer "PAT" firmware supports PDC calls which return tables.
57 ** PAT firmware only initializes PCI Console and Boot interface.
58 ** With these tables, the OS can progam all other PCI devices.
60 ** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
61 ** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
62 ** input line. If the IRT is not available, this driver assumes
63 ** INTERRUPT_LINE register has been programmed by firmware. The latter
64 ** case also means online addition of PCI cards can NOT be supported
65 ** even if HW support is present.
67 ** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
68 ** Routing Table for the entire platform.
70 ** Where's the iosapic?
71 ** --------------------
72 ** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
73 ** it's integrated as part of the PCI bus adapter, "lba". So no bus walk
74 ** will discover I/O Sapic. I/O Sapic driver learns about each device
75 ** when lba driver advertises the presence of the I/O sapic by calling
76 ** iosapic_register().
81 ** The data passed to iosapic_interrupt() is per IRQ line.
82 ** Each IRQ line will get one txn_addr/data pair. Thus each IRQ region,
83 ** will have several txn_addr/data pairs (up to 7 for current I/O SAPIC
84 ** implementations). The IRQ region "sysdata" will NOT be directly passed
85 ** to the interrupt handler like GSCtoPCI (dino.c).
87 ** iosapic interrupt handler will NOT call do_irq_mask().
88 ** It doesn't need to read a bit mask to determine which IRQ line was pulled
89 ** since it already knows based on vector_info passed to iosapic_interrupt().
91 ** One IRQ number represents both an IRQ line and a driver ISR.
92 ** The I/O sapic driver can't manage shared IRQ lines because
93 ** additional data besides the IRQ number must be passed via
94 ** irq_region_ops. do_irq() and request_irq() must manage
95 ** a sharing a bit in the mask.
97 ** iosapic_interrupt() replaces do_irq_mask() and calls do_irq().
98 ** Which IRQ line was asserted is already known since each
99 ** line has unique data associated with it. We could omit
100 ** iosapic_interrupt() from the calling path if it did NOT need
101 ** to write EOI. For unshared lines, it really doesn't.
103 ** Unfortunately, can't optimize out EOI if IRQ line isn't "shared".
104 ** N-class console "device" and some sort of heartbeat actually share
105 ** one line though only one driver is registered...<sigh>...this was
106 ** true for HP-UX at least. May not be true for parisc-linux.
109 ** Overview of exported iosapic functions
110 ** --------------------------------------
111 ** (caveat: code isn't finished yet - this is just the plan)
114 ** o initialize globals (lock, etc)
115 ** o try to read IRT. Presence of IRT determines if this is
116 ** a PAT platform or not.
118 ** iosapic_register():
119 ** o create iosapic_info instance data structure
120 ** o allocate vector_info array for this iosapic
121 ** o initialize vector_info - read corresponding IRdT?
123 ** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
124 ** o intr_pin = read cfg (INTERRUPT_PIN);
125 ** o if (device under PCI-PCI bridge)
126 ** translate slot/pin
128 ** iosapic_fixup_irq:
129 ** o if PAT platform (IRT present)
130 ** intr_pin = iosapic_xlate_pin(isi,pcidev):
131 ** intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
132 ** save IRT entry into vector_info later
133 ** write cfg INTERRUPT_LINE (with intr_line)?
135 ** intr_line = pcidev->irq
136 ** IRT pointer = NULL
138 ** o locate vector_info (needs: isi, intr_line)
139 ** o allocate processor "irq" and get txn_addr/data
140 ** o request_irq(processor_irq, iosapic_interrupt, vector_info,...)
141 ** o pcidev->irq = isi->isi_region...base + intr_line;
143 ** iosapic_interrupt:
144 ** o call do_irq(vector->isi->irq_region, vector->irq_line, regs)
145 ** o assume level triggered and write EOI
147 ** iosapic_enable_irq:
148 ** o clear any pending IRQ on that line
149 ** o enable IRdT - call enable_irq(vector[line]->processor_irq)
150 ** o write EOI in case line is already asserted.
152 ** iosapic_disable_irq:
153 ** o disable IRdT - call disable_irq(vector[line]->processor_irq)
155 ** FIXME: mask/unmask
159 /* FIXME: determine which include files are really needed */
160 #include <linux/types.h>
161 #include <linux/kernel.h>
162 #include <linux/spinlock.h>
163 #include <linux/pci.h> /* pci cfg accessor functions */
164 #include <linux/init.h>
165 #include <linux/slab.h>
166 #include <linux/smp_lock.h>
167 #include <linux/interrupt.h> /* irqaction */
168 #include <linux/irq.h> /* irq_region support */
170 #include <asm/byteorder.h> /* get in-line asm for swab */
172 #include <asm/pdcpat.h>
173 #include <asm/page.h>
174 #include <asm/segment.h>
175 #include <asm/system.h>
176 #include <asm/io.h> /* read/write functions */
177 #ifdef CONFIG_SUPERIO
178 #include <asm/superio.h>
181 #include <asm/iosapic.h>
182 #include "./iosapic_private.h"
184 #define MODULE_NAME "iosapic"
186 /* "local" compile flags */
187 #undef PCI_BRIDGE_FUNCS
189 #undef DEBUG_IOSAPIC_IRT
193 static char assert_buf
[128];
196 assert_failed (char *a
, char *f
, int l
)
199 "ASSERT(%s) failed!\nline %d in %s\n",
200 a
, /* assertion text */
208 #define ASSERT(EX) { if (!(EX)) assert_failed(# EX, __FILE__, __LINE__); }
210 #define DBG(x...) printk(x)
212 #else /* DEBUG_IOSAPIC */
218 #endif /* DEBUG_IOSAPIC */
220 #ifdef DEBUG_IOSAPIC_IRT
221 #define DBG_IRT(x...) printk(x)
223 #define DBG_IRT(x...)
227 #define IOSAPIC_REG_SELECT 0x00
228 #define IOSAPIC_REG_WINDOW 0x10
229 #define IOSAPIC_REG_EOI 0x40
231 #define IOSAPIC_REG_VERSION 0x1
233 #define IOSAPIC_IRDT_ENTRY(idx) (0x10+(idx)*2)
234 #define IOSAPIC_IRDT_ENTRY_HI(idx) (0x11+(idx)*2)
236 static inline unsigned int iosapic_read(unsigned long iosapic
, unsigned int reg
)
238 writel(reg
, iosapic
+ IOSAPIC_REG_SELECT
);
239 return readl(iosapic
+ IOSAPIC_REG_WINDOW
);
242 static inline void iosapic_write(unsigned long iosapic
, unsigned int reg
, u32 val
)
244 writel(reg
, iosapic
+ IOSAPIC_REG_SELECT
);
245 writel(val
, iosapic
+ IOSAPIC_REG_WINDOW
);
249 ** GFP_KERNEL includes __GFP_WAIT flag and that may not
250 ** be acceptable. Since this is boot time, we shouldn't have
251 ** to wait ever and this code should (will?) never get called
252 ** from the interrrupt context.
254 #define IOSAPIC_KALLOC(a_type, cnt) \
255 (a_type *) kmalloc(sizeof(a_type)*(cnt), GFP_KERNEL)
256 #define IOSAPIC_FREE(addr, f_type, cnt) kfree((void *)addr)
259 #define IOSAPIC_LOCK(lck) spin_lock_irqsave(lck, irqflags)
260 #define IOSAPIC_UNLOCK(lck) spin_unlock_irqrestore(lck, irqflags)
263 #define IOSAPIC_VERSION_MASK 0x000000ff
264 #define IOSAPIC_VERSION(ver) ((int) (ver & IOSAPIC_VERSION_MASK))
266 #define IOSAPIC_MAX_ENTRY_MASK 0x00ff0000
267 #define IOSAPIC_MAX_ENTRY_SHIFT 0x10
268 #define IOSAPIC_IRDT_MAX_ENTRY(ver) \
269 (int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
271 /* bits in the "low" I/O Sapic IRdT entry */
272 #define IOSAPIC_IRDT_ENABLE 0x10000
273 #define IOSAPIC_IRDT_PO_LOW 0x02000
274 #define IOSAPIC_IRDT_LEVEL_TRIG 0x08000
275 #define IOSAPIC_IRDT_MODE_LPRI 0x00100
277 /* bits in the "high" I/O Sapic IRdT entry */
278 #define IOSAPIC_IRDT_ID_EID_SHIFT 0x10
281 static struct iosapic_info
*iosapic_list
;
282 static spinlock_t iosapic_lock
;
283 static int iosapic_count
;
287 ** REVISIT: future platforms may have more than one IRT.
288 ** If so, the following three fields form a structure which
289 ** then be linked into a list. Names are chosen to make searching
290 ** for them easy - not necessarily accurate (eg "cell").
292 ** Alternative: iosapic_info could point to the IRT it's in.
293 ** iosapic_register() could search a list of IRT's.
295 static struct irt_entry
*irt_cell
;
296 static size_t irt_num_entry
;
303 ** The "Get PCI INT Routing Table Size" option returns the number of
304 ** entries in the PCI interrupt routing table for the cell specified
305 ** in the cell_number argument. The cell number must be for a cell
306 ** within the caller's protection domain.
308 ** The "Get PCI INT Routing Table" option returns, for the cell
309 ** specified in the cell_number argument, the PCI interrupt routing
310 ** table in the caller allocated memory pointed to by mem_addr.
311 ** We assume the IRT only contains entries for I/O SAPIC and
312 ** calculate the size based on the size of I/O sapic entries.
314 ** The PCI interrupt routing table entry format is derived from the
315 ** IA64 SAL Specification 2.4. The PCI interrupt routing table defines
316 ** the routing of PCI interrupt signals between the PCI device output
317 ** "pins" and the IO SAPICs' input "lines" (including core I/O PCI
318 ** devices). This table does NOT include information for devices/slots
319 ** behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
320 ** for the architected method of routing of IRQ's behind PPB's.
324 static int __init
/* return number of entries as success/fail flag */
325 iosapic_load_irt(unsigned long cell_num
, struct irt_entry
**irt
)
327 long status
; /* PDC return value status */
328 struct irt_entry
*table
; /* start of interrupt routing tbl */
329 unsigned long num_entries
= 0UL;
335 /* Use pat pdc routine to get interrupt routing table size */
336 DBG("calling get_irt_size (cell %ld)\n", cell_num
);
337 status
= pdc_pat_get_irt_size(&num_entries
, cell_num
);
338 DBG("get_irt_size: %ld\n", status
);
340 ASSERT(status
== PDC_OK
);
342 /* save the number of entries in the table */
343 ASSERT(0UL != num_entries
);
346 ** allocate memory for interrupt routing table
347 ** This interface isn't really right. We are assuming
348 ** the contents of the table are exclusively
349 ** for I/O sapic devices.
351 table
= IOSAPIC_KALLOC(struct irt_entry
, num_entries
);
353 printk(KERN_WARNING MODULE_NAME
": read_irt : can not alloc mem for IRT\n");
357 /* get PCI INT routing table */
358 status
= pdc_pat_get_irt(table
, cell_num
);
359 DBG("pdc_pat_get_irt: %ld\n", status
);
360 ASSERT(status
== PDC_OK
);
363 ** C3000/J5000 (and similar) platforms with Sprockets PDC
364 ** will return exactly one IRT for all iosapics.
365 ** So if we have one, don't need to get it again.
367 if (NULL
!= irt_cell
)
370 /* Should be using the Elroy's HPA, but it's ignored anyway */
371 status
= pdc_pci_irt_size(&num_entries
, 0);
372 DBG("pdc_pci_irt_size: %ld\n", status
);
374 if (PDC_OK
!= status
) {
375 /* Not a "legacy" system with I/O SAPIC either */
379 ASSERT(0UL != num_entries
);
381 table
= IOSAPIC_KALLOC(struct irt_entry
, num_entries
);
383 printk(KERN_WARNING MODULE_NAME
": read_irt : can not alloc mem for IRT\n");
387 /* HPA ignored by this call too. */
388 status
= pdc_pci_irt(num_entries
, 0, table
);
389 ASSERT(PDC_OK
== status
);
392 /* return interrupt table address */
395 #ifdef DEBUG_IOSAPIC_IRT
397 struct irt_entry
*p
= table
;
400 printk(MODULE_NAME
" Interrupt Routing Table (cell %ld)\n", cell_num
);
401 printk(MODULE_NAME
" start = 0x%p num_entries %ld entry_size %d\n",
404 (int) sizeof(struct irt_entry
));
406 for (i
= 0 ; i
< num_entries
; i
++, p
++) {
407 printk(MODULE_NAME
" %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
408 p
->entry_type
, p
->entry_length
, p
->interrupt_type
,
409 p
->polarity_trigger
, p
->src_bus_irq_devno
, p
->src_bus_id
,
410 p
->src_seg_id
, p
->dest_iosapic_intin
,
416 #endif /* DEBUG_IOSAPIC_IRT */
426 unsigned long cell
= 0;
428 /* init global data */
429 iosapic_lock
= SPIN_LOCK_UNLOCKED
;
430 iosapic_list
= (struct iosapic_info
*) NULL
;
433 DBG("iosapic_init()\n");
438 struct pdc_pat_cell_num cell_info
;
440 status
= pdc_pat_cell_get_number(&cell_info
);
441 if (status
== PDC_OK
) {
442 cell
= cell_info
.cell_num
;
448 ** get IRT for this cell.
450 irt_num_entry
= iosapic_load_irt(cell
, &irt_cell
);
451 if (0 == irt_num_entry
)
452 irt_cell
= NULL
; /* old PDC w/o iosapic */
457 ** Return the IRT entry in case we need to look something else up.
459 static struct irt_entry
*
460 irt_find_irqline(struct iosapic_info
*isi
, u8 slot
, u8 intr_pin
)
462 struct irt_entry
*i
= irt_cell
;
463 int cnt
; /* track how many entries we've looked at */
464 u8 irq_devno
= (slot
<< IRT_DEV_SHIFT
) | (intr_pin
-1);
466 DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot
, intr_pin
);
468 for (cnt
=0; cnt
< irt_num_entry
; cnt
++, i
++) {
471 ** Validate: entry_type, entry_length, interrupt_type
473 ** Difference between validate vs compare is the former
474 ** should print debug info and is not expected to "fail"
475 ** on current platforms.
477 if (i
->entry_type
!= IRT_IOSAPIC_TYPE
) {
478 DBG_IRT(KERN_WARNING MODULE_NAME
":find_irqline(0x%p): skipping entry %d type %d\n", i
, cnt
, i
->entry_type
);
482 if (i
->entry_length
!= IRT_IOSAPIC_LENGTH
) {
483 DBG_IRT(KERN_WARNING MODULE_NAME
":find_irqline(0x%p): skipping entry %d length %d\n", i
, cnt
, i
->entry_length
);
487 if (i
->interrupt_type
!= IRT_VECTORED_INTR
) {
488 DBG_IRT(KERN_WARNING MODULE_NAME
":find_irqline(0x%p): skipping entry %d interrupt_type %d\n", i
, cnt
, i
->interrupt_type
);
493 ** Compare: dest_iosapic_addr, src_bus_irq_devno
495 if (i
->dest_iosapic_addr
!= (u64
) ((long) isi
->isi_hpa
))
498 if ((i
->src_bus_irq_devno
& IRT_IRQ_DEVNO_MASK
) != irq_devno
)
502 ** Ignore: src_bus_id and rc_seg_id correlate with
503 ** iosapic_info->isi_hpa on HP platforms.
504 ** If needed, pass in "PFA" (aka config space addr)
512 printk(KERN_WARNING MODULE_NAME
": 0x%lx : no IRT entry for slot %d, pin %d\n",
513 isi
->isi_hpa
, slot
, intr_pin
);
519 ** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
520 ** Legacy PDC already does this translation for us and stores it in INTR_LINE.
522 ** PAT PDC needs to basically do what legacy PDC does:
524 ** o adjust PIN in case device is "behind" a PPB
525 ** (eg 4-port 100BT and SCSI/LAN "Combo Card")
526 ** o convert slot/pin to I/O SAPIC input line.
528 ** HP platforms only support:
529 ** o one level of skewing for any number of PPBs
530 ** o only support PCI-PCI Bridges.
532 static struct irt_entry
*
533 iosapic_xlate_pin(struct iosapic_info
*isi
, struct pci_dev
*pcidev
)
535 u8 intr_pin
, intr_slot
;
537 pci_read_config_byte(pcidev
, PCI_INTERRUPT_PIN
, &intr_pin
);
539 DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n",
540 PCI_SLOT(pcidev
->devfn
), intr_pin
);
543 /* The device does NOT support/use IRQ lines. */
547 /* Check if pcidev behind a PPB */
548 if (NULL
!= pcidev
->bus
->self
) {
549 /* Convert pcidev INTR_PIN into something we
550 ** can lookup in the IRT.
552 #ifdef PCI_BRIDGE_FUNCS
556 ** call implementation specific translation function
557 ** This is architecturally "cleaner". HP-UX doesn't
558 ** support other secondary bus types (eg. E/ISA) directly.
559 ** May be needed for other processor (eg IA64) architectures
560 ** or by some ambitous soul who wants to watch TV.
562 if (pci_bridge_funcs
->xlate_intr_line
) {
563 intr_pin
= pci_bridge_funcs
->xlate_intr_line(pcidev
);
565 #else /* PCI_BRIDGE_FUNCS */
566 struct pci_bus
*p
= pcidev
->bus
;
569 ** The "pin" is skewed ((pin + dev - 1) % 4).
571 ** This isn't very clean since I/O SAPIC must assume:
572 ** - all platforms only have PCI busses.
573 ** - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
574 ** - IRQ routing is only skewed once regardless of
575 ** the number of PPB's between iosapic and device.
576 ** (Bit3 expansion chassis follows this rule)
578 ** Advantage is it's really easy to implement.
580 intr_pin
= ((intr_pin
-1)+PCI_SLOT(pcidev
->devfn
)) % 4;
581 intr_pin
++; /* convert back to INTA-D (1-4) */
582 #endif /* PCI_BRIDGE_FUNCS */
585 ** Locate the host slot the PPB nearest the Host bus
588 while (NULL
!= p
->parent
->self
)
591 intr_slot
= PCI_SLOT(p
->self
->devfn
);
593 intr_slot
= PCI_SLOT(pcidev
->devfn
);
595 DBG_IRT("iosapic_xlate_pin: bus %d slot %d pin %d\n",
596 pcidev
->bus
->secondary
, intr_slot
, intr_pin
);
598 return irt_find_irqline(isi
, intr_slot
, intr_pin
);
603 iosapic_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
605 struct vector_info
*vi
= (struct vector_info
*) dev_id
;
606 extern void do_irq(struct irqaction
*a
, int i
, struct pt_regs
*p
);
607 int irq_num
= vi
->iosapic
->isi_region
->data
.irqbase
+ vi
->irqline
;
609 DBG("iosapic_interrupt(): irq %d line %d eoi 0x%p 0x%x\n",
610 irq
, vi
->irqline
, vi
->eoi_addr
, vi
->eoi_data
);
612 /* Do NOT need to mask/unmask IRQ. processor is already masked. */
614 do_irq(&vi
->iosapic
->isi_region
->action
[vi
->irqline
], irq_num
, regs
);
617 ** PARISC only supports PCI devices below I/O SAPIC.
618 ** PCI only supports level triggered in order to share IRQ lines.
619 ** ergo I/O SAPIC must always issue EOI on parisc.
621 ** i386/ia64 support ISA devices and have to deal with
622 ** edge-triggered interrupts too.
624 __raw_writel(vi
->eoi_data
, vi
->eoi_addr
);
630 iosapic_fixup_irq(void *isi_obj
, struct pci_dev
*pcidev
)
632 struct iosapic_info
*isi
= (struct iosapic_info
*)isi_obj
;
633 struct irt_entry
*irte
= NULL
; /* only used if PAT PDC */
634 struct vector_info
*vi
;
635 int isi_line
; /* line used by device */
639 printk(KERN_WARNING MODULE_NAME
": hpa not registered for %s\n",
644 #ifdef CONFIG_SUPERIO
646 * HACK ALERT! (non-compliant PCI device support)
648 * All SuckyIO interrupts are routed through the PIC's on function 1.
649 * But SuckyIO OHCI USB controller gets an IRT entry anyway because
650 * it advertises INT D for INT_PIN. Use that IRT entry to get the
651 * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
653 if (is_superio_device(pcidev
)) {
654 /* We must call superio_fixup_irq() to register the pdev */
655 pcidev
->irq
= superio_fixup_irq(pcidev
);
657 /* Don't return if need to program the IOSAPIC's IRT... */
658 if (PCI_FUNC(pcidev
->devfn
) != SUPERIO_USB_FN
)
661 #endif /* CONFIG_SUPERIO */
663 /* lookup IRT entry for isi/slot/pin set */
664 irte
= iosapic_xlate_pin(isi
, pcidev
);
666 printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
670 DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
674 irte
->polarity_trigger
,
675 irte
->src_bus_irq_devno
,
678 irte
->dest_iosapic_intin
,
679 (u32
) irte
->dest_iosapic_addr
);
680 isi_line
= irte
->dest_iosapic_intin
;
681 pcidev
->irq
= isi
->isi_region
->data
.irqbase
+ isi_line
;
683 /* get vector info for this input line */
684 ASSERT(NULL
!= isi
->isi_vector
);
685 vi
= &(isi
->isi_vector
[isi_line
]);
686 DBG_IRT("iosapic_fixup_irq: line %d vi 0x%p\n", isi_line
, vi
);
688 /* If this IRQ line has already been setup, skip it */
694 /* Allocate processor IRQ */
695 vi
->txn_irq
= txn_alloc_irq();
697 /* XXX/FIXME The txn_alloc_irq() code and related code should be moved
698 ** to enable_irq(). That way we only allocate processor IRQ bits
699 ** for devices that actually have drivers claiming them.
700 ** Right now we assign an IRQ to every PCI device present regardless
701 ** of whether it's used or not.
704 panic("I/O sapic: couldn't get TXN IRQ\n");
706 /* enable_irq() will use txn_* to program IRdT */
707 vi
->txn_addr
= txn_alloc_addr(vi
->txn_irq
);
708 vi
->txn_data
= txn_alloc_data(vi
->txn_irq
, 8);
709 ASSERT(vi
->txn_data
< 256); /* matches 8 above */
711 tmp
= request_irq(vi
->txn_irq
, iosapic_interrupt
, 0,
715 vi
->eoi_addr
= (u32
*) (isi
->isi_hpa
+ IOSAPIC_REG_EOI
);
716 vi
->eoi_data
= cpu_to_le32(vi
->txn_data
);
717 ASSERT(NULL
!= isi
->isi_region
);
719 DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
720 PCI_SLOT(pcidev
->devfn
), PCI_FUNC(pcidev
->irq
),
721 pcidev
->vendor
, pcidev
->device
, isi_line
, pcidev
->irq
);
728 iosapic_rd_irt_entry(struct vector_info
*vi
, u32
*dp0
, u32
*dp1
)
730 struct iosapic_info
*isp
= vi
->iosapic
;
731 u8 idx
= vi
->irqline
;
733 *dp0
= iosapic_read(isp
->isi_hpa
, IOSAPIC_IRDT_ENTRY(idx
));
734 *dp1
= iosapic_read(isp
->isi_hpa
, IOSAPIC_IRDT_ENTRY_HI(idx
));
739 iosapic_wr_irt_entry(struct vector_info
*vi
, u32 dp0
, u32 dp1
)
741 struct iosapic_info
*isp
= vi
->iosapic
;
744 ASSERT(0 != isp
->isi_hpa
);
745 DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p 0x%x 0x%x\n",
750 iosapic_write(isp
->isi_hpa
, IOSAPIC_IRDT_ENTRY(vi
->irqline
), dp0
);
752 /* Read the window register to flush the writes down to HW */
753 dp0
= readl(isp
->isi_hpa
+IOSAPIC_REG_WINDOW
);
755 iosapic_write(isp
->isi_hpa
, IOSAPIC_IRDT_ENTRY_HI(vi
->irqline
), dp1
);
757 /* Read the window register to flush the writes down to HW */
758 dp1
= readl(isp
->isi_hpa
+IOSAPIC_REG_WINDOW
);
763 ** set_irt prepares the data (dp0, dp1) according to the vector_info
764 ** and target cpu (id_eid). dp0/dp1 are then used to program I/O SAPIC
765 ** IRdT for the given "vector" (aka IRQ line).
768 iosapic_set_irt_data( struct vector_info
*vi
, u32
*dp0
, u32
*dp1
)
771 struct irt_entry
*p
= vi
->irte
;
772 ASSERT(NULL
!= vi
->irte
);
774 if ((p
->polarity_trigger
& IRT_PO_MASK
) == IRT_ACTIVE_LO
)
775 mode
|= IOSAPIC_IRDT_PO_LOW
;
777 if (((p
->polarity_trigger
>> IRT_EL_SHIFT
) & IRT_EL_MASK
) == IRT_LEVEL_TRIG
)
778 mode
|= IOSAPIC_IRDT_LEVEL_TRIG
;
782 ** PA doesn't support EXTINT or LPRIO bits.
785 ASSERT(vi
->txn_data
);
786 *dp0
= mode
| (u32
) vi
->txn_data
;
789 ** Extracting id_eid isn't a real clean way of getting it.
790 ** But the encoding is the same for both PA and IA64 platforms.
794 ** PAT PDC just hands it to us "right".
795 ** txn_addr comes from cpu_data[x].txn_addr.
797 *dp1
= (u32
) (vi
->txn_addr
);
800 ** eg if base_addr == 0xfffa0000),
801 ** we want to get 0xa0ff0000.
803 ** eid 0x0ff00000 -> 0x00ff0000
804 ** id 0x000ff000 -> 0xff000000
806 *dp1
= (((u32
)vi
->txn_addr
& 0x0ff00000) >> 4) |
807 (((u32
)vi
->txn_addr
& 0x000ff000) << 12);
809 DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0
, *dp1
);
814 iosapic_disable_irq(void *irq_dev
, int irq
)
817 struct vector_info
*vi
= &(((struct vector_info
*) irq_dev
)[irq
]);
822 IOSAPIC_LOCK(&iosapic_lock
);
824 #ifdef REVISIT_DESIGN_ISSUE
828 disable_irq()/enable_irq(): drawback of using IRQ as a "handle"
830 Current disable_irq interface only allows the irq_region support routines
831 to manage sharing of "irq" objects. The problem is the disable_irq()
832 interface specifies which IRQ line needs to be disabled but does not
833 identify the particular ISR which needs to be disabled. IO sapic
834 (and similar code in Dino) can only support one handler per IRQ
835 since they don't further encode the meaning of the IRQ number.
836 irq_region support has to hide it's implementation of "shared IRQ"
837 behind a function call.
839 Encoding the IRQ would be possible by I/O SAPIC but makes life really
840 complicated for the IRQ handler and not help performance.
842 Need more info on how Linux supports shared IRQ lines on a PC.
844 #endif /* REVISIT_DESIGN_ISSUE */
846 iosapic_rd_irt_entry(vi
, &d0
, &d1
);
847 d0
|= IOSAPIC_IRDT_ENABLE
;
848 iosapic_wr_irt_entry(vi
, d0
, d1
);
850 IOSAPIC_UNLOCK(&iosapic_lock
);
852 /* disable ISR for parent */
853 disable_irq(vi
->txn_irq
);
858 iosapic_enable_irq(void *dev
, int irq
)
860 struct vector_info
*vi
= &(((struct vector_info
*) dev
)[irq
]);
864 ASSERT(NULL
!= vi
->irte
);
866 /* data is initialized by fixup_irq */
867 ASSERT(0 < vi
->txn_irq
);
868 ASSERT(0UL != vi
->txn_data
);
870 iosapic_set_irt_data(vi
, &d0
, &d1
);
871 iosapic_wr_irt_entry(vi
, d0
, d1
);
873 #ifdef DEBUG_IOSAPIC_IRT
875 u32
*t
= (u32
*) ((ulong
) vi
->eoi_addr
& ~0xffUL
);
876 printk("iosapic_enable_irq(): regs %p", vi
->eoi_addr
);
877 for ( ; t
< vi
->eoi_addr
; t
++)
878 printk(" %x", readl(t
));
882 printk("iosapic_enable_irq(): sel ");
884 struct iosapic_info
*isp
= vi
->iosapic
;
886 for (d0
=0x10; d0
<0x1e; d0
++) {
887 d1
= iosapic_read(isp
->isi_hpa
, d0
);
895 ** Issueing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
896 ** asserted. IRQ generally should not be asserted when a driver
897 ** enables their IRQ. It can lead to "interesting" race conditions
898 ** in the driver initialization sequence.
900 __raw_writel(vi
->eoi_data
, vi
->eoi_addr
);
905 iosapic_mask_irq(void *dev
, int irq
)
912 iosapic_unmask_irq(void *dev
, int irq
)
918 static struct irq_region_ops iosapic_irq_ops
= {
919 .disable_irq
= iosapic_disable_irq
,
920 .enable_irq
= iosapic_enable_irq
,
921 .mask_irq
= iosapic_mask_irq
,
922 .unmask_irq
= iosapic_unmask_irq
927 ** squirrel away the I/O Sapic Version
930 iosapic_rd_version(struct iosapic_info
*isi
)
933 ASSERT(isi
->isi_hpa
);
935 return iosapic_read(isi
->isi_hpa
, IOSAPIC_REG_VERSION
);
940 ** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
941 ** Caller must be certain they have an I/O SAPIC and know its MMIO address.
943 ** o allocate iosapic_info and add it to the list
944 ** o read iosapic version and squirrel that away
945 ** o read size of IRdT.
946 ** o allocate and initialize isi_vector[]
947 ** o allocate isi_region (registers region handlers)
950 iosapic_register(unsigned long hpa
)
952 struct iosapic_info
*isi
= NULL
;
953 struct irt_entry
*irte
= irt_cell
;
954 struct vector_info
*vip
;
955 int cnt
; /* track how many entries we've looked at */
958 ** Astro based platforms can't support PCI OLARD if they
959 ** implement the legacy PDC (not PAT). Though Legacy PDC
960 ** supports an IRT, LBA's with no device under them
961 ** are *not* listed in the IRT.
962 ** Search the IRT and ignore iosapic's which aren't
965 ASSERT(NULL
!= irte
); /* always have built-in devices */
966 for (cnt
=0; cnt
< irt_num_entry
; cnt
++, irte
++) {
967 ASSERT(IRT_IOSAPIC_TYPE
== irte
->entry_type
);
969 ** We need sign extension of the hpa on 32-bit kernels.
970 ** The address in the IRT is *always* 64 bit and really
971 ** is an unsigned quantity (like all physical addresses).
973 if (irte
->dest_iosapic_addr
== (s64
) ((long) hpa
))
977 if (cnt
>= irt_num_entry
)
980 if ((isi
= IOSAPIC_KALLOC(struct iosapic_info
, 1)) == NULL
) {
985 memset(isi
, 0, sizeof(struct iosapic_info
));
988 isi
->isi_version
= iosapic_rd_version(isi
);
989 isi
->isi_num_vectors
= IOSAPIC_IRDT_MAX_ENTRY(isi
->isi_version
) + 1;
991 vip
= isi
->isi_vector
=
992 IOSAPIC_KALLOC(struct vector_info
, isi
->isi_num_vectors
);
995 IOSAPIC_FREE(isi
, struct iosapic_info
, 1);
999 memset(vip
, 0, sizeof(struct vector_info
) * isi
->isi_num_vectors
);
1000 sprintf(isi
->isi_name
, "IO-SAPIC%02d", iosapic_count
++);
1003 ** Initialize vector array
1005 for (cnt
=0; cnt
< isi
->isi_num_vectors
; cnt
++, vip
++) {
1006 vip
->irqline
= (unsigned char) cnt
;
1008 sprintf(vip
->name
, "%s-L%d", isi
->isi_name
, cnt
);
1011 isi
->isi_region
= alloc_irq_region(isi
->isi_num_vectors
,
1012 &iosapic_irq_ops
, isi
->isi_name
,
1013 (void *) isi
->isi_vector
);
1015 ASSERT(NULL
!= isi
->isi_region
);
1016 return ((void *) isi
);
1020 #ifdef DEBUG_IOSAPIC
1023 iosapic_prt_irt(void *irt
, long num_entry
)
1025 unsigned int i
, *irp
= (unsigned int *) irt
;
1027 ASSERT(NULL
!= irt
);
1029 printk(KERN_DEBUG MODULE_NAME
": Interrupt Routing Table (%lx entries)\n", num_entry
);
1031 for (i
=0; i
<num_entry
; i
++, irp
+= 4) {
1032 printk(KERN_DEBUG
"%p : %2d %.8x %.8x %.8x %.8x\n",
1033 irp
, i
, irp
[0], irp
[1], irp
[2], irp
[3]);
1039 iosapic_prt_vi(struct vector_info
*vi
)
1043 printk(KERN_DEBUG MODULE_NAME
": vector_info[%d] is at %p\n", vi
->irqline
, vi
);
1044 printk(KERN_DEBUG
"\t\tstatus: %.4x\n", vi
->status
);
1045 printk(KERN_DEBUG
"\t\ttxn_irq: %d\n", vi
->txn_irq
);
1046 printk(KERN_DEBUG
"\t\ttxn_addr: %lx\n", vi
->txn_addr
);
1047 printk(KERN_DEBUG
"\t\ttxn_data: %lx\n", vi
->txn_data
);
1048 printk(KERN_DEBUG
"\t\teoi_addr: %p\n", vi
->eoi_addr
);
1049 printk(KERN_DEBUG
"\t\teoi_data: %x\n", vi
->eoi_data
);
1054 iosapic_prt_isi(struct iosapic_info
*isi
)
1056 ASSERT(NULL
!= isi
);
1057 printk(KERN_DEBUG MODULE_NAME
": io_sapic_info at %p\n", isi
);
1058 printk(KERN_DEBUG
"\t\tisi_hpa: %lx\n", isi
->isi_hpa
);
1059 printk(KERN_DEBUG
"\t\tisi_status: %x\n", isi
->isi_status
);
1060 printk(KERN_DEBUG
"\t\tisi_version: %x\n", isi
->isi_version
);
1061 printk(KERN_DEBUG
"\t\tisi_vector: %p\n", isi
->isi_vector
);
1063 #endif /* DEBUG_IOSAPIC */