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