Commit 31fb1ef9 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Len Brown

[PATCH] clean up ACPI GSI/IRQ conversions (i386 part)

Add "acpi_gsi_to_irq()" as a generic replacement for "acpi_irq_to_vector()".
This converts from an ACPI global system interrupt number to a Linux IRQ.
Also, convert i386-specific terminology to use GSI when appropriate.
parent 16aa2ed9
......@@ -351,6 +351,7 @@ __setup("acpi_pic_sci=", acpi_pic_sci_setup);
#endif /* CONFIG_ACPI_BUS */
#ifdef CONFIG_X86_IO_APIC
/* deprecated in favor of acpi_gsi_to_irq */
int acpi_irq_to_vector(u32 irq)
{
if (use_pci_vector() && !platform_legacy_irq(irq))
......@@ -359,6 +360,17 @@ int acpi_irq_to_vector(u32 irq)
}
#endif
int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
{
#ifdef CONFIG_X86_IO_APIC
if (use_pci_vector() && !platform_legacy_irq(gsi))
*irq = IO_APIC_VECTOR(gsi);
else
#endif
*irq = gsi;
return 0;
}
static unsigned long __init
acpi_scan_rsdp (
unsigned long start,
......
/*
* Intel Multiprocessor Specificiation 1.1 and 1.4
* Intel Multiprocessor Specification 1.1 and 1.4
* compliant MP-table parsing routines.
*
* (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
......@@ -851,25 +851,25 @@ void __init mp_register_lapic (
struct mp_ioapic_routing {
int apic_id;
int irq_start;
int irq_end;
int gsi_base;
int gsi_end;
u32 pin_programmed[4];
} mp_ioapic_routing[MAX_IO_APICS];
static int __init mp_find_ioapic (
int irq)
int gsi)
{
int i = 0;
/* Find the IOAPIC that manages this IRQ. */
/* Find the IOAPIC that manages this GSI. */
for (i = 0; i < nr_ioapics; i++) {
if ((irq >= mp_ioapic_routing[i].irq_start)
&& (irq <= mp_ioapic_routing[i].irq_end))
if ((gsi >= mp_ioapic_routing[i].gsi_base)
&& (gsi <= mp_ioapic_routing[i].gsi_end))
return i;
}
printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d\n", irq);
printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
return -1;
}
......@@ -878,7 +878,7 @@ static int __init mp_find_ioapic (
void __init mp_register_ioapic (
u8 id,
u32 address,
u32 irq_base)
u32 gsi_base)
{
int idx = 0;
......@@ -904,19 +904,19 @@ void __init mp_register_ioapic (
mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
/*
* Build basic IRQ lookup table to facilitate irq->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI IRQs).
* Build basic GSI lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI GSIs).
*/
mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
mp_ioapic_routing[idx].irq_start = irq_base;
mp_ioapic_routing[idx].irq_end = irq_base +
mp_ioapic_routing[idx].gsi_base = gsi_base;
mp_ioapic_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx);
printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
"GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
mp_ioapic_routing[idx].irq_start,
mp_ioapic_routing[idx].irq_end);
mp_ioapic_routing[idx].gsi_base,
mp_ioapic_routing[idx].gsi_end);
return;
}
......@@ -926,7 +926,7 @@ void __init mp_override_legacy_irq (
u8 bus_irq,
u8 polarity,
u8 trigger,
u32 global_irq)
u32 gsi)
{
struct mpc_config_intsrc intsrc;
int i = 0;
......@@ -935,12 +935,12 @@ void __init mp_override_legacy_irq (
int pin = -1;
/*
* Convert 'global_irq' to 'ioapic.pin'.
* Convert 'gsi' to 'ioapic.pin'.
*/
ioapic = mp_find_ioapic(global_irq);
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0)
return;
pin = global_irq - mp_ioapic_routing[ioapic].irq_start;
pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
/*
* TBD: This check is for faulty timer entries, where the override
......@@ -965,7 +965,7 @@ void __init mp_override_legacy_irq (
/*
* If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
* Otherwise create a new entry (e.g. global_irq == 2).
* Otherwise create a new entry (e.g. gsi == 2).
*/
for (i = 0; i < mp_irq_entries; i++) {
if ((mp_irqs[i].mpc_srcbus == intsrc.mpc_srcbus)
......@@ -1036,7 +1036,7 @@ void __init mp_config_acpi_legacy_irqs (void)
extern FADT_DESCRIPTOR acpi_fadt;
void __init mp_config_ioapic_for_sci(int irq)
void __init mp_config_ioapic_for_sci(u32 gsi)
{
int ioapic;
int ioapic_pin;
......@@ -1083,11 +1083,11 @@ void __init mp_config_ioapic_for_sci(int irq)
*/
flags = entry->flags;
acpi_fadt.sci_int = entry->global_irq;
irq = entry->global_irq;
gsi = entry->global_irq;
ioapic = mp_find_ioapic(irq);
ioapic = mp_find_ioapic(gsi);
ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
/*
* MPS INTI flags:
......@@ -1095,7 +1095,7 @@ void __init mp_config_ioapic_for_sci(int irq)
* polarity: 0=default, 1=high, 3=low
* Per ACPI spec, default for SCI means level/low.
*/
io_apic_set_pci_routing(ioapic, ioapic_pin, irq,
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
(flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1));
}
......@@ -1107,7 +1107,7 @@ void __init mp_parse_prt (void)
struct acpi_prt_entry *entry = NULL;
int ioapic = -1;
int ioapic_pin = 0;
int irq = 0;
int gsi = 0;
int idx, bit = 0;
int edge_level = 0;
int active_high_low = 0;
......@@ -1119,39 +1119,39 @@ void __init mp_parse_prt (void)
list_for_each(node, &acpi_prt.entries) {
entry = list_entry(node, struct acpi_prt_entry, node);
/* Need to get irq for dynamic entry */
/* Need to get gsi for dynamic entry */
if (entry->link.handle) {
irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
if (!irq)
gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
if (!gsi)
continue;
}
else {
/* Hardwired IRQ. Assume PCI standard settings */
irq = entry->link.index;
/* Hardwired GSI. Assume PCI standard settings */
gsi = entry->link.index;
edge_level = 1;
active_high_low = 1;
}
/* Don't set up the ACPI SCI because it's already set up */
if (acpi_fadt.sci_int == irq) {
irq = acpi_irq_to_vector(irq);
entry->irq = irq; /* we still need to set entry's irq */
if (acpi_fadt.sci_int == gsi) {
/* we still need to set entry's irq */
acpi_gsi_to_irq(gsi, &entry->irq);
continue;
}
ioapic = mp_find_ioapic(irq);
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0)
continue;
ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
if (es7000_plat) {
if (!ioapic && (irq < 16))
irq += 16;
if (!ioapic && (gsi < 16))
gsi += 16;
}
/*
* Avoid pin reprogramming. PRTs typically include entries
* with redundant pin->irq mappings (but unique PCI devices);
* with redundant pin->gsi mappings (but unique PCI devices);
* we only only program the IOAPIC on the first.
*/
bit = ioapic_pin % 32;
......@@ -1165,19 +1165,19 @@ void __init mp_parse_prt (void)
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
entry->irq = acpi_irq_to_vector(irq);
acpi_gsi_to_irq(gsi, &entry->irq);
continue;
}
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) {
entry->irq = acpi_irq_to_vector(irq);
}
if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) {
acpi_gsi_to_irq(gsi, &entry->irq);
}
printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
entry->id.segment, entry->id.bus,
entry->id.device, ('A' + entry->pin),
mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
entry->id.segment, entry->id.bus,
entry->id.device, ('A' + entry->pin),
mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
entry->irq);
}
......
......@@ -123,9 +123,10 @@ static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; }
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
#ifdef CONFIG_X86_IO_APIC
extern int skip_ioapic_setup;
extern int acpi_irq_to_vector(u32 irq);
extern int acpi_irq_to_vector(u32 irq); /* deprecated in favor of acpi_gsi_to_irq */
static inline void disable_ioapic_setup(void)
{
......
......@@ -30,15 +30,15 @@ extern int using_apic_timer;
#ifdef CONFIG_ACPI_BOOT
extern void mp_register_lapic (u8 id, u8 enabled);
extern void mp_register_lapic_address (u64 address);
extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq);
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void);
extern void mp_parse_prt (void);
#ifdef CONFIG_X86_IO_APIC
extern void mp_config_ioapic_for_sci(int irq);
extern void mp_config_ioapic_for_sci(u32 gsi);
#else
static inline void mp_config_ioapic_for_sci(int irq)
static inline void mp_config_ioapic_for_sci(u32 gsi)
{ }
#endif
#endif /*CONFIG_ACPI_BOOT*/
......
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