void acpi_config_intr(device_t dev, ACPI_RESOURCE *res) { u_int irq; int pol, trig; switch (res->Type) { case ACPI_RESOURCE_TYPE_IRQ: KASSERT(res->Data.Irq.InterruptCount == 1, ("%s: multiple interrupts", __func__)); irq = res->Data.Irq.Interrupts[0]; trig = res->Data.Irq.Triggering; pol = res->Data.Irq.Polarity; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: KASSERT(res->Data.ExtendedIrq.InterruptCount == 1, ("%s: multiple interrupts", __func__)); irq = res->Data.ExtendedIrq.Interrupts[0]; trig = res->Data.ExtendedIrq.Triggering; pol = res->Data.ExtendedIrq.Polarity; break; default: panic("%s: bad resource type %u", __func__, res->Type); } if (irq == AcpiGbl_FADT.SciInterrupt) { if (bootverbose) kprintf("acpi_config_intr: Skip SCI config\n"); return; } BUS_CONFIG_INTR(dev, dev, irq, (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); }
int acpi_machdep_init(device_t dev) { struct acpi_softc *acpi_sc; acpi_sc = devclass_get_softc(devclass_find("acpi"), 0); /* Create a clone for /dev/acpi also. */ STAILQ_INIT(&acpi_sc->apm_cdevs); acpi_sc->acpi_clone = apm_create_clone(acpi_sc->acpi_dev_t, acpi_sc); clone_setup(&apm_clones); EVENTHANDLER_REGISTER(dev_clone, apm_clone, 0, 1000); acpi_install_wakeup_handler(acpi_sc); if (intr_model == ACPI_INTR_PIC) BUS_CONFIG_INTR(dev, AcpiGbl_FADT.SciInterrupt, INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW); else acpi_SetIntrModel(intr_model); SYSCTL_ADD_UINT(&acpi_sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "reset_video", CTLFLAG_RW, &acpi_reset_video, 0, "Call the VESA reset BIOS vector on the resume path"); return (0); }
static int mptable_pci_route_interrupt(device_t pcib, device_t dev, int pin) { int line, bus, slot, irq; bus = pci_get_bus(dev); slot = pci_get_slot(dev); irq = pci_get_irq(dev); line = mptable_pci_int_route(bus, slot, pin, irq); if (line >= 0) goto done; kprintf("MPTABLE: Unable to route for bus %d slot %d INT%c\n", bus, slot, 'A' + pin - 1); return PCI_INVALID_IRQ; done: BUS_CONFIG_INTR(dev, dev, line, INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW); return line; }
void acpi_config_intr(device_t dev, ACPI_RESOURCE *res) { u_int irq; int pol, trig; switch (res->Type) { case ACPI_RESOURCE_TYPE_IRQ: KASSERT(res->Data.Irq.InterruptCount == 1, ("%s: multiple interrupts", __func__)); irq = res->Data.Irq.Interrupts[0]; trig = res->Data.Irq.Triggering; pol = res->Data.Irq.Polarity; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: KASSERT(res->Data.ExtendedIrq.InterruptCount == 1, ("%s: multiple interrupts", __func__)); irq = res->Data.ExtendedIrq.Interrupts[0]; trig = res->Data.ExtendedIrq.Triggering; pol = res->Data.ExtendedIrq.Polarity; break; default: panic("%s: bad resource type %u", __func__, res->Type); } #if defined(__amd64__) || defined(__i386__) /* * XXX: Certain BIOSes have buggy AML that specify an IRQ that is * edge-sensitive and active-lo. However, edge-sensitive IRQs * should be active-hi. Force IRQs with an ISA IRQ value to be * active-hi instead. */ if (irq < 16 && trig == ACPI_EDGE_SENSITIVE && pol == ACPI_ACTIVE_LOW) pol = ACPI_ACTIVE_HIGH; #endif BUS_CONFIG_INTR(dev, irq, (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); }
int acpi_machdep_init(device_t dev) { struct acpi_softc *sc; sc = device_get_softc(dev); acpi_apm_init(sc); acpi_install_wakeup_handler(sc); if (intr_model == ACPI_INTR_PIC) BUS_CONFIG_INTR(dev, AcpiGbl_FADT.SciInterrupt, INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW); else acpi_SetIntrModel(intr_model); SYSCTL_ADD_UINT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "reset_video", CTLFLAG_RW, &acpi_reset_video, 0, "Call the VESA reset BIOS vector on the resume path"); return (0); }
/* * Route an interrupt for a child of the bridge. */ int acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin, ACPI_BUFFER *prtbuf) { ACPI_PCI_ROUTING_TABLE *prt; struct prt_lookup_request pr; ACPI_HANDLE lnkdev; int interrupt; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); interrupt = PCI_INVALID_IRQ; /* ACPI numbers pins 0-3, not 1-4 like the BIOS. */ pin--; ACPI_SERIAL_BEGIN(pcib); /* Search for a matching entry in the routing table. */ pr.pr_entry = NULL; pr.pr_pin = pin; pr.pr_slot = pci_get_slot(dev); prt_walk_table(prtbuf, prt_lookup_device, &pr); if (pr.pr_entry == NULL) { device_printf(pcib, "no PRT entry for %d.%d.INT%c\n", pci_get_bus(dev), pci_get_slot(dev), 'A' + pin); goto out; } prt = pr.pr_entry; if (bootverbose) { device_printf(pcib, "matched entry for %d.%d.INT%c", pci_get_bus(dev), pci_get_slot(dev), 'A' + pin); if (prt->Source != NULL && prt->Source[0] != '\0') printf(" (src %s:%u)", prt->Source, prt->SourceIndex); printf("\n"); } /* * If source is empty/NULL, the source index is a global IRQ number * and it's hard-wired so we're done. * * XXX: If the source index is non-zero, ignore the source device and * assume that this is a hard-wired entry. */ if (prt->Source == NULL || prt->Source[0] == '\0' || prt->SourceIndex != 0) { if (bootverbose) device_printf(pcib, "slot %d INT%c hardwired to IRQ %d\n", pci_get_slot(dev), 'A' + pin, prt->SourceIndex); if (prt->SourceIndex) { interrupt = prt->SourceIndex; BUS_CONFIG_INTR(dev, interrupt, INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW); } else device_printf(pcib, "error: invalid hard-wired IRQ of 0\n"); goto out; } /* * We have to find the source device (PCI interrupt link device). */ if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, prt->Source, &lnkdev))) { device_printf(pcib, "couldn't find PCI interrupt link device %s\n", prt->Source); goto out; } interrupt = acpi_pci_link_route_interrupt(acpi_get_device(lnkdev), prt->SourceIndex); if (bootverbose && PCI_INTERRUPT_VALID(interrupt)) device_printf(pcib, "slot %d INT%c routed to irq %d via %s\n", pci_get_slot(dev), 'A' + pin, interrupt, acpi_name(lnkdev)); out: ACPI_SERIAL_END(pcib); return_VALUE(interrupt); }