diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-06-18 20:29:31 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 04:39:07 -0400 |
commit | fcfa146e412023dd55f8855f240b2c2082dc1baa (patch) | |
tree | 76cc7c6a9b9cd1f303f2cc4f4360d9f3ce2123a5 /arch/x86/kernel/acpi/boot.c | |
parent | 95a71a45c250177854f7c530810c88a8a19a443b (diff) |
x86: update mptable fix with no ioapic v2
if the system doesn't have ioapic, we don't need to store entries for mptable
update
also let mp_config_acpi_gsi not call func in mpparse
so later could decouple mpparse with acpi more easily
Reported-by: Daniel Exner <dex@dragonslave.de>
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Daniel Exner <dex@dragonslave.de>
Cc: Len Brown <lenb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/acpi/boot.c')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 87 |
1 files changed, 56 insertions, 31 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 29b365a66cf3..91bb9a99338d 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -960,10 +960,37 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | |||
960 | nr_ioapics++; | 960 | nr_ioapics++; |
961 | } | 961 | } |
962 | 962 | ||
963 | static void assign_to_mp_irq(struct mp_config_intsrc *m, | ||
964 | struct mp_config_intsrc *mp_irq) | ||
965 | { | ||
966 | memcpy(mp_irq, m, sizeof(struct mp_config_intsrc)); | ||
967 | } | ||
968 | |||
969 | static int mp_irq_cmp(struct mp_config_intsrc *mp_irq, | ||
970 | struct mp_config_intsrc *m) | ||
971 | { | ||
972 | return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc)); | ||
973 | } | ||
974 | |||
975 | static void save_mp_irq(struct mp_config_intsrc *m) | ||
976 | { | ||
977 | int i; | ||
978 | |||
979 | for (i = 0; i < mp_irq_entries; i++) { | ||
980 | if (!mp_irq_cmp(&mp_irqs[i], m)) | ||
981 | return; | ||
982 | } | ||
983 | |||
984 | assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]); | ||
985 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
986 | panic("Max # of irq sources exceeded!!\n"); | ||
987 | } | ||
988 | |||
963 | void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | 989 | void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) |
964 | { | 990 | { |
965 | int ioapic; | 991 | int ioapic; |
966 | int pin; | 992 | int pin; |
993 | struct mp_config_intsrc mp_irq; | ||
967 | 994 | ||
968 | /* | 995 | /* |
969 | * Convert 'gsi' to 'ioapic.pin'. | 996 | * Convert 'gsi' to 'ioapic.pin'. |
@@ -981,18 +1008,15 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | |||
981 | if ((bus_irq == 0) && (trigger == 3)) | 1008 | if ((bus_irq == 0) && (trigger == 3)) |
982 | trigger = 1; | 1009 | trigger = 1; |
983 | 1010 | ||
984 | mp_irqs[mp_irq_entries].mp_type = MP_INTSRC; | 1011 | mp_irq.mp_type = MP_INTSRC; |
985 | mp_irqs[mp_irq_entries].mp_irqtype = mp_INT; | 1012 | mp_irq.mp_irqtype = mp_INT; |
986 | mp_irqs[mp_irq_entries].mp_irqflag = (trigger << 2) | polarity; | 1013 | mp_irq.mp_irqflag = (trigger << 2) | polarity; |
987 | mp_irqs[mp_irq_entries].mp_srcbus = MP_ISA_BUS; | 1014 | mp_irq.mp_srcbus = MP_ISA_BUS; |
988 | mp_irqs[mp_irq_entries].mp_srcbusirq = bus_irq; /* IRQ */ | 1015 | mp_irq.mp_srcbusirq = bus_irq; /* IRQ */ |
989 | mp_irqs[mp_irq_entries].mp_dstapic = | 1016 | mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */ |
990 | mp_ioapics[ioapic].mp_apicid; /* APIC ID */ | 1017 | mp_irq.mp_dstirq = pin; /* INTIN# */ |
991 | mp_irqs[mp_irq_entries].mp_dstirq = pin; /* INTIN# */ | ||
992 | |||
993 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
994 | panic("Max # of irq sources exceeded!!\n"); | ||
995 | 1018 | ||
1019 | save_mp_irq(&mp_irq); | ||
996 | } | 1020 | } |
997 | 1021 | ||
998 | void __init mp_config_acpi_legacy_irqs(void) | 1022 | void __init mp_config_acpi_legacy_irqs(void) |
@@ -1000,6 +1024,7 @@ void __init mp_config_acpi_legacy_irqs(void) | |||
1000 | int i; | 1024 | int i; |
1001 | int ioapic; | 1025 | int ioapic; |
1002 | unsigned int dstapic; | 1026 | unsigned int dstapic; |
1027 | struct mp_config_intsrc mp_irq; | ||
1003 | 1028 | ||
1004 | #if defined (CONFIG_MCA) || defined (CONFIG_EISA) | 1029 | #if defined (CONFIG_MCA) || defined (CONFIG_EISA) |
1005 | /* | 1030 | /* |
@@ -1052,16 +1077,15 @@ void __init mp_config_acpi_legacy_irqs(void) | |||
1052 | continue; /* IRQ already used */ | 1077 | continue; /* IRQ already used */ |
1053 | } | 1078 | } |
1054 | 1079 | ||
1055 | mp_irqs[mp_irq_entries].mp_type = MP_INTSRC; | 1080 | mp_irq.mp_type = MP_INTSRC; |
1056 | mp_irqs[mp_irq_entries].mp_irqflag = 0; /* Conforming */ | 1081 | mp_irq.mp_irqflag = 0; /* Conforming */ |
1057 | mp_irqs[mp_irq_entries].mp_srcbus = MP_ISA_BUS; | 1082 | mp_irq.mp_srcbus = MP_ISA_BUS; |
1058 | mp_irqs[mp_irq_entries].mp_dstapic = dstapic; | 1083 | mp_irq.mp_dstapic = dstapic; |
1059 | mp_irqs[mp_irq_entries].mp_irqtype = mp_INT; | 1084 | mp_irq.mp_irqtype = mp_INT; |
1060 | mp_irqs[mp_irq_entries].mp_srcbusirq = i; /* Identity mapped */ | 1085 | mp_irq.mp_srcbusirq = i; /* Identity mapped */ |
1061 | mp_irqs[mp_irq_entries].mp_dstirq = i; | 1086 | mp_irq.mp_dstirq = i; |
1062 | 1087 | ||
1063 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | 1088 | save_mp_irq(&mp_irq); |
1064 | panic("Max # of irq sources exceeded!!\n"); | ||
1065 | } | 1089 | } |
1066 | } | 1090 | } |
1067 | 1091 | ||
@@ -1169,25 +1193,26 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) | |||
1169 | int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, | 1193 | int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, |
1170 | u32 gsi, int triggering, int polarity) | 1194 | u32 gsi, int triggering, int polarity) |
1171 | { | 1195 | { |
1172 | struct mpc_config_intsrc intsrc; | 1196 | #ifdef CONFIG_X86_MPPARSE |
1197 | struct mp_config_intsrc mp_irq; | ||
1173 | int ioapic; | 1198 | int ioapic; |
1174 | 1199 | ||
1175 | if (!enable_update_mptable) | 1200 | if (!acpi_ioapic) |
1176 | return 0; | 1201 | return 0; |
1177 | 1202 | ||
1178 | /* print the entry should happen on mptable identically */ | 1203 | /* print the entry should happen on mptable identically */ |
1179 | intsrc.mpc_type = MP_INTSRC; | 1204 | mp_irq.mp_type = MP_INTSRC; |
1180 | intsrc.mpc_irqtype = mp_INT; | 1205 | mp_irq.mp_irqtype = mp_INT; |
1181 | intsrc.mpc_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | | 1206 | mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | |
1182 | (polarity == ACPI_ACTIVE_HIGH ? 1 : 3); | 1207 | (polarity == ACPI_ACTIVE_HIGH ? 1 : 3); |
1183 | intsrc.mpc_srcbus = number; | 1208 | mp_irq.mp_srcbus = number; |
1184 | intsrc.mpc_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); | 1209 | mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); |
1185 | ioapic = mp_find_ioapic(gsi); | 1210 | ioapic = mp_find_ioapic(gsi); |
1186 | intsrc.mpc_dstapic = mp_ioapic_routing[ioapic].apic_id; | 1211 | mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id; |
1187 | intsrc.mpc_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base; | 1212 | mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base; |
1188 | |||
1189 | MP_intsrc_info(&intsrc); | ||
1190 | 1213 | ||
1214 | save_mp_irq(&mp_irq); | ||
1215 | #endif | ||
1191 | return 0; | 1216 | return 0; |
1192 | } | 1217 | } |
1193 | 1218 | ||