Commit cfa08d6c authored by Alexey Starikovskiy's avatar Alexey Starikovskiy Committed by Ingo Molnar

x86: unify mp_register_gsi

Signed-off-by: default avatarAlexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent c769bfee
...@@ -994,14 +994,15 @@ void __init mp_config_acpi_legacy_irqs(void) ...@@ -994,14 +994,15 @@ void __init mp_config_acpi_legacy_irqs(void)
} }
} }
#define MAX_GSI_NUM 4096
#define IRQ_COMPRESSION_START 64
int mp_register_gsi(u32 gsi, int triggering, int polarity) int mp_register_gsi(u32 gsi, int triggering, int polarity)
{ {
int ioapic = -1; int ioapic = -1;
int ioapic_pin = 0; int ioapic_pin = 0;
int idx, bit = 0; int idx, bit = 0;
#ifdef CONFIG_X86_32
#define MAX_GSI_NUM 4096
#define IRQ_COMPRESSION_START 64
static int pci_irq = IRQ_COMPRESSION_START; static int pci_irq = IRQ_COMPRESSION_START;
/* /*
* Mapping between Global System Interrupts, which * Mapping between Global System Interrupts, which
...@@ -1009,6 +1010,11 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -1009,6 +1010,11 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
* assigned to actual devices. * assigned to actual devices.
*/ */
static int gsi_to_irq[MAX_GSI_NUM]; static int gsi_to_irq[MAX_GSI_NUM];
#else
if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
return gsi;
#endif
/* Don't set up the ACPI SCI because it's already set up */ /* Don't set up the ACPI SCI because it's already set up */
if (acpi_gbl_FADT.sci_interrupt == gsi) if (acpi_gbl_FADT.sci_interrupt == gsi)
...@@ -1022,8 +1028,10 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -1022,8 +1028,10 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
#ifdef CONFIG_X86_32
if (ioapic_renumber_irq) if (ioapic_renumber_irq)
gsi = ioapic_renumber_irq(ioapic, gsi); gsi = ioapic_renumber_irq(ioapic, gsi);
#endif
/* /*
* Avoid pin reprogramming. PRTs typically include entries * Avoid pin reprogramming. PRTs typically include entries
...@@ -1041,11 +1049,15 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -1041,11 +1049,15 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin); mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
#ifdef CONFIG_X86_32
return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]); return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
#else
return gsi;
#endif
} }
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit); mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit);
#ifdef CONFIG_X86_32
/* /*
* For GSI >= 64, use IRQ compression * For GSI >= 64, use IRQ compression
*/ */
...@@ -1079,7 +1091,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -1079,7 +1091,7 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
return gsi; return gsi;
} }
} }
#endif
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1); polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
......
...@@ -685,6 +685,8 @@ void __init find_smp_config(void) ...@@ -685,6 +685,8 @@ void __init find_smp_config(void)
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
#ifdef CONFIG_X86_IO_APIC
#define MP_ISA_BUS 0 #define MP_ISA_BUS 0
#define MP_MAX_IOAPIC_PIN 127 #define MP_MAX_IOAPIC_PIN 127
...@@ -770,7 +772,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) ...@@ -770,7 +772,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
int ioapic = -1; int ioapic = -1;
int pin = -1; int pin = -1;
/* /*
* Convert 'gsi' to 'ioapic.pin'. * Convert 'gsi' to 'ioapic.pin'.
*/ */
ioapic = mp_find_ioapic(gsi); ioapic = mp_find_ioapic(gsi);
...@@ -780,7 +782,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) ...@@ -780,7 +782,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
/* /*
* TBD: This check is for faulty timer entries, where the override * TBD: This check is for faulty timer entries, where the override
* erroneously sets the trigger to level, resulting in a HUGE * erroneously sets the trigger to level, resulting in a HUGE
* increase of timer interrupts! * increase of timer interrupts!
*/ */
if ((bus_irq == 0) && (trigger == 3)) if ((bus_irq == 0) && (trigger == 3))
...@@ -886,9 +888,22 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -886,9 +888,22 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
int ioapic = -1; int ioapic = -1;
int ioapic_pin = 0; int ioapic_pin = 0;
int idx, bit = 0; int idx, bit = 0;
#ifdef CONFIG_X86_32
#define MAX_GSI_NUM 4096
#define IRQ_COMPRESSION_START 64
static int pci_irq = IRQ_COMPRESSION_START;
/*
* Mapping between Global System Interrupts, which
* represent all possible interrupts, and IRQs
* assigned to actual devices.
*/
static int gsi_to_irq[MAX_GSI_NUM];
#else
if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
return gsi; return gsi;
#endif
/* Don't set up the ACPI SCI because it's already set up */ /* Don't set up the ACPI SCI because it's already set up */
if (acpi_gbl_FADT.sci_interrupt == gsi) if (acpi_gbl_FADT.sci_interrupt == gsi)
...@@ -902,8 +917,13 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -902,8 +917,13 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
/* #ifdef CONFIG_X86_32
* Avoid pin reprogramming. PRTs typically include entries if (ioapic_renumber_irq)
gsi = ioapic_renumber_irq(ioapic, gsi);
#endif
/*
* Avoid pin reprogramming. PRTs typically include entries
* with redundant pin->gsi mappings (but unique PCI devices); * with redundant pin->gsi mappings (but unique PCI devices);
* we only program the IOAPIC on the first. * we only program the IOAPIC on the first.
*/ */
...@@ -918,14 +938,54 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) ...@@ -918,14 +938,54 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { if ((1 << bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin); mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
#ifdef CONFIG_X86_32
return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
#else
return gsi; return gsi;
#endif
} }
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit); mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1 << bit);
#ifdef CONFIG_X86_32
/*
* For GSI >= 64, use IRQ compression
*/
if ((gsi >= IRQ_COMPRESSION_START)
&& (triggering == ACPI_LEVEL_SENSITIVE)) {
/*
* For PCI devices assign IRQs in order, avoiding gaps
* due to unused I/O APIC pins.
*/
int irq = gsi;
if (gsi < MAX_GSI_NUM) {
/*
* Retain the VIA chipset work-around (gsi > 15), but
* avoid a problem where the 8254 timer (IRQ0) is setup
* via an override (so it's not on pin 0 of the ioapic),
* and at the same time, the pin 0 interrupt is a PCI
* type. The gsi > 15 test could cause these two pins
* to be shared as IRQ0, and they are not shareable.
* So test for this condition, and if necessary, avoid
* the pin collision.
*/
gsi = pci_irq++;
/*
* Don't assign IRQ used by ACPI SCI
*/
if (gsi == acpi_gbl_FADT.sci_interrupt)
gsi = pci_irq++;
gsi_to_irq[irq] = gsi;
} else {
printk(KERN_ERR "GSI %u is too high\n", gsi);
return gsi;
}
}
#endif
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1); polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
return gsi; return gsi;
} }
#endif /* CONFIG_X86_IO_APIC */
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
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