Linux-libre 4.5-gnu
[librecmc/linux-libre.git] / drivers / acpi / utils.c
1 /*
2  *  acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
3  *
4  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6  *
7  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or (at
12  *  your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful, but
15  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  General Public License for more details.
18  *
19  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/init.h>
26 #include <linux/types.h>
27 #include <linux/hardirq.h>
28 #include <linux/acpi.h>
29 #include <linux/dynamic_debug.h>
30
31 #include "internal.h"
32 #include "sleep.h"
33
34 #define _COMPONENT              ACPI_BUS_COMPONENT
35 ACPI_MODULE_NAME("utils");
36
37 /* --------------------------------------------------------------------------
38                             Object Evaluation Helpers
39    -------------------------------------------------------------------------- */
40 static void
41 acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s)
42 {
43 #ifdef ACPI_DEBUG_OUTPUT
44         char prefix[80] = {'\0'};
45         struct acpi_buffer buffer = {sizeof(prefix), prefix};
46         acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);
47         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",
48                 (char *) prefix, p, acpi_format_exception(s)));
49 #else
50         return;
51 #endif
52 }
53
54 acpi_status
55 acpi_extract_package(union acpi_object *package,
56                      struct acpi_buffer *format, struct acpi_buffer *buffer)
57 {
58         u32 size_required = 0;
59         u32 tail_offset = 0;
60         char *format_string = NULL;
61         u32 format_count = 0;
62         u32 i = 0;
63         u8 *head = NULL;
64         u8 *tail = NULL;
65
66
67         if (!package || (package->type != ACPI_TYPE_PACKAGE)
68             || (package->package.count < 1)) {
69                 printk(KERN_WARNING PREFIX "Invalid package argument\n");
70                 return AE_BAD_PARAMETER;
71         }
72
73         if (!format || !format->pointer || (format->length < 1)) {
74                 printk(KERN_WARNING PREFIX "Invalid format argument\n");
75                 return AE_BAD_PARAMETER;
76         }
77
78         if (!buffer) {
79                 printk(KERN_WARNING PREFIX "Invalid buffer argument\n");
80                 return AE_BAD_PARAMETER;
81         }
82
83         format_count = (format->length / sizeof(char)) - 1;
84         if (format_count > package->package.count) {
85                 printk(KERN_WARNING PREFIX "Format specifies more objects [%d]"
86                               " than exist in package [%d].\n",
87                               format_count, package->package.count);
88                 return AE_BAD_DATA;
89         }
90
91         format_string = format->pointer;
92
93         /*
94          * Calculate size_required.
95          */
96         for (i = 0; i < format_count; i++) {
97
98                 union acpi_object *element = &(package->package.elements[i]);
99
100                 switch (element->type) {
101
102                 case ACPI_TYPE_INTEGER:
103                         switch (format_string[i]) {
104                         case 'N':
105                                 size_required += sizeof(u64);
106                                 tail_offset += sizeof(u64);
107                                 break;
108                         case 'S':
109                                 size_required +=
110                                     sizeof(char *) + sizeof(u64) +
111                                     sizeof(char);
112                                 tail_offset += sizeof(char *);
113                                 break;
114                         default:
115                                 printk(KERN_WARNING PREFIX "Invalid package element"
116                                               " [%d]: got number, expecting"
117                                               " [%c]\n",
118                                               i, format_string[i]);
119                                 return AE_BAD_DATA;
120                                 break;
121                         }
122                         break;
123
124                 case ACPI_TYPE_STRING:
125                 case ACPI_TYPE_BUFFER:
126                         switch (format_string[i]) {
127                         case 'S':
128                                 size_required +=
129                                     sizeof(char *) +
130                                     (element->string.length * sizeof(char)) +
131                                     sizeof(char);
132                                 tail_offset += sizeof(char *);
133                                 break;
134                         case 'B':
135                                 size_required +=
136                                     sizeof(u8 *) + element->buffer.length;
137                                 tail_offset += sizeof(u8 *);
138                                 break;
139                         default:
140                                 printk(KERN_WARNING PREFIX "Invalid package element"
141                                               " [%d] got string/buffer,"
142                                               " expecting [%c]\n",
143                                               i, format_string[i]);
144                                 return AE_BAD_DATA;
145                                 break;
146                         }
147                         break;
148                 case ACPI_TYPE_LOCAL_REFERENCE:
149                         switch (format_string[i]) {
150                         case 'R':
151                                 size_required += sizeof(void *);
152                                 tail_offset += sizeof(void *);
153                                 break;
154                         default:
155                                 printk(KERN_WARNING PREFIX "Invalid package element"
156                                               " [%d] got reference,"
157                                               " expecting [%c]\n",
158                                               i, format_string[i]);
159                                 return AE_BAD_DATA;
160                                 break;
161                         }
162                         break;
163
164                 case ACPI_TYPE_PACKAGE:
165                 default:
166                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
167                                           "Found unsupported element at index=%d\n",
168                                           i));
169                         /* TBD: handle nested packages... */
170                         return AE_SUPPORT;
171                         break;
172                 }
173         }
174
175         /*
176          * Validate output buffer.
177          */
178         if (buffer->length == ACPI_ALLOCATE_BUFFER) {
179                 buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required);
180                 if (!buffer->pointer)
181                         return AE_NO_MEMORY;
182                 buffer->length = size_required;
183         } else {
184                 if (buffer->length < size_required) {
185                         buffer->length = size_required;
186                         return AE_BUFFER_OVERFLOW;
187                 } else if (buffer->length != size_required ||
188                            !buffer->pointer) {
189                         return AE_BAD_PARAMETER;
190                 }
191         }
192
193         head = buffer->pointer;
194         tail = buffer->pointer + tail_offset;
195
196         /*
197          * Extract package data.
198          */
199         for (i = 0; i < format_count; i++) {
200
201                 u8 **pointer = NULL;
202                 union acpi_object *element = &(package->package.elements[i]);
203
204                 if (!element) {
205                         return AE_BAD_DATA;
206                 }
207
208                 switch (element->type) {
209
210                 case ACPI_TYPE_INTEGER:
211                         switch (format_string[i]) {
212                         case 'N':
213                                 *((u64 *) head) =
214                                     element->integer.value;
215                                 head += sizeof(u64);
216                                 break;
217                         case 'S':
218                                 pointer = (u8 **) head;
219                                 *pointer = tail;
220                                 *((u64 *) tail) =
221                                     element->integer.value;
222                                 head += sizeof(u64 *);
223                                 tail += sizeof(u64);
224                                 /* NULL terminate string */
225                                 *tail = (char)0;
226                                 tail += sizeof(char);
227                                 break;
228                         default:
229                                 /* Should never get here */
230                                 break;
231                         }
232                         break;
233
234                 case ACPI_TYPE_STRING:
235                 case ACPI_TYPE_BUFFER:
236                         switch (format_string[i]) {
237                         case 'S':
238                                 pointer = (u8 **) head;
239                                 *pointer = tail;
240                                 memcpy(tail, element->string.pointer,
241                                        element->string.length);
242                                 head += sizeof(char *);
243                                 tail += element->string.length * sizeof(char);
244                                 /* NULL terminate string */
245                                 *tail = (char)0;
246                                 tail += sizeof(char);
247                                 break;
248                         case 'B':
249                                 pointer = (u8 **) head;
250                                 *pointer = tail;
251                                 memcpy(tail, element->buffer.pointer,
252                                        element->buffer.length);
253                                 head += sizeof(u8 *);
254                                 tail += element->buffer.length;
255                                 break;
256                         default:
257                                 /* Should never get here */
258                                 break;
259                         }
260                         break;
261                 case ACPI_TYPE_LOCAL_REFERENCE:
262                         switch (format_string[i]) {
263                         case 'R':
264                                 *(void **)head =
265                                     (void *)element->reference.handle;
266                                 head += sizeof(void *);
267                                 break;
268                         default:
269                                 /* Should never get here */
270                                 break;
271                         }
272                         break;
273                 case ACPI_TYPE_PACKAGE:
274                         /* TBD: handle nested packages... */
275                 default:
276                         /* Should never get here */
277                         break;
278                 }
279         }
280
281         return AE_OK;
282 }
283
284 EXPORT_SYMBOL(acpi_extract_package);
285
286 acpi_status
287 acpi_evaluate_integer(acpi_handle handle,
288                       acpi_string pathname,
289                       struct acpi_object_list *arguments, unsigned long long *data)
290 {
291         acpi_status status = AE_OK;
292         union acpi_object element;
293         struct acpi_buffer buffer = { 0, NULL };
294
295         if (!data)
296                 return AE_BAD_PARAMETER;
297
298         buffer.length = sizeof(union acpi_object);
299         buffer.pointer = &element;
300         status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
301         if (ACPI_FAILURE(status)) {
302                 acpi_util_eval_error(handle, pathname, status);
303                 return status;
304         }
305
306         if (element.type != ACPI_TYPE_INTEGER) {
307                 acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
308                 return AE_BAD_DATA;
309         }
310
311         *data = element.integer.value;
312
313         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
314
315         return AE_OK;
316 }
317
318 EXPORT_SYMBOL(acpi_evaluate_integer);
319
320 acpi_status
321 acpi_evaluate_reference(acpi_handle handle,
322                         acpi_string pathname,
323                         struct acpi_object_list *arguments,
324                         struct acpi_handle_list *list)
325 {
326         acpi_status status = AE_OK;
327         union acpi_object *package = NULL;
328         union acpi_object *element = NULL;
329         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
330         u32 i = 0;
331
332
333         if (!list) {
334                 return AE_BAD_PARAMETER;
335         }
336
337         /* Evaluate object. */
338
339         status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
340         if (ACPI_FAILURE(status))
341                 goto end;
342
343         package = buffer.pointer;
344
345         if ((buffer.length == 0) || !package) {
346                 status = AE_BAD_DATA;
347                 acpi_util_eval_error(handle, pathname, status);
348                 goto end;
349         }
350         if (package->type != ACPI_TYPE_PACKAGE) {
351                 status = AE_BAD_DATA;
352                 acpi_util_eval_error(handle, pathname, status);
353                 goto end;
354         }
355         if (!package->package.count) {
356                 status = AE_BAD_DATA;
357                 acpi_util_eval_error(handle, pathname, status);
358                 goto end;
359         }
360
361         if (package->package.count > ACPI_MAX_HANDLES) {
362                 return AE_NO_MEMORY;
363         }
364         list->count = package->package.count;
365
366         /* Extract package data. */
367
368         for (i = 0; i < list->count; i++) {
369
370                 element = &(package->package.elements[i]);
371
372                 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
373                         status = AE_BAD_DATA;
374                         acpi_util_eval_error(handle, pathname, status);
375                         break;
376                 }
377
378                 if (!element->reference.handle) {
379                         status = AE_NULL_ENTRY;
380                         acpi_util_eval_error(handle, pathname, status);
381                         break;
382                 }
383                 /* Get the  acpi_handle. */
384
385                 list->handles[i] = element->reference.handle;
386                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n",
387                                   list->handles[i]));
388         }
389
390       end:
391         if (ACPI_FAILURE(status)) {
392                 list->count = 0;
393                 //kfree(list->handles);
394         }
395
396         kfree(buffer.pointer);
397
398         return status;
399 }
400
401 EXPORT_SYMBOL(acpi_evaluate_reference);
402
403 acpi_status
404 acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
405 {
406         acpi_status status;
407         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
408         union acpi_object *output;
409
410         status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer);
411
412         if (ACPI_FAILURE(status))
413                 return status;
414
415         output = buffer.pointer;
416
417         if (!output || output->type != ACPI_TYPE_PACKAGE
418             || !output->package.count
419             || output->package.elements[0].type != ACPI_TYPE_BUFFER
420             || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
421                 status = AE_TYPE;
422                 goto out;
423         }
424
425         status = acpi_decode_pld_buffer(
426                         output->package.elements[0].buffer.pointer,
427                         output->package.elements[0].buffer.length,
428                         pld);
429
430 out:
431         kfree(buffer.pointer);
432         return status;
433 }
434 EXPORT_SYMBOL(acpi_get_physical_device_location);
435
436 /**
437  * acpi_evaluate_ost: Evaluate _OST for hotplug operations
438  * @handle: ACPI device handle
439  * @source_event: source event code
440  * @status_code: status code
441  * @status_buf: optional detailed information (NULL if none)
442  *
443  * Evaluate _OST for hotplug operations. All ACPI hotplug handlers
444  * must call this function when evaluating _OST for hotplug operations.
445  * When the platform does not support _OST, this function has no effect.
446  */
447 acpi_status
448 acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
449                   struct acpi_buffer *status_buf)
450 {
451         union acpi_object params[3] = {
452                 {.type = ACPI_TYPE_INTEGER,},
453                 {.type = ACPI_TYPE_INTEGER,},
454                 {.type = ACPI_TYPE_BUFFER,}
455         };
456         struct acpi_object_list arg_list = {3, params};
457
458         params[0].integer.value = source_event;
459         params[1].integer.value = status_code;
460         if (status_buf != NULL) {
461                 params[2].buffer.pointer = status_buf->pointer;
462                 params[2].buffer.length = status_buf->length;
463         } else {
464                 params[2].buffer.pointer = NULL;
465                 params[2].buffer.length = 0;
466         }
467
468         return acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
469 }
470 EXPORT_SYMBOL(acpi_evaluate_ost);
471
472 /**
473  * acpi_handle_path: Return the object path of handle
474  *
475  * Caller must free the returned buffer
476  */
477 static char *acpi_handle_path(acpi_handle handle)
478 {
479         struct acpi_buffer buffer = {
480                 .length = ACPI_ALLOCATE_BUFFER,
481                 .pointer = NULL
482         };
483
484         if (in_interrupt() ||
485             acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK)
486                 return NULL;
487         return buffer.pointer;
488 }
489
490 /**
491  * acpi_handle_printk: Print message with ACPI prefix and object path
492  *
493  * This function is called through acpi_handle_<level> macros and prints
494  * a message with ACPI prefix and object path.  This function acquires
495  * the global namespace mutex to obtain an object path.  In interrupt
496  * context, it shows the object path as <n/a>.
497  */
498 void
499 acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...)
500 {
501         struct va_format vaf;
502         va_list args;
503         const char *path;
504
505         va_start(args, fmt);
506         vaf.fmt = fmt;
507         vaf.va = &args;
508
509         path = acpi_handle_path(handle);
510         printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf);
511
512         va_end(args);
513         kfree(path);
514 }
515 EXPORT_SYMBOL(acpi_handle_printk);
516
517 #if defined(CONFIG_DYNAMIC_DEBUG)
518 /**
519  * __acpi_handle_debug: pr_debug with ACPI prefix and object path
520  *
521  * This function is called through acpi_handle_debug macro and debug
522  * prints a message with ACPI prefix and object path. This function
523  * acquires the global namespace mutex to obtain an object path.  In
524  * interrupt context, it shows the object path as <n/a>.
525  */
526 void
527 __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle,
528                     const char *fmt, ...)
529 {
530         struct va_format vaf;
531         va_list args;
532         const char *path;
533
534         va_start(args, fmt);
535         vaf.fmt = fmt;
536         vaf.va = &args;
537
538         path = acpi_handle_path(handle);
539         __dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf);
540
541         va_end(args);
542         kfree(path);
543 }
544 EXPORT_SYMBOL(__acpi_handle_debug);
545 #endif
546
547 /**
548  * acpi_has_method: Check whether @handle has a method named @name
549  * @handle: ACPI device handle
550  * @name: name of object or method
551  *
552  * Check whether @handle has a method named @name.
553  */
554 bool acpi_has_method(acpi_handle handle, char *name)
555 {
556         acpi_handle tmp;
557
558         return ACPI_SUCCESS(acpi_get_handle(handle, name, &tmp));
559 }
560 EXPORT_SYMBOL(acpi_has_method);
561
562 acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
563                                        u64 arg)
564 {
565         union acpi_object obj = { .type = ACPI_TYPE_INTEGER };
566         struct acpi_object_list arg_list = { .count = 1, .pointer = &obj, };
567
568         obj.integer.value = arg;
569
570         return acpi_evaluate_object(handle, method, &arg_list, NULL);
571 }
572 EXPORT_SYMBOL(acpi_execute_simple_method);
573
574 /**
575  * acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations
576  * @handle: ACPI device handle
577  *
578  * Evaluate device's _EJ0 method for hotplug operations.
579  */
580 acpi_status acpi_evaluate_ej0(acpi_handle handle)
581 {
582         acpi_status status;
583
584         status = acpi_execute_simple_method(handle, "_EJ0", 1);
585         if (status == AE_NOT_FOUND)
586                 acpi_handle_warn(handle, "No _EJ0 support for device\n");
587         else if (ACPI_FAILURE(status))
588                 acpi_handle_warn(handle, "Eject failed (0x%x)\n", status);
589
590         return status;
591 }
592
593 /**
594  * acpi_evaluate_lck: Evaluate _LCK method to lock/unlock device
595  * @handle: ACPI device handle
596  * @lock: lock device if non-zero, otherwise unlock device
597  *
598  * Evaluate device's _LCK method if present to lock/unlock device
599  */
600 acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
601 {
602         acpi_status status;
603
604         status = acpi_execute_simple_method(handle, "_LCK", !!lock);
605         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
606                 if (lock)
607                         acpi_handle_warn(handle,
608                                 "Locking device failed (0x%x)\n", status);
609                 else
610                         acpi_handle_warn(handle,
611                                 "Unlocking device failed (0x%x)\n", status);
612         }
613
614         return status;
615 }
616
617 /**
618  * acpi_evaluate_dsm - evaluate device's _DSM method
619  * @handle: ACPI device handle
620  * @uuid: UUID of requested functions, should be 16 bytes
621  * @rev: revision number of requested function
622  * @func: requested function number
623  * @argv4: the function specific parameter
624  *
625  * Evaluate device's _DSM method with specified UUID, revision id and
626  * function number. Caller needs to free the returned object.
627  *
628  * Though ACPI defines the fourth parameter for _DSM should be a package,
629  * some old BIOSes do expect a buffer or an integer etc.
630  */
631 union acpi_object *
632 acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, int rev, int func,
633                   union acpi_object *argv4)
634 {
635         acpi_status ret;
636         struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
637         union acpi_object params[4];
638         struct acpi_object_list input = {
639                 .count = 4,
640                 .pointer = params,
641         };
642
643         params[0].type = ACPI_TYPE_BUFFER;
644         params[0].buffer.length = 16;
645         params[0].buffer.pointer = (char *)uuid;
646         params[1].type = ACPI_TYPE_INTEGER;
647         params[1].integer.value = rev;
648         params[2].type = ACPI_TYPE_INTEGER;
649         params[2].integer.value = func;
650         if (argv4) {
651                 params[3] = *argv4;
652         } else {
653                 params[3].type = ACPI_TYPE_PACKAGE;
654                 params[3].package.count = 0;
655                 params[3].package.elements = NULL;
656         }
657
658         ret = acpi_evaluate_object(handle, "_DSM", &input, &buf);
659         if (ACPI_SUCCESS(ret))
660                 return (union acpi_object *)buf.pointer;
661
662         if (ret != AE_NOT_FOUND)
663                 acpi_handle_warn(handle,
664                                 "failed to evaluate _DSM (0x%x)\n", ret);
665
666         return NULL;
667 }
668 EXPORT_SYMBOL(acpi_evaluate_dsm);
669
670 /**
671  * acpi_check_dsm - check if _DSM method supports requested functions.
672  * @handle: ACPI device handle
673  * @uuid: UUID of requested functions, should be 16 bytes at least
674  * @rev: revision number of requested functions
675  * @funcs: bitmap of requested functions
676  *
677  * Evaluate device's _DSM method to check whether it supports requested
678  * functions. Currently only support 64 functions at maximum, should be
679  * enough for now.
680  */
681 bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs)
682 {
683         int i;
684         u64 mask = 0;
685         union acpi_object *obj;
686
687         if (funcs == 0)
688                 return false;
689
690         obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
691         if (!obj)
692                 return false;
693
694         /* For compatibility, old BIOSes may return an integer */
695         if (obj->type == ACPI_TYPE_INTEGER)
696                 mask = obj->integer.value;
697         else if (obj->type == ACPI_TYPE_BUFFER)
698                 for (i = 0; i < obj->buffer.length && i < 8; i++)
699                         mask |= (((u8)obj->buffer.pointer[i]) << (i * 8));
700         ACPI_FREE(obj);
701
702         /*
703          * Bit 0 indicates whether there's support for any functions other than
704          * function 0 for the specified UUID and revision.
705          */
706         if ((mask & 0x1) && (mask & funcs) == funcs)
707                 return true;
708
709         return false;
710 }
711 EXPORT_SYMBOL(acpi_check_dsm);
712
713 /**
714  * acpi_dev_present - Detect presence of a given ACPI device in the system.
715  * @hid: Hardware ID of the device.
716  *
717  * Return %true if the device was present at the moment of invocation.
718  * Note that if the device is pluggable, it may since have disappeared.
719  *
720  * For this function to work, acpi_bus_scan() must have been executed
721  * which happens in the subsys_initcall() subsection. Hence, do not
722  * call from a subsys_initcall() or earlier (use acpi_get_devices()
723  * instead). Calling from module_init() is fine (which is synonymous
724  * with device_initcall()).
725  */
726 bool acpi_dev_present(const char *hid)
727 {
728         struct acpi_device_bus_id *acpi_device_bus_id;
729         bool found = false;
730
731         mutex_lock(&acpi_device_lock);
732         list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
733                 if (!strcmp(acpi_device_bus_id->bus_id, hid)) {
734                         found = true;
735                         break;
736                 }
737         mutex_unlock(&acpi_device_lock);
738
739         return found;
740 }
741 EXPORT_SYMBOL(acpi_dev_present);
742
743 /*
744  * acpi_backlight= handling, this is done here rather then in video_detect.c
745  * because __setup cannot be used in modules.
746  */
747 char acpi_video_backlight_string[16];
748 EXPORT_SYMBOL(acpi_video_backlight_string);
749
750 static int __init acpi_backlight(char *str)
751 {
752         strlcpy(acpi_video_backlight_string, str,
753                 sizeof(acpi_video_backlight_string));
754         return 1;
755 }
756 __setup("acpi_backlight=", acpi_backlight);