Lines Matching +full:intc +full:- +full:nr +full:- +full:irqs
1 // SPDX-License-Identifier: GPL-2.0
3 * Low-Level PCI Support for PC -- Routing of Interrupts
5 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
22 #include <asm/pc-conf-reg.h>
81 if (rt->signature != PIRQ_SIGNATURE || in pirq_check_routing_table()
82 rt->version != PIRQ_VERSION || in pirq_check_routing_table()
83 rt->size % 16 || in pirq_check_routing_table()
84 rt->size < sizeof(struct irq_routing_table) || in pirq_check_routing_table()
85 (limit && rt->size > limit - addr)) in pirq_check_routing_table()
88 for (i = 0; i < rt->size; i++) in pirq_check_routing_table()
112 * and finally a 16-bit word giving the IRQs devoted exclusively to PCI.
121 * Reportedly there is another $IRT table format where a 16-bit word
136 if (ir->signature != IRT_SIGNATURE || !ir->used || ir->size < ir->used) in pirq_convert_irt_table()
139 size = struct_size(ir, slots, ir->used); in pirq_convert_irt_table()
140 if (size > limit - addr) in pirq_convert_irt_table()
146 size = struct_size(rt, slots, ir->used); in pirq_convert_irt_table()
151 rt->signature = PIRQ_SIGNATURE; in pirq_convert_irt_table()
152 rt->version = PIRQ_VERSION; in pirq_convert_irt_table()
153 rt->size = size; in pirq_convert_irt_table()
154 rt->exclusive_irqs = ir->exclusive_irqs; in pirq_convert_irt_table()
155 for (i = 0; i < ir->used; i++) in pirq_convert_irt_table()
156 rt->slots[i] = ir->slots[i]; in pirq_convert_irt_table()
162 rt->checksum = -sum; in pirq_convert_irt_table()
168 * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
186 addr < bios_end - sizeof(struct irq_routing_table); in pirq_find_routing_table()
193 addr < bios_end - sizeof(struct irt_routing_table); in pirq_find_routing_table()
216 for (i = 0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) { in pirq_peer_trick()
217 e = &rt->slots[i]; in pirq_peer_trick()
222 e->bus, e->devfn / 8, e->devfn % 8, e->slot); in pirq_peer_trick()
224 DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); in pirq_peer_trick()
228 busmap[e->bus] = 1; in pirq_peer_trick()
235 pcibios_last_bus = -1; in pirq_peer_trick()
254 printk(KERN_DEBUG "PCI: setting IRQ %u as level-triggered\n", irq); in elcr_set_level_irq()
257 DBG(KERN_DEBUG " -> edge"); in elcr_set_level_irq()
266 * M1489 Cache-Memory PCI Controller (CMP) ASIC.
268 * There are four 4-bit mappings provided, spread across two PCI
273 * lines are mapped in the low and the high 4-bit nibble of the
297 * corresponding line to be passed to ISA as edge-triggered and
298 * otherwise they are passed as level-triggered. Manufacturer's
343 * - bit 0 selects between INTx Routing Table Mapping Registers,
345 * - bit 3 selects the nibble within the INTx Routing Table Mapping Register,
347 * - bits 7:4 map to bits 3:0 of the PCI INTx Sensitivity Register.
412 static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) in read_config_nybble() argument
415 unsigned reg = offset + (nr >> 1); in read_config_nybble()
418 return (nr & 1) ? (x >> 4) : (x & 0xf); in read_config_nybble()
422 unsigned nr, unsigned int val) in write_config_nybble() argument
425 unsigned reg = offset + (nr >> 1); in write_config_nybble()
428 x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val); in write_config_nybble()
442 return irqmap[read_config_nybble(router, 0x48, pirq-1)]; in pirq_ali_get()
452 write_config_nybble(router, 0x48, pirq-1, val); in pirq_ali_set()
462 * accompanying 82375EB/82375SB PCI-EISA Bridge (PCEB) ASIC.
479 * Order Number: 290476-004, March 1996
481 * "82375EB/82375SB PCI-EISA Bridge (PCEB)", Intel Corporation, Order
482 * Number: 290477-004, March 1996
498 reg += PC_CONF_I82374_PIRQ_ROUTE_CONTROL - 1; in pirq_esc_get()
516 reg += PC_CONF_I82374_PIRQ_ROUTE_CONTROL - 1; in pirq_esc_set()
557 * 290488-004, December 1995
569 reg += PCI_I82426EX_PIRQ_ROUTE_CONTROL - 1; in pirq_ib_get()
582 reg += PCI_I82426EX_PIRQ_ROUTE_CONTROL - 1; in pirq_ib_set()
589 * The VIA pirq rules are nibble-based, like ALI,
605 * The VIA pirq rules are nibble-based, like ALI,
614 return read_config_nybble(router, 0x55, pirqmap[pirq-1]); in pirq_via586_get()
622 write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); in pirq_via586_set()
627 * ITE 8330G pirq rules are nibble-based
636 return read_config_nybble(router, 0x43, pirqmap[pirq-1]); in pirq_ite_get()
644 write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); in pirq_ite_set()
666 * 0x5D bits 7:4 is INTD bits 3:0 is INTC
670 return read_config_nybble(router, 0x5C, (pirq-1)^1); in pirq_cyrix_get()
675 write_config_nybble(router, 0x5C, (pirq-1)^1, irq); in pirq_cyrix_set()
685 * There are four PCI INTx#-to-IRQ Link registers provided in the
731 reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1; in pirq_sis497_get()
745 reg += PCI_SIS497_INTA_TO_IRQ_LINK - 1; in pirq_sis497_set()
757 * - vendors have different ideas about the meaning of link values
758 * - some onboard devices (integrated in the chipset) have special
759 * links and are thus routed differently (i.e. not via PCI INTA-INTD)
760 * - different revision of the router have a different layout for
768 * allowed: 3-7, 9-12, 14-15
771 * The config-space registers located at 0x41/0x42/0x43/0x44 are
774 * link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D.
777 * Currently (2003-05-21) it appears most SiS chipsets follow the
778 * definition of routing registers from the SiS-5595 southbridge.
780 * router (ISA-bridge) should be 0x01 or 0xb0.
785 * some concern because of the two USB-OHCI HCs (original SiS 5595
788 * Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1:
792 * bit 4 channel-select primary (0), secondary (1)
797 * 0x6a: ACPI/SCI IRQ: bits 4-6 reserved
799 * 0x7e: Data Acq. Module IRQ - bits 4-6 reserved
801 * We support USBIRQ (in addition to INTA-INTD) and keep the
809 * Onchip routing for router rev-id 0x04 (try-and-error observation)
811 * 0x60/0x61/0x62/0x63: 1xEHCI and 3xOHCI (companion) USB-HCs
812 * bit 6-4 are probably unused, not like 5595
850 * VLSI: nibble offset 0x74 - educated guess due to routing table and
851 * config space of VLSI 82C534 PCI-bridge/router (1004:0102)
853 * devices, PIRQ 3 for non-pci(!) soundchip and (untested) PIRQ 6
861 dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq); in pirq_vlsi_get()
864 return read_config_nybble(router, 0x74, pirq-1); in pirq_vlsi_get()
871 dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq); in pirq_vlsi_set()
874 write_config_nybble(router, 0x74, pirq-1, irq); in pirq_vlsi_set()
907 * The AMD756 pirq rules are nibble-based
908 * offset 0x56 0-3 PIRQA 4-7 PIRQB
909 * offset 0x57 0-3 PIRQC 4-7 PIRQD
916 irq = read_config_nybble(router, 0x56, pirq - 1); in pirq_amd756_get()
917 dev_info(&dev->dev, in pirq_amd756_get()
919 dev->vendor, dev->device, pirq, irq); in pirq_amd756_get()
925 dev_info(&dev->dev, in pirq_amd756_set()
927 dev->vendor, dev->device, pirq, irq); in pirq_amd756_set()
929 write_config_nybble(router, 0x56, pirq - 1, irq); in pirq_amd756_set()
938 outb(0x10 + ((pirq - 1) >> 1), 0x24); in pirq_pico_get()
939 return ((pirq - 1) & 1) ? (inb(0x26) >> 4) : (inb(0x26) & 0xf); in pirq_pico_get()
946 outb(0x10 + ((pirq - 1) >> 1), 0x24); in pirq_pico_set()
948 x = ((pirq - 1) & 1) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | (irq)); in pirq_pico_set()
959 return pcibios_set_irq_routing(bridge, pin - 1, irq); in pirq_bios_set()
972 /* 440GX has a proprietary PIRQ router -- don't use it */ in intel_router_probe()
978 r->name = "PCEB/ESC"; in intel_router_probe()
979 r->get = pirq_esc_get; in intel_router_probe()
980 r->set = pirq_esc_set; in intel_router_probe()
1023 r->name = "PIIX/ICH"; in intel_router_probe()
1024 r->get = pirq_piix_get; in intel_router_probe()
1025 r->set = pirq_piix_set; in intel_router_probe()
1028 r->name = "PSC/IB"; in intel_router_probe()
1029 r->get = pirq_ib_get; in intel_router_probe()
1030 r->set = pirq_ib_set; in intel_router_probe()
1042 r->name = "PIIX/ICH"; in intel_router_probe()
1043 r->get = pirq_piix_get; in intel_router_probe()
1044 r->set = pirq_piix_set; in intel_router_probe()
1060 switch (router->device) { in via_router_probe()
1064 * as 586-compatible in via_router_probe()
1070 * Asus a7v-x bios wrongly reports 8235 in via_router_probe()
1071 * as 586-compatible in via_router_probe()
1078 * as 586-compatible in via_router_probe()
1087 r->name = "VIA"; in via_router_probe()
1088 r->get = pirq_via586_get; in via_router_probe()
1089 r->set = pirq_via586_set; in via_router_probe()
1098 r->name = "VIA"; in via_router_probe()
1099 r->get = pirq_via_get; in via_router_probe()
1100 r->set = pirq_via_set; in via_router_probe()
1110 r->name = "VLSI 82C534"; in vlsi_router_probe()
1111 r->get = pirq_vlsi_get; in vlsi_router_probe()
1112 r->set = pirq_vlsi_set; in vlsi_router_probe()
1125 r->name = "ServerWorks"; in serverworks_router_probe()
1126 r->get = pirq_serverworks_get; in serverworks_router_probe()
1127 r->set = pirq_serverworks_set; in serverworks_router_probe()
1137 r->name = "SiS85C497"; in sis_router_probe()
1138 r->get = pirq_sis497_get; in sis_router_probe()
1139 r->set = pirq_sis497_set; in sis_router_probe()
1142 r->name = "SiS85C503"; in sis_router_probe()
1143 r->get = pirq_sis503_get; in sis_router_probe()
1144 r->set = pirq_sis503_set; in sis_router_probe()
1154 r->name = "NatSemi"; in cyrix_router_probe()
1155 r->get = pirq_cyrix_get; in cyrix_router_probe()
1156 r->set = pirq_cyrix_set; in cyrix_router_probe()
1166 r->name = "OPTI"; in opti_router_probe()
1167 r->get = pirq_opti_get; in opti_router_probe()
1168 r->set = pirq_opti_set; in opti_router_probe()
1178 r->name = "ITE"; in ite_router_probe()
1179 r->get = pirq_ite_get; in ite_router_probe()
1180 r->set = pirq_ite_set; in ite_router_probe()
1190 r->name = "FinALi"; in ali_router_probe()
1191 r->get = pirq_finali_get; in ali_router_probe()
1192 r->set = pirq_finali_set; in ali_router_probe()
1193 r->lvl = pirq_finali_lvl; in ali_router_probe()
1197 r->name = "ALI"; in ali_router_probe()
1198 r->get = pirq_ali_get; in ali_router_probe()
1199 r->set = pirq_ali_set; in ali_router_probe()
1209 r->name = "AMD756"; in amd_router_probe()
1212 r->name = "AMD766"; in amd_router_probe()
1215 r->name = "AMD768"; in amd_router_probe()
1220 r->get = pirq_amd756_get; in amd_router_probe()
1221 r->set = pirq_amd756_set; in amd_router_probe()
1229 r->name = "PicoPower PT86C523"; in pico_router_probe()
1230 r->get = pirq_pico_get; in pico_router_probe()
1231 r->set = pirq_pico_set; in pico_router_probe()
1235 r->name = "PicoPower PT86C523 rev. BB+"; in pico_router_probe()
1236 r->get = pirq_pico_get; in pico_router_probe()
1237 r->set = pirq_pico_set; in pico_router_probe()
1274 dev->vendor, dev->device); in pirq_try_router()
1276 for (h = pirq_routers; h->vendor; h++) { in pirq_try_router()
1278 if (rt->rtr_vendor == h->vendor && in pirq_try_router()
1279 h->probe(r, dev, rt->rtr_device)) in pirq_try_router()
1282 if (dev->vendor == h->vendor && in pirq_try_router()
1283 h->probe(r, dev, dev->device)) in pirq_try_router()
1295 if (!rt->signature) { in pirq_find_router()
1297 r->set = pirq_bios_set; in pirq_find_router()
1298 r->name = "BIOS"; in pirq_find_router()
1304 r->name = "default"; in pirq_find_router()
1305 r->get = NULL; in pirq_find_router()
1306 r->set = NULL; in pirq_find_router()
1309 rt->rtr_vendor, rt->rtr_device); in pirq_find_router()
1312 if (rt->rtr_vendor) { in pirq_find_router()
1313 dev = pci_get_domain_bus_and_slot(0, rt->rtr_bus, in pirq_find_router()
1314 rt->rtr_devfn); in pirq_find_router()
1328 dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n", in pirq_find_router()
1330 pirq_router_dev->vendor, pirq_router_dev->device); in pirq_find_router()
1333 "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); in pirq_find_router()
1347 int entries = (rt->size - sizeof(struct irq_routing_table)) / in pirq_get_dev_info()
1352 for (info = rt->slots; entries--; info++) in pirq_get_dev_info()
1353 if (info->bus == dev->bus->number) { in pirq_get_dev_info()
1354 if (info->devfn == dev->devfn) in pirq_get_dev_info()
1357 PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn)) in pirq_get_dev_info()
1377 while (!info && temp_dev->bus->parent) { in pirq_get_info()
1378 struct pci_dev *bridge = temp_dev->bus->self; in pirq_get_info()
1383 dev_warn(&dev->dev, in pirq_get_info()
1386 'A' + temp_pin - 1, 'A' + dpin - 1); in pirq_get_info()
1408 dev_dbg(&dev->dev, "no interrupt pin\n"); in pcibios_lookup_irq()
1423 dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n", in pcibios_lookup_irq()
1424 'A' + dpin - 1); in pcibios_lookup_irq()
1427 pirq = info->irq[pin - 1].link; in pcibios_lookup_irq()
1428 mask = info->irq[pin - 1].bitmap; in pcibios_lookup_irq()
1430 dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + dpin - 1); in pcibios_lookup_irq()
1433 dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x", in pcibios_lookup_irq()
1434 'A' + dpin - 1, pirq, mask, pirq_table->exclusive_irqs); in pcibios_lookup_irq()
1440 if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) { in pcibios_lookup_irq()
1441 dev->irq = 11; in pcibios_lookup_irq()
1443 r->set(pirq_router_dev, dev, pirq, 11); in pcibios_lookup_irq()
1446 /* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */ in pcibios_lookup_irq()
1447 if (acer_tm360_irqrouting && dev->irq == 11 && in pcibios_lookup_irq()
1448 dev->vendor == PCI_VENDOR_ID_O2) { in pcibios_lookup_irq()
1451 dev->irq = r->get(pirq_router_dev, dev, pirq); in pcibios_lookup_irq()
1452 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); in pcibios_lookup_irq()
1459 newirq = dev->irq; in pcibios_lookup_irq()
1464 dev_warn(&dev->dev, "IRQ %d doesn't match PIRQ mask " in pcibios_lookup_irq()
1476 dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + dpin - 1, newirq); in pcibios_lookup_irq()
1482 } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \ in pcibios_lookup_irq()
1485 if (r->lvl) in pcibios_lookup_irq()
1486 r->lvl(pirq_router_dev, dev, pirq, irq); in pcibios_lookup_irq()
1489 } else if (newirq && r->set && in pcibios_lookup_irq()
1490 (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { in pcibios_lookup_irq()
1491 if (r->set(pirq_router_dev, dev, pirq, newirq)) { in pcibios_lookup_irq()
1492 if (r->lvl) in pcibios_lookup_irq()
1493 r->lvl(pirq_router_dev, dev, pirq, newirq); in pcibios_lookup_irq()
1506 dev_dbg(&dev->dev, "can't route interrupt\n"); in pcibios_lookup_irq()
1510 dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", in pcibios_lookup_irq()
1511 msg, 'A' + dpin - 1, irq); in pcibios_lookup_irq()
1523 if (info->irq[pin - 1].link == pirq) { in pcibios_lookup_irq()
1525 * We refuse to override the dev->irq in pcibios_lookup_irq()
1528 if (dev2->irq && dev2->irq != irq && \ in pcibios_lookup_irq()
1530 ((1 << dev2->irq) & mask))) { in pcibios_lookup_irq()
1532 dev_info(&dev2->dev, "IRQ routing conflict: " in pcibios_lookup_irq()
1534 dev2->irq, irq); in pcibios_lookup_irq()
1538 dev2->irq = irq; in pcibios_lookup_irq()
1541 dev_info(&dev->dev, "sharing IRQ %d with %s\n", in pcibios_lookup_irq()
1560 if (dev->irq >= 16) { in pcibios_fixup_irqs()
1561 dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq); in pcibios_fixup_irqs()
1562 dev->irq = 0; in pcibios_fixup_irqs()
1568 if (pirq_penalty[dev->irq] >= 100 && in pcibios_fixup_irqs()
1569 pirq_penalty[dev->irq] < 100000) in pcibios_fixup_irqs()
1570 pirq_penalty[dev->irq] = 0; in pcibios_fixup_irqs()
1571 pirq_penalty[dev->irq]++; in pcibios_fixup_irqs()
1586 if (!dev->irq) in pcibios_fixup_irqs()
1599 printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", in fix_broken_hp_bios_irq9()
1600 d->ident); in fix_broken_hp_bios_irq9()
1613 printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", in fix_acer_tm360_irqrouting()
1614 d->ident); in fix_acer_tm360_irqrouting()
1624 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1628 DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
1664 if (pirq_table->exclusive_irqs) { in pcibios_irq_init()
1667 if (!(pirq_table->exclusive_irqs & (1 << i))) in pcibios_irq_init()
1727 if (!io_apic_assign_pci_irqs && dev->irq) in pirq_enable_irq()
1735 if (dev->irq_managed && dev->irq > 0) in pirq_enable_irq()
1738 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, in pirq_enable_irq()
1739 PCI_SLOT(dev->devfn), pin - 1); in pirq_enable_irq()
1741 * Busses behind bridges are typically not listed in the MP-table. in pirq_enable_irq()
1747 while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ in pirq_enable_irq()
1748 struct pci_dev *bridge = dev->bus->self; in pirq_enable_irq()
1751 irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, in pirq_enable_irq()
1752 PCI_SLOT(bridge->devfn), in pirq_enable_irq()
1753 pin - 1); in pirq_enable_irq()
1755 dev_warn(&dev->dev, "using bridge %s " in pirq_enable_irq()
1757 pci_name(bridge), 'A' + pin - 1, in pirq_enable_irq()
1763 dev->irq_managed = 1; in pirq_enable_irq()
1764 dev->irq = irq; in pirq_enable_irq()
1765 dev_info(&dev->dev, "PCI->APIC IRQ transform: " in pirq_enable_irq()
1766 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq); in pirq_enable_irq()
1780 if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && in pirq_enable_irq()
1781 !(dev->class & 0x5)) in pirq_enable_irq()
1784 dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n", in pirq_enable_irq()
1785 'A' + pin - 1, msg); in pirq_enable_irq()
1792 if (dev->power.is_prepared) in mp_should_keep_irq()
1795 if (dev->power.runtime_status == RPM_SUSPENDING) in mp_should_keep_irq()
1804 if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && in pirq_disable_irq()
1805 dev->irq_managed && dev->irq) { in pirq_disable_irq()
1806 mp_unmap_irq(dev->irq); in pirq_disable_irq()
1807 dev->irq = 0; in pirq_disable_irq()
1808 dev->irq_managed = 0; in pirq_disable_irq()