Example #1
0
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;
}
/* Propagate PCI IRQ# */
static int vlv2_pci_enable_irq(struct pci_dev *pdev)
{

	u8 ir_val, dev;
	void __iomem *ilb_mem;
	struct io_apic_irq_attr irq_attr;

	ilb_mem = ioremap_nocache(ILB_BASE, ILB_SIZE);
	if (ilb_mem == NULL) {
		pr_err("%s(): can't map ILB_BASE(0x%x)\n",
			__func__, ILB_BASE);
		return -EIO;
	}

	dev = PCI_DEV_NUM(pdev->devfn);
	ir_val = ioread8(ilb_mem + ILB_IR + PCI_DEV_NUM(pdev->devfn) * 2);

	iounmap(ilb_mem);

	/* map INTA# only */
	pdev->irq = PIRQ2IRQ(IR_INTA(ir_val));
	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, pdev->irq);

	irq_attr.ioapic = mp_find_ioapic(pdev->irq);
	irq_attr.ioapic_pin = pdev->irq;
	irq_attr.trigger = 1; /* level */
	irq_attr.polarity = 1; /* active low */
	io_apic_set_pci_routing(&pdev->dev, pdev->irq, &irq_attr);

	return 0;
}
Example #3
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;
}
Example #4
0
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;
}
static inline int byt_program_ioapic(int irq, int trigger, int polarity)
{
	struct io_apic_irq_attr irq_attr;
	int ioapic;

	ioapic = mp_find_ioapic(irq);
	if (ioapic < 0)
		return -EINVAL;
	irq_attr.ioapic = ioapic;
	irq_attr.ioapic_pin = irq;
	irq_attr.trigger = trigger;
	irq_attr.polarity = polarity;
	return io_apic_set_pci_routing(NULL, irq, &irq_attr);
}
Example #6
0
static int handle_mrfl_dev_ioapic(int irq)
{
	int ret = 0;
	int ioapic;
	struct io_apic_irq_attr irq_attr;

	ioapic = mp_find_ioapic(irq);
	if (ioapic >= 0) {
		irq_attr.ioapic = ioapic;
		irq_attr.ioapic_pin = irq;
		irq_attr.trigger = 1;
		irq_attr.polarity = 0; /* Active high */
		io_apic_set_pci_routing(NULL, irq, &irq_attr);
	} else {
		pr_warn("can not find interrupt %d in ioapic\n", irq);
		ret = -EINVAL;
	}

	return ret;
}