1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/slab.h>
33#include <linux/mm.h>
34#include <linux/highmem.h>
35#include <linux/pci.h>
36#include <linux/interrupt.h>
37#include <linux/kmod.h>
38#include <linux/delay.h>
39#include <linux/workqueue.h>
40#include <linux/nmi.h>
41#include <linux/acpi.h>
42#include <linux/acpi_io.h>
43#include <linux/efi.h>
44#include <linux/ioport.h>
45#include <linux/list.h>
46#include <linux/jiffies.h>
47#include <linux/semaphore.h>
48
49#include <asm/io.h>
50#include <asm/uaccess.h>
51
52#include <acpi/acpi.h>
53#include <acpi/acpi_bus.h>
54#include <acpi/processor.h>
55
56#define _COMPONENT ACPI_OS_SERVICES
57ACPI_MODULE_NAME("osl");
58#define PREFIX "ACPI: "
59struct acpi_os_dpc {
60 acpi_osd_exec_callback function;
61 void *context;
62 struct work_struct work;
63 int wait;
64};
65
66#ifdef CONFIG_ACPI_CUSTOM_DSDT
67#include CONFIG_ACPI_CUSTOM_DSDT_FILE
68#endif
69
70#ifdef ENABLE_DEBUGGER
71#include <linux/kdb.h>
72
73
74int acpi_in_debugger;
75EXPORT_SYMBOL(acpi_in_debugger);
76
77extern char line_buf[80];
78#endif
79
80static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
81 u32 pm1b_ctrl);
82
83static acpi_osd_handler acpi_irq_handler;
84static void *acpi_irq_context;
85static struct workqueue_struct *kacpid_wq;
86static struct workqueue_struct *kacpi_notify_wq;
87static struct workqueue_struct *kacpi_hotplug_wq;
88
89
90
91
92
93struct acpi_ioremap {
94 struct list_head list;
95 void __iomem *virt;
96 acpi_physical_address phys;
97 acpi_size size;
98 unsigned long refcount;
99};
100
101static LIST_HEAD(acpi_ioremaps);
102static DEFINE_MUTEX(acpi_ioremap_lock);
103
104static void __init acpi_osi_setup_late(void);
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139static struct osi_linux {
140 unsigned int enable:1;
141 unsigned int dmi:1;
142 unsigned int cmdline:1;
143} osi_linux = {0, 0, 0};
144
145static u32 acpi_osi_handler(acpi_string interface, u32 supported)
146{
147 if (!strcmp("Linux", interface)) {
148
149 printk_once(KERN_NOTICE FW_BUG PREFIX
150 "BIOS _OSI(Linux) query %s%s\n",
151 osi_linux.enable ? "honored" : "ignored",
152 osi_linux.cmdline ? " via cmdline" :
153 osi_linux.dmi ? " via DMI" : "");
154 }
155
156 return supported;
157}
158
159static void __init acpi_request_region (struct acpi_generic_address *gas,
160 unsigned int length, char *desc)
161{
162 u64 addr;
163
164
165 memcpy(&addr, &gas->address, sizeof(addr));
166 if (!addr || !length)
167 return;
168
169
170 if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
171 request_region(addr, length, desc);
172 else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
173 request_mem_region(addr, length, desc);
174}
175
176static int __init acpi_reserve_resources(void)
177{
178 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
179 "ACPI PM1a_EVT_BLK");
180
181 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
182 "ACPI PM1b_EVT_BLK");
183
184 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
185 "ACPI PM1a_CNT_BLK");
186
187 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
188 "ACPI PM1b_CNT_BLK");
189
190 if (acpi_gbl_FADT.pm_timer_length == 4)
191 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
192
193 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
194 "ACPI PM2_CNT_BLK");
195
196
197
198 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
199 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
200 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
201
202 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
203 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
204 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
205
206 return 0;
207}
208device_initcall(acpi_reserve_resources);
209
210void acpi_os_printf(const char *fmt, ...)
211{
212 va_list args;
213 va_start(args, fmt);
214 acpi_os_vprintf(fmt, args);
215 va_end(args);
216}
217
218void acpi_os_vprintf(const char *fmt, va_list args)
219{
220 static char buffer[512];
221
222 vsprintf(buffer, fmt, args);
223
224#ifdef ENABLE_DEBUGGER
225 if (acpi_in_debugger) {
226 kdb_printf("%s", buffer);
227 } else {
228 printk(KERN_CONT "%s", buffer);
229 }
230#else
231 printk(KERN_CONT "%s", buffer);
232#endif
233}
234
235#ifdef CONFIG_KEXEC
236static unsigned long acpi_rsdp;
237static int __init setup_acpi_rsdp(char *arg)
238{
239 acpi_rsdp = simple_strtoul(arg, NULL, 16);
240 return 0;
241}
242early_param("acpi_rsdp", setup_acpi_rsdp);
243#endif
244
245acpi_physical_address __init acpi_os_get_root_pointer(void)
246{
247#ifdef CONFIG_KEXEC
248 if (acpi_rsdp)
249 return acpi_rsdp;
250#endif
251
252 if (efi_enabled(EFI_CONFIG_TABLES)) {
253 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
254 return efi.acpi20;
255 else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
256 return efi.acpi;
257 else {
258 printk(KERN_ERR PREFIX
259 "System description tables not found\n");
260 return 0;
261 }
262 } else {
263 acpi_physical_address pa = 0;
264
265 acpi_find_root_pointer(&pa);
266 return pa;
267 }
268}
269
270
271static struct acpi_ioremap *
272acpi_map_lookup(acpi_physical_address phys, acpi_size size)
273{
274 struct acpi_ioremap *map;
275
276 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
277 if (map->phys <= phys &&
278 phys + size <= map->phys + map->size)
279 return map;
280
281 return NULL;
282}
283
284
285static void __iomem *
286acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
287{
288 struct acpi_ioremap *map;
289
290 map = acpi_map_lookup(phys, size);
291 if (map)
292 return map->virt + (phys - map->phys);
293
294 return NULL;
295}
296
297void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
298{
299 struct acpi_ioremap *map;
300 void __iomem *virt = NULL;
301
302 mutex_lock(&acpi_ioremap_lock);
303 map = acpi_map_lookup(phys, size);
304 if (map) {
305 virt = map->virt + (phys - map->phys);
306 map->refcount++;
307 }
308 mutex_unlock(&acpi_ioremap_lock);
309 return virt;
310}
311EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
312
313
314static struct acpi_ioremap *
315acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
316{
317 struct acpi_ioremap *map;
318
319 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
320 if (map->virt <= virt &&
321 virt + size <= map->virt + map->size)
322 return map;
323
324 return NULL;
325}
326
327#ifndef CONFIG_IA64
328#define should_use_kmap(pfn) page_is_ram(pfn)
329#else
330
331#define should_use_kmap(pfn) 0
332#endif
333
334static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
335{
336 unsigned long pfn;
337
338 pfn = pg_off >> PAGE_SHIFT;
339 if (should_use_kmap(pfn)) {
340 if (pg_sz > PAGE_SIZE)
341 return NULL;
342 return (void __iomem __force *)kmap(pfn_to_page(pfn));
343 } else
344 return acpi_os_ioremap(pg_off, pg_sz);
345}
346
347static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
348{
349 unsigned long pfn;
350
351 pfn = pg_off >> PAGE_SHIFT;
352 if (should_use_kmap(pfn))
353 kunmap(pfn_to_page(pfn));
354 else
355 iounmap(vaddr);
356}
357
358void __iomem *__init_refok
359acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
360{
361 struct acpi_ioremap *map;
362 void __iomem *virt;
363 acpi_physical_address pg_off;
364 acpi_size pg_sz;
365
366 if (phys > ULONG_MAX) {
367 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
368 return NULL;
369 }
370
371 if (!acpi_gbl_permanent_mmap)
372 return __acpi_map_table((unsigned long)phys, size);
373
374 mutex_lock(&acpi_ioremap_lock);
375
376 map = acpi_map_lookup(phys, size);
377 if (map) {
378 map->refcount++;
379 goto out;
380 }
381
382 map = kzalloc(sizeof(*map), GFP_KERNEL);
383 if (!map) {
384 mutex_unlock(&acpi_ioremap_lock);
385 return NULL;
386 }
387
388 pg_off = round_down(phys, PAGE_SIZE);
389 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
390 virt = acpi_map(pg_off, pg_sz);
391 if (!virt) {
392 mutex_unlock(&acpi_ioremap_lock);
393 kfree(map);
394 return NULL;
395 }
396
397 INIT_LIST_HEAD(&map->list);
398 map->virt = virt;
399 map->phys = pg_off;
400 map->size = pg_sz;
401 map->refcount = 1;
402
403 list_add_tail_rcu(&map->list, &acpi_ioremaps);
404
405 out:
406 mutex_unlock(&acpi_ioremap_lock);
407 return map->virt + (phys - map->phys);
408}
409EXPORT_SYMBOL_GPL(acpi_os_map_memory);
410
411static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
412{
413 if (!--map->refcount)
414 list_del_rcu(&map->list);
415}
416
417static void acpi_os_map_cleanup(struct acpi_ioremap *map)
418{
419 if (!map->refcount) {
420 synchronize_rcu();
421 acpi_unmap(map->phys, map->virt);
422 kfree(map);
423 }
424}
425
426void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
427{
428 struct acpi_ioremap *map;
429
430 if (!acpi_gbl_permanent_mmap) {
431 __acpi_unmap_table(virt, size);
432 return;
433 }
434
435 mutex_lock(&acpi_ioremap_lock);
436 map = acpi_map_lookup_virt(virt, size);
437 if (!map) {
438 mutex_unlock(&acpi_ioremap_lock);
439 WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
440 return;
441 }
442 acpi_os_drop_map_ref(map);
443 mutex_unlock(&acpi_ioremap_lock);
444
445 acpi_os_map_cleanup(map);
446}
447EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
448
449void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
450{
451 if (!acpi_gbl_permanent_mmap)
452 __acpi_unmap_table(virt, size);
453}
454
455int acpi_os_map_generic_address(struct acpi_generic_address *gas)
456{
457 u64 addr;
458 void __iomem *virt;
459
460 if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
461 return 0;
462
463
464 memcpy(&addr, &gas->address, sizeof(addr));
465 if (!addr || !gas->bit_width)
466 return -EINVAL;
467
468 virt = acpi_os_map_memory(addr, gas->bit_width / 8);
469 if (!virt)
470 return -EIO;
471
472 return 0;
473}
474EXPORT_SYMBOL(acpi_os_map_generic_address);
475
476void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
477{
478 u64 addr;
479 struct acpi_ioremap *map;
480
481 if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
482 return;
483
484
485 memcpy(&addr, &gas->address, sizeof(addr));
486 if (!addr || !gas->bit_width)
487 return;
488
489 mutex_lock(&acpi_ioremap_lock);
490 map = acpi_map_lookup(addr, gas->bit_width / 8);
491 if (!map) {
492 mutex_unlock(&acpi_ioremap_lock);
493 return;
494 }
495 acpi_os_drop_map_ref(map);
496 mutex_unlock(&acpi_ioremap_lock);
497
498 acpi_os_map_cleanup(map);
499}
500EXPORT_SYMBOL(acpi_os_unmap_generic_address);
501
502#ifdef ACPI_FUTURE_USAGE
503acpi_status
504acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
505{
506 if (!phys || !virt)
507 return AE_BAD_PARAMETER;
508
509 *phys = virt_to_phys(virt);
510
511 return AE_OK;
512}
513#endif
514
515#define ACPI_MAX_OVERRIDE_LEN 100
516
517static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
518
519acpi_status
520acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
521 acpi_string * new_val)
522{
523 if (!init_val || !new_val)
524 return AE_BAD_PARAMETER;
525
526 *new_val = NULL;
527 if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
528 printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
529 acpi_os_name);
530 *new_val = acpi_os_name;
531 }
532
533 return AE_OK;
534}
535
536#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
537#include <linux/earlycpio.h>
538#include <linux/memblock.h>
539
540static u64 acpi_tables_addr;
541static int all_tables_size;
542
543
544u8 __init acpi_table_checksum(u8 *buffer, u32 length)
545{
546 u8 sum = 0;
547 u8 *end = buffer + length;
548
549 while (buffer < end)
550 sum = (u8) (sum + *(buffer++));
551 return sum;
552}
553
554
555static const char * const table_sigs[] = {
556 ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ,
557 ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT,
558 ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF,
559 ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET,
560 ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI,
561 ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
562 ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
563 ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
564 ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
565
566
567#define INVALID_TABLE(x, path, name) \
568 { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; }
569
570#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
571
572
573#define ACPI_OVERRIDE_TABLES 10
574
575void __init acpi_initrd_override(void *data, size_t size)
576{
577 int sig, no, table_nr = 0, total_offset = 0;
578 long offset = 0;
579 struct acpi_table_header *table;
580 char cpio_path[32] = "kernel/firmware/acpi/";
581 struct cpio_data file;
582 struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES];
583 char *p;
584
585 if (data == NULL || size == 0)
586 return;
587
588 for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) {
589 file = find_cpio_data(cpio_path, data, size, &offset);
590 if (!file.data)
591 break;
592
593 data += offset;
594 size -= offset;
595
596 if (file.size < sizeof(struct acpi_table_header))
597 INVALID_TABLE("Table smaller than ACPI header",
598 cpio_path, file.name);
599
600 table = file.data;
601
602 for (sig = 0; table_sigs[sig]; sig++)
603 if (!memcmp(table->signature, table_sigs[sig], 4))
604 break;
605
606 if (!table_sigs[sig])
607 INVALID_TABLE("Unknown signature",
608 cpio_path, file.name);
609 if (file.size != table->length)
610 INVALID_TABLE("File length does not match table length",
611 cpio_path, file.name);
612 if (acpi_table_checksum(file.data, table->length))
613 INVALID_TABLE("Bad table checksum",
614 cpio_path, file.name);
615
616 pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n",
617 table->signature, cpio_path, file.name, table->length);
618
619 all_tables_size += table->length;
620 early_initrd_files[table_nr].data = file.data;
621 early_initrd_files[table_nr].size = file.size;
622 table_nr++;
623 }
624 if (table_nr == 0)
625 return;
626
627 acpi_tables_addr =
628 memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT,
629 all_tables_size, PAGE_SIZE);
630 if (!acpi_tables_addr) {
631 WARN_ON(1);
632 return;
633 }
634
635
636
637
638
639
640
641
642
643
644 memblock_reserve(acpi_tables_addr, all_tables_size);
645 arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
646
647 p = early_ioremap(acpi_tables_addr, all_tables_size);
648
649 for (no = 0; no < table_nr; no++) {
650 memcpy(p + total_offset, early_initrd_files[no].data,
651 early_initrd_files[no].size);
652 total_offset += early_initrd_files[no].size;
653 }
654 early_iounmap(p, all_tables_size);
655}
656#endif
657
658static void acpi_table_taint(struct acpi_table_header *table)
659{
660 pr_warn(PREFIX
661 "Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
662 table->signature, table->oem_table_id);
663 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
664}
665
666
667acpi_status
668acpi_os_table_override(struct acpi_table_header * existing_table,
669 struct acpi_table_header ** new_table)
670{
671 if (!existing_table || !new_table)
672 return AE_BAD_PARAMETER;
673
674 *new_table = NULL;
675
676#ifdef CONFIG_ACPI_CUSTOM_DSDT
677 if (strncmp(existing_table->signature, "DSDT", 4) == 0)
678 *new_table = (struct acpi_table_header *)AmlCode;
679#endif
680 if (*new_table != NULL)
681 acpi_table_taint(existing_table);
682 return AE_OK;
683}
684
685acpi_status
686acpi_os_physical_table_override(struct acpi_table_header *existing_table,
687 acpi_physical_address *address,
688 u32 *table_length)
689{
690#ifndef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
691 *table_length = 0;
692 *address = 0;
693 return AE_OK;
694#else
695 int table_offset = 0;
696 struct acpi_table_header *table;
697
698 *table_length = 0;
699 *address = 0;
700
701 if (!acpi_tables_addr)
702 return AE_OK;
703
704 do {
705 if (table_offset + ACPI_HEADER_SIZE > all_tables_size) {
706 WARN_ON(1);
707 return AE_OK;
708 }
709
710 table = acpi_os_map_memory(acpi_tables_addr + table_offset,
711 ACPI_HEADER_SIZE);
712
713 if (table_offset + table->length > all_tables_size) {
714 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
715 WARN_ON(1);
716 return AE_OK;
717 }
718
719 table_offset += table->length;
720
721 if (memcmp(existing_table->signature, table->signature, 4)) {
722 acpi_os_unmap_memory(table,
723 ACPI_HEADER_SIZE);
724 continue;
725 }
726
727
728 if (memcmp(table->oem_table_id, existing_table->oem_table_id,
729 ACPI_OEM_TABLE_ID_SIZE)) {
730 acpi_os_unmap_memory(table,
731 ACPI_HEADER_SIZE);
732 continue;
733 }
734
735 table_offset -= table->length;
736 *table_length = table->length;
737 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
738 *address = acpi_tables_addr + table_offset;
739 break;
740 } while (table_offset + ACPI_HEADER_SIZE < all_tables_size);
741
742 if (*address != 0)
743 acpi_table_taint(existing_table);
744 return AE_OK;
745#endif
746}
747
748static irqreturn_t acpi_irq(int irq, void *dev_id)
749{
750 u32 handled;
751
752 handled = (*acpi_irq_handler) (acpi_irq_context);
753
754 if (handled) {
755 acpi_irq_handled++;
756 return IRQ_HANDLED;
757 } else {
758 acpi_irq_not_handled++;
759 return IRQ_NONE;
760 }
761}
762
763acpi_status
764acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
765 void *context)
766{
767 unsigned int irq;
768
769 acpi_irq_stats_init();
770
771
772
773
774
775 if (gsi != acpi_gbl_FADT.sci_interrupt)
776 return AE_BAD_PARAMETER;
777
778 if (acpi_irq_handler)
779 return AE_ALREADY_ACQUIRED;
780
781 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
782 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
783 gsi);
784 return AE_OK;
785 }
786
787 acpi_irq_handler = handler;
788 acpi_irq_context = context;
789 if (request_irq(irq, acpi_irq, IRQF_SHARED | IRQF_NO_SUSPEND, "acpi", acpi_irq)) {
790 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
791 acpi_irq_handler = NULL;
792 return AE_NOT_ACQUIRED;
793 }
794
795 return AE_OK;
796}
797
798acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
799{
800 if (irq != acpi_gbl_FADT.sci_interrupt)
801 return AE_BAD_PARAMETER;
802
803 free_irq(irq, acpi_irq);
804 acpi_irq_handler = NULL;
805
806 return AE_OK;
807}
808
809
810
811
812
813void acpi_os_sleep(u64 ms)
814{
815 schedule_timeout_interruptible(msecs_to_jiffies(ms));
816}
817
818void acpi_os_stall(u32 us)
819{
820 while (us) {
821 u32 delay = 1000;
822
823 if (delay > us)
824 delay = us;
825 udelay(delay);
826 touch_nmi_watchdog();
827 us -= delay;
828 }
829}
830
831
832
833
834
835
836u64 acpi_os_get_timer(void)
837{
838 u64 time_ns = ktime_to_ns(ktime_get());
839 do_div(time_ns, 100);
840 return time_ns;
841}
842
843acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
844{
845 u32 dummy;
846
847 if (!value)
848 value = &dummy;
849
850 *value = 0;
851 if (width <= 8) {
852 *(u8 *) value = inb(port);
853 } else if (width <= 16) {
854 *(u16 *) value = inw(port);
855 } else if (width <= 32) {
856 *(u32 *) value = inl(port);
857 } else {
858 BUG();
859 }
860
861 return AE_OK;
862}
863
864EXPORT_SYMBOL(acpi_os_read_port);
865
866acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
867{
868 if (width <= 8) {
869 outb(value, port);
870 } else if (width <= 16) {
871 outw(value, port);
872 } else if (width <= 32) {
873 outl(value, port);
874 } else {
875 BUG();
876 }
877
878 return AE_OK;
879}
880
881EXPORT_SYMBOL(acpi_os_write_port);
882
883#ifdef readq
884static inline u64 read64(const volatile void __iomem *addr)
885{
886 return readq(addr);
887}
888#else
889static inline u64 read64(const volatile void __iomem *addr)
890{
891 u64 l, h;
892 l = readl(addr);
893 h = readl(addr+4);
894 return l | (h << 32);
895}
896#endif
897
898acpi_status
899acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
900{
901 void __iomem *virt_addr;
902 unsigned int size = width / 8;
903 bool unmap = false;
904 u64 dummy;
905
906 rcu_read_lock();
907 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
908 if (!virt_addr) {
909 rcu_read_unlock();
910 virt_addr = acpi_os_ioremap(phys_addr, size);
911 if (!virt_addr)
912 return AE_BAD_ADDRESS;
913 unmap = true;
914 }
915
916 if (!value)
917 value = &dummy;
918
919 switch (width) {
920 case 8:
921 *(u8 *) value = readb(virt_addr);
922 break;
923 case 16:
924 *(u16 *) value = readw(virt_addr);
925 break;
926 case 32:
927 *(u32 *) value = readl(virt_addr);
928 break;
929 case 64:
930 *(u64 *) value = read64(virt_addr);
931 break;
932 default:
933 BUG();
934 }
935
936 if (unmap)
937 iounmap(virt_addr);
938 else
939 rcu_read_unlock();
940
941 return AE_OK;
942}
943
944#ifdef writeq
945static inline void write64(u64 val, volatile void __iomem *addr)
946{
947 writeq(val, addr);
948}
949#else
950static inline void write64(u64 val, volatile void __iomem *addr)
951{
952 writel(val, addr);
953 writel(val>>32, addr+4);
954}
955#endif
956
957acpi_status
958acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
959{
960 void __iomem *virt_addr;
961 unsigned int size = width / 8;
962 bool unmap = false;
963
964 rcu_read_lock();
965 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
966 if (!virt_addr) {
967 rcu_read_unlock();
968 virt_addr = acpi_os_ioremap(phys_addr, size);
969 if (!virt_addr)
970 return AE_BAD_ADDRESS;
971 unmap = true;
972 }
973
974 switch (width) {
975 case 8:
976 writeb(value, virt_addr);
977 break;
978 case 16:
979 writew(value, virt_addr);
980 break;
981 case 32:
982 writel(value, virt_addr);
983 break;
984 case 64:
985 write64(value, virt_addr);
986 break;
987 default:
988 BUG();
989 }
990
991 if (unmap)
992 iounmap(virt_addr);
993 else
994 rcu_read_unlock();
995
996 return AE_OK;
997}
998
999acpi_status
1000acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
1001 u64 *value, u32 width)
1002{
1003 int result, size;
1004 u32 value32;
1005
1006 if (!value)
1007 return AE_BAD_PARAMETER;
1008
1009 switch (width) {
1010 case 8:
1011 size = 1;
1012 break;
1013 case 16:
1014 size = 2;
1015 break;
1016 case 32:
1017 size = 4;
1018 break;
1019 default:
1020 return AE_ERROR;
1021 }
1022
1023 result = raw_pci_read(pci_id->segment, pci_id->bus,
1024 PCI_DEVFN(pci_id->device, pci_id->function),
1025 reg, size, &value32);
1026 *value = value32;
1027
1028 return (result ? AE_ERROR : AE_OK);
1029}
1030
1031acpi_status
1032acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
1033 u64 value, u32 width)
1034{
1035 int result, size;
1036
1037 switch (width) {
1038 case 8:
1039 size = 1;
1040 break;
1041 case 16:
1042 size = 2;
1043 break;
1044 case 32:
1045 size = 4;
1046 break;
1047 default:
1048 return AE_ERROR;
1049 }
1050
1051 result = raw_pci_write(pci_id->segment, pci_id->bus,
1052 PCI_DEVFN(pci_id->device, pci_id->function),
1053 reg, size, value);
1054
1055 return (result ? AE_ERROR : AE_OK);
1056}
1057
1058static void acpi_os_execute_deferred(struct work_struct *work)
1059{
1060 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
1061
1062 if (dpc->wait)
1063 acpi_os_wait_events_complete();
1064
1065 dpc->function(dpc->context);
1066 kfree(dpc);
1067}
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084static acpi_status __acpi_os_execute(acpi_execute_type type,
1085 acpi_osd_exec_callback function, void *context, int hp)
1086{
1087 acpi_status status = AE_OK;
1088 struct acpi_os_dpc *dpc;
1089 struct workqueue_struct *queue;
1090 int ret;
1091 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
1092 "Scheduling function [%p(%p)] for deferred execution.\n",
1093 function, context));
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
1105 if (!dpc)
1106 return AE_NO_MEMORY;
1107
1108 dpc->function = function;
1109 dpc->context = context;
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 if (hp) {
1122 queue = kacpi_hotplug_wq;
1123 dpc->wait = 1;
1124 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
1125 } else if (type == OSL_NOTIFY_HANDLER) {
1126 queue = kacpi_notify_wq;
1127 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
1128 } else {
1129 queue = kacpid_wq;
1130 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
1131 }
1132
1133
1134
1135
1136
1137
1138
1139
1140 ret = queue_work_on(0, queue, &dpc->work);
1141
1142 if (!ret) {
1143 printk(KERN_ERR PREFIX
1144 "Call to queue_work() failed.\n");
1145 status = AE_ERROR;
1146 kfree(dpc);
1147 }
1148 return status;
1149}
1150
1151acpi_status acpi_os_execute(acpi_execute_type type,
1152 acpi_osd_exec_callback function, void *context)
1153{
1154 return __acpi_os_execute(type, function, context, 0);
1155}
1156EXPORT_SYMBOL(acpi_os_execute);
1157
1158acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
1159 void *context)
1160{
1161 return __acpi_os_execute(0, function, context, 1);
1162}
1163EXPORT_SYMBOL(acpi_os_hotplug_execute);
1164
1165void acpi_os_wait_events_complete(void)
1166{
1167 flush_workqueue(kacpid_wq);
1168 flush_workqueue(kacpi_notify_wq);
1169}
1170
1171EXPORT_SYMBOL(acpi_os_wait_events_complete);
1172
1173acpi_status
1174acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
1175{
1176 struct semaphore *sem = NULL;
1177
1178 sem = acpi_os_allocate(sizeof(struct semaphore));
1179 if (!sem)
1180 return AE_NO_MEMORY;
1181 memset(sem, 0, sizeof(struct semaphore));
1182
1183 sema_init(sem, initial_units);
1184
1185 *handle = (acpi_handle *) sem;
1186
1187 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
1188 *handle, initial_units));
1189
1190 return AE_OK;
1191}
1192
1193
1194
1195
1196
1197
1198
1199
1200acpi_status acpi_os_delete_semaphore(acpi_handle handle)
1201{
1202 struct semaphore *sem = (struct semaphore *)handle;
1203
1204 if (!sem)
1205 return AE_BAD_PARAMETER;
1206
1207 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
1208
1209 BUG_ON(!list_empty(&sem->wait_list));
1210 kfree(sem);
1211 sem = NULL;
1212
1213 return AE_OK;
1214}
1215
1216
1217
1218
1219acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
1220{
1221 acpi_status status = AE_OK;
1222 struct semaphore *sem = (struct semaphore *)handle;
1223 long jiffies;
1224 int ret = 0;
1225
1226 if (!sem || (units < 1))
1227 return AE_BAD_PARAMETER;
1228
1229 if (units > 1)
1230 return AE_SUPPORT;
1231
1232 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
1233 handle, units, timeout));
1234
1235 if (timeout == ACPI_WAIT_FOREVER)
1236 jiffies = MAX_SCHEDULE_TIMEOUT;
1237 else
1238 jiffies = msecs_to_jiffies(timeout);
1239
1240 ret = down_timeout(sem, jiffies);
1241 if (ret)
1242 status = AE_TIME;
1243
1244 if (ACPI_FAILURE(status)) {
1245 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
1246 "Failed to acquire semaphore[%p|%d|%d], %s",
1247 handle, units, timeout,
1248 acpi_format_exception(status)));
1249 } else {
1250 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
1251 "Acquired semaphore[%p|%d|%d]", handle,
1252 units, timeout));
1253 }
1254
1255 return status;
1256}
1257
1258
1259
1260
1261acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
1262{
1263 struct semaphore *sem = (struct semaphore *)handle;
1264
1265 if (!sem || (units < 1))
1266 return AE_BAD_PARAMETER;
1267
1268 if (units > 1)
1269 return AE_SUPPORT;
1270
1271 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
1272 units));
1273
1274 up(sem);
1275
1276 return AE_OK;
1277}
1278
1279#ifdef ACPI_FUTURE_USAGE
1280u32 acpi_os_get_line(char *buffer)
1281{
1282
1283#ifdef ENABLE_DEBUGGER
1284 if (acpi_in_debugger) {
1285 u32 chars;
1286
1287 kdb_read(buffer, sizeof(line_buf));
1288
1289
1290 chars = strlen(buffer) - 1;
1291 buffer[chars] = '\0';
1292 }
1293#endif
1294
1295 return 0;
1296}
1297#endif
1298
1299acpi_status acpi_os_signal(u32 function, void *info)
1300{
1301 switch (function) {
1302 case ACPI_SIGNAL_FATAL:
1303 printk(KERN_ERR PREFIX "Fatal opcode executed\n");
1304 break;
1305 case ACPI_SIGNAL_BREAKPOINT:
1306
1307
1308
1309
1310
1311
1312
1313
1314 break;
1315 default:
1316 break;
1317 }
1318
1319 return AE_OK;
1320}
1321
1322static int __init acpi_os_name_setup(char *str)
1323{
1324 char *p = acpi_os_name;
1325 int count = ACPI_MAX_OVERRIDE_LEN - 1;
1326
1327 if (!str || !*str)
1328 return 0;
1329
1330 for (; count-- && str && *str; str++) {
1331 if (isalnum(*str) || *str == ' ' || *str == ':')
1332 *p++ = *str;
1333 else if (*str == '\'' || *str == '"')
1334 continue;
1335 else
1336 break;
1337 }
1338 *p = 0;
1339
1340 return 1;
1341
1342}
1343
1344__setup("acpi_os_name=", acpi_os_name_setup);
1345
1346#define OSI_STRING_LENGTH_MAX 64
1347#define OSI_STRING_ENTRIES_MAX 16
1348
1349struct osi_setup_entry {
1350 char string[OSI_STRING_LENGTH_MAX];
1351 bool enable;
1352};
1353
1354static struct osi_setup_entry __initdata
1355 osi_setup_entries[OSI_STRING_ENTRIES_MAX] = {
1356 {"Module Device", true},
1357 {"Processor Device", true},
1358 {"3.0 _SCP Extensions", true},
1359 {"Processor Aggregator Device", true},
1360};
1361
1362void __init acpi_osi_setup(char *str)
1363{
1364 struct osi_setup_entry *osi;
1365 bool enable = true;
1366 int i;
1367
1368 if (!acpi_gbl_create_osi_method)
1369 return;
1370
1371 if (str == NULL || *str == '\0') {
1372 printk(KERN_INFO PREFIX "_OSI method disabled\n");
1373 acpi_gbl_create_osi_method = FALSE;
1374 return;
1375 }
1376
1377 if (*str == '!') {
1378 str++;
1379 enable = false;
1380 }
1381
1382 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
1383 osi = &osi_setup_entries[i];
1384 if (!strcmp(osi->string, str)) {
1385 osi->enable = enable;
1386 break;
1387 } else if (osi->string[0] == '\0') {
1388 osi->enable = enable;
1389 strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
1390 break;
1391 }
1392 }
1393}
1394
1395static void __init set_osi_linux(unsigned int enable)
1396{
1397 if (osi_linux.enable != enable)
1398 osi_linux.enable = enable;
1399
1400 if (osi_linux.enable)
1401 acpi_osi_setup("Linux");
1402 else
1403 acpi_osi_setup("!Linux");
1404
1405 return;
1406}
1407
1408static void __init acpi_cmdline_osi_linux(unsigned int enable)
1409{
1410 osi_linux.cmdline = 1;
1411 osi_linux.dmi = 0;
1412 set_osi_linux(enable);
1413
1414 return;
1415}
1416
1417void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1418{
1419 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
1420
1421 if (enable == -1)
1422 return;
1423
1424 osi_linux.dmi = 1;
1425 set_osi_linux(enable);
1426
1427 return;
1428}
1429
1430
1431
1432
1433
1434
1435
1436
1437static void __init acpi_osi_setup_late(void)
1438{
1439 struct osi_setup_entry *osi;
1440 char *str;
1441 int i;
1442 acpi_status status;
1443
1444 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
1445 osi = &osi_setup_entries[i];
1446 str = osi->string;
1447
1448 if (*str == '\0')
1449 break;
1450 if (osi->enable) {
1451 status = acpi_install_interface(str);
1452
1453 if (ACPI_SUCCESS(status))
1454 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
1455 } else {
1456 status = acpi_remove_interface(str);
1457
1458 if (ACPI_SUCCESS(status))
1459 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
1460 }
1461 }
1462}
1463
1464static int __init osi_setup(char *str)
1465{
1466 if (str && !strcmp("Linux", str))
1467 acpi_cmdline_osi_linux(1);
1468 else if (str && !strcmp("!Linux", str))
1469 acpi_cmdline_osi_linux(0);
1470 else
1471 acpi_osi_setup(str);
1472
1473 return 1;
1474}
1475
1476__setup("acpi_osi=", osi_setup);
1477
1478
1479static int __init acpi_serialize_setup(char *str)
1480{
1481 printk(KERN_INFO PREFIX "serialize enabled\n");
1482
1483 acpi_gbl_all_methods_serialized = TRUE;
1484
1485 return 1;
1486}
1487
1488__setup("acpi_serialize", acpi_serialize_setup);
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506#define ENFORCE_RESOURCES_STRICT 2
1507#define ENFORCE_RESOURCES_LAX 1
1508#define ENFORCE_RESOURCES_NO 0
1509
1510static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1511
1512static int __init acpi_enforce_resources_setup(char *str)
1513{
1514 if (str == NULL || *str == '\0')
1515 return 0;
1516
1517 if (!strcmp("strict", str))
1518 acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1519 else if (!strcmp("lax", str))
1520 acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
1521 else if (!strcmp("no", str))
1522 acpi_enforce_resources = ENFORCE_RESOURCES_NO;
1523
1524 return 1;
1525}
1526
1527__setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
1528
1529
1530
1531int acpi_check_resource_conflict(const struct resource *res)
1532{
1533 acpi_adr_space_type space_id;
1534 acpi_size length;
1535 u8 warn = 0;
1536 int clash = 0;
1537
1538 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1539 return 0;
1540 if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
1541 return 0;
1542
1543 if (res->flags & IORESOURCE_IO)
1544 space_id = ACPI_ADR_SPACE_SYSTEM_IO;
1545 else
1546 space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
1547
1548 length = resource_size(res);
1549 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO)
1550 warn = 1;
1551 clash = acpi_check_address_range(space_id, res->start, length, warn);
1552
1553 if (clash) {
1554 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1555 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
1556 printk(KERN_NOTICE "ACPI: This conflict may"
1557 " cause random problems and system"
1558 " instability\n");
1559 printk(KERN_INFO "ACPI: If an ACPI driver is available"
1560 " for this device, you should use it instead of"
1561 " the native driver\n");
1562 }
1563 if (acpi_enforce_resources == ENFORCE_RESOURCES_STRICT)
1564 return -EBUSY;
1565 }
1566 return 0;
1567}
1568EXPORT_SYMBOL(acpi_check_resource_conflict);
1569
1570int acpi_check_region(resource_size_t start, resource_size_t n,
1571 const char *name)
1572{
1573 struct resource res = {
1574 .start = start,
1575 .end = start + n - 1,
1576 .name = name,
1577 .flags = IORESOURCE_IO,
1578 };
1579
1580 return acpi_check_resource_conflict(&res);
1581}
1582EXPORT_SYMBOL(acpi_check_region);
1583
1584
1585
1586
1587int acpi_resources_are_enforced(void)
1588{
1589 return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT;
1590}
1591EXPORT_SYMBOL(acpi_resources_are_enforced);
1592
1593
1594
1595
1596void acpi_os_delete_lock(acpi_spinlock handle)
1597{
1598 ACPI_FREE(handle);
1599}
1600
1601
1602
1603
1604
1605
1606
1607acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
1608{
1609 acpi_cpu_flags flags;
1610 spin_lock_irqsave(lockp, flags);
1611 return flags;
1612}
1613
1614
1615
1616
1617
1618void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
1619{
1620 spin_unlock_irqrestore(lockp, flags);
1621}
1622
1623#ifndef ACPI_USE_LOCAL_CACHE
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640acpi_status
1641acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1642{
1643 *cache = kmem_cache_create(name, size, 0, 0, NULL);
1644 if (*cache == NULL)
1645 return AE_ERROR;
1646 else
1647 return AE_OK;
1648}
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
1663{
1664 kmem_cache_shrink(cache);
1665 return (AE_OK);
1666}
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
1682{
1683 kmem_cache_destroy(cache);
1684 return (AE_OK);
1685}
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1702{
1703 kmem_cache_free(cache, object);
1704 return (AE_OK);
1705}
1706#endif
1707
1708static int __init acpi_no_auto_ssdt_setup(char *s)
1709{
1710 printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n");
1711
1712 acpi_gbl_disable_ssdt_table_load = TRUE;
1713
1714 return 1;
1715}
1716
1717__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
1718
1719acpi_status __init acpi_os_initialize(void)
1720{
1721 acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1722 acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1723 acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
1724 acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
1725
1726 return AE_OK;
1727}
1728
1729acpi_status __init acpi_os_initialize1(void)
1730{
1731 kacpid_wq = alloc_workqueue("kacpid", 0, 1);
1732 kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
1733 kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
1734 BUG_ON(!kacpid_wq);
1735 BUG_ON(!kacpi_notify_wq);
1736 BUG_ON(!kacpi_hotplug_wq);
1737 acpi_install_interface_handler(acpi_osi_handler);
1738 acpi_osi_setup_late();
1739 return AE_OK;
1740}
1741
1742acpi_status acpi_os_terminate(void)
1743{
1744 if (acpi_irq_handler) {
1745 acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt,
1746 acpi_irq_handler);
1747 }
1748
1749 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
1750 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
1751 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1752 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1753
1754 destroy_workqueue(kacpid_wq);
1755 destroy_workqueue(kacpi_notify_wq);
1756 destroy_workqueue(kacpi_hotplug_wq);
1757
1758 return AE_OK;
1759}
1760
1761acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
1762 u32 pm1b_control)
1763{
1764 int rc = 0;
1765 if (__acpi_os_prepare_sleep)
1766 rc = __acpi_os_prepare_sleep(sleep_state,
1767 pm1a_control, pm1b_control);
1768 if (rc < 0)
1769 return AE_ERROR;
1770 else if (rc > 0)
1771 return AE_CTRL_SKIP;
1772
1773 return AE_OK;
1774}
1775
1776void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
1777 u32 pm1a_ctrl, u32 pm1b_ctrl))
1778{
1779 __acpi_os_prepare_sleep = func;
1780}
1781
1782void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context,
1783 void (*func)(struct work_struct *work))
1784{
1785 struct acpi_hp_work *hp_work;
1786 int ret;
1787
1788 hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL);
1789 if (!hp_work)
1790 return;
1791
1792 hp_work->handle = handle;
1793 hp_work->type = type;
1794 hp_work->context = context;
1795
1796 INIT_WORK(&hp_work->work, func);
1797 ret = queue_work(kacpi_hotplug_wq, &hp_work->work);
1798 if (!ret)
1799 kfree(hp_work);
1800}
1801EXPORT_SYMBOL_GPL(alloc_acpi_hp_work);
1802