Skip to content

Commit

Permalink
x86: find nr_irqs_gsi with mp_ioapic_routing
Browse files Browse the repository at this point in the history
Impact: find right nr_irqs_gsi on some systems.

One test-system has gap between gsi's:

[    0.000000] ACPI: IOAPIC (id[0x04] address[0xfec00000] gsi_base[0])
[    0.000000] IOAPIC[0]: apic_id 4, version 0, address 0xfec00000, GSI 0-23
[    0.000000] ACPI: IOAPIC (id[0x05] address[0xfeafd000] gsi_base[48])
[    0.000000] IOAPIC[1]: apic_id 5, version 0, address 0xfeafd000, GSI 48-54
[    0.000000] ACPI: IOAPIC (id[0x06] address[0xfeafc000] gsi_base[56])
[    0.000000] IOAPIC[2]: apic_id 6, version 0, address 0xfeafc000, GSI 56-62
...
[    0.000000] nr_irqs_gsi: 38

So nr_irqs_gsi is not right. some irq for MSI will overwrite with io_apic.

need to get that with acpi_probe_gsi when acpi io_apic is used

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Yinghai Lu authored and Ingo Molnar committed Feb 9, 2009
1 parent e736ad5 commit 3f4a739
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
6 changes: 6 additions & 0 deletions arch/x86/include/asm/mpspec.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
u32 gsi);
extern void mp_config_acpi_legacy_irqs(void);
extern int mp_register_gsi(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);
Expand All @@ -71,6 +72,11 @@ mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
return 0;
}
#endif
#else /* !CONFIG_ACPI: */
static inline int acpi_probe_gsi(void)
{
return 0;
}
#endif /* CONFIG_ACPI */

#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
Expand Down
23 changes: 23 additions & 0 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,29 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
nr_ioapics++;
}

int __init acpi_probe_gsi(void)
{
int idx;
int gsi;
int max_gsi = 0;

if (acpi_disabled)
return 0;

if (!acpi_ioapic)
return 0;

max_gsi = 0;
for (idx = 0; idx < nr_ioapics; idx++) {
gsi = mp_ioapic_routing[idx].gsi_end;

if (gsi > max_gsi)
max_gsi = gsi;
}

return max_gsi + 1;
}

static void assign_to_mp_irq(struct mp_config_intsrc *m,
struct mp_config_intsrc *mp_irq)
{
Expand Down
20 changes: 15 additions & 5 deletions arch/x86/kernel/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3841,14 +3841,24 @@ int __init io_apic_get_redir_entries (int ioapic)

void __init probe_nr_irqs_gsi(void)
{
int idx;
int nr = 0;

for (idx = 0; idx < nr_ioapics; idx++)
nr += io_apic_get_redir_entries(idx) + 1;

if (nr > nr_irqs_gsi)
nr = acpi_probe_gsi();
if (nr > nr_irqs_gsi) {
nr_irqs_gsi = nr;
} else {
/* for acpi=off or acpi is not compiled in */
int idx;

nr = 0;
for (idx = 0; idx < nr_ioapics; idx++)
nr += io_apic_get_redir_entries(idx) + 1;

if (nr > nr_irqs_gsi)
nr_irqs_gsi = nr;
}

printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}

/* --------------------------------------------------------------------------
Expand Down

0 comments on commit 3f4a739

Please sign in to comment.