131 #include <linux/types.h>
132 #include <linux/kernel.h>
134 #include <linux/pci.h>
136 #include <linux/slab.h>
139 #include <asm/byteorder.h>
142 #include <asm/page.h>
144 #ifdef CONFIG_SUPERIO
151 #define MODULE_NAME "iosapic"
154 #undef PCI_BRIDGE_FUNCS
156 #undef DEBUG_IOSAPIC_IRT
160 #define DBG(x...) printk(x)
165 #ifdef DEBUG_IOSAPIC_IRT
166 #define DBG_IRT(x...) printk(x)
168 #define DBG_IRT(x...)
172 #define COMPARE_IRTE_ADDR(irte, hpa) ((irte)->dest_iosapic_addr == (hpa))
174 #define COMPARE_IRTE_ADDR(irte, hpa) \
175 ((irte)->dest_iosapic_addr == ((hpa) | 0xffffffff00000000ULL))
178 #define IOSAPIC_REG_SELECT 0x00
179 #define IOSAPIC_REG_WINDOW 0x10
180 #define IOSAPIC_REG_EOI 0x40
182 #define IOSAPIC_REG_VERSION 0x1
184 #define IOSAPIC_IRDT_ENTRY(idx) (0x10+(idx)*2)
185 #define IOSAPIC_IRDT_ENTRY_HI(idx) (0x11+(idx)*2)
199 #define IOSAPIC_VERSION_MASK 0x000000ff
200 #define IOSAPIC_VERSION(ver) ((int) (ver & IOSAPIC_VERSION_MASK))
202 #define IOSAPIC_MAX_ENTRY_MASK 0x00ff0000
203 #define IOSAPIC_MAX_ENTRY_SHIFT 0x10
204 #define IOSAPIC_IRDT_MAX_ENTRY(ver) \
205 (int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
208 #define IOSAPIC_IRDT_ENABLE 0x10000
209 #define IOSAPIC_IRDT_PO_LOW 0x02000
210 #define IOSAPIC_IRDT_LEVEL_TRIG 0x08000
211 #define IOSAPIC_IRDT_MODE_LPRI 0x00100
214 #define IOSAPIC_IRDT_ID_EID_SHIFT 0x10
234 static size_t irt_num_entry;
246 a = (a + 7
UL) & ~7
UL;
278 iosapic_load_irt(
unsigned long cell_num,
struct irt_entry **irt)
282 unsigned long num_entries = 0
UL;
288 DBG(
"calling get_irt_size (cell %ld)\n", cell_num);
290 DBG(
"get_irt_size: %ld\n", status);
301 table = iosapic_alloc_irt(num_entries);
304 "not alloc mem for IRT\n");
310 DBG(
"pdc_pat_get_irt: %ld\n", status);
323 DBG(
"pdc_pci_irt_size: %ld\n", status);
332 table = iosapic_alloc_irt(num_entries);
335 "not alloc mem for IRT\n");
347 #ifdef DEBUG_IOSAPIC_IRT
377 unsigned long cell = 0;
379 DBG(
"iosapic_init()\n");
394 irt_num_entry = iosapic_load_irt(cell, &irt_cell);
395 if (irt_num_entry == 0)
410 DBG_IRT(
"irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
412 for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
476 u8 intr_pin, intr_slot;
480 DBG_IRT(
"iosapic_xlate_pin(%s) SLOT %d pin %d\n",
489 if (pcidev->
bus->parent) {
493 #ifdef PCI_BRIDGE_FUNCS
503 if (pci_bridge_funcs->xlate_intr_line) {
504 intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
534 DBG_IRT(
"iosapic_xlate_pin: bus %d slot %d pin %d\n",
535 pcidev->
bus->busn_res.start, intr_slot, intr_pin);
537 return irt_find_irqline(isi, intr_slot, intr_pin);
554 DBG_IRT(
"iosapic_wr_irt_entry(): irq %d hpa %lx 0x%x 0x%x\n",
613 DBG_IRT(
"iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
617 static void iosapic_mask_irq(
struct irq_data *
d)
620 struct vector_info *vi = irq_data_get_irq_chip_data(d);
624 iosapic_rd_irt_entry(vi, &d0, &d1);
626 iosapic_wr_irt_entry(vi, d0, d1);
627 spin_unlock_irqrestore(&iosapic_lock, flags);
630 static void iosapic_unmask_irq(
struct irq_data *
d)
632 struct vector_info *vi = irq_data_get_irq_chip_data(d);
638 iosapic_set_irt_data(vi, &d0, &d1);
639 iosapic_wr_irt_entry(vi, d0, d1);
641 #ifdef DEBUG_IOSAPIC_IRT
650 printk(
"iosapic_enable_irq(): sel ");
654 for (d0=0x10; d0<0x1e; d0++) {
655 d1 = iosapic_read(isp->
addr, d0);
673 static void iosapic_eoi_irq(
struct irq_data *d)
675 struct vector_info *vi = irq_data_get_irq_chip_data(d);
682 static int iosapic_set_affinity_irq(
struct irq_data *d,
685 struct vector_info *vi = irq_data_get_irq_chip_data(d);
700 iosapic_rd_irt_entry(vi, &d0, &d1);
701 iosapic_set_irt_data(vi, &dummy_d0, &d1);
702 iosapic_wr_irt_entry(vi, d0, d1);
703 spin_unlock_irqrestore(&iosapic_lock, flags);
709 static struct irq_chip iosapic_interrupt_type = {
710 .name =
"IO-SAPIC-level",
711 .irq_unmask = iosapic_unmask_irq,
712 .irq_mask = iosapic_mask_irq,
714 .irq_eoi = iosapic_eoi_irq,
716 .irq_set_affinity = iosapic_set_affinity_irq,
733 #ifdef CONFIG_SUPERIO
753 irte = iosapic_xlate_pin(isi, pcidev);
755 printk(
"iosapic: no IRTE for %s (IRQ not connected?)\n",
759 DBG_IRT(
"iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
773 DBG_IRT(
"iosapic_fixup_irq: line %d vi 0x%p\n", isi_line, vi);
793 panic(
"I/O sapic: couldn't get TXN IRQ\n");
807 DBG_IRT(
"iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
847 for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
853 if (cnt >= irt_num_entry) {
854 DBG(
"iosapic_register() ignoring 0x%lx (NOT FOUND)\n", hpa);
887 iosapic_prt_irt(
void *irt,
long num_entry)
889 unsigned int i, *irp = (
unsigned int *) irt;
894 for (i=0; i<num_entry; i++, irp += 4) {
896 irp, i, irp[0], irp[1], irp[2], irp[3]);