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