aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/acpi/boot.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-14 16:43:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-14 16:43:24 -0400
commita3da5bf84a97d48cfaf66c6842470fc403da5121 (patch)
treecdf66c0cff8c61eedd60601fc9dffdd1ed39b880 /arch/x86/kernel/acpi/boot.c
parent3b23e665b68387f5ee7b21f7b75ceea4d9acae4a (diff)
parentd59fdcf2ac501de99c3dfb452af5e254d4342886 (diff)
Merge branch 'x86/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (821 commits) x86: make 64bit hpet_set_mapping to use ioremap too, v2 x86: get x86_phys_bits early x86: max_low_pfn_mapped fix #4 x86: change _node_to_cpumask_ptr to return const ptr x86: I/O APIC: remove an IRQ2-mask hack x86: fix numaq_tsc_disable calling x86, e820: remove end_user_pfn x86: max_low_pfn_mapped fix, #3 x86: max_low_pfn_mapped fix, #2 x86: max_low_pfn_mapped fix, #1 x86_64: fix delayed signals x86: remove conflicting nx6325 and nx6125 quirks x86: Recover timer_ack lost in the merge of the NMI watchdog x86: I/O APIC: Never configure IRQ2 x86: L-APIC: Always fully configure IRQ0 x86: L-APIC: Set IRQ0 as edge-triggered x86: merge dwarf2 headers x86: use AS_CFI instead of UNWIND_INFO x86: use ignore macro instead of hash comment x86: use matching CFI_ENDPROC ...
Diffstat (limited to 'arch/x86/kernel/acpi/boot.c')
-rw-r--r--arch/x86/kernel/acpi/boot.c442
1 files changed, 415 insertions, 27 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 33c5216fd3e1..f489d7a9be92 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -37,6 +37,7 @@
37#include <asm/pgtable.h> 37#include <asm/pgtable.h>
38#include <asm/io_apic.h> 38#include <asm/io_apic.h>
39#include <asm/apic.h> 39#include <asm/apic.h>
40#include <asm/genapic.h>
40#include <asm/io.h> 41#include <asm/io.h>
41#include <asm/mpspec.h> 42#include <asm/mpspec.h>
42#include <asm/smp.h> 43#include <asm/smp.h>
@@ -106,21 +107,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
106 */ 107 */
107enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; 108enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
108 109
109#ifdef CONFIG_X86_64
110
111/* rely on all ACPI tables being in the direct mapping */
112char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size)
113{
114 if (!phys_addr || !size)
115 return NULL;
116
117 if (phys_addr+size <= (max_pfn_mapped << PAGE_SHIFT) + PAGE_SIZE)
118 return __va(phys_addr);
119
120 return NULL;
121}
122
123#else
124 110
125/* 111/*
126 * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, 112 * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
@@ -139,11 +125,15 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
139 unsigned long base, offset, mapped_size; 125 unsigned long base, offset, mapped_size;
140 int idx; 126 int idx;
141 127
142 if (phys + size < 8 * 1024 * 1024) 128 if (!phys || !size)
129 return NULL;
130
131 if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT))
143 return __va(phys); 132 return __va(phys);
144 133
145 offset = phys & (PAGE_SIZE - 1); 134 offset = phys & (PAGE_SIZE - 1);
146 mapped_size = PAGE_SIZE - offset; 135 mapped_size = PAGE_SIZE - offset;
136 clear_fixmap(FIX_ACPI_END);
147 set_fixmap(FIX_ACPI_END, phys); 137 set_fixmap(FIX_ACPI_END, phys);
148 base = fix_to_virt(FIX_ACPI_END); 138 base = fix_to_virt(FIX_ACPI_END);
149 139
@@ -155,13 +145,13 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)
155 if (--idx < FIX_ACPI_BEGIN) 145 if (--idx < FIX_ACPI_BEGIN)
156 return NULL; /* cannot handle this */ 146 return NULL; /* cannot handle this */
157 phys += PAGE_SIZE; 147 phys += PAGE_SIZE;
148 clear_fixmap(idx);
158 set_fixmap(idx, phys); 149 set_fixmap(idx, phys);
159 mapped_size += PAGE_SIZE; 150 mapped_size += PAGE_SIZE;
160 } 151 }
161 152
162 return ((unsigned char *)base + offset); 153 return ((unsigned char *)base + offset);
163} 154}
164#endif
165 155
166#ifdef CONFIG_PCI_MMCONFIG 156#ifdef CONFIG_PCI_MMCONFIG
167/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ 157/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
@@ -338,8 +328,6 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
338 328
339#ifdef CONFIG_X86_IO_APIC 329#ifdef CONFIG_X86_IO_APIC
340 330
341struct mp_ioapic_routing mp_ioapic_routing[MAX_IO_APICS];
342
343static int __init 331static int __init
344acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) 332acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
345{ 333{
@@ -514,8 +502,6 @@ int acpi_register_gsi(u32 gsi, int triggering, int polarity)
514 * Make sure all (legacy) PCI IRQs are set as level-triggered. 502 * Make sure all (legacy) PCI IRQs are set as level-triggered.
515 */ 503 */
516 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { 504 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
517 extern void eisa_set_level_irq(unsigned int irq);
518
519 if (triggering == ACPI_LEVEL_SENSITIVE) 505 if (triggering == ACPI_LEVEL_SENSITIVE)
520 eisa_set_level_irq(gsi); 506 eisa_set_level_irq(gsi);
521 } 507 }
@@ -860,6 +846,364 @@ static int __init acpi_parse_madt_lapic_entries(void)
860#endif /* CONFIG_X86_LOCAL_APIC */ 846#endif /* CONFIG_X86_LOCAL_APIC */
861 847
862#ifdef CONFIG_X86_IO_APIC 848#ifdef CONFIG_X86_IO_APIC
849#define MP_ISA_BUS 0
850
851#ifdef CONFIG_X86_ES7000
852extern int es7000_plat;
853#endif
854
855static struct {
856 int apic_id;
857 int gsi_base;
858 int gsi_end;
859 DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
860} mp_ioapic_routing[MAX_IO_APICS];
861
862static int mp_find_ioapic(int gsi)
863{
864 int i = 0;
865
866 /* Find the IOAPIC that manages this GSI. */
867 for (i = 0; i < nr_ioapics; i++) {
868 if ((gsi >= mp_ioapic_routing[i].gsi_base)
869 && (gsi <= mp_ioapic_routing[i].gsi_end))
870 return i;
871 }
872
873 printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
874 return -1;
875}
876
877static u8 __init uniq_ioapic_id(u8 id)
878{
879#ifdef CONFIG_X86_32
880 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
881 !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
882 return io_apic_get_unique_id(nr_ioapics, id);
883 else
884 return id;
885#else
886 int i;
887 DECLARE_BITMAP(used, 256);
888 bitmap_zero(used, 256);
889 for (i = 0; i < nr_ioapics; i++) {
890 struct mp_config_ioapic *ia = &mp_ioapics[i];
891 __set_bit(ia->mp_apicid, used);
892 }
893 if (!test_bit(id, used))
894 return id;
895 return find_first_zero_bit(used, 256);
896#endif
897}
898
899static int bad_ioapic(unsigned long address)
900{
901 if (nr_ioapics >= MAX_IO_APICS) {
902 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
903 "(found %d)\n", MAX_IO_APICS, nr_ioapics);
904 panic("Recompile kernel with bigger MAX_IO_APICS!\n");
905 }
906 if (!address) {
907 printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
908 " found in table, skipping!\n");
909 return 1;
910 }
911 return 0;
912}
913
914void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
915{
916 int idx = 0;
917
918 if (bad_ioapic(address))
919 return;
920
921 idx = nr_ioapics;
922
923 mp_ioapics[idx].mp_type = MP_IOAPIC;
924 mp_ioapics[idx].mp_flags = MPC_APIC_USABLE;
925 mp_ioapics[idx].mp_apicaddr = address;
926
927 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
928 mp_ioapics[idx].mp_apicid = uniq_ioapic_id(id);
929#ifdef CONFIG_X86_32
930 mp_ioapics[idx].mp_apicver = io_apic_get_version(idx);
931#else
932 mp_ioapics[idx].mp_apicver = 0;
933#endif
934 /*
935 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
936 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
937 */
938 mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mp_apicid;
939 mp_ioapic_routing[idx].gsi_base = gsi_base;
940 mp_ioapic_routing[idx].gsi_end = gsi_base +
941 io_apic_get_redir_entries(idx);
942
943 printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
944 "GSI %d-%d\n", idx, mp_ioapics[idx].mp_apicid,
945 mp_ioapics[idx].mp_apicver, mp_ioapics[idx].mp_apicaddr,
946 mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
947
948 nr_ioapics++;
949}
950
951static void assign_to_mp_irq(struct mp_config_intsrc *m,
952 struct mp_config_intsrc *mp_irq)
953{
954 memcpy(mp_irq, m, sizeof(struct mp_config_intsrc));
955}
956
957static int mp_irq_cmp(struct mp_config_intsrc *mp_irq,
958 struct mp_config_intsrc *m)
959{
960 return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc));
961}
962
963static void save_mp_irq(struct mp_config_intsrc *m)
964{
965 int i;
966
967 for (i = 0; i < mp_irq_entries; i++) {
968 if (!mp_irq_cmp(&mp_irqs[i], m))
969 return;
970 }
971
972 assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
973 if (++mp_irq_entries == MAX_IRQ_SOURCES)
974 panic("Max # of irq sources exceeded!!\n");
975}
976
977void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
978{
979 int ioapic;
980 int pin;
981 struct mp_config_intsrc mp_irq;
982
983 /*
984 * Convert 'gsi' to 'ioapic.pin'.
985 */
986 ioapic = mp_find_ioapic(gsi);
987 if (ioapic < 0)
988 return;
989 pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
990
991 /*
992 * TBD: This check is for faulty timer entries, where the override
993 * erroneously sets the trigger to level, resulting in a HUGE
994 * increase of timer interrupts!
995 */
996 if ((bus_irq == 0) && (trigger == 3))
997 trigger = 1;
998
999 mp_irq.mp_type = MP_INTSRC;
1000 mp_irq.mp_irqtype = mp_INT;
1001 mp_irq.mp_irqflag = (trigger << 2) | polarity;
1002 mp_irq.mp_srcbus = MP_ISA_BUS;
1003 mp_irq.mp_srcbusirq = bus_irq; /* IRQ */
1004 mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */
1005 mp_irq.mp_dstirq = pin; /* INTIN# */
1006
1007 save_mp_irq(&mp_irq);
1008}
1009
1010void __init mp_config_acpi_legacy_irqs(void)
1011{
1012 int i;
1013 int ioapic;
1014 unsigned int dstapic;
1015 struct mp_config_intsrc mp_irq;
1016
1017#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
1018 /*
1019 * Fabricate the legacy ISA bus (bus #31).
1020 */
1021 mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
1022#endif
1023 set_bit(MP_ISA_BUS, mp_bus_not_pci);
1024 Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
1025
1026#ifdef CONFIG_X86_ES7000
1027 /*
1028 * Older generations of ES7000 have no legacy identity mappings
1029 */
1030 if (es7000_plat == 1)
1031 return;
1032#endif
1033
1034 /*
1035 * Locate the IOAPIC that manages the ISA IRQs (0-15).
1036 */
1037 ioapic = mp_find_ioapic(0);
1038 if (ioapic < 0)
1039 return;
1040 dstapic = mp_ioapics[ioapic].mp_apicid;
1041
1042 /*
1043 * Use the default configuration for the IRQs 0-15. Unless
1044 * overridden by (MADT) interrupt source override entries.
1045 */
1046 for (i = 0; i < 16; i++) {
1047 int idx;
1048
1049 for (idx = 0; idx < mp_irq_entries; idx++) {
1050 struct mp_config_intsrc *irq = mp_irqs + idx;
1051
1052 /* Do we already have a mapping for this ISA IRQ? */
1053 if (irq->mp_srcbus == MP_ISA_BUS
1054 && irq->mp_srcbusirq == i)
1055 break;
1056
1057 /* Do we already have a mapping for this IOAPIC pin */
1058 if (irq->mp_dstapic == dstapic &&
1059 irq->mp_dstirq == i)
1060 break;
1061 }
1062
1063 if (idx != mp_irq_entries) {
1064 printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
1065 continue; /* IRQ already used */
1066 }
1067
1068 mp_irq.mp_type = MP_INTSRC;
1069 mp_irq.mp_irqflag = 0; /* Conforming */
1070 mp_irq.mp_srcbus = MP_ISA_BUS;
1071 mp_irq.mp_dstapic = dstapic;
1072 mp_irq.mp_irqtype = mp_INT;
1073 mp_irq.mp_srcbusirq = i; /* Identity mapped */
1074 mp_irq.mp_dstirq = i;
1075
1076 save_mp_irq(&mp_irq);
1077 }
1078}
1079
1080int mp_register_gsi(u32 gsi, int triggering, int polarity)
1081{
1082 int ioapic;
1083 int ioapic_pin;
1084#ifdef CONFIG_X86_32
1085#define MAX_GSI_NUM 4096
1086#define IRQ_COMPRESSION_START 64
1087
1088 static int pci_irq = IRQ_COMPRESSION_START;
1089 /*
1090 * Mapping between Global System Interrupts, which
1091 * represent all possible interrupts, and IRQs
1092 * assigned to actual devices.
1093 */
1094 static int gsi_to_irq[MAX_GSI_NUM];
1095#else
1096
1097 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
1098 return gsi;
1099#endif
1100
1101 /* Don't set up the ACPI SCI because it's already set up */
1102 if (acpi_gbl_FADT.sci_interrupt == gsi)
1103 return gsi;
1104
1105 ioapic = mp_find_ioapic(gsi);
1106 if (ioapic < 0) {
1107 printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
1108 return gsi;
1109 }
1110
1111 ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
1112
1113#ifdef CONFIG_X86_32
1114 if (ioapic_renumber_irq)
1115 gsi = ioapic_renumber_irq(ioapic, gsi);
1116#endif
1117
1118 /*
1119 * Avoid pin reprogramming. PRTs typically include entries
1120 * with redundant pin->gsi mappings (but unique PCI devices);
1121 * we only program the IOAPIC on the first.
1122 */
1123 if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
1124 printk(KERN_ERR "Invalid reference to IOAPIC pin "
1125 "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
1126 ioapic_pin);
1127 return gsi;
1128 }
1129 if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
1130 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
1131 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1132#ifdef CONFIG_X86_32
1133 return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
1134#else
1135 return gsi;
1136#endif
1137 }
1138
1139 set_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed);
1140#ifdef CONFIG_X86_32
1141 /*
1142 * For GSI >= 64, use IRQ compression
1143 */
1144 if ((gsi >= IRQ_COMPRESSION_START)
1145 && (triggering == ACPI_LEVEL_SENSITIVE)) {
1146 /*
1147 * For PCI devices assign IRQs in order, avoiding gaps
1148 * due to unused I/O APIC pins.
1149 */
1150 int irq = gsi;
1151 if (gsi < MAX_GSI_NUM) {
1152 /*
1153 * Retain the VIA chipset work-around (gsi > 15), but
1154 * avoid a problem where the 8254 timer (IRQ0) is setup
1155 * via an override (so it's not on pin 0 of the ioapic),
1156 * and at the same time, the pin 0 interrupt is a PCI
1157 * type. The gsi > 15 test could cause these two pins
1158 * to be shared as IRQ0, and they are not shareable.
1159 * So test for this condition, and if necessary, avoid
1160 * the pin collision.
1161 */
1162 gsi = pci_irq++;
1163 /*
1164 * Don't assign IRQ used by ACPI SCI
1165 */
1166 if (gsi == acpi_gbl_FADT.sci_interrupt)
1167 gsi = pci_irq++;
1168 gsi_to_irq[irq] = gsi;
1169 } else {
1170 printk(KERN_ERR "GSI %u is too high\n", gsi);
1171 return gsi;
1172 }
1173 }
1174#endif
1175 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
1176 triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
1177 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
1178 return gsi;
1179}
1180
1181int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
1182 u32 gsi, int triggering, int polarity)
1183{
1184#ifdef CONFIG_X86_MPPARSE
1185 struct mp_config_intsrc mp_irq;
1186 int ioapic;
1187
1188 if (!acpi_ioapic)
1189 return 0;
1190
1191 /* print the entry should happen on mptable identically */
1192 mp_irq.mp_type = MP_INTSRC;
1193 mp_irq.mp_irqtype = mp_INT;
1194 mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
1195 (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
1196 mp_irq.mp_srcbus = number;
1197 mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
1198 ioapic = mp_find_ioapic(gsi);
1199 mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id;
1200 mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;
1201
1202 save_mp_irq(&mp_irq);
1203#endif
1204 return 0;
1205}
1206
863/* 1207/*
864 * Parse IOAPIC related entries in MADT 1208 * Parse IOAPIC related entries in MADT
865 * returns 0 on success, < 0 on error 1209 * returns 0 on success, < 0 on error
@@ -1009,8 +1353,6 @@ static void __init acpi_process_madt(void)
1009 return; 1353 return;
1010} 1354}
1011 1355
1012#ifdef __i386__
1013
1014static int __init disable_acpi_irq(const struct dmi_system_id *d) 1356static int __init disable_acpi_irq(const struct dmi_system_id *d)
1015{ 1357{
1016 if (!acpi_force) { 1358 if (!acpi_force) {
@@ -1061,6 +1403,16 @@ static int __init force_acpi_ht(const struct dmi_system_id *d)
1061} 1403}
1062 1404
1063/* 1405/*
1406 * Force ignoring BIOS IRQ0 pin2 override
1407 */
1408static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
1409{
1410 pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", d->ident);
1411 acpi_skip_timer_override = 1;
1412 return 0;
1413}
1414
1415/*
1064 * If your system is blacklisted here, but you find that acpi=force 1416 * If your system is blacklisted here, but you find that acpi=force
1065 * works for you, please contact acpi-devel@sourceforge.net 1417 * works for you, please contact acpi-devel@sourceforge.net
1066 */ 1418 */
@@ -1227,11 +1579,35 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
1227 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), 1579 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
1228 }, 1580 },
1229 }, 1581 },
1582 /*
1583 * HP laptops which use a DSDT reporting as HP/SB400/10000,
1584 * which includes some code which overrides all temperature
1585 * trip points to 16C if the INTIN2 input of the I/O APIC
1586 * is enabled. This input is incorrectly designated the
1587 * ISA IRQ 0 via an interrupt source override even though
1588 * it is wired to the output of the master 8259A and INTIN0
1589 * is not connected at all. Force ignoring BIOS IRQ0 pin2
1590 * override in that cases.
1591 */
1592 {
1593 .callback = dmi_ignore_irq0_timer_override,
1594 .ident = "HP NX6125 laptop",
1595 .matches = {
1596 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1597 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"),
1598 },
1599 },
1600 {
1601 .callback = dmi_ignore_irq0_timer_override,
1602 .ident = "HP NX6325 laptop",
1603 .matches = {
1604 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1605 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
1606 },
1607 },
1230 {} 1608 {}
1231}; 1609};
1232 1610
1233#endif /* __i386__ */
1234
1235/* 1611/*
1236 * acpi_boot_table_init() and acpi_boot_init() 1612 * acpi_boot_table_init() and acpi_boot_init()
1237 * called from setup_arch(), always. 1613 * called from setup_arch(), always.
@@ -1259,9 +1635,7 @@ int __init acpi_boot_table_init(void)
1259{ 1635{
1260 int error; 1636 int error;
1261 1637
1262#ifdef __i386__
1263 dmi_check_system(acpi_dmi_table); 1638 dmi_check_system(acpi_dmi_table);
1264#endif
1265 1639
1266 /* 1640 /*
1267 * If acpi_disabled, bail out 1641 * If acpi_disabled, bail out
@@ -1386,6 +1760,20 @@ static int __init parse_pci(char *arg)
1386} 1760}
1387early_param("pci", parse_pci); 1761early_param("pci", parse_pci);
1388 1762
1763int __init acpi_mps_check(void)
1764{
1765#if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE)
1766/* mptable code is not built-in*/
1767 if (acpi_disabled || acpi_noirq) {
1768 printk(KERN_WARNING "MPS support code is not built-in.\n"
1769 "Using acpi=off or acpi=noirq or pci=noacpi "
1770 "may have problem\n");
1771 return 1;
1772 }
1773#endif
1774 return 0;
1775}
1776
1389#ifdef CONFIG_X86_IO_APIC 1777#ifdef CONFIG_X86_IO_APIC
1390static int __init parse_acpi_skip_timer_override(char *arg) 1778static int __init parse_acpi_skip_timer_override(char *arg)
1391{ 1779{