x86: find nr_irqs_gsi with mp_ioapic_routing
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>
This commit is contained in:
Родитель
f72dccace7
Коммит
cc6c50066e
|
@ -73,6 +73,7 @@ extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
|
||||||
u32 gsi);
|
u32 gsi);
|
||||||
extern void mp_config_acpi_legacy_irqs(void);
|
extern void mp_config_acpi_legacy_irqs(void);
|
||||||
extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low);
|
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
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
|
extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
|
||||||
u32 gsi, int triggering, int polarity);
|
u32 gsi, int triggering, int polarity);
|
||||||
|
@ -84,6 +85,11 @@ mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#else /* !CONFIG_ACPI: */
|
||||||
|
static inline int acpi_probe_gsi(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* CONFIG_ACPI */
|
#endif /* CONFIG_ACPI */
|
||||||
|
|
||||||
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
|
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
|
||||||
|
|
|
@ -961,6 +961,29 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
|
||||||
nr_ioapics++;
|
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 mpc_intsrc *m,
|
static void assign_to_mp_irq(struct mpc_intsrc *m,
|
||||||
struct mpc_intsrc *mp_irq)
|
struct mpc_intsrc *mp_irq)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3824,9 +3824,16 @@ int __init io_apic_get_redir_entries (int ioapic)
|
||||||
|
|
||||||
void __init probe_nr_irqs_gsi(void)
|
void __init probe_nr_irqs_gsi(void)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
|
|
||||||
|
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++)
|
for (idx = 0; idx < nr_ioapics; idx++)
|
||||||
nr += io_apic_get_redir_entries(idx) + 1;
|
nr += io_apic_get_redir_entries(idx) + 1;
|
||||||
|
|
||||||
|
@ -3834,6 +3841,9 @@ void __init probe_nr_irqs_gsi(void)
|
||||||
nr_irqs_gsi = nr;
|
nr_irqs_gsi = nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SPARSE_IRQ
|
#ifdef CONFIG_SPARSE_IRQ
|
||||||
int __init arch_probe_nr_irqs(void)
|
int __init arch_probe_nr_irqs(void)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче