static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger, int polarity) { #ifdef CONFIG_X86_MPPARSE struct mpc_intsrc mp_irq; struct pci_dev *pdev; unsigned char number; unsigned int devfn; int ioapic; u8 pin; if (!acpi_ioapic) return 0; if (!dev || !dev_is_pci(dev)) return 0; pdev = to_pci_dev(dev); number = pdev->bus->number; devfn = pdev->devfn; pin = pdev->pin; /* print the entry should happen on mptable identically */ mp_irq.type = MP_INTSRC; mp_irq.irqtype = mp_INT; mp_irq.irqflag = (trigger == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | (polarity == ACPI_ACTIVE_HIGH ? 1 : 3); mp_irq.srcbus = number; mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); ioapic = mp_find_ioapic(gsi); mp_irq.dstapic = mpc_ioapic_id(ioapic); mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi); mp_save_irq(&mp_irq); #endif return 0; }
static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) { struct mpc_intsrc mp_irq; int ioapic, pin; /* Convert 'gsi' to 'ioapic.pin'(INTIN#) */ ioapic = mp_find_ioapic(gsi); if (ioapic < 0) { pr_warn("Failed to find ioapic for gsi : %u\n", gsi); return ioapic; } pin = mp_find_ioapic_pin(ioapic, gsi); mp_irq.type = MP_INTSRC; mp_irq.irqtype = mp_INT; mp_irq.irqflag = (trigger << 2) | polarity; mp_irq.srcbus = MP_ISA_BUS; mp_irq.srcbusirq = bus_irq; mp_irq.dstapic = mpc_ioapic_id(ioapic); mp_irq.dstirq = pin; mp_save_irq(&mp_irq); return 0; }
static void __init jailhouse_get_smp_config(unsigned int early) { struct ioapic_domain_cfg ioapic_cfg = { .type = IOAPIC_DOMAIN_STRICT, .ops = &mp_ioapic_irqdomain_ops, }; struct mpc_intsrc mp_irq = { .type = MP_INTSRC, .irqtype = mp_INT, .irqflag = MP_IRQPOL_ACTIVE_HIGH | MP_IRQTRIG_EDGE, }; unsigned int cpu; jailhouse_x2apic_init(); register_lapic_address(0xfee00000); for (cpu = 0; cpu < setup_data.num_cpus; cpu++) { generic_processor_info(setup_data.cpu_ids[cpu], boot_cpu_apic_version); } smp_found_config = 1; if (setup_data.standard_ioapic) { mp_register_ioapic(0, 0xfec00000, gsi_top, &ioapic_cfg); /* Register 1:1 mapping for legacy UART IRQs 3 and 4 */ mp_irq.srcbusirq = mp_irq.dstirq = 3; mp_save_irq(&mp_irq); mp_irq.srcbusirq = mp_irq.dstirq = 4; mp_save_irq(&mp_irq); } } static void jailhouse_no_restart(void) { pr_notice("Jailhouse: Restart not supported, halting\n"); machine_halt(); }
static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) { int ioapic; int pin; struct mpc_intsrc mp_irq; /* * Check bus_irq boundary. */ if (bus_irq >= NR_IRQS_LEGACY) { pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq); return; } /* * Convert 'gsi' to 'ioapic.pin'. */ ioapic = mp_find_ioapic(gsi); if (ioapic < 0) return; pin = mp_find_ioapic_pin(ioapic, gsi); /* * TBD: This check is for faulty timer entries, where the override * erroneously sets the trigger to level, resulting in a HUGE * increase of timer interrupts! */ if ((bus_irq == 0) && (trigger == 3)) trigger = 1; mp_irq.type = MP_INTSRC; mp_irq.irqtype = mp_INT; mp_irq.irqflag = (trigger << 2) | polarity; mp_irq.srcbus = MP_ISA_BUS; mp_irq.srcbusirq = bus_irq; /* IRQ */ mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */ mp_irq.dstirq = pin; /* INTIN# */ mp_save_irq(&mp_irq); /* * Reset default identity mapping if gsi is also an legacy IRQ, * otherwise there will be more than one entry with the same GSI * and acpi_isa_irq_to_gsi() may give wrong result. */ if (gsi < nr_legacy_irqs() && isa_irq_to_gsi[gsi] == gsi) isa_irq_to_gsi[gsi] = ACPI_INVALID_GSI; isa_irq_to_gsi[bus_irq] = gsi; }