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