aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-02-08 19:18:03 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-09 06:42:59 -0500
commit3f4a739c6accd651a11fcf3c7a20ec8147c42660 (patch)
treea96659b8ad16ffc9c96846413128e1b7413918d8
parente736ad548db152776de61d7a26805cfae77ce5ce (diff)
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>
-rw-r--r--arch/x86/include/asm/mpspec.h6
-rw-r--r--arch/x86/kernel/acpi/boot.c23
-rw-r--r--arch/x86/kernel/io_apic.c20
3 files changed, 44 insertions, 5 deletions
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 62d14ce3cd00..bd22f2a3713f 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -60,6 +60,7 @@ extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
60 u32 gsi); 60 u32 gsi);
61extern void mp_config_acpi_legacy_irqs(void); 61extern void mp_config_acpi_legacy_irqs(void);
62extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low); 62extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low);
63extern int acpi_probe_gsi(void);
63#ifdef CONFIG_X86_IO_APIC 64#ifdef CONFIG_X86_IO_APIC
64extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, 65extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
65 u32 gsi, int triggering, int polarity); 66 u32 gsi, int triggering, int polarity);
@@ -71,6 +72,11 @@ mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
71 return 0; 72 return 0;
72} 73}
73#endif 74#endif
75#else /* !CONFIG_ACPI: */
76static inline int acpi_probe_gsi(void)
77{
78 return 0;
79}
74#endif /* CONFIG_ACPI */ 80#endif /* CONFIG_ACPI */
75 81
76#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) 82#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index d37593c2f438..7678f10c4568 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -973,6 +973,29 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
973 nr_ioapics++; 973 nr_ioapics++;
974} 974}
975 975
976int __init acpi_probe_gsi(void)
977{
978 int idx;
979 int gsi;
980 int max_gsi = 0;
981
982 if (acpi_disabled)
983 return 0;
984
985 if (!acpi_ioapic)
986 return 0;
987
988 max_gsi = 0;
989 for (idx = 0; idx < nr_ioapics; idx++) {
990 gsi = mp_ioapic_routing[idx].gsi_end;
991
992 if (gsi > max_gsi)
993 max_gsi = gsi;
994 }
995
996 return max_gsi + 1;
997}
998
976static void assign_to_mp_irq(struct mp_config_intsrc *m, 999static void assign_to_mp_irq(struct mp_config_intsrc *m,
977 struct mp_config_intsrc *mp_irq) 1000 struct mp_config_intsrc *mp_irq)
978{ 1001{
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index 9b0c480c383b..bc7ac4da90d7 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -3841,14 +3841,24 @@ int __init io_apic_get_redir_entries (int ioapic)
3841 3841
3842void __init probe_nr_irqs_gsi(void) 3842void __init probe_nr_irqs_gsi(void)
3843{ 3843{
3844 int idx;
3845 int nr = 0; 3844 int nr = 0;
3846 3845
3847 for (idx = 0; idx < nr_ioapics; idx++) 3846 nr = acpi_probe_gsi();
3848 nr += io_apic_get_redir_entries(idx) + 1; 3847 if (nr > nr_irqs_gsi) {
3849
3850 if (nr > nr_irqs_gsi)
3851 nr_irqs_gsi = nr; 3848 nr_irqs_gsi = nr;
3849 } else {
3850 /* for acpi=off or acpi is not compiled in */
3851 int idx;
3852
3853 nr = 0;
3854 for (idx = 0; idx < nr_ioapics; idx++)
3855 nr += io_apic_get_redir_entries(idx) + 1;
3856
3857 if (nr > nr_irqs_gsi)
3858 nr_irqs_gsi = nr;
3859 }
3860
3861 printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
3852} 3862}
3853 3863
3854/* -------------------------------------------------------------------------- 3864/* --------------------------------------------------------------------------