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); 757