Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.16 2226 lines 56 kB view raw
1/* 2 * video.c - ACPI Video Driver 3 * 4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> 5 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> 6 * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> 7 * 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or (at 13 * your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 23 * 24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 */ 26 27#include <linux/kernel.h> 28#include <linux/module.h> 29#include <linux/init.h> 30#include <linux/types.h> 31#include <linux/list.h> 32#include <linux/mutex.h> 33#include <linux/input.h> 34#include <linux/backlight.h> 35#include <linux/thermal.h> 36#include <linux/sort.h> 37#include <linux/pci.h> 38#include <linux/pci_ids.h> 39#include <linux/slab.h> 40#include <linux/dmi.h> 41#include <linux/suspend.h> 42#include <linux/acpi.h> 43#include <acpi/video.h> 44#include <asm/uaccess.h> 45 46#include "internal.h" 47 48#define ACPI_VIDEO_BUS_NAME "Video Bus" 49#define ACPI_VIDEO_DEVICE_NAME "Video Device" 50#define ACPI_VIDEO_NOTIFY_SWITCH 0x80 51#define ACPI_VIDEO_NOTIFY_PROBE 0x81 52#define ACPI_VIDEO_NOTIFY_CYCLE 0x82 53#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 54#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 55 56#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 57#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 58#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 59#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 60#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 61 62#define MAX_NAME_LEN 20 63 64#define _COMPONENT ACPI_VIDEO_COMPONENT 65ACPI_MODULE_NAME("video"); 66 67MODULE_AUTHOR("Bruno Ducrot"); 68MODULE_DESCRIPTION("ACPI Video Driver"); 69MODULE_LICENSE("GPL"); 70 71static bool brightness_switch_enabled = 1; 72module_param(brightness_switch_enabled, bool, 0644); 73 74/* 75 * By default, we don't allow duplicate ACPI video bus devices 76 * under the same VGA controller 77 */ 78static bool allow_duplicates; 79module_param(allow_duplicates, bool, 0644); 80 81/* 82 * For Windows 8 systems: used to decide if video module 83 * should skip registering backlight interface of its own. 84 */ 85static int use_native_backlight_param = 1; 86module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); 87static bool use_native_backlight_dmi = false; 88 89static int register_count; 90static struct mutex video_list_lock; 91static struct list_head video_bus_head; 92static int acpi_video_bus_add(struct acpi_device *device); 93static int acpi_video_bus_remove(struct acpi_device *device); 94static void acpi_video_bus_notify(struct acpi_device *device, u32 event); 95 96static const struct acpi_device_id video_device_ids[] = { 97 {ACPI_VIDEO_HID, 0}, 98 {"", 0}, 99}; 100MODULE_DEVICE_TABLE(acpi, video_device_ids); 101 102static struct acpi_driver acpi_video_bus = { 103 .name = "video", 104 .class = ACPI_VIDEO_CLASS, 105 .ids = video_device_ids, 106 .ops = { 107 .add = acpi_video_bus_add, 108 .remove = acpi_video_bus_remove, 109 .notify = acpi_video_bus_notify, 110 }, 111}; 112 113struct acpi_video_bus_flags { 114 u8 multihead:1; /* can switch video heads */ 115 u8 rom:1; /* can retrieve a video rom */ 116 u8 post:1; /* can configure the head to */ 117 u8 reserved:5; 118}; 119 120struct acpi_video_bus_cap { 121 u8 _DOS:1; /* Enable/Disable output switching */ 122 u8 _DOD:1; /* Enumerate all devices attached to display adapter */ 123 u8 _ROM:1; /* Get ROM Data */ 124 u8 _GPD:1; /* Get POST Device */ 125 u8 _SPD:1; /* Set POST Device */ 126 u8 _VPO:1; /* Video POST Options */ 127 u8 reserved:2; 128}; 129 130struct acpi_video_device_attrib { 131 u32 display_index:4; /* A zero-based instance of the Display */ 132 u32 display_port_attachment:4; /* This field differentiates the display type */ 133 u32 display_type:4; /* Describe the specific type in use */ 134 u32 vendor_specific:4; /* Chipset Vendor Specific */ 135 u32 bios_can_detect:1; /* BIOS can detect the device */ 136 u32 depend_on_vga:1; /* Non-VGA output device whose power is related to 137 the VGA device. */ 138 u32 pipe_id:3; /* For VGA multiple-head devices. */ 139 u32 reserved:10; /* Must be 0 */ 140 u32 device_id_scheme:1; /* Device ID Scheme */ 141}; 142 143struct acpi_video_enumerated_device { 144 union { 145 u32 int_val; 146 struct acpi_video_device_attrib attrib; 147 } value; 148 struct acpi_video_device *bind_info; 149}; 150 151struct acpi_video_bus { 152 struct acpi_device *device; 153 bool backlight_registered; 154 bool backlight_notifier_registered; 155 u8 dos_setting; 156 struct acpi_video_enumerated_device *attached_array; 157 u8 attached_count; 158 struct acpi_video_bus_cap cap; 159 struct acpi_video_bus_flags flags; 160 struct list_head video_device_list; 161 struct mutex device_list_lock; /* protects video_device_list */ 162 struct list_head entry; 163 struct input_dev *input; 164 char phys[32]; /* for input device */ 165 struct notifier_block pm_nb; 166 struct notifier_block backlight_nb; 167}; 168 169struct acpi_video_device_flags { 170 u8 crt:1; 171 u8 lcd:1; 172 u8 tvout:1; 173 u8 dvi:1; 174 u8 bios:1; 175 u8 unknown:1; 176 u8 notify:1; 177 u8 reserved:1; 178}; 179 180struct acpi_video_device_cap { 181 u8 _ADR:1; /* Return the unique ID */ 182 u8 _BCL:1; /* Query list of brightness control levels supported */ 183 u8 _BCM:1; /* Set the brightness level */ 184 u8 _BQC:1; /* Get current brightness level */ 185 u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ 186 u8 _DDC:1; /* Return the EDID for this device */ 187}; 188 189struct acpi_video_brightness_flags { 190 u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ 191 u8 _BCL_reversed:1; /* _BCL package is in a reversed order */ 192 u8 _BQC_use_index:1; /* _BQC returns an index value */ 193}; 194 195struct acpi_video_device_brightness { 196 int curr; 197 int count; 198 int *levels; 199 struct acpi_video_brightness_flags flags; 200}; 201 202struct acpi_video_device { 203 unsigned long device_id; 204 struct acpi_video_device_flags flags; 205 struct acpi_video_device_cap cap; 206 struct list_head entry; 207 struct acpi_video_bus *video; 208 struct acpi_device *dev; 209 struct acpi_video_device_brightness *brightness; 210 struct backlight_device *backlight; 211 struct thermal_cooling_device *cooling_dev; 212}; 213 214static const char device_decode[][30] = { 215 "motherboard VGA device", 216 "PCI VGA device", 217 "AGP VGA device", 218 "UNKNOWN", 219}; 220 221static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data); 222static void acpi_video_device_rebind(struct acpi_video_bus *video); 223static void acpi_video_device_bind(struct acpi_video_bus *video, 224 struct acpi_video_device *device); 225static int acpi_video_device_enumerate(struct acpi_video_bus *video); 226static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, 227 int level); 228static int acpi_video_device_lcd_get_level_current( 229 struct acpi_video_device *device, 230 unsigned long long *level, bool raw); 231static int acpi_video_get_next_level(struct acpi_video_device *device, 232 u32 level_current, u32 event); 233static int acpi_video_switch_brightness(struct acpi_video_device *device, 234 int event); 235 236static bool acpi_video_use_native_backlight(void) 237{ 238 if (use_native_backlight_param != -1) 239 return use_native_backlight_param; 240 else 241 return use_native_backlight_dmi; 242} 243 244bool acpi_video_verify_backlight_support(void) 245{ 246 if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && 247 backlight_device_registered(BACKLIGHT_RAW)) 248 return false; 249 return acpi_video_backlight_support(); 250} 251EXPORT_SYMBOL_GPL(acpi_video_verify_backlight_support); 252 253/* backlight device sysfs support */ 254static int acpi_video_get_brightness(struct backlight_device *bd) 255{ 256 unsigned long long cur_level; 257 int i; 258 struct acpi_video_device *vd = bl_get_data(bd); 259 260 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false)) 261 return -EINVAL; 262 for (i = 2; i < vd->brightness->count; i++) { 263 if (vd->brightness->levels[i] == cur_level) 264 /* 265 * The first two entries are special - see page 575 266 * of the ACPI spec 3.0 267 */ 268 return i - 2; 269 } 270 return 0; 271} 272 273static int acpi_video_set_brightness(struct backlight_device *bd) 274{ 275 int request_level = bd->props.brightness + 2; 276 struct acpi_video_device *vd = bl_get_data(bd); 277 278 return acpi_video_device_lcd_set_level(vd, 279 vd->brightness->levels[request_level]); 280} 281 282static const struct backlight_ops acpi_backlight_ops = { 283 .get_brightness = acpi_video_get_brightness, 284 .update_status = acpi_video_set_brightness, 285}; 286 287/* thermal cooling device callbacks */ 288static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned 289 long *state) 290{ 291 struct acpi_device *device = cooling_dev->devdata; 292 struct acpi_video_device *video = acpi_driver_data(device); 293 294 *state = video->brightness->count - 3; 295 return 0; 296} 297 298static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned 299 long *state) 300{ 301 struct acpi_device *device = cooling_dev->devdata; 302 struct acpi_video_device *video = acpi_driver_data(device); 303 unsigned long long level; 304 int offset; 305 306 if (acpi_video_device_lcd_get_level_current(video, &level, false)) 307 return -EINVAL; 308 for (offset = 2; offset < video->brightness->count; offset++) 309 if (level == video->brightness->levels[offset]) { 310 *state = video->brightness->count - offset - 1; 311 return 0; 312 } 313 314 return -EINVAL; 315} 316 317static int 318video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) 319{ 320 struct acpi_device *device = cooling_dev->devdata; 321 struct acpi_video_device *video = acpi_driver_data(device); 322 int level; 323 324 if (state >= video->brightness->count - 2) 325 return -EINVAL; 326 327 state = video->brightness->count - state; 328 level = video->brightness->levels[state - 1]; 329 return acpi_video_device_lcd_set_level(video, level); 330} 331 332static const struct thermal_cooling_device_ops video_cooling_ops = { 333 .get_max_state = video_get_max_state, 334 .get_cur_state = video_get_cur_state, 335 .set_cur_state = video_set_cur_state, 336}; 337 338/* 339 * -------------------------------------------------------------------------- 340 * Video Management 341 * -------------------------------------------------------------------------- 342 */ 343 344static int 345acpi_video_device_lcd_query_levels(struct acpi_video_device *device, 346 union acpi_object **levels) 347{ 348 int status; 349 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 350 union acpi_object *obj; 351 352 353 *levels = NULL; 354 355 status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer); 356 if (!ACPI_SUCCESS(status)) 357 return status; 358 obj = (union acpi_object *)buffer.pointer; 359 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 360 printk(KERN_ERR PREFIX "Invalid _BCL data\n"); 361 status = -EFAULT; 362 goto err; 363 } 364 365 *levels = obj; 366 367 return 0; 368 369err: 370 kfree(buffer.pointer); 371 372 return status; 373} 374 375static int 376acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) 377{ 378 int status; 379 int state; 380 381 status = acpi_execute_simple_method(device->dev->handle, 382 "_BCM", level); 383 if (ACPI_FAILURE(status)) { 384 ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); 385 return -EIO; 386 } 387 388 device->brightness->curr = level; 389 for (state = 2; state < device->brightness->count; state++) 390 if (level == device->brightness->levels[state]) { 391 if (device->backlight) 392 device->backlight->props.brightness = state - 2; 393 return 0; 394 } 395 396 ACPI_ERROR((AE_INFO, "Current brightness invalid")); 397 return -EINVAL; 398} 399 400/* 401 * For some buggy _BQC methods, we need to add a constant value to 402 * the _BQC return value to get the actual current brightness level 403 */ 404 405static int bqc_offset_aml_bug_workaround; 406static int __init video_set_bqc_offset(const struct dmi_system_id *d) 407{ 408 bqc_offset_aml_bug_workaround = 9; 409 return 0; 410} 411 412static int __init video_set_use_native_backlight(const struct dmi_system_id *d) 413{ 414 use_native_backlight_dmi = true; 415 return 0; 416} 417 418static struct dmi_system_id video_dmi_table[] __initdata = { 419 /* 420 * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 421 */ 422 { 423 .callback = video_set_bqc_offset, 424 .ident = "Acer Aspire 5720", 425 .matches = { 426 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 427 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), 428 }, 429 }, 430 { 431 .callback = video_set_bqc_offset, 432 .ident = "Acer Aspire 5710Z", 433 .matches = { 434 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 435 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), 436 }, 437 }, 438 { 439 .callback = video_set_bqc_offset, 440 .ident = "eMachines E510", 441 .matches = { 442 DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"), 443 DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"), 444 }, 445 }, 446 { 447 .callback = video_set_bqc_offset, 448 .ident = "Acer Aspire 5315", 449 .matches = { 450 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 451 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), 452 }, 453 }, 454 { 455 .callback = video_set_bqc_offset, 456 .ident = "Acer Aspire 7720", 457 .matches = { 458 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 459 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), 460 }, 461 }, 462 { 463 .callback = video_set_use_native_backlight, 464 .ident = "ThinkPad T430 and T430s", 465 .matches = { 466 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 467 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"), 468 }, 469 }, 470 { 471 .callback = video_set_use_native_backlight, 472 .ident = "ThinkPad X230", 473 .matches = { 474 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 475 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), 476 }, 477 }, 478 { 479 .callback = video_set_use_native_backlight, 480 .ident = "ThinkPad W530", 481 .matches = { 482 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 483 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), 484 }, 485 }, 486 { 487 .callback = video_set_use_native_backlight, 488 .ident = "ThinkPad X1 Carbon", 489 .matches = { 490 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 491 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), 492 }, 493 }, 494 { 495 .callback = video_set_use_native_backlight, 496 .ident = "Lenovo Yoga 13", 497 .matches = { 498 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 499 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"), 500 }, 501 }, 502 { 503 .callback = video_set_use_native_backlight, 504 .ident = "Lenovo Yoga 2 11", 505 .matches = { 506 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 507 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), 508 }, 509 }, 510 { 511 .callback = video_set_use_native_backlight, 512 .ident = "Thinkpad Helix", 513 .matches = { 514 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 515 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"), 516 }, 517 }, 518 { 519 .callback = video_set_use_native_backlight, 520 .ident = "Dell Inspiron 7520", 521 .matches = { 522 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 523 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), 524 }, 525 }, 526 { 527 .callback = video_set_use_native_backlight, 528 .ident = "Acer Aspire 5733Z", 529 .matches = { 530 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 531 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5733Z"), 532 }, 533 }, 534 { 535 .callback = video_set_use_native_backlight, 536 .ident = "Acer Aspire 5742G", 537 .matches = { 538 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 539 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5742G"), 540 }, 541 }, 542 { 543 .callback = video_set_use_native_backlight, 544 .ident = "Acer Aspire V5-171", 545 .matches = { 546 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 547 DMI_MATCH(DMI_PRODUCT_NAME, "V5-171"), 548 }, 549 }, 550 { 551 .callback = video_set_use_native_backlight, 552 .ident = "Acer Aspire V5-431", 553 .matches = { 554 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 555 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-431"), 556 }, 557 }, 558 { 559 .callback = video_set_use_native_backlight, 560 .ident = "Acer Aspire V5-471G", 561 .matches = { 562 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 563 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-471G"), 564 }, 565 }, 566 { 567 .callback = video_set_use_native_backlight, 568 .ident = "Acer TravelMate B113", 569 .matches = { 570 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 571 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"), 572 }, 573 }, 574 { 575 .callback = video_set_use_native_backlight, 576 .ident = "HP ProBook 4340s", 577 .matches = { 578 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 579 DMI_MATCH(DMI_PRODUCT_VERSION, "HP ProBook 4340s"), 580 }, 581 }, 582 { 583 .callback = video_set_use_native_backlight, 584 .ident = "HP ProBook 4540s", 585 .matches = { 586 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 587 DMI_MATCH(DMI_PRODUCT_VERSION, "HP ProBook 4540s"), 588 }, 589 }, 590 { 591 .callback = video_set_use_native_backlight, 592 .ident = "HP ProBook 2013 models", 593 .matches = { 594 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 595 DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook "), 596 DMI_MATCH(DMI_PRODUCT_NAME, " G1"), 597 }, 598 }, 599 { 600 .callback = video_set_use_native_backlight, 601 .ident = "HP EliteBook 2013 models", 602 .matches = { 603 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 604 DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), 605 DMI_MATCH(DMI_PRODUCT_NAME, " G1"), 606 }, 607 }, 608 { 609 .callback = video_set_use_native_backlight, 610 .ident = "HP ZBook 14", 611 .matches = { 612 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 613 DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 14"), 614 }, 615 }, 616 { 617 .callback = video_set_use_native_backlight, 618 .ident = "HP ZBook 15", 619 .matches = { 620 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 621 DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 15"), 622 }, 623 }, 624 { 625 .callback = video_set_use_native_backlight, 626 .ident = "HP ZBook 17", 627 .matches = { 628 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 629 DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 17"), 630 }, 631 }, 632 { 633 .callback = video_set_use_native_backlight, 634 .ident = "HP EliteBook 8470p", 635 .matches = { 636 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 637 DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8470p"), 638 }, 639 }, 640 { 641 .callback = video_set_use_native_backlight, 642 .ident = "HP EliteBook 8780w", 643 .matches = { 644 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 645 DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), 646 }, 647 }, 648 {} 649}; 650 651static unsigned long long 652acpi_video_bqc_value_to_level(struct acpi_video_device *device, 653 unsigned long long bqc_value) 654{ 655 unsigned long long level; 656 657 if (device->brightness->flags._BQC_use_index) { 658 /* 659 * _BQC returns an index that doesn't account for 660 * the first 2 items with special meaning, so we need 661 * to compensate for that by offsetting ourselves 662 */ 663 if (device->brightness->flags._BCL_reversed) 664 bqc_value = device->brightness->count - 3 - bqc_value; 665 666 level = device->brightness->levels[bqc_value + 2]; 667 } else { 668 level = bqc_value; 669 } 670 671 level += bqc_offset_aml_bug_workaround; 672 673 return level; 674} 675 676static int 677acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 678 unsigned long long *level, bool raw) 679{ 680 acpi_status status = AE_OK; 681 int i; 682 683 if (device->cap._BQC || device->cap._BCQ) { 684 char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; 685 686 status = acpi_evaluate_integer(device->dev->handle, buf, 687 NULL, level); 688 if (ACPI_SUCCESS(status)) { 689 if (raw) { 690 /* 691 * Caller has indicated he wants the raw 692 * value returned by _BQC, so don't furtherly 693 * mess with the value. 694 */ 695 return 0; 696 } 697 698 *level = acpi_video_bqc_value_to_level(device, *level); 699 700 for (i = 2; i < device->brightness->count; i++) 701 if (device->brightness->levels[i] == *level) { 702 device->brightness->curr = *level; 703 return 0; 704 } 705 /* 706 * BQC returned an invalid level. 707 * Stop using it. 708 */ 709 ACPI_WARNING((AE_INFO, 710 "%s returned an invalid level", 711 buf)); 712 device->cap._BQC = device->cap._BCQ = 0; 713 } else { 714 /* 715 * Fixme: 716 * should we return an error or ignore this failure? 717 * dev->brightness->curr is a cached value which stores 718 * the correct current backlight level in most cases. 719 * ACPI video backlight still works w/ buggy _BQC. 720 * http://bugzilla.kernel.org/show_bug.cgi?id=12233 721 */ 722 ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf)); 723 device->cap._BQC = device->cap._BCQ = 0; 724 } 725 } 726 727 *level = device->brightness->curr; 728 return 0; 729} 730 731static int 732acpi_video_device_EDID(struct acpi_video_device *device, 733 union acpi_object **edid, ssize_t length) 734{ 735 int status; 736 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 737 union acpi_object *obj; 738 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 739 struct acpi_object_list args = { 1, &arg0 }; 740 741 742 *edid = NULL; 743 744 if (!device) 745 return -ENODEV; 746 if (length == 128) 747 arg0.integer.value = 1; 748 else if (length == 256) 749 arg0.integer.value = 2; 750 else 751 return -EINVAL; 752 753 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer); 754 if (ACPI_FAILURE(status)) 755 return -ENODEV; 756 757 obj = buffer.pointer; 758 759 if (obj && obj->type == ACPI_TYPE_BUFFER) 760 *edid = obj; 761 else { 762 printk(KERN_ERR PREFIX "Invalid _DDC data\n"); 763 status = -EFAULT; 764 kfree(obj); 765 } 766 767 return status; 768} 769 770/* bus */ 771 772/* 773 * Arg: 774 * video : video bus device pointer 775 * bios_flag : 776 * 0. The system BIOS should NOT automatically switch(toggle) 777 * the active display output. 778 * 1. The system BIOS should automatically switch (toggle) the 779 * active display output. No switch event. 780 * 2. The _DGS value should be locked. 781 * 3. The system BIOS should not automatically switch (toggle) the 782 * active display output, but instead generate the display switch 783 * event notify code. 784 * lcd_flag : 785 * 0. The system BIOS should automatically control the brightness level 786 * of the LCD when the power changes from AC to DC 787 * 1. The system BIOS should NOT automatically control the brightness 788 * level of the LCD when the power changes from AC to DC. 789 * Return Value: 790 * -EINVAL wrong arg. 791 */ 792 793static int 794acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) 795{ 796 acpi_status status; 797 798 if (!video->cap._DOS) 799 return 0; 800 801 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) 802 return -EINVAL; 803 video->dos_setting = (lcd_flag << 2) | bios_flag; 804 status = acpi_execute_simple_method(video->device->handle, "_DOS", 805 (lcd_flag << 2) | bios_flag); 806 if (ACPI_FAILURE(status)) 807 return -EIO; 808 809 return 0; 810} 811 812/* 813 * Simple comparison function used to sort backlight levels. 814 */ 815 816static int 817acpi_video_cmp_level(const void *a, const void *b) 818{ 819 return *(int *)a - *(int *)b; 820} 821 822/* 823 * Decides if _BQC/_BCQ for this system is usable 824 * 825 * We do this by changing the level first and then read out the current 826 * brightness level, if the value does not match, find out if it is using 827 * index. If not, clear the _BQC/_BCQ capability. 828 */ 829static int acpi_video_bqc_quirk(struct acpi_video_device *device, 830 int max_level, int current_level) 831{ 832 struct acpi_video_device_brightness *br = device->brightness; 833 int result; 834 unsigned long long level; 835 int test_level; 836 837 /* don't mess with existing known broken systems */ 838 if (bqc_offset_aml_bug_workaround) 839 return 0; 840 841 /* 842 * Some systems always report current brightness level as maximum 843 * through _BQC, we need to test another value for them. 844 */ 845 test_level = current_level == max_level ? br->levels[3] : max_level; 846 847 result = acpi_video_device_lcd_set_level(device, test_level); 848 if (result) 849 return result; 850 851 result = acpi_video_device_lcd_get_level_current(device, &level, true); 852 if (result) 853 return result; 854 855 if (level != test_level) { 856 /* buggy _BQC found, need to find out if it uses index */ 857 if (level < br->count) { 858 if (br->flags._BCL_reversed) 859 level = br->count - 3 - level; 860 if (br->levels[level + 2] == test_level) 861 br->flags._BQC_use_index = 1; 862 } 863 864 if (!br->flags._BQC_use_index) 865 device->cap._BQC = device->cap._BCQ = 0; 866 } 867 868 return 0; 869} 870 871 872/* 873 * Arg: 874 * device : video output device (LCD, CRT, ..) 875 * 876 * Return Value: 877 * Maximum brightness level 878 * 879 * Allocate and initialize device->brightness. 880 */ 881 882static int 883acpi_video_init_brightness(struct acpi_video_device *device) 884{ 885 union acpi_object *obj = NULL; 886 int i, max_level = 0, count = 0, level_ac_battery = 0; 887 unsigned long long level, level_old; 888 union acpi_object *o; 889 struct acpi_video_device_brightness *br = NULL; 890 int result = -EINVAL; 891 u32 value; 892 893 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { 894 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " 895 "LCD brightness level\n")); 896 goto out; 897 } 898 899 if (obj->package.count < 2) 900 goto out; 901 902 br = kzalloc(sizeof(*br), GFP_KERNEL); 903 if (!br) { 904 printk(KERN_ERR "can't allocate memory\n"); 905 result = -ENOMEM; 906 goto out; 907 } 908 909 br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels), 910 GFP_KERNEL); 911 if (!br->levels) { 912 result = -ENOMEM; 913 goto out_free; 914 } 915 916 for (i = 0; i < obj->package.count; i++) { 917 o = (union acpi_object *)&obj->package.elements[i]; 918 if (o->type != ACPI_TYPE_INTEGER) { 919 printk(KERN_ERR PREFIX "Invalid data\n"); 920 continue; 921 } 922 value = (u32) o->integer.value; 923 /* Skip duplicate entries */ 924 if (count > 2 && br->levels[count - 1] == value) 925 continue; 926 927 br->levels[count] = value; 928 929 if (br->levels[count] > max_level) 930 max_level = br->levels[count]; 931 count++; 932 } 933 934 /* 935 * some buggy BIOS don't export the levels 936 * when machine is on AC/Battery in _BCL package. 937 * In this case, the first two elements in _BCL packages 938 * are also supported brightness levels that OS should take care of. 939 */ 940 for (i = 2; i < count; i++) { 941 if (br->levels[i] == br->levels[0]) 942 level_ac_battery++; 943 if (br->levels[i] == br->levels[1]) 944 level_ac_battery++; 945 } 946 947 if (level_ac_battery < 2) { 948 level_ac_battery = 2 - level_ac_battery; 949 br->flags._BCL_no_ac_battery_levels = 1; 950 for (i = (count - 1 + level_ac_battery); i >= 2; i--) 951 br->levels[i] = br->levels[i - level_ac_battery]; 952 count += level_ac_battery; 953 } else if (level_ac_battery > 2) 954 ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package")); 955 956 /* Check if the _BCL package is in a reversed order */ 957 if (max_level == br->levels[2]) { 958 br->flags._BCL_reversed = 1; 959 sort(&br->levels[2], count - 2, sizeof(br->levels[2]), 960 acpi_video_cmp_level, NULL); 961 } else if (max_level != br->levels[count - 1]) 962 ACPI_ERROR((AE_INFO, 963 "Found unordered _BCL package")); 964 965 br->count = count; 966 device->brightness = br; 967 968 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ 969 br->curr = level = max_level; 970 971 if (!device->cap._BQC) 972 goto set_level; 973 974 result = acpi_video_device_lcd_get_level_current(device, 975 &level_old, true); 976 if (result) 977 goto out_free_levels; 978 979 result = acpi_video_bqc_quirk(device, max_level, level_old); 980 if (result) 981 goto out_free_levels; 982 /* 983 * cap._BQC may get cleared due to _BQC is found to be broken 984 * in acpi_video_bqc_quirk, so check again here. 985 */ 986 if (!device->cap._BQC) 987 goto set_level; 988 989 level = acpi_video_bqc_value_to_level(device, level_old); 990 /* 991 * On some buggy laptops, _BQC returns an uninitialized 992 * value when invoked for the first time, i.e. 993 * level_old is invalid (no matter whether it's a level 994 * or an index). Set the backlight to max_level in this case. 995 */ 996 for (i = 2; i < br->count; i++) 997 if (level == br->levels[i]) 998 break; 999 if (i == br->count || !level) 1000 level = max_level; 1001 1002set_level: 1003 result = acpi_video_device_lcd_set_level(device, level); 1004 if (result) 1005 goto out_free_levels; 1006 1007 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1008 "found %d brightness levels\n", count - 2)); 1009 kfree(obj); 1010 return result; 1011 1012out_free_levels: 1013 kfree(br->levels); 1014out_free: 1015 kfree(br); 1016out: 1017 device->brightness = NULL; 1018 kfree(obj); 1019 return result; 1020} 1021 1022/* 1023 * Arg: 1024 * device : video output device (LCD, CRT, ..) 1025 * 1026 * Return Value: 1027 * None 1028 * 1029 * Find out all required AML methods defined under the output 1030 * device. 1031 */ 1032 1033static void acpi_video_device_find_cap(struct acpi_video_device *device) 1034{ 1035 if (acpi_has_method(device->dev->handle, "_ADR")) 1036 device->cap._ADR = 1; 1037 if (acpi_has_method(device->dev->handle, "_BCL")) 1038 device->cap._BCL = 1; 1039 if (acpi_has_method(device->dev->handle, "_BCM")) 1040 device->cap._BCM = 1; 1041 if (acpi_has_method(device->dev->handle, "_BQC")) { 1042 device->cap._BQC = 1; 1043 } else if (acpi_has_method(device->dev->handle, "_BCQ")) { 1044 printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); 1045 device->cap._BCQ = 1; 1046 } 1047 1048 if (acpi_has_method(device->dev->handle, "_DDC")) 1049 device->cap._DDC = 1; 1050} 1051 1052/* 1053 * Arg: 1054 * device : video output device (VGA) 1055 * 1056 * Return Value: 1057 * None 1058 * 1059 * Find out all required AML methods defined under the video bus device. 1060 */ 1061 1062static void acpi_video_bus_find_cap(struct acpi_video_bus *video) 1063{ 1064 if (acpi_has_method(video->device->handle, "_DOS")) 1065 video->cap._DOS = 1; 1066 if (acpi_has_method(video->device->handle, "_DOD")) 1067 video->cap._DOD = 1; 1068 if (acpi_has_method(video->device->handle, "_ROM")) 1069 video->cap._ROM = 1; 1070 if (acpi_has_method(video->device->handle, "_GPD")) 1071 video->cap._GPD = 1; 1072 if (acpi_has_method(video->device->handle, "_SPD")) 1073 video->cap._SPD = 1; 1074 if (acpi_has_method(video->device->handle, "_VPO")) 1075 video->cap._VPO = 1; 1076} 1077 1078/* 1079 * Check whether the video bus device has required AML method to 1080 * support the desired features 1081 */ 1082 1083static int acpi_video_bus_check(struct acpi_video_bus *video) 1084{ 1085 acpi_status status = -ENOENT; 1086 struct pci_dev *dev; 1087 1088 if (!video) 1089 return -EINVAL; 1090 1091 dev = acpi_get_pci_dev(video->device->handle); 1092 if (!dev) 1093 return -ENODEV; 1094 pci_dev_put(dev); 1095 1096 /* 1097 * Since there is no HID, CID and so on for VGA driver, we have 1098 * to check well known required nodes. 1099 */ 1100 1101 /* Does this device support video switching? */ 1102 if (video->cap._DOS || video->cap._DOD) { 1103 if (!video->cap._DOS) { 1104 printk(KERN_WARNING FW_BUG 1105 "ACPI(%s) defines _DOD but not _DOS\n", 1106 acpi_device_bid(video->device)); 1107 } 1108 video->flags.multihead = 1; 1109 status = 0; 1110 } 1111 1112 /* Does this device support retrieving a video ROM? */ 1113 if (video->cap._ROM) { 1114 video->flags.rom = 1; 1115 status = 0; 1116 } 1117 1118 /* Does this device support configuring which video device to POST? */ 1119 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) { 1120 video->flags.post = 1; 1121 status = 0; 1122 } 1123 1124 return status; 1125} 1126 1127/* 1128 * -------------------------------------------------------------------------- 1129 * Driver Interface 1130 * -------------------------------------------------------------------------- 1131 */ 1132 1133/* device interface */ 1134static struct acpi_video_device_attrib * 1135acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) 1136{ 1137 struct acpi_video_enumerated_device *ids; 1138 int i; 1139 1140 for (i = 0; i < video->attached_count; i++) { 1141 ids = &video->attached_array[i]; 1142 if ((ids->value.int_val & 0xffff) == device_id) 1143 return &ids->value.attrib; 1144 } 1145 1146 return NULL; 1147} 1148 1149static int 1150acpi_video_get_device_type(struct acpi_video_bus *video, 1151 unsigned long device_id) 1152{ 1153 struct acpi_video_enumerated_device *ids; 1154 int i; 1155 1156 for (i = 0; i < video->attached_count; i++) { 1157 ids = &video->attached_array[i]; 1158 if ((ids->value.int_val & 0xffff) == device_id) 1159 return ids->value.int_val; 1160 } 1161 1162 return 0; 1163} 1164 1165static int 1166acpi_video_bus_get_one_device(struct acpi_device *device, 1167 struct acpi_video_bus *video) 1168{ 1169 unsigned long long device_id; 1170 int status, device_type; 1171 struct acpi_video_device *data; 1172 struct acpi_video_device_attrib *attribute; 1173 1174 status = 1175 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1176 /* Some device omits _ADR, we skip them instead of fail */ 1177 if (ACPI_FAILURE(status)) 1178 return 0; 1179 1180 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); 1181 if (!data) 1182 return -ENOMEM; 1183 1184 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); 1185 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1186 device->driver_data = data; 1187 1188 data->device_id = device_id; 1189 data->video = video; 1190 data->dev = device; 1191 1192 attribute = acpi_video_get_device_attr(video, device_id); 1193 1194 if (attribute && attribute->device_id_scheme) { 1195 switch (attribute->display_type) { 1196 case ACPI_VIDEO_DISPLAY_CRT: 1197 data->flags.crt = 1; 1198 break; 1199 case ACPI_VIDEO_DISPLAY_TV: 1200 data->flags.tvout = 1; 1201 break; 1202 case ACPI_VIDEO_DISPLAY_DVI: 1203 data->flags.dvi = 1; 1204 break; 1205 case ACPI_VIDEO_DISPLAY_LCD: 1206 data->flags.lcd = 1; 1207 break; 1208 default: 1209 data->flags.unknown = 1; 1210 break; 1211 } 1212 if (attribute->bios_can_detect) 1213 data->flags.bios = 1; 1214 } else { 1215 /* Check for legacy IDs */ 1216 device_type = acpi_video_get_device_type(video, device_id); 1217 /* Ignore bits 16 and 18-20 */ 1218 switch (device_type & 0xffe2ffff) { 1219 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: 1220 data->flags.crt = 1; 1221 break; 1222 case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: 1223 data->flags.lcd = 1; 1224 break; 1225 case ACPI_VIDEO_DISPLAY_LEGACY_TV: 1226 data->flags.tvout = 1; 1227 break; 1228 default: 1229 data->flags.unknown = 1; 1230 } 1231 } 1232 1233 acpi_video_device_bind(video, data); 1234 acpi_video_device_find_cap(data); 1235 1236 mutex_lock(&video->device_list_lock); 1237 list_add_tail(&data->entry, &video->video_device_list); 1238 mutex_unlock(&video->device_list_lock); 1239 1240 return status; 1241} 1242 1243/* 1244 * Arg: 1245 * video : video bus device 1246 * 1247 * Return: 1248 * none 1249 * 1250 * Enumerate the video device list of the video bus, 1251 * bind the ids with the corresponding video devices 1252 * under the video bus. 1253 */ 1254 1255static void acpi_video_device_rebind(struct acpi_video_bus *video) 1256{ 1257 struct acpi_video_device *dev; 1258 1259 mutex_lock(&video->device_list_lock); 1260 1261 list_for_each_entry(dev, &video->video_device_list, entry) 1262 acpi_video_device_bind(video, dev); 1263 1264 mutex_unlock(&video->device_list_lock); 1265} 1266 1267/* 1268 * Arg: 1269 * video : video bus device 1270 * device : video output device under the video 1271 * bus 1272 * 1273 * Return: 1274 * none 1275 * 1276 * Bind the ids with the corresponding video devices 1277 * under the video bus. 1278 */ 1279 1280static void 1281acpi_video_device_bind(struct acpi_video_bus *video, 1282 struct acpi_video_device *device) 1283{ 1284 struct acpi_video_enumerated_device *ids; 1285 int i; 1286 1287 for (i = 0; i < video->attached_count; i++) { 1288 ids = &video->attached_array[i]; 1289 if (device->device_id == (ids->value.int_val & 0xffff)) { 1290 ids->bind_info = device; 1291 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); 1292 } 1293 } 1294} 1295 1296/* 1297 * Arg: 1298 * video : video bus device 1299 * 1300 * Return: 1301 * < 0 : error 1302 * 1303 * Call _DOD to enumerate all devices attached to display adapter 1304 * 1305 */ 1306 1307static int acpi_video_device_enumerate(struct acpi_video_bus *video) 1308{ 1309 int status; 1310 int count; 1311 int i; 1312 struct acpi_video_enumerated_device *active_list; 1313 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1314 union acpi_object *dod = NULL; 1315 union acpi_object *obj; 1316 1317 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); 1318 if (!ACPI_SUCCESS(status)) { 1319 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); 1320 return status; 1321 } 1322 1323 dod = buffer.pointer; 1324 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { 1325 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); 1326 status = -EFAULT; 1327 goto out; 1328 } 1329 1330 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", 1331 dod->package.count)); 1332 1333 active_list = kcalloc(1 + dod->package.count, 1334 sizeof(struct acpi_video_enumerated_device), 1335 GFP_KERNEL); 1336 if (!active_list) { 1337 status = -ENOMEM; 1338 goto out; 1339 } 1340 1341 count = 0; 1342 for (i = 0; i < dod->package.count; i++) { 1343 obj = &dod->package.elements[i]; 1344 1345 if (obj->type != ACPI_TYPE_INTEGER) { 1346 printk(KERN_ERR PREFIX 1347 "Invalid _DOD data in element %d\n", i); 1348 continue; 1349 } 1350 1351 active_list[count].value.int_val = obj->integer.value; 1352 active_list[count].bind_info = NULL; 1353 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, 1354 (int)obj->integer.value)); 1355 count++; 1356 } 1357 1358 kfree(video->attached_array); 1359 1360 video->attached_array = active_list; 1361 video->attached_count = count; 1362 1363out: 1364 kfree(buffer.pointer); 1365 return status; 1366} 1367 1368static int 1369acpi_video_get_next_level(struct acpi_video_device *device, 1370 u32 level_current, u32 event) 1371{ 1372 int min, max, min_above, max_below, i, l, delta = 255; 1373 max = max_below = 0; 1374 min = min_above = 255; 1375 /* Find closest level to level_current */ 1376 for (i = 2; i < device->brightness->count; i++) { 1377 l = device->brightness->levels[i]; 1378 if (abs(l - level_current) < abs(delta)) { 1379 delta = l - level_current; 1380 if (!delta) 1381 break; 1382 } 1383 } 1384 /* Ajust level_current to closest available level */ 1385 level_current += delta; 1386 for (i = 2; i < device->brightness->count; i++) { 1387 l = device->brightness->levels[i]; 1388 if (l < min) 1389 min = l; 1390 if (l > max) 1391 max = l; 1392 if (l < min_above && l > level_current) 1393 min_above = l; 1394 if (l > max_below && l < level_current) 1395 max_below = l; 1396 } 1397 1398 switch (event) { 1399 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: 1400 return (level_current < max) ? min_above : min; 1401 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: 1402 return (level_current < max) ? min_above : max; 1403 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: 1404 return (level_current > min) ? max_below : min; 1405 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: 1406 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: 1407 return 0; 1408 default: 1409 return level_current; 1410 } 1411} 1412 1413static int 1414acpi_video_switch_brightness(struct acpi_video_device *device, int event) 1415{ 1416 unsigned long long level_current, level_next; 1417 int result = -EINVAL; 1418 1419 /* no warning message if acpi_backlight=vendor or a quirk is used */ 1420 if (!acpi_video_verify_backlight_support()) 1421 return 0; 1422 1423 if (!device->brightness) 1424 goto out; 1425 1426 result = acpi_video_device_lcd_get_level_current(device, 1427 &level_current, 1428 false); 1429 if (result) 1430 goto out; 1431 1432 level_next = acpi_video_get_next_level(device, level_current, event); 1433 1434 result = acpi_video_device_lcd_set_level(device, level_next); 1435 1436 if (!result) 1437 backlight_force_update(device->backlight, 1438 BACKLIGHT_UPDATE_HOTKEY); 1439 1440out: 1441 if (result) 1442 printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); 1443 1444 return result; 1445} 1446 1447int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, 1448 void **edid) 1449{ 1450 struct acpi_video_bus *video; 1451 struct acpi_video_device *video_device; 1452 union acpi_object *buffer = NULL; 1453 acpi_status status; 1454 int i, length; 1455 1456 if (!device || !acpi_driver_data(device)) 1457 return -EINVAL; 1458 1459 video = acpi_driver_data(device); 1460 1461 for (i = 0; i < video->attached_count; i++) { 1462 video_device = video->attached_array[i].bind_info; 1463 length = 256; 1464 1465 if (!video_device) 1466 continue; 1467 1468 if (!video_device->cap._DDC) 1469 continue; 1470 1471 if (type) { 1472 switch (type) { 1473 case ACPI_VIDEO_DISPLAY_CRT: 1474 if (!video_device->flags.crt) 1475 continue; 1476 break; 1477 case ACPI_VIDEO_DISPLAY_TV: 1478 if (!video_device->flags.tvout) 1479 continue; 1480 break; 1481 case ACPI_VIDEO_DISPLAY_DVI: 1482 if (!video_device->flags.dvi) 1483 continue; 1484 break; 1485 case ACPI_VIDEO_DISPLAY_LCD: 1486 if (!video_device->flags.lcd) 1487 continue; 1488 break; 1489 } 1490 } else if (video_device->device_id != device_id) { 1491 continue; 1492 } 1493 1494 status = acpi_video_device_EDID(video_device, &buffer, length); 1495 1496 if (ACPI_FAILURE(status) || !buffer || 1497 buffer->type != ACPI_TYPE_BUFFER) { 1498 length = 128; 1499 status = acpi_video_device_EDID(video_device, &buffer, 1500 length); 1501 if (ACPI_FAILURE(status) || !buffer || 1502 buffer->type != ACPI_TYPE_BUFFER) { 1503 continue; 1504 } 1505 } 1506 1507 *edid = buffer->buffer.pointer; 1508 return length; 1509 } 1510 1511 return -ENODEV; 1512} 1513EXPORT_SYMBOL(acpi_video_get_edid); 1514 1515static int 1516acpi_video_bus_get_devices(struct acpi_video_bus *video, 1517 struct acpi_device *device) 1518{ 1519 int status = 0; 1520 struct acpi_device *dev; 1521 1522 /* 1523 * There are systems where video module known to work fine regardless 1524 * of broken _DOD and ignoring returned value here doesn't cause 1525 * any issues later. 1526 */ 1527 acpi_video_device_enumerate(video); 1528 1529 list_for_each_entry(dev, &device->children, node) { 1530 1531 status = acpi_video_bus_get_one_device(dev, video); 1532 if (status) { 1533 dev_err(&dev->dev, "Can't attach device\n"); 1534 break; 1535 } 1536 } 1537 return status; 1538} 1539 1540/* acpi_video interface */ 1541 1542/* 1543 * Win8 requires setting bit2 of _DOS to let firmware know it shouldn't 1544 * preform any automatic brightness change on receiving a notification. 1545 */ 1546static int acpi_video_bus_start_devices(struct acpi_video_bus *video) 1547{ 1548 return acpi_video_bus_DOS(video, 0, 1549 acpi_osi_is_win8() ? 1 : 0); 1550} 1551 1552static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 1553{ 1554 return acpi_video_bus_DOS(video, 0, 1555 acpi_osi_is_win8() ? 0 : 1); 1556} 1557 1558static void acpi_video_bus_notify(struct acpi_device *device, u32 event) 1559{ 1560 struct acpi_video_bus *video = acpi_driver_data(device); 1561 struct input_dev *input; 1562 int keycode = 0; 1563 1564 if (!video || !video->input) 1565 return; 1566 1567 input = video->input; 1568 1569 switch (event) { 1570 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 1571 * most likely via hotkey. */ 1572 keycode = KEY_SWITCHVIDEOMODE; 1573 break; 1574 1575 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 1576 * connector. */ 1577 acpi_video_device_enumerate(video); 1578 acpi_video_device_rebind(video); 1579 keycode = KEY_SWITCHVIDEOMODE; 1580 break; 1581 1582 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ 1583 keycode = KEY_SWITCHVIDEOMODE; 1584 break; 1585 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ 1586 keycode = KEY_VIDEO_NEXT; 1587 break; 1588 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ 1589 keycode = KEY_VIDEO_PREV; 1590 break; 1591 1592 default: 1593 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1594 "Unsupported event [0x%x]\n", event)); 1595 break; 1596 } 1597 1598 if (acpi_notifier_call_chain(device, event, 0)) 1599 /* Something vetoed the keypress. */ 1600 keycode = 0; 1601 1602 if (keycode) { 1603 input_report_key(input, keycode, 1); 1604 input_sync(input); 1605 input_report_key(input, keycode, 0); 1606 input_sync(input); 1607 } 1608 1609 return; 1610} 1611 1612static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) 1613{ 1614 struct acpi_video_device *video_device = data; 1615 struct acpi_device *device = NULL; 1616 struct acpi_video_bus *bus; 1617 struct input_dev *input; 1618 int keycode = 0; 1619 1620 if (!video_device) 1621 return; 1622 1623 device = video_device->dev; 1624 bus = video_device->video; 1625 input = bus->input; 1626 1627 switch (event) { 1628 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ 1629 if (brightness_switch_enabled) 1630 acpi_video_switch_brightness(video_device, event); 1631 keycode = KEY_BRIGHTNESS_CYCLE; 1632 break; 1633 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ 1634 if (brightness_switch_enabled) 1635 acpi_video_switch_brightness(video_device, event); 1636 keycode = KEY_BRIGHTNESSUP; 1637 break; 1638 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ 1639 if (brightness_switch_enabled) 1640 acpi_video_switch_brightness(video_device, event); 1641 keycode = KEY_BRIGHTNESSDOWN; 1642 break; 1643 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ 1644 if (brightness_switch_enabled) 1645 acpi_video_switch_brightness(video_device, event); 1646 keycode = KEY_BRIGHTNESS_ZERO; 1647 break; 1648 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ 1649 if (brightness_switch_enabled) 1650 acpi_video_switch_brightness(video_device, event); 1651 keycode = KEY_DISPLAY_OFF; 1652 break; 1653 default: 1654 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1655 "Unsupported event [0x%x]\n", event)); 1656 break; 1657 } 1658 1659 acpi_notifier_call_chain(device, event, 0); 1660 1661 if (keycode) { 1662 input_report_key(input, keycode, 1); 1663 input_sync(input); 1664 input_report_key(input, keycode, 0); 1665 input_sync(input); 1666 } 1667 1668 return; 1669} 1670 1671static int acpi_video_resume(struct notifier_block *nb, 1672 unsigned long val, void *ign) 1673{ 1674 struct acpi_video_bus *video; 1675 struct acpi_video_device *video_device; 1676 int i; 1677 1678 switch (val) { 1679 case PM_HIBERNATION_PREPARE: 1680 case PM_SUSPEND_PREPARE: 1681 case PM_RESTORE_PREPARE: 1682 return NOTIFY_DONE; 1683 } 1684 1685 video = container_of(nb, struct acpi_video_bus, pm_nb); 1686 1687 dev_info(&video->device->dev, "Restoring backlight state\n"); 1688 1689 for (i = 0; i < video->attached_count; i++) { 1690 video_device = video->attached_array[i].bind_info; 1691 if (video_device && video_device->backlight) 1692 acpi_video_set_brightness(video_device->backlight); 1693 } 1694 1695 return NOTIFY_OK; 1696} 1697 1698static acpi_status 1699acpi_video_bus_match(acpi_handle handle, u32 level, void *context, 1700 void **return_value) 1701{ 1702 struct acpi_device *device = context; 1703 struct acpi_device *sibling; 1704 int result; 1705 1706 if (handle == device->handle) 1707 return AE_CTRL_TERMINATE; 1708 1709 result = acpi_bus_get_device(handle, &sibling); 1710 if (result) 1711 return AE_OK; 1712 1713 if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME)) 1714 return AE_ALREADY_EXISTS; 1715 1716 return AE_OK; 1717} 1718 1719static void acpi_video_dev_register_backlight(struct acpi_video_device *device) 1720{ 1721 struct backlight_properties props; 1722 struct pci_dev *pdev; 1723 acpi_handle acpi_parent; 1724 struct device *parent = NULL; 1725 int result; 1726 static int count; 1727 char *name; 1728 1729 result = acpi_video_init_brightness(device); 1730 if (result) 1731 return; 1732 name = kasprintf(GFP_KERNEL, "acpi_video%d", count); 1733 if (!name) 1734 return; 1735 count++; 1736 1737 acpi_get_parent(device->dev->handle, &acpi_parent); 1738 1739 pdev = acpi_get_pci_dev(acpi_parent); 1740 if (pdev) { 1741 parent = &pdev->dev; 1742 pci_dev_put(pdev); 1743 } 1744 1745 memset(&props, 0, sizeof(struct backlight_properties)); 1746 props.type = BACKLIGHT_FIRMWARE; 1747 props.max_brightness = device->brightness->count - 3; 1748 device->backlight = backlight_device_register(name, 1749 parent, 1750 device, 1751 &acpi_backlight_ops, 1752 &props); 1753 kfree(name); 1754 if (IS_ERR(device->backlight)) 1755 return; 1756 1757 /* 1758 * Save current brightness level in case we have to restore it 1759 * before acpi_video_device_lcd_set_level() is called next time. 1760 */ 1761 device->backlight->props.brightness = 1762 acpi_video_get_brightness(device->backlight); 1763 1764 device->cooling_dev = thermal_cooling_device_register("LCD", 1765 device->dev, &video_cooling_ops); 1766 if (IS_ERR(device->cooling_dev)) { 1767 /* 1768 * Set cooling_dev to NULL so we don't crash trying to free it. 1769 * Also, why the hell we are returning early and not attempt to 1770 * register video output if cooling device registration failed? 1771 * -- dtor 1772 */ 1773 device->cooling_dev = NULL; 1774 return; 1775 } 1776 1777 dev_info(&device->dev->dev, "registered as cooling_device%d\n", 1778 device->cooling_dev->id); 1779 result = sysfs_create_link(&device->dev->dev.kobj, 1780 &device->cooling_dev->device.kobj, 1781 "thermal_cooling"); 1782 if (result) 1783 printk(KERN_ERR PREFIX "Create sysfs link\n"); 1784 result = sysfs_create_link(&device->cooling_dev->device.kobj, 1785 &device->dev->dev.kobj, "device"); 1786 if (result) 1787 printk(KERN_ERR PREFIX "Create sysfs link\n"); 1788} 1789 1790static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) 1791{ 1792 struct acpi_video_device *dev; 1793 1794 if (video->backlight_registered) 1795 return 0; 1796 1797 if (!acpi_video_verify_backlight_support()) 1798 return 0; 1799 1800 mutex_lock(&video->device_list_lock); 1801 list_for_each_entry(dev, &video->video_device_list, entry) 1802 acpi_video_dev_register_backlight(dev); 1803 mutex_unlock(&video->device_list_lock); 1804 1805 video->backlight_registered = true; 1806 1807 video->pm_nb.notifier_call = acpi_video_resume; 1808 video->pm_nb.priority = 0; 1809 return register_pm_notifier(&video->pm_nb); 1810} 1811 1812static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device) 1813{ 1814 if (device->backlight) { 1815 backlight_device_unregister(device->backlight); 1816 device->backlight = NULL; 1817 } 1818 if (device->brightness) { 1819 kfree(device->brightness->levels); 1820 kfree(device->brightness); 1821 device->brightness = NULL; 1822 } 1823 if (device->cooling_dev) { 1824 sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling"); 1825 sysfs_remove_link(&device->cooling_dev->device.kobj, "device"); 1826 thermal_cooling_device_unregister(device->cooling_dev); 1827 device->cooling_dev = NULL; 1828 } 1829} 1830 1831static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) 1832{ 1833 struct acpi_video_device *dev; 1834 int error; 1835 1836 if (!video->backlight_registered) 1837 return 0; 1838 1839 error = unregister_pm_notifier(&video->pm_nb); 1840 1841 mutex_lock(&video->device_list_lock); 1842 list_for_each_entry(dev, &video->video_device_list, entry) 1843 acpi_video_dev_unregister_backlight(dev); 1844 mutex_unlock(&video->device_list_lock); 1845 1846 video->backlight_registered = false; 1847 1848 return error; 1849} 1850 1851static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device) 1852{ 1853 acpi_status status; 1854 struct acpi_device *adev = device->dev; 1855 1856 status = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY, 1857 acpi_video_device_notify, device); 1858 if (ACPI_FAILURE(status)) 1859 dev_err(&adev->dev, "Error installing notify handler\n"); 1860 else 1861 device->flags.notify = 1; 1862} 1863 1864static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video) 1865{ 1866 struct input_dev *input; 1867 struct acpi_video_device *dev; 1868 int error; 1869 1870 video->input = input = input_allocate_device(); 1871 if (!input) { 1872 error = -ENOMEM; 1873 goto out; 1874 } 1875 1876 error = acpi_video_bus_start_devices(video); 1877 if (error) 1878 goto err_free_input; 1879 1880 snprintf(video->phys, sizeof(video->phys), 1881 "%s/video/input0", acpi_device_hid(video->device)); 1882 1883 input->name = acpi_device_name(video->device); 1884 input->phys = video->phys; 1885 input->id.bustype = BUS_HOST; 1886 input->id.product = 0x06; 1887 input->dev.parent = &video->device->dev; 1888 input->evbit[0] = BIT(EV_KEY); 1889 set_bit(KEY_SWITCHVIDEOMODE, input->keybit); 1890 set_bit(KEY_VIDEO_NEXT, input->keybit); 1891 set_bit(KEY_VIDEO_PREV, input->keybit); 1892 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); 1893 set_bit(KEY_BRIGHTNESSUP, input->keybit); 1894 set_bit(KEY_BRIGHTNESSDOWN, input->keybit); 1895 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); 1896 set_bit(KEY_DISPLAY_OFF, input->keybit); 1897 1898 error = input_register_device(input); 1899 if (error) 1900 goto err_stop_dev; 1901 1902 mutex_lock(&video->device_list_lock); 1903 list_for_each_entry(dev, &video->video_device_list, entry) 1904 acpi_video_dev_add_notify_handler(dev); 1905 mutex_unlock(&video->device_list_lock); 1906 1907 return 0; 1908 1909err_stop_dev: 1910 acpi_video_bus_stop_devices(video); 1911err_free_input: 1912 input_free_device(input); 1913 video->input = NULL; 1914out: 1915 return error; 1916} 1917 1918static void acpi_video_dev_remove_notify_handler(struct acpi_video_device *dev) 1919{ 1920 if (dev->flags.notify) { 1921 acpi_remove_notify_handler(dev->dev->handle, ACPI_DEVICE_NOTIFY, 1922 acpi_video_device_notify); 1923 dev->flags.notify = 0; 1924 } 1925} 1926 1927static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video) 1928{ 1929 struct acpi_video_device *dev; 1930 1931 mutex_lock(&video->device_list_lock); 1932 list_for_each_entry(dev, &video->video_device_list, entry) 1933 acpi_video_dev_remove_notify_handler(dev); 1934 mutex_unlock(&video->device_list_lock); 1935 1936 acpi_video_bus_stop_devices(video); 1937 input_unregister_device(video->input); 1938 video->input = NULL; 1939} 1940 1941static int acpi_video_backlight_notify(struct notifier_block *nb, 1942 unsigned long val, void *bd) 1943{ 1944 struct backlight_device *backlight = bd; 1945 struct acpi_video_bus *video; 1946 1947 /* acpi_video_verify_backlight_support only cares about raw devices */ 1948 if (backlight->props.type != BACKLIGHT_RAW) 1949 return NOTIFY_DONE; 1950 1951 video = container_of(nb, struct acpi_video_bus, backlight_nb); 1952 1953 switch (val) { 1954 case BACKLIGHT_REGISTERED: 1955 if (!acpi_video_verify_backlight_support()) 1956 acpi_video_bus_unregister_backlight(video); 1957 break; 1958 case BACKLIGHT_UNREGISTERED: 1959 acpi_video_bus_register_backlight(video); 1960 break; 1961 } 1962 1963 return NOTIFY_OK; 1964} 1965 1966static int acpi_video_bus_add_backlight_notify_handler( 1967 struct acpi_video_bus *video) 1968{ 1969 int error; 1970 1971 video->backlight_nb.notifier_call = acpi_video_backlight_notify; 1972 video->backlight_nb.priority = 0; 1973 error = backlight_register_notifier(&video->backlight_nb); 1974 if (error == 0) 1975 video->backlight_notifier_registered = true; 1976 1977 return error; 1978} 1979 1980static int acpi_video_bus_remove_backlight_notify_handler( 1981 struct acpi_video_bus *video) 1982{ 1983 if (!video->backlight_notifier_registered) 1984 return 0; 1985 1986 video->backlight_notifier_registered = false; 1987 1988 return backlight_unregister_notifier(&video->backlight_nb); 1989} 1990 1991static int acpi_video_bus_put_devices(struct acpi_video_bus *video) 1992{ 1993 struct acpi_video_device *dev, *next; 1994 1995 mutex_lock(&video->device_list_lock); 1996 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { 1997 list_del(&dev->entry); 1998 kfree(dev); 1999 } 2000 mutex_unlock(&video->device_list_lock); 2001 2002 return 0; 2003} 2004 2005static int instance; 2006 2007static int acpi_video_bus_add(struct acpi_device *device) 2008{ 2009 struct acpi_video_bus *video; 2010 int error; 2011 acpi_status status; 2012 2013 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, 2014 device->parent->handle, 1, 2015 acpi_video_bus_match, NULL, 2016 device, NULL); 2017 if (status == AE_ALREADY_EXISTS) { 2018 printk(KERN_WARNING FW_BUG 2019 "Duplicate ACPI video bus devices for the" 2020 " same VGA controller, please try module " 2021 "parameter \"video.allow_duplicates=1\"" 2022 "if the current driver doesn't work.\n"); 2023 if (!allow_duplicates) 2024 return -ENODEV; 2025 } 2026 2027 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); 2028 if (!video) 2029 return -ENOMEM; 2030 2031 /* a hack to fix the duplicate name "VID" problem on T61 */ 2032 if (!strcmp(device->pnp.bus_id, "VID")) { 2033 if (instance) 2034 device->pnp.bus_id[3] = '0' + instance; 2035 instance++; 2036 } 2037 /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ 2038 if (!strcmp(device->pnp.bus_id, "VGA")) { 2039 if (instance) 2040 device->pnp.bus_id[3] = '0' + instance; 2041 instance++; 2042 } 2043 2044 video->device = device; 2045 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); 2046 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 2047 device->driver_data = video; 2048 2049 acpi_video_bus_find_cap(video); 2050 error = acpi_video_bus_check(video); 2051 if (error) 2052 goto err_free_video; 2053 2054 mutex_init(&video->device_list_lock); 2055 INIT_LIST_HEAD(&video->video_device_list); 2056 2057 error = acpi_video_bus_get_devices(video, device); 2058 if (error) 2059 goto err_put_video; 2060 2061 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 2062 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 2063 video->flags.multihead ? "yes" : "no", 2064 video->flags.rom ? "yes" : "no", 2065 video->flags.post ? "yes" : "no"); 2066 mutex_lock(&video_list_lock); 2067 list_add_tail(&video->entry, &video_bus_head); 2068 mutex_unlock(&video_list_lock); 2069 2070 acpi_video_bus_register_backlight(video); 2071 acpi_video_bus_add_notify_handler(video); 2072 acpi_video_bus_add_backlight_notify_handler(video); 2073 2074 return 0; 2075 2076err_put_video: 2077 acpi_video_bus_put_devices(video); 2078 kfree(video->attached_array); 2079err_free_video: 2080 kfree(video); 2081 device->driver_data = NULL; 2082 2083 return error; 2084} 2085 2086static int acpi_video_bus_remove(struct acpi_device *device) 2087{ 2088 struct acpi_video_bus *video = NULL; 2089 2090 2091 if (!device || !acpi_driver_data(device)) 2092 return -EINVAL; 2093 2094 video = acpi_driver_data(device); 2095 2096 acpi_video_bus_remove_backlight_notify_handler(video); 2097 acpi_video_bus_remove_notify_handler(video); 2098 acpi_video_bus_unregister_backlight(video); 2099 acpi_video_bus_put_devices(video); 2100 2101 mutex_lock(&video_list_lock); 2102 list_del(&video->entry); 2103 mutex_unlock(&video_list_lock); 2104 2105 kfree(video->attached_array); 2106 kfree(video); 2107 2108 return 0; 2109} 2110 2111static int __init is_i740(struct pci_dev *dev) 2112{ 2113 if (dev->device == 0x00D1) 2114 return 1; 2115 if (dev->device == 0x7000) 2116 return 1; 2117 return 0; 2118} 2119 2120static int __init intel_opregion_present(void) 2121{ 2122 int opregion = 0; 2123 struct pci_dev *dev = NULL; 2124 u32 address; 2125 2126 for_each_pci_dev(dev) { 2127 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 2128 continue; 2129 if (dev->vendor != PCI_VENDOR_ID_INTEL) 2130 continue; 2131 /* We don't want to poke around undefined i740 registers */ 2132 if (is_i740(dev)) 2133 continue; 2134 pci_read_config_dword(dev, 0xfc, &address); 2135 if (!address) 2136 continue; 2137 opregion = 1; 2138 } 2139 return opregion; 2140} 2141 2142int acpi_video_register(void) 2143{ 2144 int result = 0; 2145 if (register_count) { 2146 /* 2147 * if the function of acpi_video_register is already called, 2148 * don't register the acpi_vide_bus again and return no error. 2149 */ 2150 return 0; 2151 } 2152 2153 mutex_init(&video_list_lock); 2154 INIT_LIST_HEAD(&video_bus_head); 2155 2156 result = acpi_bus_register_driver(&acpi_video_bus); 2157 if (result < 0) 2158 return -ENODEV; 2159 2160 /* 2161 * When the acpi_video_bus is loaded successfully, increase 2162 * the counter reference. 2163 */ 2164 register_count = 1; 2165 2166 return 0; 2167} 2168EXPORT_SYMBOL(acpi_video_register); 2169 2170void acpi_video_unregister(void) 2171{ 2172 if (!register_count) { 2173 /* 2174 * If the acpi video bus is already unloaded, don't 2175 * unload it again and return directly. 2176 */ 2177 return; 2178 } 2179 acpi_bus_unregister_driver(&acpi_video_bus); 2180 2181 register_count = 0; 2182 2183 return; 2184} 2185EXPORT_SYMBOL(acpi_video_unregister); 2186 2187void acpi_video_unregister_backlight(void) 2188{ 2189 struct acpi_video_bus *video; 2190 2191 if (!register_count) 2192 return; 2193 2194 mutex_lock(&video_list_lock); 2195 list_for_each_entry(video, &video_bus_head, entry) 2196 acpi_video_bus_unregister_backlight(video); 2197 mutex_unlock(&video_list_lock); 2198} 2199EXPORT_SYMBOL(acpi_video_unregister_backlight); 2200 2201/* 2202 * This is kind of nasty. Hardware using Intel chipsets may require 2203 * the video opregion code to be run first in order to initialise 2204 * state before any ACPI video calls are made. To handle this we defer 2205 * registration of the video class until the opregion code has run. 2206 */ 2207 2208static int __init acpi_video_init(void) 2209{ 2210 dmi_check_system(video_dmi_table); 2211 2212 if (intel_opregion_present()) 2213 return 0; 2214 2215 return acpi_video_register(); 2216} 2217 2218static void __exit acpi_video_exit(void) 2219{ 2220 acpi_video_unregister(); 2221 2222 return; 2223} 2224 2225module_init(acpi_video_init); 2226module_exit(acpi_video_exit);