Commit a31f8205 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar

x86/acpi: call mp_config_acpi_gsi() in mp_register_gsi()

The patch to call mp_config_acpi_gsi() from the ACPI IRQ registration
code never got mainline because there were open discussions about it.

This call is needed to properly update the kernel's copy of the mptable,
when the update_mptable boot parameter is needed.

Now that the dust has settled with the APIC unification, and since there
were no objections when the patch was re-submitted, try this again.

[ Impact: fix the update_mptable boot parameter ]
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Len Brown <lenb@kernel.org>
LKML-Reference: <4A01C387.7090103@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent ee214558
......@@ -77,17 +77,8 @@ extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low);
extern int acpi_probe_gsi(void);
#ifdef CONFIG_X86_IO_APIC
extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
u32 gsi, int triggering, int polarity);
extern int mp_find_ioapic(int gsi);
extern int mp_find_ioapic_pin(int ioapic, int gsi);
#else
static inline int
mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
u32 gsi, int triggering, int polarity)
{
return 0;
}
#endif
#else /* !CONFIG_ACPI: */
static inline int acpi_probe_gsi(void)
......
......@@ -33,6 +33,7 @@
#include <linux/irq.h>
#include <linux/bootmem.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <asm/pgtable.h>
#include <asm/io_apic.h>
......@@ -1158,6 +1159,44 @@ void __init mp_config_acpi_legacy_irqs(void)
}
}
static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int triggering,
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)
return 0;
if (dev->bus != &pci_bus_type)
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 = (triggering == 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 = mp_ioapic_routing[ioapic].apic_id;
mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
save_mp_irq(&mp_irq);
#endif
return 0;
}
int mp_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
{
int ioapic;
......@@ -1189,6 +1228,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
ioapic_pin);
return gsi;
}
mp_config_acpi_gsi(dev, gsi, triggering, polarity);
/*
* Avoid pin reprogramming. PRTs typically include entries
......@@ -1208,32 +1248,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity)
return gsi;
}
int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
u32 gsi, int triggering, int polarity)
{
#ifdef CONFIG_X86_MPPARSE
struct mpc_intsrc mp_irq;
int ioapic;
if (!acpi_ioapic)
return 0;
/* print the entry should happen on mptable identically */
mp_irq.type = MP_INTSRC;
mp_irq.irqtype = mp_INT;
mp_irq.irqflag = (triggering == 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 = mp_ioapic_routing[ioapic].apic_id;
mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
save_mp_irq(&mp_irq);
#endif
return 0;
}
/*
* Parse IOAPIC related entries in MADT
* returns 0 on success, < 0 on error
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment