0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) "ACPI: utils: " fmt
0010
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/init.h>
0015 #include <linux/types.h>
0016 #include <linux/hardirq.h>
0017 #include <linux/acpi.h>
0018 #include <linux/dynamic_debug.h>
0019
0020 #include "internal.h"
0021 #include "sleep.h"
0022
0023
0024
0025
0026 static void acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s)
0027 {
0028 acpi_handle_debug(h, "Evaluate [%s]: %s\n", p, acpi_format_exception(s));
0029 }
0030
0031 acpi_status
0032 acpi_extract_package(union acpi_object *package,
0033 struct acpi_buffer *format, struct acpi_buffer *buffer)
0034 {
0035 u32 size_required = 0;
0036 u32 tail_offset = 0;
0037 char *format_string = NULL;
0038 u32 format_count = 0;
0039 u32 i = 0;
0040 u8 *head = NULL;
0041 u8 *tail = NULL;
0042
0043
0044 if (!package || (package->type != ACPI_TYPE_PACKAGE)
0045 || (package->package.count < 1)) {
0046 pr_debug("Invalid package argument\n");
0047 return AE_BAD_PARAMETER;
0048 }
0049
0050 if (!format || !format->pointer || (format->length < 1)) {
0051 pr_debug("Invalid format argument\n");
0052 return AE_BAD_PARAMETER;
0053 }
0054
0055 if (!buffer) {
0056 pr_debug("Invalid buffer argument\n");
0057 return AE_BAD_PARAMETER;
0058 }
0059
0060 format_count = (format->length / sizeof(char)) - 1;
0061 if (format_count > package->package.count) {
0062 pr_debug("Format specifies more objects [%d] than present [%d]\n",
0063 format_count, package->package.count);
0064 return AE_BAD_DATA;
0065 }
0066
0067 format_string = format->pointer;
0068
0069
0070
0071
0072 for (i = 0; i < format_count; i++) {
0073
0074 union acpi_object *element = &(package->package.elements[i]);
0075
0076 switch (element->type) {
0077
0078 case ACPI_TYPE_INTEGER:
0079 switch (format_string[i]) {
0080 case 'N':
0081 size_required += sizeof(u64);
0082 tail_offset += sizeof(u64);
0083 break;
0084 case 'S':
0085 size_required +=
0086 sizeof(char *) + sizeof(u64) +
0087 sizeof(char);
0088 tail_offset += sizeof(char *);
0089 break;
0090 default:
0091 pr_debug("Invalid package element [%d]: got number, expected [%c]\n",
0092 i, format_string[i]);
0093 return AE_BAD_DATA;
0094 }
0095 break;
0096
0097 case ACPI_TYPE_STRING:
0098 case ACPI_TYPE_BUFFER:
0099 switch (format_string[i]) {
0100 case 'S':
0101 size_required +=
0102 sizeof(char *) +
0103 (element->string.length * sizeof(char)) +
0104 sizeof(char);
0105 tail_offset += sizeof(char *);
0106 break;
0107 case 'B':
0108 size_required +=
0109 sizeof(u8 *) + element->buffer.length;
0110 tail_offset += sizeof(u8 *);
0111 break;
0112 default:
0113 pr_debug("Invalid package element [%d] got string/buffer, expected [%c]\n",
0114 i, format_string[i]);
0115 return AE_BAD_DATA;
0116 }
0117 break;
0118 case ACPI_TYPE_LOCAL_REFERENCE:
0119 switch (format_string[i]) {
0120 case 'R':
0121 size_required += sizeof(void *);
0122 tail_offset += sizeof(void *);
0123 break;
0124 default:
0125 pr_debug("Invalid package element [%d] got reference, expected [%c]\n",
0126 i, format_string[i]);
0127 return AE_BAD_DATA;
0128 }
0129 break;
0130
0131 case ACPI_TYPE_PACKAGE:
0132 default:
0133 pr_debug("Unsupported element at index=%d\n", i);
0134
0135 return AE_SUPPORT;
0136 }
0137 }
0138
0139
0140
0141
0142 if (buffer->length == ACPI_ALLOCATE_BUFFER) {
0143 buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required);
0144 if (!buffer->pointer)
0145 return AE_NO_MEMORY;
0146 buffer->length = size_required;
0147 } else {
0148 if (buffer->length < size_required) {
0149 buffer->length = size_required;
0150 return AE_BUFFER_OVERFLOW;
0151 } else if (buffer->length != size_required ||
0152 !buffer->pointer) {
0153 return AE_BAD_PARAMETER;
0154 }
0155 }
0156
0157 head = buffer->pointer;
0158 tail = buffer->pointer + tail_offset;
0159
0160
0161
0162
0163 for (i = 0; i < format_count; i++) {
0164
0165 u8 **pointer = NULL;
0166 union acpi_object *element = &(package->package.elements[i]);
0167
0168 switch (element->type) {
0169
0170 case ACPI_TYPE_INTEGER:
0171 switch (format_string[i]) {
0172 case 'N':
0173 *((u64 *) head) =
0174 element->integer.value;
0175 head += sizeof(u64);
0176 break;
0177 case 'S':
0178 pointer = (u8 **) head;
0179 *pointer = tail;
0180 *((u64 *) tail) =
0181 element->integer.value;
0182 head += sizeof(u64 *);
0183 tail += sizeof(u64);
0184
0185 *tail = (char)0;
0186 tail += sizeof(char);
0187 break;
0188 default:
0189
0190 break;
0191 }
0192 break;
0193
0194 case ACPI_TYPE_STRING:
0195 case ACPI_TYPE_BUFFER:
0196 switch (format_string[i]) {
0197 case 'S':
0198 pointer = (u8 **) head;
0199 *pointer = tail;
0200 memcpy(tail, element->string.pointer,
0201 element->string.length);
0202 head += sizeof(char *);
0203 tail += element->string.length * sizeof(char);
0204
0205 *tail = (char)0;
0206 tail += sizeof(char);
0207 break;
0208 case 'B':
0209 pointer = (u8 **) head;
0210 *pointer = tail;
0211 memcpy(tail, element->buffer.pointer,
0212 element->buffer.length);
0213 head += sizeof(u8 *);
0214 tail += element->buffer.length;
0215 break;
0216 default:
0217
0218 break;
0219 }
0220 break;
0221 case ACPI_TYPE_LOCAL_REFERENCE:
0222 switch (format_string[i]) {
0223 case 'R':
0224 *(void **)head =
0225 (void *)element->reference.handle;
0226 head += sizeof(void *);
0227 break;
0228 default:
0229
0230 break;
0231 }
0232 break;
0233 case ACPI_TYPE_PACKAGE:
0234
0235 default:
0236
0237 break;
0238 }
0239 }
0240
0241 return AE_OK;
0242 }
0243
0244 EXPORT_SYMBOL(acpi_extract_package);
0245
0246 acpi_status
0247 acpi_evaluate_integer(acpi_handle handle,
0248 acpi_string pathname,
0249 struct acpi_object_list *arguments, unsigned long long *data)
0250 {
0251 acpi_status status = AE_OK;
0252 union acpi_object element;
0253 struct acpi_buffer buffer = { 0, NULL };
0254
0255 if (!data)
0256 return AE_BAD_PARAMETER;
0257
0258 buffer.length = sizeof(union acpi_object);
0259 buffer.pointer = &element;
0260 status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
0261 if (ACPI_FAILURE(status)) {
0262 acpi_util_eval_error(handle, pathname, status);
0263 return status;
0264 }
0265
0266 if (element.type != ACPI_TYPE_INTEGER) {
0267 acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
0268 return AE_BAD_DATA;
0269 }
0270
0271 *data = element.integer.value;
0272
0273 acpi_handle_debug(handle, "Return value [%llu]\n", *data);
0274
0275 return AE_OK;
0276 }
0277
0278 EXPORT_SYMBOL(acpi_evaluate_integer);
0279
0280 int acpi_get_local_address(acpi_handle handle, u32 *addr)
0281 {
0282 unsigned long long adr;
0283 acpi_status status;
0284
0285 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
0286 if (ACPI_FAILURE(status))
0287 return -ENODATA;
0288
0289 *addr = (u32)adr;
0290 return 0;
0291 }
0292 EXPORT_SYMBOL(acpi_get_local_address);
0293
0294 #define ACPI_MAX_SUB_BUF_SIZE 9
0295
0296 const char *acpi_get_subsystem_id(acpi_handle handle)
0297 {
0298 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0299 union acpi_object *obj;
0300 acpi_status status;
0301 const char *sub;
0302 size_t len;
0303
0304 status = acpi_evaluate_object(handle, METHOD_NAME__SUB, NULL, &buffer);
0305 if (ACPI_FAILURE(status)) {
0306 acpi_handle_debug(handle, "Reading ACPI _SUB failed: %#x\n", status);
0307 return ERR_PTR(-ENODATA);
0308 }
0309
0310 obj = buffer.pointer;
0311 if (obj->type == ACPI_TYPE_STRING) {
0312 len = strlen(obj->string.pointer);
0313 if (len < ACPI_MAX_SUB_BUF_SIZE && len > 0) {
0314 sub = kstrdup(obj->string.pointer, GFP_KERNEL);
0315 if (!sub)
0316 sub = ERR_PTR(-ENOMEM);
0317 } else {
0318 acpi_handle_err(handle, "ACPI _SUB Length %zu is Invalid\n", len);
0319 sub = ERR_PTR(-ENODATA);
0320 }
0321 } else {
0322 acpi_handle_warn(handle, "Warning ACPI _SUB did not return a string\n");
0323 sub = ERR_PTR(-ENODATA);
0324 }
0325
0326 acpi_os_free(buffer.pointer);
0327
0328 return sub;
0329 }
0330 EXPORT_SYMBOL_GPL(acpi_get_subsystem_id);
0331
0332 acpi_status
0333 acpi_evaluate_reference(acpi_handle handle,
0334 acpi_string pathname,
0335 struct acpi_object_list *arguments,
0336 struct acpi_handle_list *list)
0337 {
0338 acpi_status status = AE_OK;
0339 union acpi_object *package = NULL;
0340 union acpi_object *element = NULL;
0341 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0342 u32 i = 0;
0343
0344
0345 if (!list) {
0346 return AE_BAD_PARAMETER;
0347 }
0348
0349
0350
0351 status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
0352 if (ACPI_FAILURE(status))
0353 goto end;
0354
0355 package = buffer.pointer;
0356
0357 if ((buffer.length == 0) || !package) {
0358 status = AE_BAD_DATA;
0359 acpi_util_eval_error(handle, pathname, status);
0360 goto end;
0361 }
0362 if (package->type != ACPI_TYPE_PACKAGE) {
0363 status = AE_BAD_DATA;
0364 acpi_util_eval_error(handle, pathname, status);
0365 goto end;
0366 }
0367 if (!package->package.count) {
0368 status = AE_BAD_DATA;
0369 acpi_util_eval_error(handle, pathname, status);
0370 goto end;
0371 }
0372
0373 if (package->package.count > ACPI_MAX_HANDLES) {
0374 kfree(package);
0375 return AE_NO_MEMORY;
0376 }
0377 list->count = package->package.count;
0378
0379
0380
0381 for (i = 0; i < list->count; i++) {
0382
0383 element = &(package->package.elements[i]);
0384
0385 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
0386 status = AE_BAD_DATA;
0387 acpi_util_eval_error(handle, pathname, status);
0388 break;
0389 }
0390
0391 if (!element->reference.handle) {
0392 status = AE_NULL_ENTRY;
0393 acpi_util_eval_error(handle, pathname, status);
0394 break;
0395 }
0396
0397
0398 list->handles[i] = element->reference.handle;
0399 acpi_handle_debug(list->handles[i], "Found in reference list\n");
0400 }
0401
0402 end:
0403 if (ACPI_FAILURE(status)) {
0404 list->count = 0;
0405
0406 }
0407
0408 kfree(buffer.pointer);
0409
0410 return status;
0411 }
0412
0413 EXPORT_SYMBOL(acpi_evaluate_reference);
0414
0415 acpi_status
0416 acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
0417 {
0418 acpi_status status;
0419 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0420 union acpi_object *output;
0421
0422 status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer);
0423
0424 if (ACPI_FAILURE(status))
0425 return status;
0426
0427 output = buffer.pointer;
0428
0429 if (!output || output->type != ACPI_TYPE_PACKAGE
0430 || !output->package.count
0431 || output->package.elements[0].type != ACPI_TYPE_BUFFER
0432 || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
0433 status = AE_TYPE;
0434 goto out;
0435 }
0436
0437 status = acpi_decode_pld_buffer(
0438 output->package.elements[0].buffer.pointer,
0439 output->package.elements[0].buffer.length,
0440 pld);
0441
0442 out:
0443 kfree(buffer.pointer);
0444 return status;
0445 }
0446 EXPORT_SYMBOL(acpi_get_physical_device_location);
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 acpi_status
0460 acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
0461 struct acpi_buffer *status_buf)
0462 {
0463 union acpi_object params[3] = {
0464 {.type = ACPI_TYPE_INTEGER,},
0465 {.type = ACPI_TYPE_INTEGER,},
0466 {.type = ACPI_TYPE_BUFFER,}
0467 };
0468 struct acpi_object_list arg_list = {3, params};
0469
0470 params[0].integer.value = source_event;
0471 params[1].integer.value = status_code;
0472 if (status_buf != NULL) {
0473 params[2].buffer.pointer = status_buf->pointer;
0474 params[2].buffer.length = status_buf->length;
0475 } else {
0476 params[2].buffer.pointer = NULL;
0477 params[2].buffer.length = 0;
0478 }
0479
0480 return acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
0481 }
0482 EXPORT_SYMBOL(acpi_evaluate_ost);
0483
0484
0485
0486
0487
0488
0489
0490 static char *acpi_handle_path(acpi_handle handle)
0491 {
0492 struct acpi_buffer buffer = {
0493 .length = ACPI_ALLOCATE_BUFFER,
0494 .pointer = NULL
0495 };
0496
0497 if (in_interrupt() ||
0498 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK)
0499 return NULL;
0500 return buffer.pointer;
0501 }
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514 void
0515 acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...)
0516 {
0517 struct va_format vaf;
0518 va_list args;
0519 const char *path;
0520
0521 va_start(args, fmt);
0522 vaf.fmt = fmt;
0523 vaf.va = &args;
0524
0525 path = acpi_handle_path(handle);
0526 printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf);
0527
0528 va_end(args);
0529 kfree(path);
0530 }
0531 EXPORT_SYMBOL(acpi_handle_printk);
0532
0533 #if defined(CONFIG_DYNAMIC_DEBUG)
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545 void
0546 __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle,
0547 const char *fmt, ...)
0548 {
0549 struct va_format vaf;
0550 va_list args;
0551 const char *path;
0552
0553 va_start(args, fmt);
0554 vaf.fmt = fmt;
0555 vaf.va = &args;
0556
0557 path = acpi_handle_path(handle);
0558 __dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf);
0559
0560 va_end(args);
0561 kfree(path);
0562 }
0563 EXPORT_SYMBOL(__acpi_handle_debug);
0564 #endif
0565
0566
0567
0568
0569
0570
0571
0572 void acpi_evaluation_failure_warn(acpi_handle handle, const char *name,
0573 acpi_status status)
0574 {
0575 acpi_handle_warn(handle, "%s evaluation failed: %s\n", name,
0576 acpi_format_exception(status));
0577 }
0578 EXPORT_SYMBOL_GPL(acpi_evaluation_failure_warn);
0579
0580
0581
0582
0583
0584
0585
0586
0587 bool acpi_has_method(acpi_handle handle, char *name)
0588 {
0589 acpi_handle tmp;
0590
0591 return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp));
0592 }
0593 EXPORT_SYMBOL(acpi_has_method);
0594
0595 acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
0596 u64 arg)
0597 {
0598 union acpi_object obj = { .type = ACPI_TYPE_INTEGER };
0599 struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, };
0600
0601 obj.integer.value = arg;
0602
0603 return acpi_evaluate_object(handle, method, &arg_list, NULL);
0604 }
0605 EXPORT_SYMBOL(acpi_execute_simple_method);
0606
0607
0608
0609
0610
0611
0612
0613 acpi_status acpi_evaluate_ej0(acpi_handle handle)
0614 {
0615 acpi_status status;
0616
0617 status = acpi_execute_simple_method(handle, "_EJ0", 1);
0618 if (status == AE_NOT_FOUND)
0619 acpi_handle_warn(handle, "No _EJ0 support for device\n");
0620 else if (ACPI_FAILURE(status))
0621 acpi_handle_warn(handle, "Eject failed (0x%x)\n", status);
0622
0623 return status;
0624 }
0625
0626
0627
0628
0629
0630
0631
0632
0633 acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
0634 {
0635 acpi_status status;
0636
0637 status = acpi_execute_simple_method(handle, "_LCK", !!lock);
0638 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
0639 if (lock)
0640 acpi_handle_warn(handle,
0641 "Locking device failed (0x%x)\n", status);
0642 else
0643 acpi_handle_warn(handle,
0644 "Unlocking device failed (0x%x)\n", status);
0645 }
0646
0647 return status;
0648 }
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659 acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function)
0660 {
0661 struct acpi_object_list arg_list;
0662 union acpi_object params[2];
0663
0664 params[0].type = ACPI_TYPE_INTEGER;
0665 params[0].integer.value = space_id;
0666 params[1].type = ACPI_TYPE_INTEGER;
0667 params[1].integer.value = function;
0668 arg_list.count = 2;
0669 arg_list.pointer = params;
0670
0671 return acpi_evaluate_object(handle, "_REG", &arg_list, NULL);
0672 }
0673 EXPORT_SYMBOL(acpi_evaluate_reg);
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689 union acpi_object *
0690 acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 func,
0691 union acpi_object *argv4)
0692 {
0693 acpi_status ret;
0694 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
0695 union acpi_object params[4];
0696 struct acpi_object_list input = {
0697 .count = 4,
0698 .pointer = params,
0699 };
0700
0701 params[0].type = ACPI_TYPE_BUFFER;
0702 params[0].buffer.length = 16;
0703 params[0].buffer.pointer = (u8 *)guid;
0704 params[1].type = ACPI_TYPE_INTEGER;
0705 params[1].integer.value = rev;
0706 params[2].type = ACPI_TYPE_INTEGER;
0707 params[2].integer.value = func;
0708 if (argv4) {
0709 params[3] = *argv4;
0710 } else {
0711 params[3].type = ACPI_TYPE_PACKAGE;
0712 params[3].package.count = 0;
0713 params[3].package.elements = NULL;
0714 }
0715
0716 ret = acpi_evaluate_object(handle, "_DSM", &input, &buf);
0717 if (ACPI_SUCCESS(ret))
0718 return (union acpi_object *)buf.pointer;
0719
0720 if (ret != AE_NOT_FOUND)
0721 acpi_handle_warn(handle,
0722 "failed to evaluate _DSM %pUb (0x%x)\n", guid, ret);
0723
0724 return NULL;
0725 }
0726 EXPORT_SYMBOL(acpi_evaluate_dsm);
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739 bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs)
0740 {
0741 int i;
0742 u64 mask = 0;
0743 union acpi_object *obj;
0744
0745 if (funcs == 0)
0746 return false;
0747
0748 obj = acpi_evaluate_dsm(handle, guid, rev, 0, NULL);
0749 if (!obj)
0750 return false;
0751
0752
0753 if (obj->type == ACPI_TYPE_INTEGER)
0754 mask = obj->integer.value;
0755 else if (obj->type == ACPI_TYPE_BUFFER)
0756 for (i = 0; i < obj->buffer.length && i < 8; i++)
0757 mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));
0758 ACPI_FREE(obj);
0759
0760
0761
0762
0763
0764 if ((mask & 0x1) && (mask & funcs) == funcs)
0765 return true;
0766
0767 return false;
0768 }
0769 EXPORT_SYMBOL(acpi_check_dsm);
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780 bool acpi_dev_hid_uid_match(struct acpi_device *adev,
0781 const char *hid2, const char *uid2)
0782 {
0783 const char *hid1 = acpi_device_hid(adev);
0784 const char *uid1 = acpi_device_uid(adev);
0785
0786 if (strcmp(hid1, hid2))
0787 return false;
0788
0789 if (!uid2)
0790 return true;
0791
0792 return uid1 && !strcmp(uid1, uid2);
0793 }
0794 EXPORT_SYMBOL(acpi_dev_hid_uid_match);
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809 bool acpi_dev_found(const char *hid)
0810 {
0811 struct acpi_device_bus_id *acpi_device_bus_id;
0812 bool found = false;
0813
0814 mutex_lock(&acpi_device_lock);
0815 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
0816 if (!strcmp(acpi_device_bus_id->bus_id, hid)) {
0817 found = true;
0818 break;
0819 }
0820 mutex_unlock(&acpi_device_lock);
0821
0822 return found;
0823 }
0824 EXPORT_SYMBOL(acpi_dev_found);
0825
0826 struct acpi_dev_match_info {
0827 struct acpi_device_id hid[2];
0828 const char *uid;
0829 s64 hrv;
0830 };
0831
0832 static int acpi_dev_match_cb(struct device *dev, const void *data)
0833 {
0834 struct acpi_device *adev = to_acpi_device(dev);
0835 const struct acpi_dev_match_info *match = data;
0836 unsigned long long hrv;
0837 acpi_status status;
0838
0839 if (acpi_match_device_ids(adev, match->hid))
0840 return 0;
0841
0842 if (match->uid && (!adev->pnp.unique_id ||
0843 strcmp(adev->pnp.unique_id, match->uid)))
0844 return 0;
0845
0846 if (match->hrv == -1)
0847 return 1;
0848
0849 status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv);
0850 if (ACPI_FAILURE(status))
0851 return 0;
0852
0853 return hrv == match->hrv;
0854 }
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876 bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
0877 {
0878 struct acpi_dev_match_info match = {};
0879 struct device *dev;
0880
0881 strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
0882 match.uid = uid;
0883 match.hrv = hrv;
0884
0885 dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb);
0886 put_device(dev);
0887 return !!dev;
0888 }
0889 EXPORT_SYMBOL(acpi_dev_present);
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907 struct acpi_device *
0908 acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv)
0909 {
0910 struct device *start = adev ? &adev->dev : NULL;
0911 struct acpi_dev_match_info match = {};
0912 struct device *dev;
0913
0914 strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
0915 match.uid = uid;
0916 match.hrv = hrv;
0917
0918 dev = bus_find_device(&acpi_bus_type, start, &match, acpi_dev_match_cb);
0919 acpi_dev_put(adev);
0920 return dev ? to_acpi_device(dev) : NULL;
0921 }
0922 EXPORT_SYMBOL(acpi_dev_get_next_match_dev);
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937 struct acpi_device *
0938 acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
0939 {
0940 return acpi_dev_get_next_match_dev(NULL, hid, uid, hrv);
0941 }
0942 EXPORT_SYMBOL(acpi_dev_get_first_match_dev);
0943
0944
0945
0946
0947
0948
0949 bool acpi_reduced_hardware(void)
0950 {
0951 return acpi_gbl_reduced_hardware;
0952 }
0953 EXPORT_SYMBOL_GPL(acpi_reduced_hardware);
0954
0955
0956
0957
0958
0959 char acpi_video_backlight_string[16];
0960 EXPORT_SYMBOL(acpi_video_backlight_string);
0961
0962 static int __init acpi_backlight(char *str)
0963 {
0964 strlcpy(acpi_video_backlight_string, str,
0965 sizeof(acpi_video_backlight_string));
0966 return 1;
0967 }
0968 __setup("acpi_backlight=", acpi_backlight);
0969
0970
0971
0972
0973
0974
0975
0976
0977 int acpi_match_platform_list(const struct acpi_platform_list *plat)
0978 {
0979 struct acpi_table_header hdr;
0980 int idx = 0;
0981
0982 if (acpi_disabled)
0983 return -ENODEV;
0984
0985 for (; plat->oem_id[0]; plat++, idx++) {
0986 if (ACPI_FAILURE(acpi_get_table_header(plat->table, 0, &hdr)))
0987 continue;
0988
0989 if (strncmp(plat->oem_id, hdr.oem_id, ACPI_OEM_ID_SIZE))
0990 continue;
0991
0992 if (strncmp(plat->oem_table_id, hdr.oem_table_id, ACPI_OEM_TABLE_ID_SIZE))
0993 continue;
0994
0995 if ((plat->pred == all_versions) ||
0996 (plat->pred == less_than_or_equal && hdr.oem_revision <= plat->oem_revision) ||
0997 (plat->pred == greater_than_or_equal && hdr.oem_revision >= plat->oem_revision) ||
0998 (plat->pred == equal && hdr.oem_revision == plat->oem_revision))
0999 return idx;
1000 }
1001
1002 return -ENODEV;
1003 }
1004 EXPORT_SYMBOL(acpi_match_platform_list);