Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * acpi_osl.c - OS-dependent functions ($Revision: 83 $)
4 : : *
5 : : * Copyright (C) 2000 Andrew Henroid
6 : : * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
7 : : * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
8 : : * Copyright (c) 2008 Intel Corporation
9 : : * Author: Matthew Wilcox <willy@linux.intel.com>
10 : : */
11 : :
12 : : #include <linux/module.h>
13 : : #include <linux/kernel.h>
14 : : #include <linux/slab.h>
15 : : #include <linux/mm.h>
16 : : #include <linux/highmem.h>
17 : : #include <linux/lockdep.h>
18 : : #include <linux/pci.h>
19 : : #include <linux/interrupt.h>
20 : : #include <linux/kmod.h>
21 : : #include <linux/delay.h>
22 : : #include <linux/workqueue.h>
23 : : #include <linux/nmi.h>
24 : : #include <linux/acpi.h>
25 : : #include <linux/efi.h>
26 : : #include <linux/ioport.h>
27 : : #include <linux/list.h>
28 : : #include <linux/jiffies.h>
29 : : #include <linux/semaphore.h>
30 : : #include <linux/security.h>
31 : :
32 : : #include <asm/io.h>
33 : : #include <linux/uaccess.h>
34 : : #include <linux/io-64-nonatomic-lo-hi.h>
35 : :
36 : : #include "acpica/accommon.h"
37 : : #include "acpica/acnamesp.h"
38 : : #include "internal.h"
39 : :
40 : : #define _COMPONENT ACPI_OS_SERVICES
41 : : ACPI_MODULE_NAME("osl");
42 : :
43 : : struct acpi_os_dpc {
44 : : acpi_osd_exec_callback function;
45 : : void *context;
46 : : struct work_struct work;
47 : : };
48 : :
49 : : #ifdef ENABLE_DEBUGGER
50 : : #include <linux/kdb.h>
51 : :
52 : : /* stuff for debugger support */
53 : : int acpi_in_debugger;
54 : : EXPORT_SYMBOL(acpi_in_debugger);
55 : : #endif /*ENABLE_DEBUGGER */
56 : :
57 : : static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
58 : : u32 pm1b_ctrl);
59 : : static int (*__acpi_os_prepare_extended_sleep)(u8 sleep_state, u32 val_a,
60 : : u32 val_b);
61 : :
62 : : static acpi_osd_handler acpi_irq_handler;
63 : : static void *acpi_irq_context;
64 : : static struct workqueue_struct *kacpid_wq;
65 : : static struct workqueue_struct *kacpi_notify_wq;
66 : : static struct workqueue_struct *kacpi_hotplug_wq;
67 : : static bool acpi_os_initialized;
68 : : unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
69 : : bool acpi_permanent_mmap = false;
70 : :
71 : : /*
72 : : * This list of permanent mappings is for memory that may be accessed from
73 : : * interrupt context, where we can't do the ioremap().
74 : : */
75 : : struct acpi_ioremap {
76 : : struct list_head list;
77 : : void __iomem *virt;
78 : : acpi_physical_address phys;
79 : : acpi_size size;
80 : : unsigned long refcount;
81 : : };
82 : :
83 : : static LIST_HEAD(acpi_ioremaps);
84 : : static DEFINE_MUTEX(acpi_ioremap_lock);
85 : : #define acpi_ioremap_lock_held() lock_is_held(&acpi_ioremap_lock.dep_map)
86 : :
87 : 624 : static void __init acpi_request_region (struct acpi_generic_address *gas,
88 : : unsigned int length, char *desc)
89 : : {
90 : 624 : u64 addr;
91 : :
92 : : /* Handle possible alignment issues */
93 : 624 : memcpy(&addr, &gas->address, sizeof(addr));
94 [ + + + - ]: 624 : if (!addr || !length)
95 : : return;
96 : :
97 : : /* Resources are never freed */
98 [ + - ]: 312 : if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
99 : 312 : request_region(addr, length, desc);
100 [ # # ]: 0 : else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
101 : 0 : request_mem_region(addr, length, desc);
102 : : }
103 : :
104 : 78 : static int __init acpi_reserve_resources(void)
105 : : {
106 : 78 : acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
107 : : "ACPI PM1a_EVT_BLK");
108 : :
109 : 78 : acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
110 : : "ACPI PM1b_EVT_BLK");
111 : :
112 : 78 : acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
113 : : "ACPI PM1a_CNT_BLK");
114 : :
115 : 78 : acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
116 : : "ACPI PM1b_CNT_BLK");
117 : :
118 [ + - ]: 78 : if (acpi_gbl_FADT.pm_timer_length == 4)
119 : 78 : acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
120 : :
121 : 78 : acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
122 : : "ACPI PM2_CNT_BLK");
123 : :
124 : : /* Length of GPE blocks must be a non-negative multiple of 2 */
125 : :
126 [ + - ]: 78 : if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
127 : 78 : acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
128 : : acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
129 : :
130 [ + - ]: 78 : if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
131 : 78 : acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
132 : : acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
133 : :
134 : 78 : return 0;
135 : : }
136 : : fs_initcall_sync(acpi_reserve_resources);
137 : :
138 : 1404 : void acpi_os_printf(const char *fmt, ...)
139 : : {
140 : 1404 : va_list args;
141 : 1404 : va_start(args, fmt);
142 : 1404 : acpi_os_vprintf(fmt, args);
143 : 1404 : va_end(args);
144 : 1404 : }
145 : : EXPORT_SYMBOL(acpi_os_printf);
146 : :
147 : 2106 : void acpi_os_vprintf(const char *fmt, va_list args)
148 : : {
149 : 2106 : static char buffer[512];
150 : :
151 : 2106 : vsprintf(buffer, fmt, args);
152 : :
153 : : #ifdef ENABLE_DEBUGGER
154 : : if (acpi_in_debugger) {
155 : : kdb_printf("%s", buffer);
156 : : } else {
157 : : if (printk_get_level(buffer))
158 : : printk("%s", buffer);
159 : : else
160 : : printk(KERN_CONT "%s", buffer);
161 : : }
162 : : #else
163 [ + + ]: 2106 : if (acpi_debugger_write_log(buffer) < 0) {
164 [ + + + - ]: 2808 : if (printk_get_level(buffer))
165 : 702 : printk("%s", buffer);
166 : : else
167 : 1404 : printk(KERN_CONT "%s", buffer);
168 : : }
169 : : #endif
170 : 2106 : }
171 : :
172 : : #ifdef CONFIG_KEXEC
173 : : static unsigned long acpi_rsdp;
174 : 0 : static int __init setup_acpi_rsdp(char *arg)
175 : : {
176 : 0 : return kstrtoul(arg, 16, &acpi_rsdp);
177 : : }
178 : : early_param("acpi_rsdp", setup_acpi_rsdp);
179 : : #endif
180 : :
181 : 78 : acpi_physical_address __init acpi_os_get_root_pointer(void)
182 : : {
183 : 78 : acpi_physical_address pa;
184 : :
185 : : #ifdef CONFIG_KEXEC
186 : : /*
187 : : * We may have been provided with an RSDP on the command line,
188 : : * but if a malicious user has done so they may be pointing us
189 : : * at modified ACPI tables that could alter kernel behaviour -
190 : : * so, we check the lockdown status before making use of
191 : : * it. If we trust it then also stash it in an architecture
192 : : * specific location (if appropriate) so it can be carried
193 : : * over further kexec()s.
194 : : */
195 [ - + - - ]: 78 : if (acpi_rsdp && !security_locked_down(LOCKDOWN_ACPI_TABLES)) {
196 : 0 : acpi_arch_set_root_pointer(acpi_rsdp);
197 : 0 : return acpi_rsdp;
198 : : }
199 : : #endif
200 : 78 : pa = acpi_arch_get_root_pointer();
201 [ - + ]: 78 : if (pa)
202 : : return pa;
203 : :
204 [ # # ]: 0 : if (efi_enabled(EFI_CONFIG_TABLES)) {
205 [ # # ]: 0 : if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
206 : : return efi.acpi20;
207 [ # # ]: 0 : if (efi.acpi != EFI_INVALID_TABLE_ADDR)
208 : : return efi.acpi;
209 : 0 : pr_err(PREFIX "System description tables not found\n");
210 : 0 : } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
211 : 0 : acpi_find_root_pointer(&pa);
212 : : }
213 : :
214 : 0 : return pa;
215 : : }
216 : :
217 : : /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
218 : : static struct acpi_ioremap *
219 : 1248 : acpi_map_lookup(acpi_physical_address phys, acpi_size size)
220 : : {
221 : 1248 : struct acpi_ioremap *map;
222 : :
223 [ - - - - : 1950 : list_for_each_entry_rcu(map, &acpi_ioremaps, list, acpi_ioremap_lock_held())
- - - - +
+ ]
224 [ - - - - : 1716 : if (map->phys <= phys &&
- - - - +
+ ]
225 [ - - - - : 1170 : phys + size <= map->phys + map->size)
- - - - +
+ ]
226 : : return map;
227 : :
228 : : return NULL;
229 : : }
230 : :
231 : : /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
232 : : static void __iomem *
233 : 0 : acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
234 : : {
235 : 0 : struct acpi_ioremap *map;
236 : :
237 : 0 : map = acpi_map_lookup(phys, size);
238 [ # # # # ]: 0 : if (map)
239 : 0 : return map->virt + (phys - map->phys);
240 : :
241 : : return NULL;
242 : : }
243 : :
244 : 0 : void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
245 : : {
246 : 0 : struct acpi_ioremap *map;
247 : 0 : void __iomem *virt = NULL;
248 : :
249 : 0 : mutex_lock(&acpi_ioremap_lock);
250 : 0 : map = acpi_map_lookup(phys, size);
251 [ # # ]: 0 : if (map) {
252 : 0 : virt = map->virt + (phys - map->phys);
253 : 0 : map->refcount++;
254 : : }
255 : 0 : mutex_unlock(&acpi_ioremap_lock);
256 : 0 : return virt;
257 : : }
258 : : EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
259 : :
260 : : /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
261 : : static struct acpi_ioremap *
262 : 780 : acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
263 : : {
264 : 780 : struct acpi_ioremap *map;
265 : :
266 [ + - ]: 1170 : list_for_each_entry_rcu(map, &acpi_ioremaps, list, acpi_ioremap_lock_held())
267 [ + - ]: 1170 : if (map->virt <= virt &&
268 [ + + ]: 1170 : virt + size <= map->virt + map->size)
269 : : return map;
270 : :
271 : : return NULL;
272 : : }
273 : :
274 : : #if defined(CONFIG_IA64) || defined(CONFIG_ARM64)
275 : : /* ioremap will take care of cache attributes */
276 : : #define should_use_kmap(pfn) 0
277 : : #else
278 : : #define should_use_kmap(pfn) page_is_ram(pfn)
279 : : #endif
280 : :
281 : 234 : static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
282 : : {
283 : 234 : unsigned long pfn;
284 : :
285 : 234 : pfn = pg_off >> PAGE_SHIFT;
286 [ - + ]: 234 : if (should_use_kmap(pfn)) {
287 [ # # ]: 0 : if (pg_sz > PAGE_SIZE)
288 : : return NULL;
289 : 0 : return (void __iomem __force *)kmap(pfn_to_page(pfn));
290 : : } else
291 : 234 : return acpi_os_ioremap(pg_off, pg_sz);
292 : : }
293 : :
294 : 0 : static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
295 : : {
296 : 0 : unsigned long pfn;
297 : :
298 : 0 : pfn = pg_off >> PAGE_SHIFT;
299 [ # # ]: 0 : if (should_use_kmap(pfn))
300 : : kunmap(pfn_to_page(pfn));
301 : : else
302 : 0 : iounmap(vaddr);
303 : 0 : }
304 : :
305 : : /**
306 : : * acpi_os_map_iomem - Get a virtual address for a given physical address range.
307 : : * @phys: Start of the physical address range to map.
308 : : * @size: Size of the physical address range to map.
309 : : *
310 : : * Look up the given physical address range in the list of existing ACPI memory
311 : : * mappings. If found, get a reference to it and return a pointer to it (its
312 : : * virtual address). If not found, map it, add it to that list and return a
313 : : * pointer to it.
314 : : *
315 : : * During early init (when acpi_permanent_mmap has not been set yet) this
316 : : * routine simply calls __acpi_map_table() to get the job done.
317 : : */
318 : : void __iomem __ref
319 : 3588 : *acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
320 : : {
321 : 3588 : struct acpi_ioremap *map;
322 : 3588 : void __iomem *virt;
323 : 3588 : acpi_physical_address pg_off;
324 : 3588 : acpi_size pg_sz;
325 : :
326 : 3588 : if (phys > ULONG_MAX) {
327 : : printk(KERN_ERR PREFIX "Cannot map memory that high\n");
328 : : return NULL;
329 : : }
330 : :
331 [ + + ]: 3588 : if (!acpi_permanent_mmap)
332 : 2340 : return __acpi_map_table((unsigned long)phys, size);
333 : :
334 : 1248 : mutex_lock(&acpi_ioremap_lock);
335 : : /* Check if there's a suitable mapping already. */
336 : 1248 : map = acpi_map_lookup(phys, size);
337 [ + + ]: 1248 : if (map) {
338 : 1014 : map->refcount++;
339 : 1014 : goto out;
340 : : }
341 : :
342 : 234 : map = kzalloc(sizeof(*map), GFP_KERNEL);
343 [ - + ]: 234 : if (!map) {
344 : 0 : mutex_unlock(&acpi_ioremap_lock);
345 : 0 : return NULL;
346 : : }
347 : :
348 : 234 : pg_off = round_down(phys, PAGE_SIZE);
349 : 234 : pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
350 : 234 : virt = acpi_map(pg_off, pg_sz);
351 [ - + ]: 234 : if (!virt) {
352 : 0 : mutex_unlock(&acpi_ioremap_lock);
353 : 0 : kfree(map);
354 : 0 : return NULL;
355 : : }
356 : :
357 : 234 : INIT_LIST_HEAD(&map->list);
358 : 234 : map->virt = virt;
359 : 234 : map->phys = pg_off;
360 : 234 : map->size = pg_sz;
361 : 234 : map->refcount = 1;
362 : :
363 : 234 : list_add_tail_rcu(&map->list, &acpi_ioremaps);
364 : :
365 : 1248 : out:
366 : 1248 : mutex_unlock(&acpi_ioremap_lock);
367 : 1248 : return map->virt + (phys - map->phys);
368 : : }
369 : : EXPORT_SYMBOL_GPL(acpi_os_map_iomem);
370 : :
371 : 3588 : void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
372 : : {
373 : 3588 : return (void *)acpi_os_map_iomem(phys, size);
374 : : }
375 : : EXPORT_SYMBOL_GPL(acpi_os_map_memory);
376 : :
377 : : /* Must be called with mutex_lock(&acpi_ioremap_lock) */
378 : 780 : static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map)
379 : : {
380 : 780 : unsigned long refcount = --map->refcount;
381 : :
382 : 780 : if (!refcount)
383 : 0 : list_del_rcu(&map->list);
384 : 780 : return refcount;
385 : : }
386 : :
387 : 0 : static void acpi_os_map_cleanup(struct acpi_ioremap *map)
388 : : {
389 : 0 : synchronize_rcu_expedited();
390 : 0 : acpi_unmap(map->phys, map->virt);
391 : 0 : kfree(map);
392 : 0 : }
393 : :
394 : : /**
395 : : * acpi_os_unmap_iomem - Drop a memory mapping reference.
396 : : * @virt: Start of the address range to drop a reference to.
397 : : * @size: Size of the address range to drop a reference to.
398 : : *
399 : : * Look up the given virtual address range in the list of existing ACPI memory
400 : : * mappings, drop a reference to it and unmap it if there are no more active
401 : : * references to it.
402 : : *
403 : : * During early init (when acpi_permanent_mmap has not been set yet) this
404 : : * routine simply calls __acpi_unmap_table() to get the job done. Since
405 : : * __acpi_unmap_table() is an __init function, the __ref annotation is needed
406 : : * here.
407 : : */
408 : 3120 : void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
409 : : {
410 : 3120 : struct acpi_ioremap *map;
411 : 3120 : unsigned long refcount;
412 : :
413 [ + + ]: 3120 : if (!acpi_permanent_mmap) {
414 : 2340 : __acpi_unmap_table(virt, size);
415 : 2340 : return;
416 : : }
417 : :
418 : 780 : mutex_lock(&acpi_ioremap_lock);
419 : 780 : map = acpi_map_lookup_virt(virt, size);
420 [ - + ]: 780 : if (!map) {
421 : 0 : mutex_unlock(&acpi_ioremap_lock);
422 : 0 : WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
423 : 0 : return;
424 : : }
425 [ - + ]: 780 : refcount = acpi_os_drop_map_ref(map);
426 : 780 : mutex_unlock(&acpi_ioremap_lock);
427 : :
428 [ - + ]: 780 : if (!refcount)
429 : 0 : acpi_os_map_cleanup(map);
430 : : }
431 : : EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
432 : :
433 : 3120 : void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
434 : : {
435 : 3120 : return acpi_os_unmap_iomem((void __iomem *)virt, size);
436 : : }
437 : : EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
438 : :
439 : 312 : int acpi_os_map_generic_address(struct acpi_generic_address *gas)
440 : : {
441 : 312 : u64 addr;
442 : 312 : void __iomem *virt;
443 : :
444 [ + + ]: 312 : if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
445 : : return 0;
446 : :
447 : : /* Handle possible alignment issues */
448 : 156 : memcpy(&addr, &gas->address, sizeof(addr));
449 [ - + - - ]: 156 : if (!addr || !gas->bit_width)
450 : : return -EINVAL;
451 : :
452 : 0 : virt = acpi_os_map_iomem(addr, gas->bit_width / 8);
453 [ # # ]: 0 : if (!virt)
454 : 0 : return -EIO;
455 : :
456 : : return 0;
457 : : }
458 : : EXPORT_SYMBOL(acpi_os_map_generic_address);
459 : :
460 : 0 : void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
461 : : {
462 : 0 : u64 addr;
463 : 0 : struct acpi_ioremap *map;
464 : 0 : unsigned long refcount;
465 : :
466 [ # # ]: 0 : if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
467 : : return;
468 : :
469 : : /* Handle possible alignment issues */
470 : 0 : memcpy(&addr, &gas->address, sizeof(addr));
471 [ # # # # ]: 0 : if (!addr || !gas->bit_width)
472 : : return;
473 : :
474 : 0 : mutex_lock(&acpi_ioremap_lock);
475 : 0 : map = acpi_map_lookup(addr, gas->bit_width / 8);
476 [ # # ]: 0 : if (!map) {
477 : 0 : mutex_unlock(&acpi_ioremap_lock);
478 : 0 : return;
479 : : }
480 [ # # ]: 0 : refcount = acpi_os_drop_map_ref(map);
481 : 0 : mutex_unlock(&acpi_ioremap_lock);
482 : :
483 [ # # ]: 0 : if (!refcount)
484 : 0 : acpi_os_map_cleanup(map);
485 : : }
486 : : EXPORT_SYMBOL(acpi_os_unmap_generic_address);
487 : :
488 : : #ifdef ACPI_FUTURE_USAGE
489 : : acpi_status
490 : : acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
491 : : {
492 : : if (!phys || !virt)
493 : : return AE_BAD_PARAMETER;
494 : :
495 : : *phys = virt_to_phys(virt);
496 : :
497 : : return AE_OK;
498 : : }
499 : : #endif
500 : :
501 : : #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
502 : : static bool acpi_rev_override;
503 : :
504 : 0 : int __init acpi_rev_override_setup(char *str)
505 : : {
506 : 0 : acpi_rev_override = true;
507 : 0 : return 1;
508 : : }
509 : : __setup("acpi_rev_override", acpi_rev_override_setup);
510 : : #else
511 : : #define acpi_rev_override false
512 : : #endif
513 : :
514 : : #define ACPI_MAX_OVERRIDE_LEN 100
515 : :
516 : : static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
517 : :
518 : : acpi_status
519 : 312 : acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
520 : : acpi_string *new_val)
521 : : {
522 [ + - ]: 312 : if (!init_val || !new_val)
523 : : return AE_BAD_PARAMETER;
524 : :
525 : 312 : *new_val = NULL;
526 [ + + - + ]: 312 : if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
527 : 0 : printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
528 : : acpi_os_name);
529 : 0 : *new_val = acpi_os_name;
530 : : }
531 : :
532 [ + + - + ]: 312 : if (!memcmp(init_val->name, "_REV", 4) && acpi_rev_override) {
533 : 0 : printk(KERN_INFO PREFIX "Overriding _REV return value to 5\n");
534 : 0 : *new_val = (char *)5;
535 : : }
536 : :
537 : : return AE_OK;
538 : : }
539 : :
540 : 0 : static irqreturn_t acpi_irq(int irq, void *dev_id)
541 : : {
542 : 0 : u32 handled;
543 : :
544 : 0 : handled = (*acpi_irq_handler) (acpi_irq_context);
545 : :
546 [ # # ]: 0 : if (handled) {
547 : 0 : acpi_irq_handled++;
548 : 0 : return IRQ_HANDLED;
549 : : } else {
550 : 0 : acpi_irq_not_handled++;
551 : 0 : return IRQ_NONE;
552 : : }
553 : : }
554 : :
555 : : acpi_status
556 : 78 : acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
557 : : void *context)
558 : : {
559 : 78 : unsigned int irq;
560 : :
561 : 78 : acpi_irq_stats_init();
562 : :
563 : : /*
564 : : * ACPI interrupts different from the SCI in our copy of the FADT are
565 : : * not supported.
566 : : */
567 [ + - ]: 78 : if (gsi != acpi_gbl_FADT.sci_interrupt)
568 : : return AE_BAD_PARAMETER;
569 : :
570 [ + - ]: 78 : if (acpi_irq_handler)
571 : : return AE_ALREADY_ACQUIRED;
572 : :
573 [ - + ]: 78 : if (acpi_gsi_to_irq(gsi, &irq) < 0) {
574 : 0 : printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
575 : : gsi);
576 : 0 : return AE_OK;
577 : : }
578 : :
579 : 78 : acpi_irq_handler = handler;
580 : 78 : acpi_irq_context = context;
581 [ - + ]: 78 : if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
582 : 0 : printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
583 : 0 : acpi_irq_handler = NULL;
584 : 0 : return AE_NOT_ACQUIRED;
585 : : }
586 : 78 : acpi_sci_irq = irq;
587 : :
588 : 78 : return AE_OK;
589 : : }
590 : :
591 : 0 : acpi_status acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler handler)
592 : : {
593 [ # # # # ]: 0 : if (gsi != acpi_gbl_FADT.sci_interrupt || !acpi_sci_irq_valid())
594 : : return AE_BAD_PARAMETER;
595 : :
596 : 0 : free_irq(acpi_sci_irq, acpi_irq);
597 : 0 : acpi_irq_handler = NULL;
598 : 0 : acpi_sci_irq = INVALID_ACPI_IRQ;
599 : :
600 : 0 : return AE_OK;
601 : : }
602 : :
603 : : /*
604 : : * Running in interpreter thread context, safe to sleep
605 : : */
606 : :
607 : 0 : void acpi_os_sleep(u64 ms)
608 : : {
609 : 0 : msleep(ms);
610 : 0 : }
611 : :
612 : 0 : void acpi_os_stall(u32 us)
613 : : {
614 [ # # ]: 0 : while (us) {
615 : 0 : u32 delay = 1000;
616 : :
617 [ # # ]: 0 : if (delay > us)
618 : 0 : delay = us;
619 [ # # # # ]: 0 : udelay(delay);
620 : 0 : touch_nmi_watchdog();
621 : 0 : us -= delay;
622 : : }
623 : 0 : }
624 : :
625 : : /*
626 : : * Support ACPI 3.0 AML Timer operand. Returns a 64-bit free-running,
627 : : * monotonically increasing timer with 100ns granularity. Do not use
628 : : * ktime_get() to implement this function because this function may get
629 : : * called after timekeeping has been suspended. Note: calling this function
630 : : * after timekeeping has been suspended may lead to unexpected results
631 : : * because when timekeeping is suspended the jiffies counter is not
632 : : * incremented. See also timekeeping_suspend().
633 : : */
634 : 86523 : u64 acpi_os_get_timer(void)
635 : : {
636 : 86523 : return (get_jiffies_64() - INITIAL_JIFFIES) *
637 : : (ACPI_100NSEC_PER_SEC / HZ);
638 : : }
639 : :
640 : 2964 : acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
641 : : {
642 : 2964 : u32 dummy;
643 : :
644 [ - + ]: 2964 : if (!value)
645 : 0 : value = &dummy;
646 : :
647 : 2964 : *value = 0;
648 [ + + ]: 2964 : if (width <= 8) {
649 : 1716 : *(u8 *) value = inb(port);
650 [ + - ]: 1248 : } else if (width <= 16) {
651 : 1248 : *(u16 *) value = inw(port);
652 [ # # ]: 0 : } else if (width <= 32) {
653 : 0 : *(u32 *) value = inl(port);
654 : : } else {
655 : 0 : BUG();
656 : : }
657 : :
658 : 2964 : return AE_OK;
659 : : }
660 : :
661 : : EXPORT_SYMBOL(acpi_os_read_port);
662 : :
663 : 1950 : acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
664 : : {
665 [ + + ]: 1950 : if (width <= 8) {
666 : 702 : outb(value, port);
667 [ + + ]: 1248 : } else if (width <= 16) {
668 : 1014 : outw(value, port);
669 [ + - ]: 234 : } else if (width <= 32) {
670 : 234 : outl(value, port);
671 : : } else {
672 : 0 : BUG();
673 : : }
674 : :
675 : 1950 : return AE_OK;
676 : : }
677 : :
678 : : EXPORT_SYMBOL(acpi_os_write_port);
679 : :
680 : 0 : int acpi_os_read_iomem(void __iomem *virt_addr, u64 *value, u32 width)
681 : : {
682 : :
683 [ # # # # : 0 : switch (width) {
# ]
684 : : case 8:
685 : 0 : *(u8 *) value = readb(virt_addr);
686 : 0 : break;
687 : : case 16:
688 : 0 : *(u16 *) value = readw(virt_addr);
689 : 0 : break;
690 : : case 32:
691 : 0 : *(u32 *) value = readl(virt_addr);
692 : 0 : break;
693 : : case 64:
694 : 0 : *(u64 *) value = readq(virt_addr);
695 : 0 : break;
696 : : default:
697 : : return -EINVAL;
698 : : }
699 : :
700 : : return 0;
701 : : }
702 : :
703 : : acpi_status
704 : 0 : acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
705 : : {
706 : 0 : void __iomem *virt_addr;
707 : 0 : unsigned int size = width / 8;
708 : 0 : bool unmap = false;
709 : 0 : u64 dummy;
710 : 0 : int error;
711 : :
712 : 0 : rcu_read_lock();
713 : 0 : virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
714 [ # # ]: 0 : if (!virt_addr) {
715 : 0 : rcu_read_unlock();
716 : 0 : virt_addr = acpi_os_ioremap(phys_addr, size);
717 [ # # ]: 0 : if (!virt_addr)
718 : : return AE_BAD_ADDRESS;
719 : : unmap = true;
720 : : }
721 : :
722 [ # # ]: 0 : if (!value)
723 : 0 : value = &dummy;
724 : :
725 [ # # # # : 0 : error = acpi_os_read_iomem(virt_addr, value, width);
# ]
726 [ # # ]: 0 : BUG_ON(error);
727 : :
728 [ # # ]: 0 : if (unmap)
729 : 0 : iounmap(virt_addr);
730 : : else
731 : 0 : rcu_read_unlock();
732 : :
733 : : return AE_OK;
734 : : }
735 : :
736 : : acpi_status
737 : 0 : acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
738 : : {
739 : 0 : void __iomem *virt_addr;
740 : 0 : unsigned int size = width / 8;
741 : 0 : bool unmap = false;
742 : :
743 : 0 : rcu_read_lock();
744 : 0 : virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
745 [ # # ]: 0 : if (!virt_addr) {
746 : 0 : rcu_read_unlock();
747 : 0 : virt_addr = acpi_os_ioremap(phys_addr, size);
748 [ # # ]: 0 : if (!virt_addr)
749 : : return AE_BAD_ADDRESS;
750 : : unmap = true;
751 : : }
752 : :
753 [ # # # # : 0 : switch (width) {
# ]
754 : 0 : case 8:
755 : 0 : writeb(value, virt_addr);
756 : : break;
757 : 0 : case 16:
758 : 0 : writew(value, virt_addr);
759 : : break;
760 : 0 : case 32:
761 : 0 : writel(value, virt_addr);
762 : : break;
763 : : case 64:
764 : 0 : writeq(value, virt_addr);
765 : : break;
766 : 0 : default:
767 : 0 : BUG();
768 : : }
769 : :
770 [ # # ]: 0 : if (unmap)
771 : 0 : iounmap(virt_addr);
772 : : else
773 : 0 : rcu_read_unlock();
774 : :
775 : : return AE_OK;
776 : : }
777 : :
778 : : #ifdef CONFIG_PCI
779 : : acpi_status
780 : 3432 : acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
781 : : u64 *value, u32 width)
782 : : {
783 : 3432 : int result, size;
784 : 3432 : u32 value32;
785 : :
786 [ + - ]: 3432 : if (!value)
787 : : return AE_BAD_PARAMETER;
788 : :
789 [ - - + - ]: 3432 : switch (width) {
790 : : case 8:
791 : : size = 1;
792 : : break;
793 : 0 : case 16:
794 : 0 : size = 2;
795 : 0 : break;
796 : 0 : case 32:
797 : 0 : size = 4;
798 : 0 : break;
799 : : default:
800 : : return AE_ERROR;
801 : : }
802 : :
803 : 3432 : result = raw_pci_read(pci_id->segment, pci_id->bus,
804 : 3432 : PCI_DEVFN(pci_id->device, pci_id->function),
805 : : reg, size, &value32);
806 : 3432 : *value = value32;
807 : :
808 [ + - ]: 3432 : return (result ? AE_ERROR : AE_OK);
809 : : }
810 : :
811 : : acpi_status
812 : 390 : acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
813 : : u64 value, u32 width)
814 : : {
815 : 390 : int result, size;
816 : :
817 [ - - + - ]: 390 : switch (width) {
818 : : case 8:
819 : : size = 1;
820 : : break;
821 : 0 : case 16:
822 : 0 : size = 2;
823 : 0 : break;
824 : 0 : case 32:
825 : 0 : size = 4;
826 : 0 : break;
827 : : default:
828 : : return AE_ERROR;
829 : : }
830 : :
831 : 390 : result = raw_pci_write(pci_id->segment, pci_id->bus,
832 : 390 : PCI_DEVFN(pci_id->device, pci_id->function),
833 : : reg, size, value);
834 : :
835 [ + - ]: 390 : return (result ? AE_ERROR : AE_OK);
836 : : }
837 : : #endif
838 : :
839 : 0 : static void acpi_os_execute_deferred(struct work_struct *work)
840 : : {
841 : 0 : struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
842 : :
843 : 0 : dpc->function(dpc->context);
844 : 0 : kfree(dpc);
845 : 0 : }
846 : :
847 : : #ifdef CONFIG_ACPI_DEBUGGER
848 : : static struct acpi_debugger acpi_debugger;
849 : : static bool acpi_debugger_initialized;
850 : :
851 : : int acpi_register_debugger(struct module *owner,
852 : : const struct acpi_debugger_ops *ops)
853 : : {
854 : : int ret = 0;
855 : :
856 : : mutex_lock(&acpi_debugger.lock);
857 : : if (acpi_debugger.ops) {
858 : : ret = -EBUSY;
859 : : goto err_lock;
860 : : }
861 : :
862 : : acpi_debugger.owner = owner;
863 : : acpi_debugger.ops = ops;
864 : :
865 : : err_lock:
866 : : mutex_unlock(&acpi_debugger.lock);
867 : : return ret;
868 : : }
869 : : EXPORT_SYMBOL(acpi_register_debugger);
870 : :
871 : : void acpi_unregister_debugger(const struct acpi_debugger_ops *ops)
872 : : {
873 : : mutex_lock(&acpi_debugger.lock);
874 : : if (ops == acpi_debugger.ops) {
875 : : acpi_debugger.ops = NULL;
876 : : acpi_debugger.owner = NULL;
877 : : }
878 : : mutex_unlock(&acpi_debugger.lock);
879 : : }
880 : : EXPORT_SYMBOL(acpi_unregister_debugger);
881 : :
882 : : int acpi_debugger_create_thread(acpi_osd_exec_callback function, void *context)
883 : : {
884 : : int ret;
885 : : int (*func)(acpi_osd_exec_callback, void *);
886 : : struct module *owner;
887 : :
888 : : if (!acpi_debugger_initialized)
889 : : return -ENODEV;
890 : : mutex_lock(&acpi_debugger.lock);
891 : : if (!acpi_debugger.ops) {
892 : : ret = -ENODEV;
893 : : goto err_lock;
894 : : }
895 : : if (!try_module_get(acpi_debugger.owner)) {
896 : : ret = -ENODEV;
897 : : goto err_lock;
898 : : }
899 : : func = acpi_debugger.ops->create_thread;
900 : : owner = acpi_debugger.owner;
901 : : mutex_unlock(&acpi_debugger.lock);
902 : :
903 : : ret = func(function, context);
904 : :
905 : : mutex_lock(&acpi_debugger.lock);
906 : : module_put(owner);
907 : : err_lock:
908 : : mutex_unlock(&acpi_debugger.lock);
909 : : return ret;
910 : : }
911 : :
912 : : ssize_t acpi_debugger_write_log(const char *msg)
913 : : {
914 : : ssize_t ret;
915 : : ssize_t (*func)(const char *);
916 : : struct module *owner;
917 : :
918 : : if (!acpi_debugger_initialized)
919 : : return -ENODEV;
920 : : mutex_lock(&acpi_debugger.lock);
921 : : if (!acpi_debugger.ops) {
922 : : ret = -ENODEV;
923 : : goto err_lock;
924 : : }
925 : : if (!try_module_get(acpi_debugger.owner)) {
926 : : ret = -ENODEV;
927 : : goto err_lock;
928 : : }
929 : : func = acpi_debugger.ops->write_log;
930 : : owner = acpi_debugger.owner;
931 : : mutex_unlock(&acpi_debugger.lock);
932 : :
933 : : ret = func(msg);
934 : :
935 : : mutex_lock(&acpi_debugger.lock);
936 : : module_put(owner);
937 : : err_lock:
938 : : mutex_unlock(&acpi_debugger.lock);
939 : : return ret;
940 : : }
941 : :
942 : : ssize_t acpi_debugger_read_cmd(char *buffer, size_t buffer_length)
943 : : {
944 : : ssize_t ret;
945 : : ssize_t (*func)(char *, size_t);
946 : : struct module *owner;
947 : :
948 : : if (!acpi_debugger_initialized)
949 : : return -ENODEV;
950 : : mutex_lock(&acpi_debugger.lock);
951 : : if (!acpi_debugger.ops) {
952 : : ret = -ENODEV;
953 : : goto err_lock;
954 : : }
955 : : if (!try_module_get(acpi_debugger.owner)) {
956 : : ret = -ENODEV;
957 : : goto err_lock;
958 : : }
959 : : func = acpi_debugger.ops->read_cmd;
960 : : owner = acpi_debugger.owner;
961 : : mutex_unlock(&acpi_debugger.lock);
962 : :
963 : : ret = func(buffer, buffer_length);
964 : :
965 : : mutex_lock(&acpi_debugger.lock);
966 : : module_put(owner);
967 : : err_lock:
968 : : mutex_unlock(&acpi_debugger.lock);
969 : : return ret;
970 : : }
971 : :
972 : : int acpi_debugger_wait_command_ready(void)
973 : : {
974 : : int ret;
975 : : int (*func)(bool, char *, size_t);
976 : : struct module *owner;
977 : :
978 : : if (!acpi_debugger_initialized)
979 : : return -ENODEV;
980 : : mutex_lock(&acpi_debugger.lock);
981 : : if (!acpi_debugger.ops) {
982 : : ret = -ENODEV;
983 : : goto err_lock;
984 : : }
985 : : if (!try_module_get(acpi_debugger.owner)) {
986 : : ret = -ENODEV;
987 : : goto err_lock;
988 : : }
989 : : func = acpi_debugger.ops->wait_command_ready;
990 : : owner = acpi_debugger.owner;
991 : : mutex_unlock(&acpi_debugger.lock);
992 : :
993 : : ret = func(acpi_gbl_method_executing,
994 : : acpi_gbl_db_line_buf, ACPI_DB_LINE_BUFFER_SIZE);
995 : :
996 : : mutex_lock(&acpi_debugger.lock);
997 : : module_put(owner);
998 : : err_lock:
999 : : mutex_unlock(&acpi_debugger.lock);
1000 : : return ret;
1001 : : }
1002 : :
1003 : : int acpi_debugger_notify_command_complete(void)
1004 : : {
1005 : : int ret;
1006 : : int (*func)(void);
1007 : : struct module *owner;
1008 : :
1009 : : if (!acpi_debugger_initialized)
1010 : : return -ENODEV;
1011 : : mutex_lock(&acpi_debugger.lock);
1012 : : if (!acpi_debugger.ops) {
1013 : : ret = -ENODEV;
1014 : : goto err_lock;
1015 : : }
1016 : : if (!try_module_get(acpi_debugger.owner)) {
1017 : : ret = -ENODEV;
1018 : : goto err_lock;
1019 : : }
1020 : : func = acpi_debugger.ops->notify_command_complete;
1021 : : owner = acpi_debugger.owner;
1022 : : mutex_unlock(&acpi_debugger.lock);
1023 : :
1024 : : ret = func();
1025 : :
1026 : : mutex_lock(&acpi_debugger.lock);
1027 : : module_put(owner);
1028 : : err_lock:
1029 : : mutex_unlock(&acpi_debugger.lock);
1030 : : return ret;
1031 : : }
1032 : :
1033 : : int __init acpi_debugger_init(void)
1034 : : {
1035 : : mutex_init(&acpi_debugger.lock);
1036 : : acpi_debugger_initialized = true;
1037 : : return 0;
1038 : : }
1039 : : #endif
1040 : :
1041 : : /*******************************************************************************
1042 : : *
1043 : : * FUNCTION: acpi_os_execute
1044 : : *
1045 : : * PARAMETERS: Type - Type of the callback
1046 : : * Function - Function to be executed
1047 : : * Context - Function parameters
1048 : : *
1049 : : * RETURN: Status
1050 : : *
1051 : : * DESCRIPTION: Depending on type, either queues function for deferred execution or
1052 : : * immediately executes function on a separate thread.
1053 : : *
1054 : : ******************************************************************************/
1055 : :
1056 : 0 : acpi_status acpi_os_execute(acpi_execute_type type,
1057 : : acpi_osd_exec_callback function, void *context)
1058 : : {
1059 : 0 : acpi_status status = AE_OK;
1060 : 0 : struct acpi_os_dpc *dpc;
1061 : 0 : struct workqueue_struct *queue;
1062 : 0 : int ret;
1063 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
1064 : : "Scheduling function [%p(%p)] for deferred execution.\n",
1065 : 0 : function, context));
1066 : :
1067 [ # # ]: 0 : if (type == OSL_DEBUGGER_MAIN_THREAD) {
1068 : 0 : ret = acpi_debugger_create_thread(function, context);
1069 : 0 : if (ret) {
1070 : 0 : pr_err("Call to kthread_create() failed.\n");
1071 : 0 : status = AE_ERROR;
1072 : : }
1073 : 0 : goto out_thread;
1074 : : }
1075 : :
1076 : : /*
1077 : : * Allocate/initialize DPC structure. Note that this memory will be
1078 : : * freed by the callee. The kernel handles the work_struct list in a
1079 : : * way that allows us to also free its memory inside the callee.
1080 : : * Because we may want to schedule several tasks with different
1081 : : * parameters we can't use the approach some kernel code uses of
1082 : : * having a static work_struct.
1083 : : */
1084 : :
1085 : 0 : dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
1086 [ # # ]: 0 : if (!dpc)
1087 : : return AE_NO_MEMORY;
1088 : :
1089 : 0 : dpc->function = function;
1090 : 0 : dpc->context = context;
1091 : :
1092 : : /*
1093 : : * To prevent lockdep from complaining unnecessarily, make sure that
1094 : : * there is a different static lockdep key for each workqueue by using
1095 : : * INIT_WORK() for each of them separately.
1096 : : */
1097 [ # # ]: 0 : if (type == OSL_NOTIFY_HANDLER) {
1098 : 0 : queue = kacpi_notify_wq;
1099 : 0 : INIT_WORK(&dpc->work, acpi_os_execute_deferred);
1100 [ # # ]: 0 : } else if (type == OSL_GPE_HANDLER) {
1101 : 0 : queue = kacpid_wq;
1102 : 0 : INIT_WORK(&dpc->work, acpi_os_execute_deferred);
1103 : : } else {
1104 : 0 : pr_err("Unsupported os_execute type %d.\n", type);
1105 : 0 : status = AE_ERROR;
1106 : : }
1107 : :
1108 : 0 : if (ACPI_FAILURE(status))
1109 : 0 : goto err_workqueue;
1110 : :
1111 : : /*
1112 : : * On some machines, a software-initiated SMI causes corruption unless
1113 : : * the SMI runs on CPU 0. An SMI can be initiated by any AML, but
1114 : : * typically it's done in GPE-related methods that are run via
1115 : : * workqueues, so we can avoid the known corruption cases by always
1116 : : * queueing on CPU 0.
1117 : : */
1118 : 0 : ret = queue_work_on(0, queue, &dpc->work);
1119 [ # # ]: 0 : if (!ret) {
1120 : 0 : printk(KERN_ERR PREFIX
1121 : : "Call to queue_work() failed.\n");
1122 : 0 : status = AE_ERROR;
1123 : : }
1124 : 0 : err_workqueue:
1125 [ # # ]: 0 : if (ACPI_FAILURE(status))
1126 : 0 : kfree(dpc);
1127 : 0 : out_thread:
1128 : : return status;
1129 : : }
1130 : : EXPORT_SYMBOL(acpi_os_execute);
1131 : :
1132 : 0 : void acpi_os_wait_events_complete(void)
1133 : : {
1134 : : /*
1135 : : * Make sure the GPE handler or the fixed event handler is not used
1136 : : * on another CPU after removal.
1137 : : */
1138 [ # # ]: 0 : if (acpi_sci_irq_valid())
1139 : 0 : synchronize_hardirq(acpi_sci_irq);
1140 : 0 : flush_workqueue(kacpid_wq);
1141 : 0 : flush_workqueue(kacpi_notify_wq);
1142 : 0 : }
1143 : : EXPORT_SYMBOL(acpi_os_wait_events_complete);
1144 : :
1145 : : struct acpi_hp_work {
1146 : : struct work_struct work;
1147 : : struct acpi_device *adev;
1148 : : u32 src;
1149 : : };
1150 : :
1151 : 0 : static void acpi_hotplug_work_fn(struct work_struct *work)
1152 : : {
1153 : 0 : struct acpi_hp_work *hpw = container_of(work, struct acpi_hp_work, work);
1154 : :
1155 : 0 : acpi_os_wait_events_complete();
1156 : 0 : acpi_device_hotplug(hpw->adev, hpw->src);
1157 : 0 : kfree(hpw);
1158 : 0 : }
1159 : :
1160 : 0 : acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src)
1161 : : {
1162 : 0 : struct acpi_hp_work *hpw;
1163 : :
1164 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
1165 : : "Scheduling hotplug event (%p, %u) for deferred execution.\n",
1166 : 0 : adev, src));
1167 : :
1168 : 0 : hpw = kmalloc(sizeof(*hpw), GFP_KERNEL);
1169 [ # # ]: 0 : if (!hpw)
1170 : : return AE_NO_MEMORY;
1171 : :
1172 : 0 : INIT_WORK(&hpw->work, acpi_hotplug_work_fn);
1173 : 0 : hpw->adev = adev;
1174 : 0 : hpw->src = src;
1175 : : /*
1176 : : * We can't run hotplug code in kacpid_wq/kacpid_notify_wq etc., because
1177 : : * the hotplug code may call driver .remove() functions, which may
1178 : : * invoke flush_scheduled_work()/acpi_os_wait_events_complete() to flush
1179 : : * these workqueues.
1180 : : */
1181 [ # # ]: 0 : if (!queue_work(kacpi_hotplug_wq, &hpw->work)) {
1182 : 0 : kfree(hpw);
1183 : 0 : return AE_ERROR;
1184 : : }
1185 : : return AE_OK;
1186 : : }
1187 : :
1188 : 0 : bool acpi_queue_hotplug_work(struct work_struct *work)
1189 : : {
1190 : 0 : return queue_work(kacpi_hotplug_wq, work);
1191 : : }
1192 : :
1193 : : acpi_status
1194 : 1404 : acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
1195 : : {
1196 : 1404 : struct semaphore *sem = NULL;
1197 : :
1198 : 1404 : sem = acpi_os_allocate_zeroed(sizeof(struct semaphore));
1199 [ + - ]: 1404 : if (!sem)
1200 : : return AE_NO_MEMORY;
1201 : :
1202 : 1404 : sema_init(sem, initial_units);
1203 : :
1204 : 1404 : *handle = (acpi_handle *) sem;
1205 : :
1206 : : ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n",
1207 : 1404 : *handle, initial_units));
1208 : :
1209 : 1404 : return AE_OK;
1210 : : }
1211 : :
1212 : : /*
1213 : : * TODO: A better way to delete semaphores? Linux doesn't have a
1214 : : * 'delete_semaphore()' function -- may result in an invalid
1215 : : * pointer dereference for non-synchronized consumers. Should
1216 : : * we at least check for blocked threads and signal/cancel them?
1217 : : */
1218 : :
1219 : 0 : acpi_status acpi_os_delete_semaphore(acpi_handle handle)
1220 : : {
1221 : 0 : struct semaphore *sem = (struct semaphore *)handle;
1222 : :
1223 [ # # ]: 0 : if (!sem)
1224 : : return AE_BAD_PARAMETER;
1225 : :
1226 : 0 : ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
1227 : :
1228 [ # # ]: 0 : BUG_ON(!list_empty(&sem->wait_list));
1229 : 0 : kfree(sem);
1230 : 0 : sem = NULL;
1231 : :
1232 : 0 : return AE_OK;
1233 : : }
1234 : :
1235 : : /*
1236 : : * TODO: Support for units > 1?
1237 : : */
1238 : 944016 : acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
1239 : : {
1240 : 944016 : acpi_status status = AE_OK;
1241 : 944016 : struct semaphore *sem = (struct semaphore *)handle;
1242 : 944016 : long jiffies;
1243 : 944016 : int ret = 0;
1244 : :
1245 [ + + ]: 944016 : if (!acpi_os_initialized)
1246 : : return AE_OK;
1247 : :
1248 [ + - ]: 940584 : if (!sem || (units < 1))
1249 : : return AE_BAD_PARAMETER;
1250 : :
1251 [ + - ]: 940584 : if (units > 1)
1252 : : return AE_SUPPORT;
1253 : :
1254 : : ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
1255 : 940584 : handle, units, timeout));
1256 : :
1257 [ + + ]: 940584 : if (timeout == ACPI_WAIT_FOREVER)
1258 : : jiffies = MAX_SCHEDULE_TIMEOUT;
1259 : : else
1260 [ - + ]: 3900 : jiffies = msecs_to_jiffies(timeout);
1261 : :
1262 : 940584 : ret = down_timeout(sem, jiffies);
1263 [ - + ]: 940584 : if (ret)
1264 : 0 : status = AE_TIME;
1265 : :
1266 : : if (ACPI_FAILURE(status)) {
1267 : : ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
1268 : : "Failed to acquire semaphore[%p|%d|%d], %s",
1269 : : handle, units, timeout,
1270 : : acpi_format_exception(status)));
1271 : : } else {
1272 : : ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
1273 : : "Acquired semaphore[%p|%d|%d]", handle,
1274 : : units, timeout));
1275 : : }
1276 : :
1277 : : return status;
1278 : : }
1279 : :
1280 : : /*
1281 : : * TODO: Support for units > 1?
1282 : : */
1283 : 944016 : acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
1284 : : {
1285 : 944016 : struct semaphore *sem = (struct semaphore *)handle;
1286 : :
1287 [ + + ]: 944016 : if (!acpi_os_initialized)
1288 : : return AE_OK;
1289 : :
1290 [ + - ]: 940584 : if (!sem || (units < 1))
1291 : : return AE_BAD_PARAMETER;
1292 : :
1293 [ + - ]: 940584 : if (units > 1)
1294 : : return AE_SUPPORT;
1295 : :
1296 : : ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
1297 : 940584 : units));
1298 : :
1299 : 940584 : up(sem);
1300 : :
1301 : 940584 : return AE_OK;
1302 : : }
1303 : :
1304 : 0 : acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
1305 : : {
1306 : : #ifdef ENABLE_DEBUGGER
1307 : : if (acpi_in_debugger) {
1308 : : u32 chars;
1309 : :
1310 : : kdb_read(buffer, buffer_length);
1311 : :
1312 : : /* remove the CR kdb includes */
1313 : : chars = strlen(buffer) - 1;
1314 : : buffer[chars] = '\0';
1315 : : }
1316 : : #else
1317 : 0 : int ret;
1318 : :
1319 : 0 : ret = acpi_debugger_read_cmd(buffer, buffer_length);
1320 : 0 : if (ret < 0)
1321 : 0 : return AE_ERROR;
1322 : : if (bytes_read)
1323 : : *bytes_read = ret;
1324 : : #endif
1325 : :
1326 : : return AE_OK;
1327 : : }
1328 : : EXPORT_SYMBOL(acpi_os_get_line);
1329 : :
1330 : 0 : acpi_status acpi_os_wait_command_ready(void)
1331 : : {
1332 : 0 : int ret;
1333 : :
1334 : 0 : ret = acpi_debugger_wait_command_ready();
1335 : 0 : if (ret < 0)
1336 : 0 : return AE_ERROR;
1337 : : return AE_OK;
1338 : : }
1339 : :
1340 : 0 : acpi_status acpi_os_notify_command_complete(void)
1341 : : {
1342 : 0 : int ret;
1343 : :
1344 : 0 : ret = acpi_debugger_notify_command_complete();
1345 : 0 : if (ret < 0)
1346 : 0 : return AE_ERROR;
1347 : : return AE_OK;
1348 : : }
1349 : :
1350 : 0 : acpi_status acpi_os_signal(u32 function, void *info)
1351 : : {
1352 [ # # ]: 0 : switch (function) {
1353 : 0 : case ACPI_SIGNAL_FATAL:
1354 : 0 : printk(KERN_ERR PREFIX "Fatal opcode executed\n");
1355 : 0 : break;
1356 : : case ACPI_SIGNAL_BREAKPOINT:
1357 : : /*
1358 : : * AML Breakpoint
1359 : : * ACPI spec. says to treat it as a NOP unless
1360 : : * you are debugging. So if/when we integrate
1361 : : * AML debugger into the kernel debugger its
1362 : : * hook will go here. But until then it is
1363 : : * not useful to print anything on breakpoints.
1364 : : */
1365 : : break;
1366 : : default:
1367 : : break;
1368 : : }
1369 : :
1370 : 0 : return AE_OK;
1371 : : }
1372 : :
1373 : 0 : static int __init acpi_os_name_setup(char *str)
1374 : : {
1375 : 0 : char *p = acpi_os_name;
1376 : 0 : int count = ACPI_MAX_OVERRIDE_LEN - 1;
1377 : :
1378 [ # # # # ]: 0 : if (!str || !*str)
1379 : : return 0;
1380 : :
1381 [ # # # # ]: 0 : for (; count-- && *str; str++) {
1382 [ # # # # : 0 : if (isalnum(*str) || *str == ' ' || *str == ':')
# # ]
1383 : 0 : *p++ = *str;
1384 [ # # ]: 0 : else if (*str == '\'' || *str == '"')
1385 : 0 : continue;
1386 : : else
1387 : : break;
1388 : : }
1389 : 0 : *p = 0;
1390 : :
1391 : 0 : return 1;
1392 : :
1393 : : }
1394 : :
1395 : : __setup("acpi_os_name=", acpi_os_name_setup);
1396 : :
1397 : : /*
1398 : : * Disable the auto-serialization of named objects creation methods.
1399 : : *
1400 : : * This feature is enabled by default. It marks the AML control methods
1401 : : * that contain the opcodes to create named objects as "Serialized".
1402 : : */
1403 : 0 : static int __init acpi_no_auto_serialize_setup(char *str)
1404 : : {
1405 : 0 : acpi_gbl_auto_serialize_methods = FALSE;
1406 : 0 : pr_info("ACPI: auto-serialization disabled\n");
1407 : :
1408 : 0 : return 1;
1409 : : }
1410 : :
1411 : : __setup("acpi_no_auto_serialize", acpi_no_auto_serialize_setup);
1412 : :
1413 : : /* Check of resource interference between native drivers and ACPI
1414 : : * OperationRegions (SystemIO and System Memory only).
1415 : : * IO ports and memory declared in ACPI might be used by the ACPI subsystem
1416 : : * in arbitrary AML code and can interfere with legacy drivers.
1417 : : * acpi_enforce_resources= can be set to:
1418 : : *
1419 : : * - strict (default) (2)
1420 : : * -> further driver trying to access the resources will not load
1421 : : * - lax (1)
1422 : : * -> further driver trying to access the resources will load, but you
1423 : : * get a system message that something might go wrong...
1424 : : *
1425 : : * - no (0)
1426 : : * -> ACPI Operation Region resources will not be registered
1427 : : *
1428 : : */
1429 : : #define ENFORCE_RESOURCES_STRICT 2
1430 : : #define ENFORCE_RESOURCES_LAX 1
1431 : : #define ENFORCE_RESOURCES_NO 0
1432 : :
1433 : : static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1434 : :
1435 : 0 : static int __init acpi_enforce_resources_setup(char *str)
1436 : : {
1437 [ # # # # ]: 0 : if (str == NULL || *str == '\0')
1438 : : return 0;
1439 : :
1440 [ # # ]: 0 : if (!strcmp("strict", str))
1441 : 0 : acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
1442 [ # # ]: 0 : else if (!strcmp("lax", str))
1443 : 0 : acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
1444 [ # # ]: 0 : else if (!strcmp("no", str))
1445 : 0 : acpi_enforce_resources = ENFORCE_RESOURCES_NO;
1446 : :
1447 : : return 1;
1448 : : }
1449 : :
1450 : : __setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
1451 : :
1452 : : /* Check for resource conflicts between ACPI OperationRegions and native
1453 : : * drivers */
1454 : 0 : int acpi_check_resource_conflict(const struct resource *res)
1455 : : {
1456 : 0 : acpi_adr_space_type space_id;
1457 : 0 : acpi_size length;
1458 : 0 : u8 warn = 0;
1459 : 0 : int clash = 0;
1460 : :
1461 [ # # ]: 0 : if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1462 : : return 0;
1463 [ # # ]: 0 : if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
1464 : : return 0;
1465 : :
1466 [ # # ]: 0 : if (res->flags & IORESOURCE_IO)
1467 : : space_id = ACPI_ADR_SPACE_SYSTEM_IO;
1468 : : else
1469 : 0 : space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
1470 : :
1471 : 0 : length = resource_size(res);
1472 : 0 : if (acpi_enforce_resources != ENFORCE_RESOURCES_NO)
1473 : 0 : warn = 1;
1474 : 0 : clash = acpi_check_address_range(space_id, res->start, length, warn);
1475 : :
1476 [ # # ]: 0 : if (clash) {
1477 [ # # ]: 0 : if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1478 [ # # ]: 0 : if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
1479 : 0 : printk(KERN_NOTICE "ACPI: This conflict may"
1480 : : " cause random problems and system"
1481 : : " instability\n");
1482 : 0 : printk(KERN_INFO "ACPI: If an ACPI driver is available"
1483 : : " for this device, you should use it instead of"
1484 : : " the native driver\n");
1485 : : }
1486 [ # # ]: 0 : if (acpi_enforce_resources == ENFORCE_RESOURCES_STRICT)
1487 : 0 : return -EBUSY;
1488 : : }
1489 : : return 0;
1490 : : }
1491 : : EXPORT_SYMBOL(acpi_check_resource_conflict);
1492 : :
1493 : 0 : int acpi_check_region(resource_size_t start, resource_size_t n,
1494 : : const char *name)
1495 : : {
1496 : 0 : struct resource res = {
1497 : : .start = start,
1498 : 0 : .end = start + n - 1,
1499 : : .name = name,
1500 : : .flags = IORESOURCE_IO,
1501 : : };
1502 : :
1503 : 0 : return acpi_check_resource_conflict(&res);
1504 : : }
1505 : : EXPORT_SYMBOL(acpi_check_region);
1506 : :
1507 : 0 : static acpi_status acpi_deactivate_mem_region(acpi_handle handle, u32 level,
1508 : : void *_res, void **return_value)
1509 : : {
1510 : 0 : struct acpi_mem_space_context **mem_ctx;
1511 : 0 : union acpi_operand_object *handler_obj;
1512 : 0 : union acpi_operand_object *region_obj2;
1513 : 0 : union acpi_operand_object *region_obj;
1514 : 0 : struct resource *res = _res;
1515 : 0 : acpi_status status;
1516 : :
1517 : 0 : region_obj = acpi_ns_get_attached_object(handle);
1518 [ # # ]: 0 : if (!region_obj)
1519 : : return AE_OK;
1520 : :
1521 : 0 : handler_obj = region_obj->region.handler;
1522 [ # # ]: 0 : if (!handler_obj)
1523 : : return AE_OK;
1524 : :
1525 [ # # ]: 0 : if (region_obj->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
1526 : : return AE_OK;
1527 : :
1528 [ # # ]: 0 : if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE))
1529 : : return AE_OK;
1530 : :
1531 : 0 : region_obj2 = acpi_ns_get_secondary_object(region_obj);
1532 [ # # ]: 0 : if (!region_obj2)
1533 : : return AE_OK;
1534 : :
1535 : 0 : mem_ctx = (void *)®ion_obj2->extra.region_context;
1536 : :
1537 [ # # ]: 0 : if (!(mem_ctx[0]->address >= res->start &&
1538 [ # # ]: 0 : mem_ctx[0]->address < res->end))
1539 : : return AE_OK;
1540 : :
1541 : 0 : status = handler_obj->address_space.setup(region_obj,
1542 : : ACPI_REGION_DEACTIVATE,
1543 : : NULL, (void **)mem_ctx);
1544 [ # # ]: 0 : if (ACPI_SUCCESS(status))
1545 : 0 : region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
1546 : :
1547 : : return status;
1548 : : }
1549 : :
1550 : : /**
1551 : : * acpi_release_memory - Release any mappings done to a memory region
1552 : : * @handle: Handle to namespace node
1553 : : * @res: Memory resource
1554 : : * @level: A level that terminates the search
1555 : : *
1556 : : * Walks through @handle and unmaps all SystemMemory Operation Regions that
1557 : : * overlap with @res and that have already been activated (mapped).
1558 : : *
1559 : : * This is a helper that allows drivers to place special requirements on memory
1560 : : * region that may overlap with operation regions, primarily allowing them to
1561 : : * safely map the region as non-cached memory.
1562 : : *
1563 : : * The unmapped Operation Regions will be automatically remapped next time they
1564 : : * are called, so the drivers do not need to do anything else.
1565 : : */
1566 : 0 : acpi_status acpi_release_memory(acpi_handle handle, struct resource *res,
1567 : : u32 level)
1568 : : {
1569 [ # # ]: 0 : if (!(res->flags & IORESOURCE_MEM))
1570 : : return AE_TYPE;
1571 : :
1572 : 0 : return acpi_walk_namespace(ACPI_TYPE_REGION, handle, level,
1573 : : acpi_deactivate_mem_region, NULL, res, NULL);
1574 : : }
1575 : : EXPORT_SYMBOL_GPL(acpi_release_memory);
1576 : :
1577 : : /*
1578 : : * Let drivers know whether the resource checks are effective
1579 : : */
1580 : 0 : int acpi_resources_are_enforced(void)
1581 : : {
1582 : 0 : return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT;
1583 : : }
1584 : : EXPORT_SYMBOL(acpi_resources_are_enforced);
1585 : :
1586 : : /*
1587 : : * Deallocate the memory for a spinlock.
1588 : : */
1589 : 0 : void acpi_os_delete_lock(acpi_spinlock handle)
1590 : : {
1591 : 0 : ACPI_FREE(handle);
1592 : 0 : }
1593 : :
1594 : : /*
1595 : : * Acquire a spinlock.
1596 : : *
1597 : : * handle is a pointer to the spinlock_t.
1598 : : */
1599 : :
1600 : 34751007 : acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
1601 : : {
1602 : 34751007 : acpi_cpu_flags flags;
1603 : 34751007 : spin_lock_irqsave(lockp, flags);
1604 : 34751007 : return flags;
1605 : : }
1606 : :
1607 : : /*
1608 : : * Release a spinlock. See above.
1609 : : */
1610 : :
1611 : 34751007 : void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
1612 : : {
1613 : 34751007 : spin_unlock_irqrestore(lockp, flags);
1614 : 34751007 : }
1615 : :
1616 : : #ifndef ACPI_USE_LOCAL_CACHE
1617 : :
1618 : : /*******************************************************************************
1619 : : *
1620 : : * FUNCTION: acpi_os_create_cache
1621 : : *
1622 : : * PARAMETERS: name - Ascii name for the cache
1623 : : * size - Size of each cached object
1624 : : * depth - Maximum depth of the cache (in objects) <ignored>
1625 : : * cache - Where the new cache object is returned
1626 : : *
1627 : : * RETURN: status
1628 : : *
1629 : : * DESCRIPTION: Create a cache object
1630 : : *
1631 : : ******************************************************************************/
1632 : :
1633 : : acpi_status
1634 : 390 : acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1635 : : {
1636 : 390 : *cache = kmem_cache_create(name, size, 0, 0, NULL);
1637 [ + - ]: 390 : if (*cache == NULL)
1638 : : return AE_ERROR;
1639 : : else
1640 : 390 : return AE_OK;
1641 : : }
1642 : :
1643 : : /*******************************************************************************
1644 : : *
1645 : : * FUNCTION: acpi_os_purge_cache
1646 : : *
1647 : : * PARAMETERS: Cache - Handle to cache object
1648 : : *
1649 : : * RETURN: Status
1650 : : *
1651 : : * DESCRIPTION: Free all objects within the requested cache.
1652 : : *
1653 : : ******************************************************************************/
1654 : :
1655 : 312 : acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
1656 : : {
1657 : 312 : kmem_cache_shrink(cache);
1658 : 312 : return (AE_OK);
1659 : : }
1660 : :
1661 : : /*******************************************************************************
1662 : : *
1663 : : * FUNCTION: acpi_os_delete_cache
1664 : : *
1665 : : * PARAMETERS: Cache - Handle to cache object
1666 : : *
1667 : : * RETURN: Status
1668 : : *
1669 : : * DESCRIPTION: Free all objects within the requested cache and delete the
1670 : : * cache object.
1671 : : *
1672 : : ******************************************************************************/
1673 : :
1674 : 0 : acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
1675 : : {
1676 : 0 : kmem_cache_destroy(cache);
1677 : 0 : return (AE_OK);
1678 : : }
1679 : :
1680 : : /*******************************************************************************
1681 : : *
1682 : : * FUNCTION: acpi_os_release_object
1683 : : *
1684 : : * PARAMETERS: Cache - Handle to cache object
1685 : : * Object - The object to be released
1686 : : *
1687 : : * RETURN: None
1688 : : *
1689 : : * DESCRIPTION: Release an object to the specified cache. If cache is full,
1690 : : * the object is deleted.
1691 : : *
1692 : : ******************************************************************************/
1693 : :
1694 : 16662837 : acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1695 : : {
1696 : 16662837 : kmem_cache_free(cache, object);
1697 : 16662837 : return (AE_OK);
1698 : : }
1699 : : #endif
1700 : :
1701 : 0 : static int __init acpi_no_static_ssdt_setup(char *s)
1702 : : {
1703 : 0 : acpi_gbl_disable_ssdt_table_install = TRUE;
1704 : 0 : pr_info("ACPI: static SSDT installation disabled\n");
1705 : :
1706 : 0 : return 0;
1707 : : }
1708 : :
1709 : : early_param("acpi_no_static_ssdt", acpi_no_static_ssdt_setup);
1710 : :
1711 : 0 : static int __init acpi_disable_return_repair(char *s)
1712 : : {
1713 : 0 : printk(KERN_NOTICE PREFIX
1714 : : "ACPI: Predefined validation mechanism disabled\n");
1715 : 0 : acpi_gbl_disable_auto_repair = TRUE;
1716 : :
1717 : 0 : return 1;
1718 : : }
1719 : :
1720 : : __setup("acpica_no_return_repair", acpi_disable_return_repair);
1721 : :
1722 : 78 : acpi_status __init acpi_os_initialize(void)
1723 : : {
1724 : 78 : acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1725 : 78 : acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1726 : 78 : acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
1727 : 78 : acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
1728 [ - + ]: 78 : if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) {
1729 : : /*
1730 : : * Use acpi_os_map_generic_address to pre-map the reset
1731 : : * register if it's in system memory.
1732 : : */
1733 : 0 : int rv;
1734 : :
1735 : 0 : rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
1736 : 0 : pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
1737 : : }
1738 : 78 : acpi_os_initialized = true;
1739 : :
1740 : 78 : return AE_OK;
1741 : : }
1742 : :
1743 : 78 : acpi_status __init acpi_os_initialize1(void)
1744 : : {
1745 : 78 : kacpid_wq = alloc_workqueue("kacpid", 0, 1);
1746 : 78 : kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
1747 : 78 : kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
1748 [ - + ]: 78 : BUG_ON(!kacpid_wq);
1749 [ - + ]: 78 : BUG_ON(!kacpi_notify_wq);
1750 [ - + ]: 78 : BUG_ON(!kacpi_hotplug_wq);
1751 : 78 : acpi_osi_init();
1752 : 78 : return AE_OK;
1753 : : }
1754 : :
1755 : 0 : acpi_status acpi_os_terminate(void)
1756 : : {
1757 [ # # ]: 0 : if (acpi_irq_handler) {
1758 : 0 : acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt,
1759 : : acpi_irq_handler);
1760 : : }
1761 : :
1762 : 0 : acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
1763 : 0 : acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
1764 : 0 : acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1765 : 0 : acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1766 [ # # ]: 0 : if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)
1767 : 0 : acpi_os_unmap_generic_address(&acpi_gbl_FADT.reset_register);
1768 : :
1769 : 0 : destroy_workqueue(kacpid_wq);
1770 : 0 : destroy_workqueue(kacpi_notify_wq);
1771 : 0 : destroy_workqueue(kacpi_hotplug_wq);
1772 : :
1773 : 0 : return AE_OK;
1774 : : }
1775 : :
1776 : 0 : acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
1777 : : u32 pm1b_control)
1778 : : {
1779 : 0 : int rc = 0;
1780 [ # # ]: 0 : if (__acpi_os_prepare_sleep)
1781 : 0 : rc = __acpi_os_prepare_sleep(sleep_state,
1782 : : pm1a_control, pm1b_control);
1783 [ # # # # ]: 0 : if (rc < 0)
1784 : : return AE_ERROR;
1785 [ # # # # ]: 0 : else if (rc > 0)
1786 : 0 : return AE_CTRL_TERMINATE;
1787 : :
1788 : : return AE_OK;
1789 : : }
1790 : :
1791 : 0 : void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
1792 : : u32 pm1a_ctrl, u32 pm1b_ctrl))
1793 : : {
1794 : 0 : __acpi_os_prepare_sleep = func;
1795 : 0 : }
1796 : :
1797 : : #if (ACPI_REDUCED_HARDWARE)
1798 : : acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
1799 : : u32 val_b)
1800 : : {
1801 : : int rc = 0;
1802 : : if (__acpi_os_prepare_extended_sleep)
1803 : : rc = __acpi_os_prepare_extended_sleep(sleep_state,
1804 : : val_a, val_b);
1805 : : if (rc < 0)
1806 : : return AE_ERROR;
1807 : : else if (rc > 0)
1808 : : return AE_CTRL_TERMINATE;
1809 : :
1810 : : return AE_OK;
1811 : : }
1812 : : #else
1813 : 0 : acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
1814 : : u32 val_b)
1815 : : {
1816 : 0 : return AE_OK;
1817 : : }
1818 : : #endif
1819 : :
1820 : 0 : void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
1821 : : u32 val_a, u32 val_b))
1822 : : {
1823 : 0 : __acpi_os_prepare_extended_sleep = func;
1824 : 0 : }
1825 : :
1826 : 0 : acpi_status acpi_os_enter_sleep(u8 sleep_state,
1827 : : u32 reg_a_value, u32 reg_b_value)
1828 : : {
1829 : 0 : acpi_status status;
1830 : :
1831 [ # # ]: 0 : if (acpi_gbl_reduced_hardware)
1832 : : status = acpi_os_prepare_extended_sleep(sleep_state,
1833 : : reg_a_value,
1834 : : reg_b_value);
1835 : : else
1836 [ # # ]: 0 : status = acpi_os_prepare_sleep(sleep_state,
1837 : : reg_a_value, reg_b_value);
1838 : 0 : return status;
1839 : : }
|