1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
9 #define pr_fmt(fmt) "ACPI: utils: " fmt
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/init.h>
15 #include <linux/types.h>
16 #include <linux/hardirq.h>
17 #include <linux/acpi.h>
18 #include <linux/dynamic_debug.h>
23 /* --------------------------------------------------------------------------
24 Object Evaluation Helpers
25 -------------------------------------------------------------------------- */
26 static void acpi_util_eval_error(acpi_handle h
, acpi_string p
, acpi_status s
)
28 acpi_handle_debug(h
, "Evaluate [%s]: %s\n", p
, acpi_format_exception(s
));
32 acpi_extract_package(union acpi_object
*package
,
33 struct acpi_buffer
*format
, struct acpi_buffer
*buffer
)
35 u32 size_required
= 0;
37 char *format_string
= NULL
;
44 if (!package
|| (package
->type
!= ACPI_TYPE_PACKAGE
)
45 || (package
->package
.count
< 1)) {
46 pr_debug("Invalid package argument\n");
47 return AE_BAD_PARAMETER
;
50 if (!format
|| !format
->pointer
|| (format
->length
< 1)) {
51 pr_debug("Invalid format argument\n");
52 return AE_BAD_PARAMETER
;
56 pr_debug("Invalid buffer argument\n");
57 return AE_BAD_PARAMETER
;
60 format_count
= (format
->length
/ sizeof(char)) - 1;
61 if (format_count
> package
->package
.count
) {
62 pr_debug("Format specifies more objects [%d] than present [%d]\n",
63 format_count
, package
->package
.count
);
67 format_string
= format
->pointer
;
70 * Calculate size_required.
72 for (i
= 0; i
< format_count
; i
++) {
74 union acpi_object
*element
= &(package
->package
.elements
[i
]);
76 switch (element
->type
) {
78 case ACPI_TYPE_INTEGER
:
79 switch (format_string
[i
]) {
81 size_required
+= sizeof(u64
);
82 tail_offset
+= sizeof(u64
);
86 sizeof(char *) + sizeof(u64
) +
88 tail_offset
+= sizeof(char *);
91 pr_debug("Invalid package element [%d]: got number, expected [%c]\n",
97 case ACPI_TYPE_STRING
:
98 case ACPI_TYPE_BUFFER
:
99 switch (format_string
[i
]) {
103 (element
->string
.length
* sizeof(char)) +
105 tail_offset
+= sizeof(char *);
109 sizeof(u8
*) + element
->buffer
.length
;
110 tail_offset
+= sizeof(u8
*);
113 pr_debug("Invalid package element [%d] got string/buffer, expected [%c]\n",
114 i
, format_string
[i
]);
118 case ACPI_TYPE_LOCAL_REFERENCE
:
119 switch (format_string
[i
]) {
121 size_required
+= sizeof(void *);
122 tail_offset
+= sizeof(void *);
125 pr_debug("Invalid package element [%d] got reference, expected [%c]\n",
126 i
, format_string
[i
]);
131 case ACPI_TYPE_PACKAGE
:
133 pr_debug("Unsupported element at index=%d\n", i
);
134 /* TBD: handle nested packages... */
140 * Validate output buffer.
142 if (buffer
->length
== ACPI_ALLOCATE_BUFFER
) {
143 buffer
->pointer
= ACPI_ALLOCATE_ZEROED(size_required
);
144 if (!buffer
->pointer
)
146 buffer
->length
= size_required
;
148 if (buffer
->length
< size_required
) {
149 buffer
->length
= size_required
;
150 return AE_BUFFER_OVERFLOW
;
151 } else if (buffer
->length
!= size_required
||
153 return AE_BAD_PARAMETER
;
157 head
= buffer
->pointer
;
158 tail
= buffer
->pointer
+ tail_offset
;
161 * Extract package data.
163 for (i
= 0; i
< format_count
; i
++) {
166 union acpi_object
*element
= &(package
->package
.elements
[i
]);
168 switch (element
->type
) {
170 case ACPI_TYPE_INTEGER
:
171 switch (format_string
[i
]) {
174 element
->integer
.value
;
178 pointer
= (u8
**) head
;
181 element
->integer
.value
;
182 head
+= sizeof(u64
*);
184 /* NULL terminate string */
186 tail
+= sizeof(char);
189 /* Should never get here */
194 case ACPI_TYPE_STRING
:
195 case ACPI_TYPE_BUFFER
:
196 switch (format_string
[i
]) {
198 pointer
= (u8
**) head
;
200 memcpy(tail
, element
->string
.pointer
,
201 element
->string
.length
);
202 head
+= sizeof(char *);
203 tail
+= element
->string
.length
* sizeof(char);
204 /* NULL terminate string */
206 tail
+= sizeof(char);
209 pointer
= (u8
**) head
;
211 memcpy(tail
, element
->buffer
.pointer
,
212 element
->buffer
.length
);
213 head
+= sizeof(u8
*);
214 tail
+= element
->buffer
.length
;
217 /* Should never get here */
221 case ACPI_TYPE_LOCAL_REFERENCE
:
222 switch (format_string
[i
]) {
225 (void *)element
->reference
.handle
;
226 head
+= sizeof(void *);
229 /* Should never get here */
233 case ACPI_TYPE_PACKAGE
:
234 /* TBD: handle nested packages... */
236 /* Should never get here */
244 EXPORT_SYMBOL(acpi_extract_package
);
247 acpi_evaluate_integer(acpi_handle handle
,
248 acpi_string pathname
,
249 struct acpi_object_list
*arguments
, unsigned long long *data
)
251 acpi_status status
= AE_OK
;
252 union acpi_object element
;
253 struct acpi_buffer buffer
= { 0, NULL
};
256 return AE_BAD_PARAMETER
;
258 buffer
.length
= sizeof(union acpi_object
);
259 buffer
.pointer
= &element
;
260 status
= acpi_evaluate_object(handle
, pathname
, arguments
, &buffer
);
261 if (ACPI_FAILURE(status
)) {
262 acpi_util_eval_error(handle
, pathname
, status
);
266 if (element
.type
!= ACPI_TYPE_INTEGER
) {
267 acpi_util_eval_error(handle
, pathname
, AE_BAD_DATA
);
271 *data
= element
.integer
.value
;
273 acpi_handle_debug(handle
, "Return value [%llu]\n", *data
);
278 EXPORT_SYMBOL(acpi_evaluate_integer
);
280 int acpi_get_local_u64_address(acpi_handle handle
, u64
*addr
)
284 status
= acpi_evaluate_integer(handle
, METHOD_NAME__ADR
, NULL
, addr
);
285 if (ACPI_FAILURE(status
))
289 EXPORT_SYMBOL(acpi_get_local_u64_address
);
291 int acpi_get_local_address(acpi_handle handle
, u32
*addr
)
296 ret
= acpi_get_local_u64_address(handle
, &adr
);
302 EXPORT_SYMBOL(acpi_get_local_address
);
304 #define ACPI_MAX_SUB_BUF_SIZE 9
306 const char *acpi_get_subsystem_id(acpi_handle handle
)
308 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
309 union acpi_object
*obj
;
314 status
= acpi_evaluate_object(handle
, METHOD_NAME__SUB
, NULL
, &buffer
);
315 if (ACPI_FAILURE(status
)) {
316 acpi_handle_debug(handle
, "Reading ACPI _SUB failed: %#x\n", status
);
317 return ERR_PTR(-ENODATA
);
320 obj
= buffer
.pointer
;
321 if (obj
->type
== ACPI_TYPE_STRING
) {
322 len
= strlen(obj
->string
.pointer
);
323 if (len
< ACPI_MAX_SUB_BUF_SIZE
&& len
> 0) {
324 sub
= kstrdup(obj
->string
.pointer
, GFP_KERNEL
);
326 sub
= ERR_PTR(-ENOMEM
);
328 acpi_handle_err(handle
, "ACPI _SUB Length %zu is Invalid\n", len
);
329 sub
= ERR_PTR(-ENODATA
);
332 acpi_handle_warn(handle
, "Warning ACPI _SUB did not return a string\n");
333 sub
= ERR_PTR(-ENODATA
);
336 acpi_os_free(buffer
.pointer
);
340 EXPORT_SYMBOL_GPL(acpi_get_subsystem_id
);
342 bool acpi_evaluate_reference(acpi_handle handle
, acpi_string pathname
,
343 struct acpi_object_list
*arguments
,
344 struct acpi_handle_list
*list
)
346 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
347 union acpi_object
*package
;
355 /* Evaluate object. */
357 status
= acpi_evaluate_object(handle
, pathname
, arguments
, &buffer
);
358 if (ACPI_FAILURE(status
))
361 package
= buffer
.pointer
;
363 if (buffer
.length
== 0 || !package
||
364 package
->type
!= ACPI_TYPE_PACKAGE
|| !package
->package
.count
)
367 list
->count
= package
->package
.count
;
368 list
->handles
= kcalloc(list
->count
, sizeof(*list
->handles
), GFP_KERNEL
);
372 /* Extract package data. */
374 for (i
= 0; i
< list
->count
; i
++) {
375 union acpi_object
*element
= &(package
->package
.elements
[i
]);
377 if (element
->type
!= ACPI_TYPE_LOCAL_REFERENCE
||
378 !element
->reference
.handle
)
381 /* Get the acpi_handle. */
383 list
->handles
[i
] = element
->reference
.handle
;
384 acpi_handle_debug(list
->handles
[i
], "Found in reference list\n");
390 kfree(buffer
.pointer
);
395 kfree(list
->handles
);
396 list
->handles
= NULL
;
402 acpi_util_eval_error(handle
, pathname
, status
);
406 EXPORT_SYMBOL(acpi_evaluate_reference
);
409 * acpi_handle_list_equal - Check if two ACPI handle lists are the same
410 * @list1: First list to compare.
411 * @list2: Second list to compare.
413 * Return true if the given ACPI handle lists are of the same size and
414 * contain the same ACPI handles in the same order. Otherwise, return false.
416 bool acpi_handle_list_equal(struct acpi_handle_list
*list1
,
417 struct acpi_handle_list
*list2
)
419 return list1
->count
== list2
->count
&&
420 !memcmp(list1
->handles
, list2
->handles
,
421 list1
->count
* sizeof(*list1
->handles
));
423 EXPORT_SYMBOL_GPL(acpi_handle_list_equal
);
426 * acpi_handle_list_replace - Replace one ACPI handle list with another
427 * @dst: ACPI handle list to replace.
428 * @src: Source ACPI handle list.
430 * Free the handles table in @dst, move the handles table from @src to @dst,
431 * copy count from @src to @dst and clear @src.
433 void acpi_handle_list_replace(struct acpi_handle_list
*dst
,
434 struct acpi_handle_list
*src
)
439 dst
->count
= src
->count
;
440 dst
->handles
= src
->handles
;
445 EXPORT_SYMBOL_GPL(acpi_handle_list_replace
);
448 * acpi_handle_list_free - Free the handles table in an ACPI handle list
449 * @list: ACPI handle list to free.
451 * Free the handles table in @list and clear its count field.
453 void acpi_handle_list_free(struct acpi_handle_list
*list
)
458 kfree(list
->handles
);
461 EXPORT_SYMBOL_GPL(acpi_handle_list_free
);
464 * acpi_device_dep - Check ACPI device dependency
465 * @target: ACPI handle of the target ACPI device.
466 * @match: ACPI handle to look up in the target's _DEP list.
468 * Return true if @match is present in the list returned by _DEP for
469 * @target or false otherwise.
471 bool acpi_device_dep(acpi_handle target
, acpi_handle match
)
473 struct acpi_handle_list dep_devices
;
477 if (!acpi_has_method(target
, "_DEP"))
480 if (!acpi_evaluate_reference(target
, "_DEP", NULL
, &dep_devices
)) {
481 acpi_handle_debug(target
, "Failed to evaluate _DEP.\n");
485 for (i
= 0; i
< dep_devices
.count
; i
++) {
486 if (dep_devices
.handles
[i
] == match
) {
492 acpi_handle_list_free(&dep_devices
);
495 EXPORT_SYMBOL_GPL(acpi_device_dep
);
498 acpi_get_physical_device_location(acpi_handle handle
, struct acpi_pld_info
**pld
)
501 struct acpi_buffer buffer
= { ACPI_ALLOCATE_BUFFER
, NULL
};
502 union acpi_object
*output
;
504 status
= acpi_evaluate_object(handle
, "_PLD", NULL
, &buffer
);
506 if (ACPI_FAILURE(status
))
509 output
= buffer
.pointer
;
511 if (!output
|| output
->type
!= ACPI_TYPE_PACKAGE
512 || !output
->package
.count
513 || output
->package
.elements
[0].type
!= ACPI_TYPE_BUFFER
514 || output
->package
.elements
[0].buffer
.length
< ACPI_PLD_REV1_BUFFER_SIZE
) {
519 status
= acpi_decode_pld_buffer(
520 output
->package
.elements
[0].buffer
.pointer
,
521 output
->package
.elements
[0].buffer
.length
,
525 kfree(buffer
.pointer
);
528 EXPORT_SYMBOL(acpi_get_physical_device_location
);
531 * acpi_evaluate_ost: Evaluate _OST for hotplug operations
532 * @handle: ACPI device handle
533 * @source_event: source event code
534 * @status_code: status code
535 * @status_buf: optional detailed information (NULL if none)
537 * Evaluate _OST for hotplug operations. All ACPI hotplug handlers
538 * must call this function when evaluating _OST for hotplug operations.
539 * When the platform does not support _OST, this function has no effect.
542 acpi_evaluate_ost(acpi_handle handle
, u32 source_event
, u32 status_code
,
543 struct acpi_buffer
*status_buf
)
545 union acpi_object params
[3] = {
546 {.type
= ACPI_TYPE_INTEGER
,},
547 {.type
= ACPI_TYPE_INTEGER
,},
548 {.type
= ACPI_TYPE_BUFFER
,}
550 struct acpi_object_list arg_list
= {3, params
};
552 params
[0].integer
.value
= source_event
;
553 params
[1].integer
.value
= status_code
;
554 if (status_buf
!= NULL
) {
555 params
[2].buffer
.pointer
= status_buf
->pointer
;
556 params
[2].buffer
.length
= status_buf
->length
;
558 params
[2].buffer
.pointer
= NULL
;
559 params
[2].buffer
.length
= 0;
562 return acpi_evaluate_object(handle
, "_OST", &arg_list
, NULL
);
564 EXPORT_SYMBOL(acpi_evaluate_ost
);
567 * acpi_handle_path: Return the object path of handle
568 * @handle: ACPI device handle
570 * Caller must free the returned buffer
572 char *acpi_handle_path(acpi_handle handle
)
574 struct acpi_buffer buffer
= {
575 .length
= ACPI_ALLOCATE_BUFFER
,
579 if (in_interrupt() ||
580 acpi_get_name(handle
, ACPI_FULL_PATHNAME
, &buffer
) != AE_OK
)
582 return buffer
.pointer
;
586 * acpi_handle_printk: Print message with ACPI prefix and object path
588 * @handle: ACPI device handle
589 * @fmt: format string
591 * This function is called through acpi_handle_<level> macros and prints
592 * a message with ACPI prefix and object path. This function acquires
593 * the global namespace mutex to obtain an object path. In interrupt
594 * context, it shows the object path as <n/a>.
597 acpi_handle_printk(const char *level
, acpi_handle handle
, const char *fmt
, ...)
599 struct va_format vaf
;
607 path
= acpi_handle_path(handle
);
608 printk("%sACPI: %s: %pV", level
, path
? path
: "<n/a>", &vaf
);
613 EXPORT_SYMBOL(acpi_handle_printk
);
615 #if defined(CONFIG_DYNAMIC_DEBUG)
617 * __acpi_handle_debug: pr_debug with ACPI prefix and object path
618 * @descriptor: Dynamic Debug descriptor
619 * @handle: ACPI device handle
620 * @fmt: format string
622 * This function is called through acpi_handle_debug macro and debug
623 * prints a message with ACPI prefix and object path. This function
624 * acquires the global namespace mutex to obtain an object path. In
625 * interrupt context, it shows the object path as <n/a>.
628 __acpi_handle_debug(struct _ddebug
*descriptor
, acpi_handle handle
,
629 const char *fmt
, ...)
631 struct va_format vaf
;
639 path
= acpi_handle_path(handle
);
640 __dynamic_pr_debug(descriptor
, "ACPI: %s: %pV", path
? path
: "<n/a>", &vaf
);
645 EXPORT_SYMBOL(__acpi_handle_debug
);
649 * acpi_evaluation_failure_warn - Log evaluation failure warning.
650 * @handle: Parent object handle.
651 * @name: Name of the object whose evaluation has failed.
652 * @status: Status value returned by the failing object evaluation.
654 void acpi_evaluation_failure_warn(acpi_handle handle
, const char *name
,
657 acpi_handle_warn(handle
, "%s evaluation failed: %s\n", name
,
658 acpi_format_exception(status
));
660 EXPORT_SYMBOL_GPL(acpi_evaluation_failure_warn
);
663 * acpi_has_method: Check whether @handle has a method named @name
664 * @handle: ACPI device handle
665 * @name: name of object or method
667 * Check whether @handle has a method named @name.
669 bool acpi_has_method(acpi_handle handle
, char *name
)
673 return ACPI_SUCCESS(acpi_get_handle(handle
, name
, &tmp
));
675 EXPORT_SYMBOL(acpi_has_method
);
677 acpi_status
acpi_execute_simple_method(acpi_handle handle
, char *method
,
680 union acpi_object obj
= { .type
= ACPI_TYPE_INTEGER
};
681 struct acpi_object_list arg_list
= { .count
= 1, .pointer
= &obj
, };
683 obj
.integer
.value
= arg
;
685 return acpi_evaluate_object(handle
, method
, &arg_list
, NULL
);
687 EXPORT_SYMBOL(acpi_execute_simple_method
);
690 * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations
691 * @handle: ACPI device handle
693 * Evaluate device's _EJ0 method for hotplug operations.
695 acpi_status
acpi_evaluate_ej0(acpi_handle handle
)
699 status
= acpi_execute_simple_method(handle
, "_EJ0", 1);
700 if (status
== AE_NOT_FOUND
)
701 acpi_handle_warn(handle
, "No _EJ0 support for device\n");
702 else if (ACPI_FAILURE(status
))
703 acpi_handle_warn(handle
, "Eject failed (0x%x)\n", status
);
709 * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device
710 * @handle: ACPI device handle
711 * @lock: lock device if non-zero, otherwise unlock device
713 * Evaluate device's _LCK method if present to lock/unlock device
715 acpi_status
acpi_evaluate_lck(acpi_handle handle
, int lock
)
719 status
= acpi_execute_simple_method(handle
, "_LCK", !!lock
);
720 if (ACPI_FAILURE(status
) && status
!= AE_NOT_FOUND
) {
722 acpi_handle_warn(handle
,
723 "Locking device failed (0x%x)\n", status
);
725 acpi_handle_warn(handle
,
726 "Unlocking device failed (0x%x)\n", status
);
733 * acpi_evaluate_reg: Evaluate _REG method to register OpRegion presence
734 * @handle: ACPI device handle
735 * @space_id: ACPI address space id to register OpRegion presence for
736 * @function: Parameter to pass to _REG one of ACPI_REG_CONNECT or
737 * ACPI_REG_DISCONNECT
739 * Evaluate device's _REG method to register OpRegion presence.
741 acpi_status
acpi_evaluate_reg(acpi_handle handle
, u8 space_id
, u32 function
)
743 struct acpi_object_list arg_list
;
744 union acpi_object params
[2];
746 params
[0].type
= ACPI_TYPE_INTEGER
;
747 params
[0].integer
.value
= space_id
;
748 params
[1].type
= ACPI_TYPE_INTEGER
;
749 params
[1].integer
.value
= function
;
751 arg_list
.pointer
= params
;
753 return acpi_evaluate_object(handle
, "_REG", &arg_list
, NULL
);
755 EXPORT_SYMBOL(acpi_evaluate_reg
);
758 * acpi_evaluate_dsm - evaluate device's _DSM method
759 * @handle: ACPI device handle
760 * @guid: GUID of requested functions, should be 16 bytes
761 * @rev: revision number of requested function
762 * @func: requested function number
763 * @argv4: the function specific parameter
765 * Evaluate device's _DSM method with specified GUID, revision id and
766 * function number. Caller needs to free the returned object.
768 * Though ACPI defines the fourth parameter for _DSM should be a package,
769 * some old BIOSes do expect a buffer or an integer etc.
772 acpi_evaluate_dsm(acpi_handle handle
, const guid_t
*guid
, u64 rev
, u64 func
,
773 union acpi_object
*argv4
)
776 struct acpi_buffer buf
= {ACPI_ALLOCATE_BUFFER
, NULL
};
777 union acpi_object params
[4];
778 struct acpi_object_list input
= {
783 params
[0].type
= ACPI_TYPE_BUFFER
;
784 params
[0].buffer
.length
= 16;
785 params
[0].buffer
.pointer
= (u8
*)guid
;
786 params
[1].type
= ACPI_TYPE_INTEGER
;
787 params
[1].integer
.value
= rev
;
788 params
[2].type
= ACPI_TYPE_INTEGER
;
789 params
[2].integer
.value
= func
;
793 params
[3].type
= ACPI_TYPE_PACKAGE
;
794 params
[3].package
.count
= 0;
795 params
[3].package
.elements
= NULL
;
798 ret
= acpi_evaluate_object(handle
, "_DSM", &input
, &buf
);
799 if (ACPI_SUCCESS(ret
))
800 return (union acpi_object
*)buf
.pointer
;
802 if (ret
!= AE_NOT_FOUND
)
803 acpi_handle_warn(handle
,
804 "failed to evaluate _DSM %pUb rev:%lld func:%lld (0x%x)\n",
805 guid
, rev
, func
, ret
);
809 EXPORT_SYMBOL(acpi_evaluate_dsm
);
812 * acpi_check_dsm - check if _DSM method supports requested functions.
813 * @handle: ACPI device handle
814 * @guid: GUID of requested functions, should be 16 bytes at least
815 * @rev: revision number of requested functions
816 * @funcs: bitmap of requested functions
818 * Evaluate device's _DSM method to check whether it supports requested
819 * functions. Currently only support 64 functions at maximum, should be
822 bool acpi_check_dsm(acpi_handle handle
, const guid_t
*guid
, u64 rev
, u64 funcs
)
826 union acpi_object
*obj
;
831 obj
= acpi_evaluate_dsm(handle
, guid
, rev
, 0, NULL
);
835 /* For compatibility, old BIOSes may return an integer */
836 if (obj
->type
== ACPI_TYPE_INTEGER
)
837 mask
= obj
->integer
.value
;
838 else if (obj
->type
== ACPI_TYPE_BUFFER
)
839 for (i
= 0; i
< obj
->buffer
.length
&& i
< 8; i
++)
840 mask
|= (((u64
)obj
->buffer
.pointer
[i
]) << (i
* 8));
844 * Bit 0 indicates whether there's support for any functions other than
845 * function 0 for the specified GUID and revision.
847 if ((mask
& 0x1) && (mask
& funcs
) == funcs
)
852 EXPORT_SYMBOL(acpi_check_dsm
);
855 * acpi_dev_uid_to_integer - treat ACPI device _UID as integer
856 * @adev: ACPI device to get _UID from
857 * @integer: output buffer for integer
859 * Considers _UID as integer and converts it to @integer.
861 * Returns 0 on success, or negative error code otherwise.
863 int acpi_dev_uid_to_integer(struct acpi_device
*adev
, u64
*integer
)
870 uid
= acpi_device_uid(adev
);
874 return kstrtou64(uid
, 0, integer
);
876 EXPORT_SYMBOL(acpi_dev_uid_to_integer
);
879 * acpi_dev_found - Detect presence of a given ACPI device in the namespace.
880 * @hid: Hardware ID of the device.
882 * Return %true if the device was present at the moment of invocation.
883 * Note that if the device is pluggable, it may since have disappeared.
885 * For this function to work, acpi_bus_scan() must have been executed
886 * which happens in the subsys_initcall() subsection. Hence, do not
887 * call from a subsys_initcall() or earlier (use acpi_get_devices()
888 * instead). Calling from module_init() is fine (which is synonymous
889 * with device_initcall()).
891 bool acpi_dev_found(const char *hid
)
893 struct acpi_device_bus_id
*acpi_device_bus_id
;
896 mutex_lock(&acpi_device_lock
);
897 list_for_each_entry(acpi_device_bus_id
, &acpi_bus_id_list
, node
)
898 if (!strcmp(acpi_device_bus_id
->bus_id
, hid
)) {
902 mutex_unlock(&acpi_device_lock
);
906 EXPORT_SYMBOL(acpi_dev_found
);
908 struct acpi_dev_match_info
{
909 struct acpi_device_id hid
[2];
914 static int acpi_dev_match_cb(struct device
*dev
, const void *data
)
916 struct acpi_device
*adev
= to_acpi_device(dev
);
917 const struct acpi_dev_match_info
*match
= data
;
918 unsigned long long hrv
;
921 if (acpi_match_device_ids(adev
, match
->hid
))
924 if (match
->uid
&& !acpi_dev_uid_match(adev
, match
->uid
))
927 if (match
->hrv
== -1)
930 status
= acpi_evaluate_integer(adev
->handle
, "_HRV", NULL
, &hrv
);
931 if (ACPI_FAILURE(status
))
934 return hrv
== match
->hrv
;
938 * acpi_dev_present - Detect that a given ACPI device is present
939 * @hid: Hardware ID of the device.
940 * @uid: Unique ID of the device, pass NULL to not check _UID
941 * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
943 * Return %true if a matching device was present at the moment of invocation.
944 * Note that if the device is pluggable, it may since have disappeared.
946 * Note that unlike acpi_dev_found() this function checks the status
947 * of the device. So for devices which are present in the DSDT, but
948 * which are disabled (their _STA callback returns 0) this function
951 * For this function to work, acpi_bus_scan() must have been executed
952 * which happens in the subsys_initcall() subsection. Hence, do not
953 * call from a subsys_initcall() or earlier (use acpi_get_devices()
954 * instead). Calling from module_init() is fine (which is synonymous
955 * with device_initcall()).
957 bool acpi_dev_present(const char *hid
, const char *uid
, s64 hrv
)
959 struct acpi_dev_match_info match
= {};
962 strscpy(match
.hid
[0].id
, hid
, sizeof(match
.hid
[0].id
));
966 dev
= bus_find_device(&acpi_bus_type
, NULL
, &match
, acpi_dev_match_cb
);
970 EXPORT_SYMBOL(acpi_dev_present
);
973 * acpi_dev_get_next_match_dev - Return the next match of ACPI device
974 * @adev: Pointer to the previous ACPI device matching this @hid, @uid and @hrv
975 * @hid: Hardware ID of the device.
976 * @uid: Unique ID of the device, pass NULL to not check _UID
977 * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
979 * Return the next match of ACPI device if another matching device was present
980 * at the moment of invocation, or NULL otherwise.
982 * The caller is responsible for invoking acpi_dev_put() on the returned device.
983 * On the other hand the function invokes acpi_dev_put() on the given @adev
984 * assuming that its reference counter had been increased beforehand.
986 * See additional information in acpi_dev_present() as well.
989 acpi_dev_get_next_match_dev(struct acpi_device
*adev
, const char *hid
, const char *uid
, s64 hrv
)
991 struct device
*start
= adev
? &adev
->dev
: NULL
;
992 struct acpi_dev_match_info match
= {};
995 strscpy(match
.hid
[0].id
, hid
, sizeof(match
.hid
[0].id
));
999 dev
= bus_find_device(&acpi_bus_type
, start
, &match
, acpi_dev_match_cb
);
1001 return dev
? to_acpi_device(dev
) : NULL
;
1003 EXPORT_SYMBOL(acpi_dev_get_next_match_dev
);
1006 * acpi_dev_get_first_match_dev - Return the first match of ACPI device
1007 * @hid: Hardware ID of the device.
1008 * @uid: Unique ID of the device, pass NULL to not check _UID
1009 * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
1011 * Return the first match of ACPI device if a matching device was present
1012 * at the moment of invocation, or NULL otherwise.
1014 * The caller is responsible for invoking acpi_dev_put() on the returned device.
1016 * See additional information in acpi_dev_present() as well.
1018 struct acpi_device
*
1019 acpi_dev_get_first_match_dev(const char *hid
, const char *uid
, s64 hrv
)
1021 return acpi_dev_get_next_match_dev(NULL
, hid
, uid
, hrv
);
1023 EXPORT_SYMBOL(acpi_dev_get_first_match_dev
);
1026 * acpi_reduced_hardware - Return if this is an ACPI-reduced-hw machine
1028 * Return true when running on an ACPI-reduced-hw machine, false otherwise.
1030 bool acpi_reduced_hardware(void)
1032 return acpi_gbl_reduced_hardware
;
1034 EXPORT_SYMBOL_GPL(acpi_reduced_hardware
);
1037 * acpi_backlight= handling, this is done here rather then in video_detect.c
1038 * because __setup cannot be used in modules.
1040 char acpi_video_backlight_string
[16];
1041 EXPORT_SYMBOL(acpi_video_backlight_string
);
1043 static int __init
acpi_backlight(char *str
)
1045 strscpy(acpi_video_backlight_string
, str
,
1046 sizeof(acpi_video_backlight_string
));
1049 __setup("acpi_backlight=", acpi_backlight
);
1052 * acpi_match_platform_list - Check if the system matches with a given list
1053 * @plat: pointer to acpi_platform_list table terminated by a NULL entry
1055 * Return the matched index if the system is found in the platform list.
1056 * Otherwise, return a negative error code.
1058 int acpi_match_platform_list(const struct acpi_platform_list
*plat
)
1060 struct acpi_table_header hdr
;
1066 for (; plat
->oem_id
[0]; plat
++, idx
++) {
1067 if (ACPI_FAILURE(acpi_get_table_header(plat
->table
, 0, &hdr
)))
1070 if (strncmp(plat
->oem_id
, hdr
.oem_id
, ACPI_OEM_ID_SIZE
))
1073 if (strncmp(plat
->oem_table_id
, hdr
.oem_table_id
, ACPI_OEM_TABLE_ID_SIZE
))
1076 if ((plat
->pred
== all_versions
) ||
1077 (plat
->pred
== less_than_or_equal
&& hdr
.oem_revision
<= plat
->oem_revision
) ||
1078 (plat
->pred
== greater_than_or_equal
&& hdr
.oem_revision
>= plat
->oem_revision
) ||
1079 (plat
->pred
== equal
&& hdr
.oem_revision
== plat
->oem_revision
))
1085 EXPORT_SYMBOL(acpi_match_platform_list
);