Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6595 | serge | 1 | /* |
2 | * boot.c - Architecture-Specific Low-Level ACPI Boot Support |
||
3 | * |
||
4 | * Copyright (C) 2001, 2002 Paul Diefenbaugh |
||
5 | * Copyright (C) 2001 Jun Nakajima |
||
6 | * |
||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or modify |
||
10 | * it under the terms of the GNU General Public License as published by |
||
11 | * the Free Software Foundation; either version 2 of the License, or |
||
12 | * (at your option) any later version. |
||
13 | * |
||
14 | * This program is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | * GNU General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU General Public License |
||
20 | * along with this program; if not, write to the Free Software |
||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
22 | * |
||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||
24 | */ |
||
25 | |||
26 | #include |
||
27 | #include |
||
28 | #include |
||
29 | #include |
||
30 | #include |
||
31 | |||
32 | static inline void outb(u8 v, u16 port) |
||
33 | { |
||
34 | asm volatile("outb %0,%1" : : "a" (v), "dN" (port)); |
||
35 | } |
||
36 | static inline u8 inb(u16 port) |
||
37 | { |
||
38 | u8 v; |
||
39 | asm volatile("inb %1,%0" : "=a" (v) : "dN" (port)); |
||
40 | return v; |
||
41 | } |
||
42 | |||
43 | |||
44 | static int __initdata acpi_force = 0; |
||
45 | int acpi_disabled; |
||
46 | EXPORT_SYMBOL(acpi_disabled); |
||
47 | |||
48 | #ifdef CONFIG_X86_64 |
||
49 | # include |
||
50 | #endif /* X86 */ |
||
51 | |||
52 | #define PREFIX "ACPI: " |
||
53 | |||
54 | int acpi_noirq; /* skip ACPI IRQ initialization */ |
||
55 | int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ |
||
56 | EXPORT_SYMBOL(acpi_pci_disabled); |
||
57 | |||
58 | int acpi_ioapic; |
||
59 | int acpi_strict; |
||
60 | u8 acpi_sci_flags __initdata; |
||
61 | /* |
||
62 | * acpi_pic_sci_set_trigger() |
||
63 | * |
||
64 | * use ELCR to set PIC-mode trigger type for SCI |
||
65 | * |
||
66 | * If a PIC-mode SCI is not recognized or gives spurious IRQ7's |
||
67 | * it may require Edge Trigger -- use "acpi_sci=edge" |
||
68 | * |
||
69 | * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers |
||
70 | * for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge. |
||
71 | * ECLR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0) |
||
72 | * ECLR2 is IRQs 8-15 (IRQ 8, 13 must be 0) |
||
73 | */ |
||
74 | |||
75 | void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) |
||
76 | { |
||
77 | unsigned int mask = 1 << irq; |
||
78 | unsigned int old, new; |
||
79 | |||
80 | /* Real old ELCR mask */ |
||
81 | // old = inb(0x4d0) | (inb(0x4d1) << 8); |
||
82 | |||
83 | /* |
||
84 | * If we use ACPI to set PCI IRQs, then we should clear ELCR |
||
85 | * since we will set it correctly as we enable the PCI irq |
||
86 | * routing. |
||
87 | */ |
||
88 | new = acpi_noirq ? old : 0; |
||
89 | |||
90 | /* |
||
91 | * Update SCI information in the ELCR, it isn't in the PCI |
||
92 | * routing tables.. |
||
93 | */ |
||
94 | switch (trigger) { |
||
95 | case 1: /* Edge - clear */ |
||
96 | new &= ~mask; |
||
97 | break; |
||
98 | case 3: /* Level - set */ |
||
99 | new |= mask; |
||
100 | break; |
||
101 | } |
||
102 | |||
103 | if (old == new) |
||
104 | return; |
||
105 | |||
106 | printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old); |
||
107 | // outb(new, 0x4d0); |
||
108 | // outb(new >> 8, 0x4d1); |
||
109 | } |
||
110 | |||
111 | static int __init acpi_parse_sbf(struct acpi_table_header *table) |
||
112 | { |
||
113 | struct acpi_table_boot *sb = (struct acpi_table_boot *)table; |
||
114 | |||
115 | sbf_port = sb->cmos_index; /* Save CMOS port */ |
||
116 | |||
117 | return 0; |
||
118 | } |
||
119 | |||
120 | #ifdef CONFIG_HPET_TIMER |
||
121 | #include |
||
122 | |||
123 | static struct resource *hpet_res __initdata; |
||
124 | |||
125 | static int __init acpi_parse_hpet(struct acpi_table_header *table) |
||
126 | { |
||
127 | struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table; |
||
128 | |||
129 | if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) { |
||
130 | printk(KERN_WARNING PREFIX "HPET timers must be located in " |
||
131 | "memory.\n"); |
||
132 | return -1; |
||
133 | } |
||
134 | |||
135 | hpet_address = hpet_tbl->address.address; |
||
136 | hpet_blockid = hpet_tbl->sequence; |
||
137 | |||
138 | /* |
||
139 | * Some broken BIOSes advertise HPET at 0x0. We really do not |
||
140 | * want to allocate a resource there. |
||
141 | */ |
||
142 | if (!hpet_address) { |
||
143 | printk(KERN_WARNING PREFIX |
||
144 | "HPET id: %#x base: %#lx is invalid\n", |
||
145 | hpet_tbl->id, hpet_address); |
||
146 | return 0; |
||
147 | } |
||
148 | #ifdef CONFIG_X86_64 |
||
149 | /* |
||
150 | * Some even more broken BIOSes advertise HPET at |
||
151 | * 0xfed0000000000000 instead of 0xfed00000. Fix it up and add |
||
152 | * some noise: |
||
153 | */ |
||
154 | if (hpet_address == 0xfed0000000000000UL) { |
||
155 | if (!hpet_force_user) { |
||
156 | printk(KERN_WARNING PREFIX "HPET id: %#x " |
||
157 | "base: 0xfed0000000000000 is bogus\n " |
||
158 | "try hpet=force on the kernel command line to " |
||
159 | "fix it up to 0xfed00000.\n", hpet_tbl->id); |
||
160 | hpet_address = 0; |
||
161 | return 0; |
||
162 | } |
||
163 | printk(KERN_WARNING PREFIX |
||
164 | "HPET id: %#x base: 0xfed0000000000000 fixed up " |
||
165 | "to 0xfed00000.\n", hpet_tbl->id); |
||
166 | hpet_address >>= 32; |
||
167 | } |
||
168 | #endif |
||
169 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", |
||
170 | hpet_tbl->id, hpet_address); |
||
171 | |||
172 | /* |
||
173 | * Allocate and initialize the HPET firmware resource for adding into |
||
174 | * the resource tree during the lateinit timeframe. |
||
175 | */ |
||
176 | #define HPET_RESOURCE_NAME_SIZE 9 |
||
177 | hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); |
||
178 | |||
179 | hpet_res->name = (void *)&hpet_res[1]; |
||
180 | hpet_res->flags = IORESOURCE_MEM; |
||
181 | snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u", |
||
182 | hpet_tbl->sequence); |
||
183 | |||
184 | hpet_res->start = hpet_address; |
||
185 | hpet_res->end = hpet_address + (1 * 1024) - 1; |
||
186 | |||
187 | return 0; |
||
188 | } |
||
189 | |||
190 | /* |
||
191 | * hpet_insert_resource inserts the HPET resources used into the resource |
||
192 | * tree. |
||
193 | */ |
||
194 | static __init int hpet_insert_resource(void) |
||
195 | { |
||
196 | if (!hpet_res) |
||
197 | return 1; |
||
198 | |||
199 | return insert_resource(&iomem_resource, hpet_res); |
||
200 | } |
||
201 | |||
202 | late_initcall(hpet_insert_resource); |
||
203 | |||
204 | #else |
||
205 | #define acpi_parse_hpet NULL |
||
206 | #endif |
||
207 | |||
208 | static int __init acpi_parse_fadt(struct acpi_table_header *table) |
||
209 | { |
||
210 | |||
211 | #ifdef CONFIG_X86_PM_TIMER |
||
212 | /* detect the location of the ACPI PM Timer */ |
||
213 | if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) { |
||
214 | /* FADT rev. 2 */ |
||
215 | if (acpi_gbl_FADT.xpm_timer_block.space_id != |
||
216 | ACPI_ADR_SPACE_SYSTEM_IO) |
||
217 | return 0; |
||
218 | |||
219 | pmtmr_ioport = acpi_gbl_FADT.xpm_timer_block.address; |
||
220 | /* |
||
221 | * "X" fields are optional extensions to the original V1.0 |
||
222 | * fields, so we must selectively expand V1.0 fields if the |
||
223 | * corresponding X field is zero. |
||
224 | */ |
||
225 | if (!pmtmr_ioport) |
||
226 | pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; |
||
227 | } else { |
||
228 | /* FADT rev. 1 */ |
||
229 | pmtmr_ioport = acpi_gbl_FADT.pm_timer_block; |
||
230 | } |
||
231 | if (pmtmr_ioport) |
||
232 | printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", |
||
233 | pmtmr_ioport); |
||
234 | #endif |
||
235 | return 0; |
||
236 | } |
||
237 | |||
238 | |||
239 | #ifdef CONFIG_X86_IO_APIC |
||
240 | #else |
||
241 | static inline int acpi_parse_madt_ioapic_entries(void) |
||
242 | { |
||
243 | return -1; |
||
244 | } |
||
245 | #endif /* !CONFIG_X86_IO_APIC */ |
||
246 | |||
247 | static void __init early_acpi_process_madt(void) |
||
248 | { |
||
249 | #ifdef CONFIG_X86_LOCAL_APIC |
||
250 | int error; |
||
251 | |||
252 | if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { |
||
253 | |||
254 | /* |
||
255 | * Parse MADT LAPIC entries |
||
256 | */ |
||
257 | error = early_acpi_parse_madt_lapic_addr_ovr(); |
||
258 | if (!error) { |
||
259 | acpi_lapic = 1; |
||
260 | smp_found_config = 1; |
||
261 | } |
||
262 | if (error == -EINVAL) { |
||
263 | /* |
||
264 | * Dell Precision Workstation 410, 610 come here. |
||
265 | */ |
||
266 | printk(KERN_ERR PREFIX |
||
267 | "Invalid BIOS MADT, disabling ACPI\n"); |
||
268 | disable_acpi(); |
||
269 | } |
||
270 | } |
||
271 | #endif |
||
272 | } |
||
273 | |||
274 | static void __init acpi_process_madt(void) |
||
275 | { |
||
276 | #ifdef CONFIG_X86_LOCAL_APIC |
||
277 | int error; |
||
278 | |||
279 | if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { |
||
280 | |||
281 | /* |
||
282 | * Parse MADT LAPIC entries |
||
283 | */ |
||
284 | error = acpi_parse_madt_lapic_entries(); |
||
285 | if (!error) { |
||
286 | acpi_lapic = 1; |
||
287 | |||
288 | /* |
||
289 | * Parse MADT IO-APIC entries |
||
290 | */ |
||
291 | mutex_lock(&acpi_ioapic_lock); |
||
292 | error = acpi_parse_madt_ioapic_entries(); |
||
293 | mutex_unlock(&acpi_ioapic_lock); |
||
294 | if (!error) { |
||
295 | acpi_set_irq_model_ioapic(); |
||
296 | |||
297 | smp_found_config = 1; |
||
298 | } |
||
299 | } |
||
300 | if (error == -EINVAL) { |
||
301 | /* |
||
302 | * Dell Precision Workstation 410, 610 come here. |
||
303 | */ |
||
304 | printk(KERN_ERR PREFIX |
||
305 | "Invalid BIOS MADT, disabling ACPI\n"); |
||
306 | disable_acpi(); |
||
307 | } |
||
308 | } else { |
||
309 | /* |
||
310 | * ACPI found no MADT, and so ACPI wants UP PIC mode. |
||
311 | * In the event an MPS table was found, forget it. |
||
312 | * Boot with "acpi=off" to use MPS on such a system. |
||
313 | */ |
||
314 | if (smp_found_config) { |
||
315 | printk(KERN_WARNING PREFIX |
||
316 | "No APIC-table, disabling MPS\n"); |
||
317 | smp_found_config = 0; |
||
318 | } |
||
319 | } |
||
320 | |||
321 | /* |
||
322 | * ACPI supports both logical (e.g. Hyper-Threading) and physical |
||
323 | * processors, where MPS only supports physical. |
||
324 | */ |
||
325 | if (acpi_lapic && acpi_ioapic) |
||
326 | printk(KERN_INFO "Using ACPI (MADT) for SMP configuration " |
||
327 | "information\n"); |
||
328 | else if (acpi_lapic) |
||
329 | printk(KERN_INFO "Using ACPI for processor (LAPIC) " |
||
330 | "configuration information\n"); |
||
331 | #endif |
||
332 | return; |
||
333 | } |
||
334 | |||
335 | static int __init disable_acpi_irq(const struct dmi_system_id *d) |
||
336 | { |
||
337 | if (!acpi_force) { |
||
338 | printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", |
||
339 | d->ident); |
||
340 | acpi_noirq_set(); |
||
341 | } |
||
342 | return 0; |
||
343 | } |
||
344 | |||
345 | static int __init disable_acpi_pci(const struct dmi_system_id *d) |
||
346 | { |
||
347 | if (!acpi_force) { |
||
348 | printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", |
||
349 | d->ident); |
||
350 | acpi_disable_pci(); |
||
351 | } |
||
352 | return 0; |
||
353 | } |
||
354 | |||
355 | static int __init dmi_disable_acpi(const struct dmi_system_id *d) |
||
356 | { |
||
357 | if (!acpi_force) { |
||
358 | printk(KERN_NOTICE "%s detected: acpi off\n", d->ident); |
||
359 | disable_acpi(); |
||
360 | } else { |
||
361 | printk(KERN_NOTICE |
||
362 | "Warning: DMI blacklist says broken, but acpi forced\n"); |
||
363 | } |
||
364 | return 0; |
||
365 | } |
||
366 | |||
367 | /* |
||
368 | * Force ignoring BIOS IRQ0 override |
||
369 | */ |
||
370 | static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) |
||
371 | { |
||
372 | if (!acpi_skip_timer_override) { |
||
373 | pr_notice("%s detected: Ignoring BIOS IRQ0 override\n", |
||
374 | d->ident); |
||
375 | acpi_skip_timer_override = 1; |
||
376 | } |
||
377 | return 0; |
||
378 | } |
||
379 | |||
380 | /* |
||
381 | * If your system is blacklisted here, but you find that acpi=force |
||
382 | * works for you, please contact linux-acpi@vger.kernel.org |
||
383 | */ |
||
384 | static struct dmi_system_id __initdata acpi_dmi_table[] = { |
||
385 | /* |
||
386 | * Boxes that need ACPI disabled |
||
387 | */ |
||
388 | { |
||
389 | .callback = dmi_disable_acpi, |
||
390 | .ident = "IBM Thinkpad", |
||
391 | .matches = { |
||
392 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
||
393 | DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), |
||
394 | }, |
||
395 | }, |
||
396 | |||
397 | /* |
||
398 | * Boxes that need ACPI PCI IRQ routing disabled |
||
399 | */ |
||
400 | { |
||
401 | .callback = disable_acpi_irq, |
||
402 | .ident = "ASUS A7V", |
||
403 | .matches = { |
||
404 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), |
||
405 | DMI_MATCH(DMI_BOARD_NAME, " |
||
406 | /* newer BIOS, Revision 1011, does work */ |
||
407 | DMI_MATCH(DMI_BIOS_VERSION, |
||
408 | "ASUS A7V ACPI BIOS Revision 1007"), |
||
409 | }, |
||
410 | }, |
||
411 | { |
||
412 | /* |
||
413 | * Latest BIOS for IBM 600E (1.16) has bad pcinum |
||
414 | * for LPC bridge, which is needed for the PCI |
||
415 | * interrupt links to work. DSDT fix is in bug 5966. |
||
416 | * 2645, 2646 model numbers are shared with 600/600E/600X |
||
417 | */ |
||
418 | .callback = disable_acpi_irq, |
||
419 | .ident = "IBM Thinkpad 600 Series 2645", |
||
420 | .matches = { |
||
421 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
||
422 | DMI_MATCH(DMI_BOARD_NAME, "2645"), |
||
423 | }, |
||
424 | }, |
||
425 | { |
||
426 | .callback = disable_acpi_irq, |
||
427 | .ident = "IBM Thinkpad 600 Series 2646", |
||
428 | .matches = { |
||
429 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
||
430 | DMI_MATCH(DMI_BOARD_NAME, "2646"), |
||
431 | }, |
||
432 | }, |
||
433 | /* |
||
434 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled |
||
435 | */ |
||
436 | { /* _BBN 0 bug */ |
||
437 | .callback = disable_acpi_pci, |
||
438 | .ident = "ASUS PR-DLS", |
||
439 | .matches = { |
||
440 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
||
441 | DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), |
||
442 | DMI_MATCH(DMI_BIOS_VERSION, |
||
443 | "ASUS PR-DLS ACPI BIOS Revision 1010"), |
||
444 | DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") |
||
445 | }, |
||
446 | }, |
||
447 | { |
||
448 | .callback = disable_acpi_pci, |
||
449 | .ident = "Acer TravelMate 36x Laptop", |
||
450 | .matches = { |
||
451 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
||
452 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
||
453 | }, |
||
454 | }, |
||
455 | {} |
||
456 | }; |
||
457 | |||
458 | /* second table for DMI checks that should run after early-quirks */ |
||
459 | static struct dmi_system_id __initdata acpi_dmi_table_late[] = { |
||
460 | /* |
||
461 | * HP laptops which use a DSDT reporting as HP/SB400/10000, |
||
462 | * which includes some code which overrides all temperature |
||
463 | * trip points to 16C if the INTIN2 input of the I/O APIC |
||
464 | * is enabled. This input is incorrectly designated the |
||
465 | * ISA IRQ 0 via an interrupt source override even though |
||
466 | * it is wired to the output of the master 8259A and INTIN0 |
||
467 | * is not connected at all. Force ignoring BIOS IRQ0 |
||
468 | * override in that cases. |
||
469 | */ |
||
470 | { |
||
471 | .callback = dmi_ignore_irq0_timer_override, |
||
472 | .ident = "HP nx6115 laptop", |
||
473 | .matches = { |
||
474 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
||
475 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6115"), |
||
476 | }, |
||
477 | }, |
||
478 | { |
||
479 | .callback = dmi_ignore_irq0_timer_override, |
||
480 | .ident = "HP NX6125 laptop", |
||
481 | .matches = { |
||
482 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
||
483 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"), |
||
484 | }, |
||
485 | }, |
||
486 | { |
||
487 | .callback = dmi_ignore_irq0_timer_override, |
||
488 | .ident = "HP NX6325 laptop", |
||
489 | .matches = { |
||
490 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
||
491 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), |
||
492 | }, |
||
493 | }, |
||
494 | { |
||
495 | .callback = dmi_ignore_irq0_timer_override, |
||
496 | .ident = "HP 6715b laptop", |
||
497 | .matches = { |
||
498 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
||
499 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), |
||
500 | }, |
||
501 | }, |
||
502 | { |
||
503 | .callback = dmi_ignore_irq0_timer_override, |
||
504 | .ident = "FUJITSU SIEMENS", |
||
505 | .matches = { |
||
506 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
||
507 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), |
||
508 | }, |
||
509 | }, |
||
510 | {} |
||
511 | }; |
||
512 | |||
513 | /* |
||
514 | * acpi_boot_table_init() and acpi_boot_init() |
||
515 | * called from setup_arch(), always. |
||
516 | * 1. checksums all tables |
||
517 | * 2. enumerates lapics |
||
518 | * 3. enumerates io-apics |
||
519 | * |
||
520 | * acpi_table_init() is separate to allow reading SRAT without |
||
521 | * other side effects. |
||
522 | * |
||
523 | * side effects of acpi_boot_init: |
||
524 | * acpi_lapic = 1 if LAPIC found |
||
525 | * acpi_ioapic = 1 if IOAPIC found |
||
526 | * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; |
||
527 | * if acpi_blacklisted() acpi_disabled = 1; |
||
528 | * acpi_irq_model=... |
||
529 | * ... |
||
530 | */ |
||
531 | |||
532 | void __init acpi_boot_table_init(void) |
||
533 | { |
||
534 | dmi_check_system(acpi_dmi_table); |
||
535 | |||
536 | /* |
||
537 | * If acpi_disabled, bail out |
||
538 | */ |
||
539 | if (acpi_disabled) |
||
540 | return; |
||
541 | |||
542 | /* |
||
543 | * Initialize the ACPI boot-time table parser. |
||
544 | */ |
||
545 | if (acpi_table_init()) { |
||
546 | disable_acpi(); |
||
547 | return; |
||
548 | } |
||
549 | |||
550 | acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); |
||
551 | |||
552 | /* |
||
553 | * blacklist may disable ACPI entirely |
||
554 | */ |
||
555 | if (acpi_blacklisted()) { |
||
556 | if (acpi_force) { |
||
557 | printk(KERN_WARNING PREFIX "acpi=force override\n"); |
||
558 | } else { |
||
559 | printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); |
||
560 | disable_acpi(); |
||
561 | return; |
||
562 | } |
||
563 | } |
||
564 | } |
||
565 | |||
566 | int __init early_acpi_boot_init(void) |
||
567 | { |
||
568 | /* |
||
569 | * If acpi_disabled, bail out |
||
570 | */ |
||
571 | if (acpi_disabled) |
||
572 | return 1; |
||
573 | |||
574 | /* |
||
575 | * Process the Multiple APIC Description Table (MADT), if present |
||
576 | */ |
||
577 | early_acpi_process_madt(); |
||
578 | |||
579 | /* |
||
580 | * Hardware-reduced ACPI mode initialization: |
||
581 | */ |
||
582 | // acpi_reduced_hw_init(); |
||
583 | |||
584 | return 0; |
||
585 | } |
||
586 | |||
587 | int __init acpi_boot_init(void) |
||
588 | { |
||
589 | /* those are executed after early-quirks are executed */ |
||
590 | dmi_check_system(acpi_dmi_table_late); |
||
591 | |||
592 | /* |
||
593 | * If acpi_disabled, bail out |
||
594 | */ |
||
595 | if (acpi_disabled) |
||
596 | return 1; |
||
597 | |||
598 | // acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); |
||
599 | |||
600 | /* |
||
601 | * set sci_int and PM timer address |
||
602 | */ |
||
603 | acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt); |
||
604 | |||
605 | /* |
||
606 | * Process the Multiple APIC Description Table (MADT), if present |
||
607 | */ |
||
608 | acpi_process_madt(); |
||
609 | |||
610 | acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); |
||
611 | |||
612 | // if (!acpi_noirq) |
||
613 | // x86_init.pci.init = pci_acpi_init; |
||
614 | |||
615 | return 0; |
||
616 | }><>><> |