1
2
3
4
5
6
7
8#define pr_fmt(fmt) "ACPI: " fmt
9
10#include <linux/init.h>
11#include <linux/acpi.h>
12#include <linux/acpi_pmtmr.h>
13#include <linux/efi.h>
14#include <linux/cpumask.h>
15#include <linux/export.h>
16#include <linux/dmi.h>
17#include <linux/irq.h>
18#include <linux/slab.h>
19#include <linux/memblock.h>
20#include <linux/ioport.h>
21#include <linux/pci.h>
22#include <linux/efi-bgrt.h>
23#include <linux/serial_core.h>
24#include <linux/pgtable.h>
25
26#include <asm/e820/api.h>
27#include <asm/irqdomain.h>
28#include <asm/pci_x86.h>
29#include <asm/io_apic.h>
30#include <asm/apic.h>
31#include <asm/io.h>
32#include <asm/mpspec.h>
33#include <asm/smp.h>
34#include <asm/i8259.h>
35#include <asm/setup.h>
36
37#include "sleep.h"
38static int __initdata acpi_force = 0;
39int acpi_disabled;
40EXPORT_SYMBOL(acpi_disabled);
41
42#ifdef CONFIG_X86_64
43# include <asm/proto.h>
44#endif
45
46int acpi_noirq;
47static int acpi_nobgrt;
48int acpi_pci_disabled;
49EXPORT_SYMBOL(acpi_pci_disabled);
50
51int acpi_lapic;
52int acpi_ioapic;
53int acpi_strict;
54int acpi_disable_cmcff;
55
56
57u8 acpi_sci_flags __initdata;
58u32 acpi_sci_override_gsi __initdata = INVALID_ACPI_IRQ;
59int acpi_skip_timer_override __initdata;
60int acpi_use_timer_override __initdata;
61int acpi_fix_pin2_polarity __initdata;
62
63#ifdef CONFIG_X86_LOCAL_APIC
64static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
65static bool acpi_support_online_capable;
66#endif
67
68#ifdef CONFIG_X86_IO_APIC
69
70
71
72
73
74
75
76
77
78
79
80static DEFINE_MUTEX(acpi_ioapic_lock);
81#endif
82
83
84
85
86
87
88
89
90
91enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
92
93
94
95
96
97
98static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
99 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
100};
101
102
103
104
105
106void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
107{
108
109 if (!phys || !size)
110 return NULL;
111
112 return early_memremap(phys, size);
113}
114
115void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
116{
117 if (!map || !size)
118 return;
119
120 early_memunmap(map, size);
121}
122
123#ifdef CONFIG_X86_LOCAL_APIC
124static int __init acpi_parse_madt(struct acpi_table_header *table)
125{
126 struct acpi_table_madt *madt = NULL;
127
128 if (!boot_cpu_has(X86_FEATURE_APIC))
129 return -EINVAL;
130
131 madt = (struct acpi_table_madt *)table;
132 if (!madt) {
133 pr_warn("Unable to map MADT\n");
134 return -ENODEV;
135 }
136
137 if (madt->address) {
138 acpi_lapic_addr = (u64) madt->address;
139
140 pr_debug("Local APIC address 0x%08x\n", madt->address);
141 }
142 if (madt->header.revision >= 5)
143 acpi_support_online_capable = true;
144
145 default_acpi_madt_oem_check(madt->header.oem_id,
146 madt->header.oem_table_id);
147
148 return 0;
149}
150
151
152
153
154
155
156
157
158
159static int acpi_register_lapic(int id, u32 acpiid, u8 enabled)
160{
161 unsigned int ver = 0;
162 int cpu;
163
164 if (id >= MAX_LOCAL_APIC) {
165 pr_info("skipped apicid that is too big\n");
166 return -EINVAL;
167 }
168
169 if (!enabled) {
170 ++disabled_cpus;
171 return -EINVAL;
172 }
173
174 if (boot_cpu_physical_apicid != -1U)
175 ver = boot_cpu_apic_version;
176
177 cpu = generic_processor_info(id, ver);
178 if (cpu >= 0)
179 early_per_cpu(x86_cpu_to_acpiid, cpu) = acpiid;
180
181 return cpu;
182}
183
184static int __init
185acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end)
186{
187 struct acpi_madt_local_x2apic *processor = NULL;
188#ifdef CONFIG_X86_X2APIC
189 u32 apic_id;
190 u8 enabled;
191#endif
192
193 processor = (struct acpi_madt_local_x2apic *)header;
194
195 if (BAD_MADT_ENTRY(processor, end))
196 return -EINVAL;
197
198 acpi_table_print_madt_entry(&header->common);
199
200#ifdef CONFIG_X86_X2APIC
201 apic_id = processor->local_apic_id;
202 enabled = processor->lapic_flags & ACPI_MADT_ENABLED;
203
204
205 if (apic_id == 0xffffffff)
206 return 0;
207
208
209
210
211
212
213
214
215 if (!apic->apic_id_valid(apic_id)) {
216 if (enabled)
217 pr_warn("x2apic entry ignored\n");
218 return 0;
219 }
220
221 acpi_register_lapic(apic_id, processor->uid, enabled);
222#else
223 pr_warn("x2apic entry ignored\n");
224#endif
225
226 return 0;
227}
228
229static int __init
230acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end)
231{
232 struct acpi_madt_local_apic *processor = NULL;
233
234 processor = (struct acpi_madt_local_apic *)header;
235
236 if (BAD_MADT_ENTRY(processor, end))
237 return -EINVAL;
238
239 acpi_table_print_madt_entry(&header->common);
240
241
242 if (processor->id == 0xff)
243 return 0;
244
245
246 if (acpi_support_online_capable &&
247 !(processor->lapic_flags & ACPI_MADT_ENABLED) &&
248 !(processor->lapic_flags & ACPI_MADT_ONLINE_CAPABLE))
249 return 0;
250
251
252
253
254
255
256
257
258 acpi_register_lapic(processor->id,
259 processor->processor_id,
260 processor->lapic_flags & ACPI_MADT_ENABLED);
261
262 return 0;
263}
264
265static int __init
266acpi_parse_sapic(union acpi_subtable_headers *header, const unsigned long end)
267{
268 struct acpi_madt_local_sapic *processor = NULL;
269
270 processor = (struct acpi_madt_local_sapic *)header;
271
272 if (BAD_MADT_ENTRY(processor, end))
273 return -EINVAL;
274
275 acpi_table_print_madt_entry(&header->common);
276
277 acpi_register_lapic((processor->id << 8) | processor->eid,
278 processor->processor_id,
279 processor->lapic_flags & ACPI_MADT_ENABLED);
280
281 return 0;
282}
283
284static int __init
285acpi_parse_lapic_addr_ovr(union acpi_subtable_headers * header,
286 const unsigned long end)
287{
288 struct acpi_madt_local_apic_override *lapic_addr_ovr = NULL;
289
290 lapic_addr_ovr = (struct acpi_madt_local_apic_override *)header;
291
292 if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
293 return -EINVAL;
294
295 acpi_table_print_madt_entry(&header->common);
296
297 acpi_lapic_addr = lapic_addr_ovr->address;
298
299 return 0;
300}
301
302static int __init
303acpi_parse_x2apic_nmi(union acpi_subtable_headers *header,
304 const unsigned long end)
305{
306 struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL;
307
308 x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
309
310 if (BAD_MADT_ENTRY(x2apic_nmi, end))
311 return -EINVAL;
312
313 acpi_table_print_madt_entry(&header->common);
314
315 if (x2apic_nmi->lint != 1)
316 pr_warn("NMI not connected to LINT 1!\n");
317
318 return 0;
319}
320
321static int __init
322acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long end)
323{
324 struct acpi_madt_local_apic_nmi *lapic_nmi = NULL;
325
326 lapic_nmi = (struct acpi_madt_local_apic_nmi *)header;
327
328 if (BAD_MADT_ENTRY(lapic_nmi, end))
329 return -EINVAL;
330
331 acpi_table_print_madt_entry(&header->common);
332
333 if (lapic_nmi->lint != 1)
334 pr_warn("NMI not connected to LINT 1!\n");
335
336 return 0;
337}
338
339#endif
340
341#ifdef CONFIG_X86_IO_APIC
342#define MP_ISA_BUS 0
343
344static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
345 u8 trigger, u32 gsi);
346
347static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
348 u32 gsi)
349{
350
351
352
353 if (bus_irq >= NR_IRQS_LEGACY) {
354 pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq);
355 return;
356 }
357
358
359
360
361
362
363 if ((bus_irq == 0) && (trigger == 3))
364 trigger = 1;
365
366 if (mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi) < 0)
367 return;
368
369
370
371
372
373 if (gsi < nr_legacy_irqs() && isa_irq_to_gsi[gsi] == gsi)
374 isa_irq_to_gsi[gsi] = INVALID_ACPI_IRQ;
375 isa_irq_to_gsi[bus_irq] = gsi;
376}
377
378static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
379 int polarity)
380{
381#ifdef CONFIG_X86_MPPARSE
382 struct mpc_intsrc mp_irq;
383 struct pci_dev *pdev;
384 unsigned char number;
385 unsigned int devfn;
386 int ioapic;
387 u8 pin;
388
389 if (!acpi_ioapic)
390 return 0;
391 if (!dev || !dev_is_pci(dev))
392 return 0;
393
394 pdev = to_pci_dev(dev);
395 number = pdev->bus->number;
396 devfn = pdev->devfn;
397 pin = pdev->pin;
398
399 mp_irq.type = MP_INTSRC;
400 mp_irq.irqtype = mp_INT;
401 mp_irq.irqflag = (trigger == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
402 (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
403 mp_irq.srcbus = number;
404 mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
405 ioapic = mp_find_ioapic(gsi);
406 mp_irq.dstapic = mpc_ioapic_id(ioapic);
407 mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
408
409 mp_save_irq(&mp_irq);
410#endif
411 return 0;
412}
413
414static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
415 u8 trigger, u32 gsi)
416{
417 struct mpc_intsrc mp_irq;
418 int ioapic, pin;
419
420
421 ioapic = mp_find_ioapic(gsi);
422 if (ioapic < 0) {
423 pr_warn("Failed to find ioapic for gsi : %u\n", gsi);
424 return ioapic;
425 }
426
427 pin = mp_find_ioapic_pin(ioapic, gsi);
428
429 mp_irq.type = MP_INTSRC;
430 mp_irq.irqtype = mp_INT;
431 mp_irq.irqflag = (trigger << 2) | polarity;
432 mp_irq.srcbus = MP_ISA_BUS;
433 mp_irq.srcbusirq = bus_irq;
434 mp_irq.dstapic = mpc_ioapic_id(ioapic);
435 mp_irq.dstirq = pin;
436
437 mp_save_irq(&mp_irq);
438
439 return 0;
440}
441
442static int __init
443acpi_parse_ioapic(union acpi_subtable_headers * header, const unsigned long end)
444{
445 struct acpi_madt_io_apic *ioapic = NULL;
446 struct ioapic_domain_cfg cfg = {
447 .type = IOAPIC_DOMAIN_DYNAMIC,
448 .ops = &mp_ioapic_irqdomain_ops,
449 };
450
451 ioapic = (struct acpi_madt_io_apic *)header;
452
453 if (BAD_MADT_ENTRY(ioapic, end))
454 return -EINVAL;
455
456 acpi_table_print_madt_entry(&header->common);
457
458
459 if (ioapic->global_irq_base < nr_legacy_irqs())
460 cfg.type = IOAPIC_DOMAIN_LEGACY;
461
462 mp_register_ioapic(ioapic->id, ioapic->address, ioapic->global_irq_base,
463 &cfg);
464
465 return 0;
466}
467
468
469
470
471static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
472{
473 if (trigger == 0)
474 trigger = 3;
475
476 if (polarity == 0)
477 polarity = 3;
478
479
480 if (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)
481 trigger = (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
482
483 if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK)
484 polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK;
485
486 if (bus_irq < NR_IRQS_LEGACY)
487 mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
488 else
489 mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi);
490
491 acpi_penalize_sci_irq(bus_irq, trigger, polarity);
492
493
494
495
496
497 acpi_sci_override_gsi = gsi;
498 return;
499}
500
501static int __init
502acpi_parse_int_src_ovr(union acpi_subtable_headers * header,
503 const unsigned long end)
504{
505 struct acpi_madt_interrupt_override *intsrc = NULL;
506
507 intsrc = (struct acpi_madt_interrupt_override *)header;
508
509 if (BAD_MADT_ENTRY(intsrc, end))
510 return -EINVAL;
511
512 acpi_table_print_madt_entry(&header->common);
513
514 if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
515 acpi_sci_ioapic_setup(intsrc->source_irq,
516 intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
517 (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
518 intsrc->global_irq);
519 return 0;
520 }
521
522 if (intsrc->source_irq == 0) {
523 if (acpi_skip_timer_override) {
524 pr_warn("BIOS IRQ0 override ignored.\n");
525 return 0;
526 }
527
528 if ((intsrc->global_irq == 2) && acpi_fix_pin2_polarity
529 && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) {
530 intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK;
531 pr_warn("BIOS IRQ0 pin2 override: forcing polarity to high active.\n");
532 }
533 }
534
535 mp_override_legacy_irq(intsrc->source_irq,
536 intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
537 (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
538 intsrc->global_irq);
539
540 return 0;
541}
542
543static int __init
544acpi_parse_nmi_src(union acpi_subtable_headers * header, const unsigned long end)
545{
546 struct acpi_madt_nmi_source *nmi_src = NULL;
547
548 nmi_src = (struct acpi_madt_nmi_source *)header;
549
550 if (BAD_MADT_ENTRY(nmi_src, end))
551 return -EINVAL;
552
553 acpi_table_print_madt_entry(&header->common);
554
555
556
557 return 0;
558}
559
560#endif
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
577{
578 unsigned int mask = 1 << irq;
579 unsigned int old, new;
580
581
582 old = inb(PIC_ELCR1) | (inb(PIC_ELCR2) << 8);
583
584
585
586
587
588
589 new = acpi_noirq ? old : 0;
590
591
592
593
594
595 switch (trigger) {
596 case 1:
597 new &= ~mask;
598 break;
599 case 3:
600 new |= mask;
601 break;
602 }
603
604 if (old == new)
605 return;
606
607 pr_warn("setting ELCR to %04x (from %04x)\n", new, old);
608 outb(new, PIC_ELCR1);
609 outb(new >> 8, PIC_ELCR2);
610}
611
612int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
613{
614 int rc, irq, trigger, polarity;
615
616 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
617 *irqp = gsi;
618 return 0;
619 }
620
621 rc = acpi_get_override_irq(gsi, &trigger, &polarity);
622 if (rc)
623 return rc;
624
625 trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
626 polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
627 irq = acpi_register_gsi(NULL, gsi, trigger, polarity);
628 if (irq < 0)
629 return irq;
630
631 *irqp = irq;
632 return 0;
633}
634EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
635
636int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
637{
638 if (isa_irq < nr_legacy_irqs() &&
639 isa_irq_to_gsi[isa_irq] != INVALID_ACPI_IRQ) {
640 *gsi = isa_irq_to_gsi[isa_irq];
641 return 0;
642 }
643
644 return -1;
645}
646
647static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
648 int trigger, int polarity)
649{
650#ifdef CONFIG_PCI
651
652
653
654 if (trigger == ACPI_LEVEL_SENSITIVE)
655 elcr_set_level_irq(gsi);
656#endif
657
658 return gsi;
659}
660
661#ifdef CONFIG_X86_LOCAL_APIC
662static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
663 int trigger, int polarity)
664{
665 int irq = gsi;
666#ifdef CONFIG_X86_IO_APIC
667 int node;
668 struct irq_alloc_info info;
669
670 node = dev ? dev_to_node(dev) : NUMA_NO_NODE;
671 trigger = trigger == ACPI_EDGE_SENSITIVE ? 0 : 1;
672 polarity = polarity == ACPI_ACTIVE_HIGH ? 0 : 1;
673 ioapic_set_alloc_attr(&info, node, trigger, polarity);
674
675 mutex_lock(&acpi_ioapic_lock);
676 irq = mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC, &info);
677
678 if (irq >= 0 && enable_update_mptable && gsi != acpi_gbl_FADT.sci_interrupt)
679 mp_config_acpi_gsi(dev, gsi, trigger, polarity);
680 mutex_unlock(&acpi_ioapic_lock);
681#endif
682
683 return irq;
684}
685
686static void acpi_unregister_gsi_ioapic(u32 gsi)
687{
688#ifdef CONFIG_X86_IO_APIC
689 int irq;
690
691 mutex_lock(&acpi_ioapic_lock);
692 irq = mp_map_gsi_to_irq(gsi, 0, NULL);
693 if (irq > 0)
694 mp_unmap_irq(irq);
695 mutex_unlock(&acpi_ioapic_lock);
696#endif
697}
698#endif
699
700int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
701 int trigger, int polarity) = acpi_register_gsi_pic;
702void (*__acpi_unregister_gsi)(u32 gsi) = NULL;
703
704#ifdef CONFIG_ACPI_SLEEP
705int (*acpi_suspend_lowlevel)(void) = x86_acpi_suspend_lowlevel;
706#else
707int (*acpi_suspend_lowlevel)(void);
708#endif
709
710
711
712
713
714int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
715{
716 return __acpi_register_gsi(dev, gsi, trigger, polarity);
717}
718EXPORT_SYMBOL_GPL(acpi_register_gsi);
719
720void acpi_unregister_gsi(u32 gsi)
721{
722 if (__acpi_unregister_gsi)
723 __acpi_unregister_gsi(gsi);
724}
725EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
726
727#ifdef CONFIG_X86_LOCAL_APIC
728static void __init acpi_set_irq_model_ioapic(void)
729{
730 acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
731 __acpi_register_gsi = acpi_register_gsi_ioapic;
732 __acpi_unregister_gsi = acpi_unregister_gsi_ioapic;
733 acpi_ioapic = 1;
734}
735#endif
736
737
738
739
740#ifdef CONFIG_ACPI_HOTPLUG_CPU
741#include <acpi/processor.h>
742
743static int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
744{
745#ifdef CONFIG_ACPI_NUMA
746 int nid;
747
748 nid = acpi_get_node(handle);
749 if (nid != NUMA_NO_NODE) {
750 set_apicid_to_node(physid, nid);
751 numa_set_node(cpu, nid);
752 }
753#endif
754 return 0;
755}
756
757int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id,
758 int *pcpu)
759{
760 int cpu;
761
762 cpu = acpi_register_lapic(physid, acpi_id, ACPI_MADT_ENABLED);
763 if (cpu < 0) {
764 pr_info("Unable to map lapic to logical cpu number\n");
765 return cpu;
766 }
767
768 acpi_processor_set_pdc(handle);
769 acpi_map_cpu2node(handle, cpu, physid);
770
771 *pcpu = cpu;
772 return 0;
773}
774EXPORT_SYMBOL(acpi_map_cpu);
775
776int acpi_unmap_cpu(int cpu)
777{
778#ifdef CONFIG_ACPI_NUMA
779 set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE);
780#endif
781
782 per_cpu(x86_cpu_to_apicid, cpu) = -1;
783 set_cpu_present(cpu, false);
784 num_processors--;
785
786 return (0);
787}
788EXPORT_SYMBOL(acpi_unmap_cpu);
789#endif
790
791int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
792{
793 int ret = -ENOSYS;
794#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
795 int ioapic_id;
796 u64 addr;
797 struct ioapic_domain_cfg cfg = {
798 .type = IOAPIC_DOMAIN_DYNAMIC,
799 .ops = &mp_ioapic_irqdomain_ops,
800 };
801
802 ioapic_id = acpi_get_ioapic_id(handle, gsi_base, &addr);
803 if (ioapic_id < 0) {
804 unsigned long long uid;
805 acpi_status status;
806
807 status = acpi_evaluate_integer(handle, METHOD_NAME__UID,
808 NULL, &uid);
809 if (ACPI_FAILURE(status)) {
810 acpi_handle_warn(handle, "failed to get IOAPIC ID.\n");
811 return -EINVAL;
812 }
813 ioapic_id = (int)uid;
814 }
815
816 mutex_lock(&acpi_ioapic_lock);
817 ret = mp_register_ioapic(ioapic_id, phys_addr, gsi_base, &cfg);
818 mutex_unlock(&acpi_ioapic_lock);
819#endif
820
821 return ret;
822}
823EXPORT_SYMBOL(acpi_register_ioapic);
824
825int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
826{
827 int ret = -ENOSYS;
828
829#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
830 mutex_lock(&acpi_ioapic_lock);
831 ret = mp_unregister_ioapic(gsi_base);
832 mutex_unlock(&acpi_ioapic_lock);
833#endif
834
835 return ret;
836}
837EXPORT_SYMBOL(acpi_unregister_ioapic);
838
839
840
841
842
843
844
845
846
847
848int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base)
849{
850 int ret = 0;
851
852#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
853 mutex_lock(&acpi_ioapic_lock);
854 ret = mp_ioapic_registered(gsi_base);
855 mutex_unlock(&acpi_ioapic_lock);
856#endif
857
858 return ret;
859}
860
861static int __init acpi_parse_sbf(struct acpi_table_header *table)
862{
863 struct acpi_table_boot *sb = (struct acpi_table_boot *)table;
864
865 sbf_port = sb->cmos_index;
866
867 return 0;
868}
869
870#ifdef CONFIG_HPET_TIMER
871#include <asm/hpet.h>
872
873static struct resource *hpet_res __initdata;
874
875static int __init acpi_parse_hpet(struct acpi_table_header *table)
876{
877 struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table;
878
879 if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) {
880 pr_warn("HPET timers must be located in memory.\n");
881 return -1;
882 }
883
884 hpet_address = hpet_tbl->address.address;
885 hpet_blockid = hpet_tbl->sequence;
886
887
888
889
890
891 if (!hpet_address) {
892 pr_warn("HPET id: %#x base: %#lx is invalid\n", hpet_tbl->id, hpet_address);
893 return 0;
894 }
895#ifdef CONFIG_X86_64
896
897
898
899
900
901 if (hpet_address == 0xfed0000000000000UL) {
902 if (!hpet_force_user) {
903 pr_warn("HPET id: %#x base: 0xfed0000000000000 is bogus, try hpet=force on the kernel command line to fix it up to 0xfed00000.\n",
904 hpet_tbl->id);
905 hpet_address = 0;
906 return 0;
907 }
908 pr_warn("HPET id: %#x base: 0xfed0000000000000 fixed up to 0xfed00000.\n",
909 hpet_tbl->id);
910 hpet_address >>= 32;
911 }
912#endif
913 pr_info("HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address);
914
915
916
917
918
919#define HPET_RESOURCE_NAME_SIZE 9
920 hpet_res = memblock_alloc(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE,
921 SMP_CACHE_BYTES);
922 if (!hpet_res)
923 panic("%s: Failed to allocate %zu bytes\n", __func__,
924 sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE);
925
926 hpet_res->name = (void *)&hpet_res[1];
927 hpet_res->flags = IORESOURCE_MEM;
928 snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u",
929 hpet_tbl->sequence);
930
931 hpet_res->start = hpet_address;
932 hpet_res->end = hpet_address + (1 * 1024) - 1;
933
934 return 0;
935}
936
937
938
939
940
941static __init int hpet_insert_resource(void)
942{
943 if (!hpet_res)
944 return 1;
945
946 return insert_resource(&iomem_resource, hpet_res);
947}
948
949late_initcall(hpet_insert_resource);
950
951#else
952#define acpi_parse_hpet NULL
953#endif
954
955static int __init acpi_parse_fadt(struct acpi_table_header *table)
956{
957 if (!(acpi_gbl_FADT.boot_flags & ACPI_FADT_LEGACY_DEVICES)) {
958 pr_debug("no legacy devices present\n");
959 x86_platform.legacy.devices.pnpbios = 0;
960 }
961
962 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
963 !(acpi_gbl_FADT.boot_flags & ACPI_FADT_8042) &&
964 x86_platform.legacy.i8042 != X86_LEGACY_I8042_PLATFORM_ABSENT) {
965 pr_debug("i8042 controller is absent\n");
966 x86_platform.legacy.i8042 = X86_LEGACY_I8042_FIRMWARE_ABSENT;
967 }
968
969 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) {
970 pr_debug("not registering RTC platform device\n");
971 x86_platform.legacy.rtc = 0;
972 }
973
974 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_VGA) {
975 pr_debug("probing for VGA not safe\n");
976 x86_platform.legacy.no_vga = 1;
977 }
978
979#ifdef CONFIG_X86_PM_TIMER
980
981 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) {
982
983 if (acpi_gbl_FADT.xpm_timer_block.space_id !=
984 ACPI_ADR_SPACE_SYSTEM_IO)
985 return 0;
986
987 pmtmr_ioport = acpi_gbl_FADT.xpm_timer_block.address;
988
989
990
991
992
993 if (!pmtmr_ioport)
994 pmtmr_ioport = acpi_gbl_FADT.pm_timer_block;
995 } else {
996
997 pmtmr_ioport = acpi_gbl_FADT.pm_timer_block;
998 }
999 if (pmtmr_ioport)
1000 pr_info("PM-Timer IO Port: %#x\n", pmtmr_ioport);
1001#endif
1002 return 0;
1003}
1004
1005#ifdef CONFIG_X86_LOCAL_APIC
1006
1007
1008
1009
1010
1011static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
1012{
1013 int count;
1014
1015 if (!boot_cpu_has(X86_FEATURE_APIC))
1016 return -ENODEV;
1017
1018
1019
1020
1021
1022
1023 count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
1024 acpi_parse_lapic_addr_ovr, 0);
1025 if (count < 0) {
1026 pr_err("Error parsing LAPIC address override entry\n");
1027 return count;
1028 }
1029
1030 register_lapic_address(acpi_lapic_addr);
1031
1032 return count;
1033}
1034
1035static int __init acpi_parse_madt_lapic_entries(void)
1036{
1037 int count;
1038 int x2count = 0;
1039 int ret;
1040 struct acpi_subtable_proc madt_proc[2];
1041
1042 if (!boot_cpu_has(X86_FEATURE_APIC))
1043 return -ENODEV;
1044
1045 count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
1046 acpi_parse_sapic, MAX_LOCAL_APIC);
1047
1048 if (!count) {
1049 memset(madt_proc, 0, sizeof(madt_proc));
1050 madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
1051 madt_proc[0].handler = acpi_parse_lapic;
1052 madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
1053 madt_proc[1].handler = acpi_parse_x2apic;
1054 ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
1055 sizeof(struct acpi_table_madt),
1056 madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
1057 if (ret < 0) {
1058 pr_err("Error parsing LAPIC/X2APIC entries\n");
1059 return ret;
1060 }
1061
1062 count = madt_proc[0].count;
1063 x2count = madt_proc[1].count;
1064 }
1065 if (!count && !x2count) {
1066 pr_err("No LAPIC entries present\n");
1067
1068 return -ENODEV;
1069 } else if (count < 0 || x2count < 0) {
1070 pr_err("Error parsing LAPIC entry\n");
1071
1072 return count;
1073 }
1074
1075 x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
1076 acpi_parse_x2apic_nmi, 0);
1077 count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI,
1078 acpi_parse_lapic_nmi, 0);
1079 if (count < 0 || x2count < 0) {
1080 pr_err("Error parsing LAPIC NMI entry\n");
1081
1082 return count;
1083 }
1084 return 0;
1085}
1086#endif
1087
1088#ifdef CONFIG_X86_IO_APIC
1089static void __init mp_config_acpi_legacy_irqs(void)
1090{
1091 int i;
1092 struct mpc_intsrc mp_irq;
1093
1094#ifdef CONFIG_EISA
1095
1096
1097
1098 mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
1099#endif
1100 set_bit(MP_ISA_BUS, mp_bus_not_pci);
1101 pr_debug("Bus #%d is ISA (nIRQs: %d)\n", MP_ISA_BUS, nr_legacy_irqs());
1102
1103
1104
1105
1106
1107 for (i = 0; i < nr_legacy_irqs(); i++) {
1108 int ioapic, pin;
1109 unsigned int dstapic;
1110 int idx;
1111 u32 gsi;
1112
1113
1114 if (acpi_isa_irq_to_gsi(i, &gsi))
1115 continue;
1116
1117
1118
1119
1120 ioapic = mp_find_ioapic(gsi);
1121 if (ioapic < 0)
1122 continue;
1123 pin = mp_find_ioapic_pin(ioapic, gsi);
1124 dstapic = mpc_ioapic_id(ioapic);
1125
1126 for (idx = 0; idx < mp_irq_entries; idx++) {
1127 struct mpc_intsrc *irq = mp_irqs + idx;
1128
1129
1130 if (irq->srcbus == MP_ISA_BUS && irq->srcbusirq == i)
1131 break;
1132
1133
1134 if (irq->dstapic == dstapic && irq->dstirq == pin)
1135 break;
1136 }
1137
1138 if (idx != mp_irq_entries) {
1139 pr_debug("ACPI: IRQ%d used by override.\n", i);
1140 continue;
1141 }
1142
1143 mp_irq.type = MP_INTSRC;
1144 mp_irq.irqflag = 0;
1145 mp_irq.srcbus = MP_ISA_BUS;
1146 mp_irq.dstapic = dstapic;
1147 mp_irq.irqtype = mp_INT;
1148 mp_irq.srcbusirq = i;
1149 mp_irq.dstirq = pin;
1150
1151 mp_save_irq(&mp_irq);
1152 }
1153}
1154
1155
1156
1157
1158
1159static int __init acpi_parse_madt_ioapic_entries(void)
1160{
1161 int count;
1162
1163
1164
1165
1166
1167
1168
1169 if (acpi_disabled || acpi_noirq)
1170 return -ENODEV;
1171
1172 if (!boot_cpu_has(X86_FEATURE_APIC))
1173 return -ENODEV;
1174
1175
1176
1177
1178 if (skip_ioapic_setup) {
1179 pr_info("Skipping IOAPIC probe due to 'noapic' option.\n");
1180 return -ENODEV;
1181 }
1182
1183 count = acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic,
1184 MAX_IO_APICS);
1185 if (!count) {
1186 pr_err("No IOAPIC entries present\n");
1187 return -ENODEV;
1188 } else if (count < 0) {
1189 pr_err("Error parsing IOAPIC entry\n");
1190 return count;
1191 }
1192
1193 count = acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE,
1194 acpi_parse_int_src_ovr, nr_irqs);
1195 if (count < 0) {
1196 pr_err("Error parsing interrupt source overrides entry\n");
1197
1198 return count;
1199 }
1200
1201
1202
1203
1204
1205
1206 if (acpi_sci_override_gsi == INVALID_ACPI_IRQ && !acpi_gbl_reduced_hardware)
1207 acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
1208 acpi_gbl_FADT.sci_interrupt);
1209
1210
1211 mp_config_acpi_legacy_irqs();
1212
1213 count = acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE,
1214 acpi_parse_nmi_src, nr_irqs);
1215 if (count < 0) {
1216 pr_err("Error parsing NMI SRC entry\n");
1217
1218 return count;
1219 }
1220
1221 return 0;
1222}
1223#else
1224static inline int acpi_parse_madt_ioapic_entries(void)
1225{
1226 return -1;
1227}
1228#endif
1229
1230static void __init early_acpi_process_madt(void)
1231{
1232#ifdef CONFIG_X86_LOCAL_APIC
1233 int error;
1234
1235 if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
1236
1237
1238
1239
1240 error = early_acpi_parse_madt_lapic_addr_ovr();
1241 if (!error) {
1242 acpi_lapic = 1;
1243 smp_found_config = 1;
1244 }
1245 if (error == -EINVAL) {
1246
1247
1248
1249 pr_err("Invalid BIOS MADT, disabling ACPI\n");
1250 disable_acpi();
1251 }
1252 }
1253#endif
1254}
1255
1256static void __init acpi_process_madt(void)
1257{
1258#ifdef CONFIG_X86_LOCAL_APIC
1259 int error;
1260
1261 if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
1262
1263
1264
1265
1266 error = acpi_parse_madt_lapic_entries();
1267 if (!error) {
1268 acpi_lapic = 1;
1269
1270
1271
1272
1273 mutex_lock(&acpi_ioapic_lock);
1274 error = acpi_parse_madt_ioapic_entries();
1275 mutex_unlock(&acpi_ioapic_lock);
1276 if (!error) {
1277 acpi_set_irq_model_ioapic();
1278
1279 smp_found_config = 1;
1280 }
1281 }
1282 if (error == -EINVAL) {
1283
1284
1285
1286 pr_err("Invalid BIOS MADT, disabling ACPI\n");
1287 disable_acpi();
1288 }
1289 } else {
1290
1291
1292
1293
1294
1295 if (smp_found_config) {
1296 pr_warn("No APIC-table, disabling MPS\n");
1297 smp_found_config = 0;
1298 }
1299 }
1300
1301
1302
1303
1304
1305 if (acpi_lapic && acpi_ioapic)
1306 pr_info("Using ACPI (MADT) for SMP configuration information\n");
1307 else if (acpi_lapic)
1308 pr_info("Using ACPI for processor (LAPIC) configuration information\n");
1309#endif
1310 return;
1311}
1312
1313static int __init disable_acpi_irq(const struct dmi_system_id *d)
1314{
1315 if (!acpi_force) {
1316 pr_notice("%s detected: force use of acpi=noirq\n", d->ident);
1317 acpi_noirq_set();
1318 }
1319 return 0;
1320}
1321
1322static int __init disable_acpi_pci(const struct dmi_system_id *d)
1323{
1324 if (!acpi_force) {
1325 pr_notice("%s detected: force use of pci=noacpi\n", d->ident);
1326 acpi_disable_pci();
1327 }
1328 return 0;
1329}
1330
1331static int __init dmi_disable_acpi(const struct dmi_system_id *d)
1332{
1333 if (!acpi_force) {
1334 pr_notice("%s detected: acpi off\n", d->ident);
1335 disable_acpi();
1336 } else {
1337 pr_notice("Warning: DMI blacklist says broken, but acpi forced\n");
1338 }
1339 return 0;
1340}
1341
1342
1343
1344
1345static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
1346{
1347 if (!acpi_skip_timer_override) {
1348 pr_notice("%s detected: Ignoring BIOS IRQ0 override\n",
1349 d->ident);
1350 acpi_skip_timer_override = 1;
1351 }
1352 return 0;
1353}
1354
1355
1356
1357
1358
1359
1360
1361
1362void __init acpi_generic_reduced_hw_init(void)
1363{
1364
1365
1366
1367
1368 x86_init.timers.timer_init = x86_init_noop;
1369 x86_init.irqs.pre_vector_init = x86_init_noop;
1370 legacy_pic = &null_legacy_pic;
1371}
1372
1373static void __init acpi_reduced_hw_init(void)
1374{
1375 if (acpi_gbl_reduced_hardware)
1376 x86_init.acpi.reduced_hw_early_init();
1377}
1378
1379
1380
1381
1382
1383static const struct dmi_system_id acpi_dmi_table[] __initconst = {
1384
1385
1386
1387 {
1388 .callback = dmi_disable_acpi,
1389 .ident = "IBM Thinkpad",
1390 .matches = {
1391 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
1392 DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
1393 },
1394 },
1395
1396
1397
1398
1399 {
1400 .callback = disable_acpi_irq,
1401 .ident = "ASUS A7V",
1402 .matches = {
1403 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
1404 DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
1405
1406 DMI_MATCH(DMI_BIOS_VERSION,
1407 "ASUS A7V ACPI BIOS Revision 1007"),
1408 },
1409 },
1410 {
1411
1412
1413
1414
1415
1416
1417 .callback = disable_acpi_irq,
1418 .ident = "IBM Thinkpad 600 Series 2645",
1419 .matches = {
1420 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
1421 DMI_MATCH(DMI_BOARD_NAME, "2645"),
1422 },
1423 },
1424 {
1425 .callback = disable_acpi_irq,
1426 .ident = "IBM Thinkpad 600 Series 2646",
1427 .matches = {
1428 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
1429 DMI_MATCH(DMI_BOARD_NAME, "2646"),
1430 },
1431 },
1432
1433
1434
1435 {
1436 .callback = disable_acpi_pci,
1437 .ident = "ASUS PR-DLS",
1438 .matches = {
1439 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1440 DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
1441 DMI_MATCH(DMI_BIOS_VERSION,
1442 "ASUS PR-DLS ACPI BIOS Revision 1010"),
1443 DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
1444 },
1445 },
1446 {
1447 .callback = disable_acpi_pci,
1448 .ident = "Acer TravelMate 36x Laptop",
1449 .matches = {
1450 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1451 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
1452 },
1453 },
1454 {}
1455};
1456
1457
1458static const struct dmi_system_id acpi_dmi_table_late[] __initconst = {
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469 {
1470 .callback = dmi_ignore_irq0_timer_override,
1471 .ident = "HP nx6115 laptop",
1472 .matches = {
1473 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1474 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6115"),
1475 },
1476 },
1477 {
1478 .callback = dmi_ignore_irq0_timer_override,
1479 .ident = "HP NX6125 laptop",
1480 .matches = {
1481 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1482 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6125"),
1483 },
1484 },
1485 {
1486 .callback = dmi_ignore_irq0_timer_override,
1487 .ident = "HP NX6325 laptop",
1488 .matches = {
1489 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1490 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
1491 },
1492 },
1493 {
1494 .callback = dmi_ignore_irq0_timer_override,
1495 .ident = "HP 6715b laptop",
1496 .matches = {
1497 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1498 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
1499 },
1500 },
1501 {
1502 .callback = dmi_ignore_irq0_timer_override,
1503 .ident = "FUJITSU SIEMENS",
1504 .matches = {
1505 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
1506 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
1507 },
1508 },
1509 {}
1510};
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531void __init acpi_boot_table_init(void)
1532{
1533 dmi_check_system(acpi_dmi_table);
1534
1535
1536
1537
1538 if (acpi_disabled)
1539 return;
1540
1541
1542
1543
1544 if (acpi_locate_initial_tables())
1545 disable_acpi();
1546 else
1547 acpi_reserve_initial_tables();
1548}
1549
1550int __init early_acpi_boot_init(void)
1551{
1552 if (acpi_disabled)
1553 return 1;
1554
1555 acpi_table_init_complete();
1556
1557 acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
1558
1559
1560
1561
1562 if (acpi_blacklisted()) {
1563 if (acpi_force) {
1564 pr_warn("acpi=force override\n");
1565 } else {
1566 pr_warn("Disabling ACPI support\n");
1567 disable_acpi();
1568 return 1;
1569 }
1570 }
1571
1572
1573
1574
1575 early_acpi_process_madt();
1576
1577
1578
1579
1580 acpi_reduced_hw_init();
1581
1582 return 0;
1583}
1584
1585int __init acpi_boot_init(void)
1586{
1587
1588 dmi_check_system(acpi_dmi_table_late);
1589
1590
1591
1592
1593 if (acpi_disabled)
1594 return 1;
1595
1596 acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
1597
1598
1599
1600
1601 acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
1602
1603
1604
1605
1606 acpi_process_madt();
1607
1608 acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
1609 if (IS_ENABLED(CONFIG_ACPI_BGRT) && !acpi_nobgrt)
1610 acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
1611
1612 if (!acpi_noirq)
1613 x86_init.pci.init = pci_acpi_init;
1614
1615
1616 acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
1617 return 0;
1618}
1619
1620static int __init parse_acpi(char *arg)
1621{
1622 if (!arg)
1623 return -EINVAL;
1624
1625
1626 if (strcmp(arg, "off") == 0) {
1627 disable_acpi();
1628 }
1629
1630 else if (strcmp(arg, "force") == 0) {
1631 acpi_force = 1;
1632 acpi_disabled = 0;
1633 }
1634
1635 else if (strcmp(arg, "strict") == 0) {
1636 acpi_strict = 1;
1637 }
1638
1639 else if (strcmp(arg, "rsdt") == 0) {
1640 acpi_gbl_do_not_use_xsdt = TRUE;
1641 }
1642
1643 else if (strcmp(arg, "noirq") == 0) {
1644 acpi_noirq_set();
1645 }
1646
1647 else if (strcmp(arg, "copy_dsdt") == 0) {
1648 acpi_gbl_copy_dsdt_locally = 1;
1649 }
1650
1651 else if (strcmp(arg, "nocmcff") == 0) {
1652 acpi_disable_cmcff = 1;
1653 } else {
1654
1655 return -EINVAL;
1656 }
1657 return 0;
1658}
1659early_param("acpi", parse_acpi);
1660
1661static int __init parse_acpi_bgrt(char *arg)
1662{
1663 acpi_nobgrt = true;
1664 return 0;
1665}
1666early_param("bgrt_disable", parse_acpi_bgrt);
1667
1668
1669static int __init parse_pci(char *arg)
1670{
1671 if (arg && strcmp(arg, "noacpi") == 0)
1672 acpi_disable_pci();
1673 return 0;
1674}
1675early_param("pci", parse_pci);
1676
1677int __init acpi_mps_check(void)
1678{
1679#if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE)
1680
1681 if (acpi_disabled || acpi_noirq) {
1682 pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n");
1683 return 1;
1684 }
1685#endif
1686 return 0;
1687}
1688
1689#ifdef CONFIG_X86_IO_APIC
1690static int __init parse_acpi_skip_timer_override(char *arg)
1691{
1692 acpi_skip_timer_override = 1;
1693 return 0;
1694}
1695early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override);
1696
1697static int __init parse_acpi_use_timer_override(char *arg)
1698{
1699 acpi_use_timer_override = 1;
1700 return 0;
1701}
1702early_param("acpi_use_timer_override", parse_acpi_use_timer_override);
1703#endif
1704
1705static int __init setup_acpi_sci(char *s)
1706{
1707 if (!s)
1708 return -EINVAL;
1709 if (!strcmp(s, "edge"))
1710 acpi_sci_flags = ACPI_MADT_TRIGGER_EDGE |
1711 (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK);
1712 else if (!strcmp(s, "level"))
1713 acpi_sci_flags = ACPI_MADT_TRIGGER_LEVEL |
1714 (acpi_sci_flags & ~ACPI_MADT_TRIGGER_MASK);
1715 else if (!strcmp(s, "high"))
1716 acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_HIGH |
1717 (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK);
1718 else if (!strcmp(s, "low"))
1719 acpi_sci_flags = ACPI_MADT_POLARITY_ACTIVE_LOW |
1720 (acpi_sci_flags & ~ACPI_MADT_POLARITY_MASK);
1721 else
1722 return -EINVAL;
1723 return 0;
1724}
1725early_param("acpi_sci", setup_acpi_sci);
1726
1727int __acpi_acquire_global_lock(unsigned int *lock)
1728{
1729 unsigned int old, new, val;
1730 do {
1731 old = *lock;
1732 new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
1733 val = cmpxchg(lock, old, new);
1734 } while (unlikely (val != old));
1735 return ((new & 0x3) < 3) ? -1 : 0;
1736}
1737
1738int __acpi_release_global_lock(unsigned int *lock)
1739{
1740 unsigned int old, new, val;
1741 do {
1742 old = *lock;
1743 new = old & ~0x3;
1744 val = cmpxchg(lock, old, new);
1745 } while (unlikely (val != old));
1746 return old & 0x1;
1747}
1748
1749void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
1750{
1751 e820__range_add(addr, size, E820_TYPE_ACPI);
1752 e820__update_table_print();
1753}
1754
1755void x86_default_set_root_pointer(u64 addr)
1756{
1757 boot_params.acpi_rsdp_addr = addr;
1758}
1759
1760u64 x86_default_get_root_pointer(void)
1761{
1762 return boot_params.acpi_rsdp_addr;
1763}
1764