linux/drivers/acpi/video.c
<<
>>
Prefs
   1/*
   2 *  video.c - ACPI Video Driver ($Revision:$)
   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 <asm/uaccess.h>
  41#include <linux/dmi.h>
  42#include <acpi/acpi_bus.h>
  43#include <acpi/acpi_drivers.h>
  44#include <linux/suspend.h>
  45#include <acpi/video.h>
  46
  47#define PREFIX "ACPI: "
  48
  49#define ACPI_VIDEO_BUS_NAME             "Video Bus"
  50#define ACPI_VIDEO_DEVICE_NAME          "Video Device"
  51#define ACPI_VIDEO_NOTIFY_SWITCH        0x80
  52#define ACPI_VIDEO_NOTIFY_PROBE         0x81
  53#define ACPI_VIDEO_NOTIFY_CYCLE         0x82
  54#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT   0x83
  55#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT   0x84
  56
  57#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS      0x85
  58#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x86
  59#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS        0x87
  60#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS       0x88
  61#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF           0x89
  62
  63#define MAX_NAME_LEN    20
  64
  65#define _COMPONENT              ACPI_VIDEO_COMPONENT
  66ACPI_MODULE_NAME("video");
  67
  68MODULE_AUTHOR("Bruno Ducrot");
  69MODULE_DESCRIPTION("ACPI Video Driver");
  70MODULE_LICENSE("GPL");
  71
  72static bool brightness_switch_enabled = 1;
  73module_param(brightness_switch_enabled, bool, 0644);
  74
  75/*
  76 * By default, we don't allow duplicate ACPI video bus devices
  77 * under the same VGA controller
  78 */
  79static bool allow_duplicates;
  80module_param(allow_duplicates, bool, 0644);
  81
  82/*
  83 * Some BIOSes claim they use minimum backlight at boot,
  84 * and this may bring dimming screen after boot
  85 */
  86static bool use_bios_initial_backlight = 1;
  87module_param(use_bios_initial_backlight, bool, 0644);
  88
  89static int register_count = 0;
  90static int acpi_video_bus_add(struct acpi_device *device);
  91static int acpi_video_bus_remove(struct acpi_device *device, int type);
  92static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
  93
  94static const struct acpi_device_id video_device_ids[] = {
  95        {ACPI_VIDEO_HID, 0},
  96        {"", 0},
  97};
  98MODULE_DEVICE_TABLE(acpi, video_device_ids);
  99
 100static struct acpi_driver acpi_video_bus = {
 101        .name = "video",
 102        .class = ACPI_VIDEO_CLASS,
 103        .ids = video_device_ids,
 104        .ops = {
 105                .add = acpi_video_bus_add,
 106                .remove = acpi_video_bus_remove,
 107                .notify = acpi_video_bus_notify,
 108                },
 109};
 110
 111struct acpi_video_bus_flags {
 112        u8 multihead:1;         /* can switch video heads */
 113        u8 rom:1;               /* can retrieve a video rom */
 114        u8 post:1;              /* can configure the head to */
 115        u8 reserved:5;
 116};
 117
 118struct acpi_video_bus_cap {
 119        u8 _DOS:1;              /*Enable/Disable output switching */
 120        u8 _DOD:1;              /*Enumerate all devices attached to display adapter */
 121        u8 _ROM:1;              /*Get ROM Data */
 122        u8 _GPD:1;              /*Get POST Device */
 123        u8 _SPD:1;              /*Set POST Device */
 124        u8 _VPO:1;              /*Video POST Options */
 125        u8 reserved:2;
 126};
 127
 128struct acpi_video_device_attrib {
 129        u32 display_index:4;    /* A zero-based instance of the Display */
 130        u32 display_port_attachment:4;  /*This field differentiates the display type */
 131        u32 display_type:4;     /*Describe the specific type in use */
 132        u32 vendor_specific:4;  /*Chipset Vendor Specific */
 133        u32 bios_can_detect:1;  /*BIOS can detect the device */
 134        u32 depend_on_vga:1;    /*Non-VGA output device whose power is related to 
 135                                   the VGA device. */
 136        u32 pipe_id:3;          /*For VGA multiple-head devices. */
 137        u32 reserved:10;        /*Must be 0 */
 138        u32 device_id_scheme:1; /*Device ID Scheme */
 139};
 140
 141struct acpi_video_enumerated_device {
 142        union {
 143                u32 int_val;
 144                struct acpi_video_device_attrib attrib;
 145        } value;
 146        struct acpi_video_device *bind_info;
 147};
 148
 149struct acpi_video_bus {
 150        struct acpi_device *device;
 151        u8 dos_setting;
 152        struct acpi_video_enumerated_device *attached_array;
 153        u8 attached_count;
 154        struct acpi_video_bus_cap cap;
 155        struct acpi_video_bus_flags flags;
 156        struct list_head video_device_list;
 157        struct mutex device_list_lock;  /* protects video_device_list */
 158        struct input_dev *input;
 159        char phys[32];  /* for input device */
 160        struct notifier_block pm_nb;
 161};
 162
 163struct acpi_video_device_flags {
 164        u8 crt:1;
 165        u8 lcd:1;
 166        u8 tvout:1;
 167        u8 dvi:1;
 168        u8 bios:1;
 169        u8 unknown:1;
 170        u8 reserved:2;
 171};
 172
 173struct acpi_video_device_cap {
 174        u8 _ADR:1;              /*Return the unique ID */
 175        u8 _BCL:1;              /*Query list of brightness control levels supported */
 176        u8 _BCM:1;              /*Set the brightness level */
 177        u8 _BQC:1;              /* Get current brightness level */
 178        u8 _BCQ:1;              /* Some buggy BIOS uses _BCQ instead of _BQC */
 179        u8 _DDC:1;              /*Return the EDID for this device */
 180};
 181
 182struct acpi_video_brightness_flags {
 183        u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
 184        u8 _BCL_reversed:1;             /* _BCL package is in a reversed order*/
 185        u8 _BCL_use_index:1;            /* levels in _BCL are index values */
 186        u8 _BCM_use_index:1;            /* input of _BCM is an index value */
 187        u8 _BQC_use_index:1;            /* _BQC returns an index value */
 188};
 189
 190struct acpi_video_device_brightness {
 191        int curr;
 192        int count;
 193        int *levels;
 194        struct acpi_video_brightness_flags flags;
 195};
 196
 197struct acpi_video_device {
 198        unsigned long device_id;
 199        struct acpi_video_device_flags flags;
 200        struct acpi_video_device_cap cap;
 201        struct list_head entry;
 202        struct acpi_video_bus *video;
 203        struct acpi_device *dev;
 204        struct acpi_video_device_brightness *brightness;
 205        struct backlight_device *backlight;
 206        struct thermal_cooling_device *cooling_dev;
 207};
 208
 209static const char device_decode[][30] = {
 210        "motherboard VGA device",
 211        "PCI VGA device",
 212        "AGP VGA device",
 213        "UNKNOWN",
 214};
 215
 216static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);
 217static void acpi_video_device_rebind(struct acpi_video_bus *video);
 218static void acpi_video_device_bind(struct acpi_video_bus *video,
 219                                   struct acpi_video_device *device);
 220static int acpi_video_device_enumerate(struct acpi_video_bus *video);
 221static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
 222                        int level);
 223static int acpi_video_device_lcd_get_level_current(
 224                        struct acpi_video_device *device,
 225                        unsigned long long *level, int init);
 226static int acpi_video_get_next_level(struct acpi_video_device *device,
 227                                     u32 level_current, u32 event);
 228static int acpi_video_switch_brightness(struct acpi_video_device *device,
 229                                         int event);
 230
 231/*backlight device sysfs support*/
 232static int acpi_video_get_brightness(struct backlight_device *bd)
 233{
 234        unsigned long long cur_level;
 235        int i;
 236        struct acpi_video_device *vd =
 237                (struct acpi_video_device *)bl_get_data(bd);
 238
 239        if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0))
 240                return -EINVAL;
 241        for (i = 2; i < vd->brightness->count; i++) {
 242                if (vd->brightness->levels[i] == cur_level)
 243                        /* The first two entries are special - see page 575
 244                           of the ACPI spec 3.0 */
 245                        return i-2;
 246        }
 247        return 0;
 248}
 249
 250static int acpi_video_set_brightness(struct backlight_device *bd)
 251{
 252        int request_level = bd->props.brightness + 2;
 253        struct acpi_video_device *vd =
 254                (struct acpi_video_device *)bl_get_data(bd);
 255
 256        return acpi_video_device_lcd_set_level(vd,
 257                                vd->brightness->levels[request_level]);
 258}
 259
 260static const struct backlight_ops acpi_backlight_ops = {
 261        .get_brightness = acpi_video_get_brightness,
 262        .update_status  = acpi_video_set_brightness,
 263};
 264
 265/* thermal cooling device callbacks */
 266static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned
 267                               long *state)
 268{
 269        struct acpi_device *device = cooling_dev->devdata;
 270        struct acpi_video_device *video = acpi_driver_data(device);
 271
 272        *state = video->brightness->count - 3;
 273        return 0;
 274}
 275
 276static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned
 277                               long *state)
 278{
 279        struct acpi_device *device = cooling_dev->devdata;
 280        struct acpi_video_device *video = acpi_driver_data(device);
 281        unsigned long long level;
 282        int offset;
 283
 284        if (acpi_video_device_lcd_get_level_current(video, &level, 0))
 285                return -EINVAL;
 286        for (offset = 2; offset < video->brightness->count; offset++)
 287                if (level == video->brightness->levels[offset]) {
 288                        *state = video->brightness->count - offset - 1;
 289                        return 0;
 290                }
 291
 292        return -EINVAL;
 293}
 294
 295static int
 296video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state)
 297{
 298        struct acpi_device *device = cooling_dev->devdata;
 299        struct acpi_video_device *video = acpi_driver_data(device);
 300        int level;
 301
 302        if ( state >= video->brightness->count - 2)
 303                return -EINVAL;
 304
 305        state = video->brightness->count - state;
 306        level = video->brightness->levels[state -1];
 307        return acpi_video_device_lcd_set_level(video, level);
 308}
 309
 310static const struct thermal_cooling_device_ops video_cooling_ops = {
 311        .get_max_state = video_get_max_state,
 312        .get_cur_state = video_get_cur_state,
 313        .set_cur_state = video_set_cur_state,
 314};
 315
 316/* --------------------------------------------------------------------------
 317                               Video Management
 318   -------------------------------------------------------------------------- */
 319
 320static int
 321acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
 322                                   union acpi_object **levels)
 323{
 324        int status;
 325        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 326        union acpi_object *obj;
 327
 328
 329        *levels = NULL;
 330
 331        status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
 332        if (!ACPI_SUCCESS(status))
 333                return status;
 334        obj = (union acpi_object *)buffer.pointer;
 335        if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
 336                printk(KERN_ERR PREFIX "Invalid _BCL data\n");
 337                status = -EFAULT;
 338                goto err;
 339        }
 340
 341        *levels = obj;
 342
 343        return 0;
 344
 345      err:
 346        kfree(buffer.pointer);
 347
 348        return status;
 349}
 350
 351static int
 352acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 353{
 354        int status;
 355        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 356        struct acpi_object_list args = { 1, &arg0 };
 357        int state;
 358
 359        arg0.integer.value = level;
 360
 361        status = acpi_evaluate_object(device->dev->handle, "_BCM",
 362                                      &args, NULL);
 363        if (ACPI_FAILURE(status)) {
 364                ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
 365                return -EIO;
 366        }
 367
 368        device->brightness->curr = level;
 369        for (state = 2; state < device->brightness->count; state++)
 370                if (level == device->brightness->levels[state]) {
 371                        if (device->backlight)
 372                                device->backlight->props.brightness = state - 2;
 373                        return 0;
 374                }
 375
 376        ACPI_ERROR((AE_INFO, "Current brightness invalid"));
 377        return -EINVAL;
 378}
 379
 380/*
 381 * For some buggy _BQC methods, we need to add a constant value to
 382 * the _BQC return value to get the actual current brightness level
 383 */
 384
 385static int bqc_offset_aml_bug_workaround;
 386static int __init video_set_bqc_offset(const struct dmi_system_id *d)
 387{
 388        bqc_offset_aml_bug_workaround = 9;
 389        return 0;
 390}
 391
 392static struct dmi_system_id video_dmi_table[] __initdata = {
 393        /*
 394         * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
 395         */
 396        {
 397         .callback = video_set_bqc_offset,
 398         .ident = "Acer Aspire 5720",
 399         .matches = {
 400                DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
 401                DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
 402                },
 403        },
 404        {
 405         .callback = video_set_bqc_offset,
 406         .ident = "Acer Aspire 5710Z",
 407         .matches = {
 408                DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
 409                DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
 410                },
 411        },
 412        {
 413         .callback = video_set_bqc_offset,
 414         .ident = "eMachines E510",
 415         .matches = {
 416                DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"),
 417                DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"),
 418                },
 419        },
 420        {
 421         .callback = video_set_bqc_offset,
 422         .ident = "Acer Aspire 5315",
 423         .matches = {
 424                DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
 425                DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
 426                },
 427        },
 428        {
 429         .callback = video_set_bqc_offset,
 430         .ident = "Acer Aspire 7720",
 431         .matches = {
 432                DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
 433                DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"),
 434                },
 435        },
 436        {}
 437};
 438
 439static int
 440acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
 441                                        unsigned long long *level, int init)
 442{
 443        acpi_status status = AE_OK;
 444        int i;
 445
 446        if (device->cap._BQC || device->cap._BCQ) {
 447                char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
 448
 449                status = acpi_evaluate_integer(device->dev->handle, buf,
 450                                                NULL, level);
 451                if (ACPI_SUCCESS(status)) {
 452                        if (device->brightness->flags._BQC_use_index) {
 453                                if (device->brightness->flags._BCL_reversed)
 454                                        *level = device->brightness->count
 455                                                                 - 3 - (*level);
 456                                *level = device->brightness->levels[*level + 2];
 457
 458                        }
 459                        *level += bqc_offset_aml_bug_workaround;
 460                        for (i = 2; i < device->brightness->count; i++)
 461                                if (device->brightness->levels[i] == *level) {
 462                                        device->brightness->curr = *level;
 463                                        return 0;
 464                        }
 465                        if (!init) {
 466                                /*
 467                                 * BQC returned an invalid level.
 468                                 * Stop using it.
 469                                 */
 470                                ACPI_WARNING((AE_INFO,
 471                                              "%s returned an invalid level",
 472                                              buf));
 473                                device->cap._BQC = device->cap._BCQ = 0;
 474                        }
 475                } else {
 476                        /* Fixme:
 477                         * should we return an error or ignore this failure?
 478                         * dev->brightness->curr is a cached value which stores
 479                         * the correct current backlight level in most cases.
 480                         * ACPI video backlight still works w/ buggy _BQC.
 481                         * http://bugzilla.kernel.org/show_bug.cgi?id=12233
 482                         */
 483                        ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
 484                        device->cap._BQC = device->cap._BCQ = 0;
 485                }
 486        }
 487
 488        *level = device->brightness->curr;
 489        return 0;
 490}
 491
 492static int
 493acpi_video_device_EDID(struct acpi_video_device *device,
 494                       union acpi_object **edid, ssize_t length)
 495{
 496        int status;
 497        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 498        union acpi_object *obj;
 499        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 500        struct acpi_object_list args = { 1, &arg0 };
 501
 502
 503        *edid = NULL;
 504
 505        if (!device)
 506                return -ENODEV;
 507        if (length == 128)
 508                arg0.integer.value = 1;
 509        else if (length == 256)
 510                arg0.integer.value = 2;
 511        else
 512                return -EINVAL;
 513
 514        status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
 515        if (ACPI_FAILURE(status))
 516                return -ENODEV;
 517
 518        obj = buffer.pointer;
 519
 520        if (obj && obj->type == ACPI_TYPE_BUFFER)
 521                *edid = obj;
 522        else {
 523                printk(KERN_ERR PREFIX "Invalid _DDC data\n");
 524                status = -EFAULT;
 525                kfree(obj);
 526        }
 527
 528        return status;
 529}
 530
 531/* bus */
 532
 533/*
 534 *  Arg:
 535 *      video           : video bus device pointer
 536 *      bios_flag       : 
 537 *              0.      The system BIOS should NOT automatically switch(toggle)
 538 *                      the active display output.
 539 *              1.      The system BIOS should automatically switch (toggle) the
 540 *                      active display output. No switch event.
 541 *              2.      The _DGS value should be locked.
 542 *              3.      The system BIOS should not automatically switch (toggle) the
 543 *                      active display output, but instead generate the display switch
 544 *                      event notify code.
 545 *      lcd_flag        :
 546 *              0.      The system BIOS should automatically control the brightness level
 547 *                      of the LCD when the power changes from AC to DC
 548 *              1.      The system BIOS should NOT automatically control the brightness 
 549 *                      level of the LCD when the power changes from AC to DC.
 550 * Return Value:
 551 *              -EINVAL wrong arg.
 552 */
 553
 554static int
 555acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
 556{
 557        acpi_status status;
 558        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 559        struct acpi_object_list args = { 1, &arg0 };
 560
 561        if (!video->cap._DOS)
 562                return 0;
 563
 564        if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)
 565                return -EINVAL;
 566        arg0.integer.value = (lcd_flag << 2) | bios_flag;
 567        video->dos_setting = arg0.integer.value;
 568        status = acpi_evaluate_object(video->device->handle, "_DOS",
 569                &args, NULL);
 570        if (ACPI_FAILURE(status))
 571                return -EIO;
 572
 573        return 0;
 574}
 575
 576/*
 577 * Simple comparison function used to sort backlight levels.
 578 */
 579
 580static int
 581acpi_video_cmp_level(const void *a, const void *b)
 582{
 583        return *(int *)a - *(int *)b;
 584}
 585
 586/*
 587 *  Arg:        
 588 *      device  : video output device (LCD, CRT, ..)
 589 *
 590 *  Return Value:
 591 *      Maximum brightness level
 592 *
 593 *  Allocate and initialize device->brightness.
 594 */
 595
 596static int
 597acpi_video_init_brightness(struct acpi_video_device *device)
 598{
 599        union acpi_object *obj = NULL;
 600        int i, max_level = 0, count = 0, level_ac_battery = 0;
 601        unsigned long long level, level_old;
 602        union acpi_object *o;
 603        struct acpi_video_device_brightness *br = NULL;
 604        int result = -EINVAL;
 605
 606        if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
 607                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
 608                                                "LCD brightness level\n"));
 609                goto out;
 610        }
 611
 612        if (obj->package.count < 2)
 613                goto out;
 614
 615        br = kzalloc(sizeof(*br), GFP_KERNEL);
 616        if (!br) {
 617                printk(KERN_ERR "can't allocate memory\n");
 618                result = -ENOMEM;
 619                goto out;
 620        }
 621
 622        br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
 623                                GFP_KERNEL);
 624        if (!br->levels) {
 625                result = -ENOMEM;
 626                goto out_free;
 627        }
 628
 629        for (i = 0; i < obj->package.count; i++) {
 630                o = (union acpi_object *)&obj->package.elements[i];
 631                if (o->type != ACPI_TYPE_INTEGER) {
 632                        printk(KERN_ERR PREFIX "Invalid data\n");
 633                        continue;
 634                }
 635                br->levels[count] = (u32) o->integer.value;
 636
 637                if (br->levels[count] > max_level)
 638                        max_level = br->levels[count];
 639                count++;
 640        }
 641
 642        /*
 643         * some buggy BIOS don't export the levels
 644         * when machine is on AC/Battery in _BCL package.
 645         * In this case, the first two elements in _BCL packages
 646         * are also supported brightness levels that OS should take care of.
 647         */
 648        for (i = 2; i < count; i++) {
 649                if (br->levels[i] == br->levels[0])
 650                        level_ac_battery++;
 651                if (br->levels[i] == br->levels[1])
 652                        level_ac_battery++;
 653        }
 654
 655        if (level_ac_battery < 2) {
 656                level_ac_battery = 2 - level_ac_battery;
 657                br->flags._BCL_no_ac_battery_levels = 1;
 658                for (i = (count - 1 + level_ac_battery); i >= 2; i--)
 659                        br->levels[i] = br->levels[i - level_ac_battery];
 660                count += level_ac_battery;
 661        } else if (level_ac_battery > 2)
 662                ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
 663
 664        /* Check if the _BCL package is in a reversed order */
 665        if (max_level == br->levels[2]) {
 666                br->flags._BCL_reversed = 1;
 667                sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
 668                        acpi_video_cmp_level, NULL);
 669        } else if (max_level != br->levels[count - 1])
 670                ACPI_ERROR((AE_INFO,
 671                            "Found unordered _BCL package\n"));
 672
 673        br->count = count;
 674        device->brightness = br;
 675
 676        /* Check the input/output of _BQC/_BCL/_BCM */
 677        if ((max_level < 100) && (max_level <= (count - 2)))
 678                br->flags._BCL_use_index = 1;
 679
 680        /*
 681         * _BCM is always consistent with _BCL,
 682         * at least for all the laptops we have ever seen.
 683         */
 684        br->flags._BCM_use_index = br->flags._BCL_use_index;
 685
 686        /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
 687        br->curr = level = max_level;
 688
 689        if (!device->cap._BQC)
 690                goto set_level;
 691
 692        result = acpi_video_device_lcd_get_level_current(device, &level_old, 1);
 693        if (result)
 694                goto out_free_levels;
 695
 696        /*
 697         * Set the level to maximum and check if _BQC uses indexed value
 698         */
 699        result = acpi_video_device_lcd_set_level(device, max_level);
 700        if (result)
 701                goto out_free_levels;
 702
 703        result = acpi_video_device_lcd_get_level_current(device, &level, 0);
 704        if (result)
 705                goto out_free_levels;
 706
 707        br->flags._BQC_use_index = (level == max_level ? 0 : 1);
 708
 709        if (!br->flags._BQC_use_index) {
 710                /*
 711                 * Set the backlight to the initial state.
 712                 * On some buggy laptops, _BQC returns an uninitialized value
 713                 * when invoked for the first time, i.e. level_old is invalid.
 714                 * set the backlight to max_level in this case
 715                 */
 716                if (use_bios_initial_backlight) {
 717                        for (i = 2; i < br->count; i++)
 718                                if (level_old == br->levels[i])
 719                                        level = level_old;
 720                }
 721                goto set_level;
 722        }
 723
 724        if (br->flags._BCL_reversed)
 725                level_old = (br->count - 1) - level_old;
 726        level = br->levels[level_old];
 727
 728set_level:
 729        result = acpi_video_device_lcd_set_level(device, level);
 730        if (result)
 731                goto out_free_levels;
 732
 733        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 734                          "found %d brightness levels\n", count - 2));
 735        kfree(obj);
 736        return result;
 737
 738out_free_levels:
 739        kfree(br->levels);
 740out_free:
 741        kfree(br);
 742out:
 743        device->brightness = NULL;
 744        kfree(obj);
 745        return result;
 746}
 747
 748/*
 749 *  Arg:
 750 *      device  : video output device (LCD, CRT, ..)
 751 *
 752 *  Return Value:
 753 *      None
 754 *
 755 *  Find out all required AML methods defined under the output
 756 *  device.
 757 */
 758
 759static void acpi_video_device_find_cap(struct acpi_video_device *device)
 760{
 761        acpi_handle h_dummy1;
 762
 763        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
 764                device->cap._ADR = 1;
 765        }
 766        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) {
 767                device->cap._BCL = 1;
 768        }
 769        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
 770                device->cap._BCM = 1;
 771        }
 772        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
 773                device->cap._BQC = 1;
 774        else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
 775                                &h_dummy1))) {
 776                printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
 777                device->cap._BCQ = 1;
 778        }
 779
 780        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
 781                device->cap._DDC = 1;
 782        }
 783
 784        if (acpi_video_backlight_support()) {
 785                struct backlight_properties props;
 786                struct pci_dev *pdev;
 787                acpi_handle acpi_parent;
 788                struct device *parent = NULL;
 789                int result;
 790                static int count = 0;
 791                char *name;
 792
 793                result = acpi_video_init_brightness(device);
 794                if (result)
 795                        return;
 796                name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
 797                if (!name)
 798                        return;
 799                count++;
 800
 801                acpi_get_parent(device->dev->handle, &acpi_parent);
 802
 803                pdev = acpi_get_pci_dev(acpi_parent);
 804                if (pdev) {
 805                        parent = &pdev->dev;
 806                        pci_dev_put(pdev);
 807                }
 808
 809                memset(&props, 0, sizeof(struct backlight_properties));
 810                props.type = BACKLIGHT_FIRMWARE;
 811                props.max_brightness = device->brightness->count - 3;
 812                device->backlight = backlight_device_register(name,
 813                                                              parent,
 814                                                              device,
 815                                                              &acpi_backlight_ops,
 816                                                              &props);
 817                kfree(name);
 818                if (IS_ERR(device->backlight))
 819                        return;
 820
 821                /*
 822                 * Save current brightness level in case we have to restore it
 823                 * before acpi_video_device_lcd_set_level() is called next time.
 824                 */
 825                device->backlight->props.brightness =
 826                                acpi_video_get_brightness(device->backlight);
 827
 828                device->cooling_dev = thermal_cooling_device_register("LCD",
 829                                        device->dev, &video_cooling_ops);
 830                if (IS_ERR(device->cooling_dev)) {
 831                        /*
 832                         * Set cooling_dev to NULL so we don't crash trying to
 833                         * free it.
 834                         * Also, why the hell we are returning early and
 835                         * not attempt to register video output if cooling
 836                         * device registration failed?
 837                         * -- dtor
 838                         */
 839                        device->cooling_dev = NULL;
 840                        return;
 841                }
 842
 843                dev_info(&device->dev->dev, "registered as cooling_device%d\n",
 844                         device->cooling_dev->id);
 845                result = sysfs_create_link(&device->dev->dev.kobj,
 846                                &device->cooling_dev->device.kobj,
 847                                "thermal_cooling");
 848                if (result)
 849                        printk(KERN_ERR PREFIX "Create sysfs link\n");
 850                result = sysfs_create_link(&device->cooling_dev->device.kobj,
 851                                &device->dev->dev.kobj, "device");
 852                if (result)
 853                        printk(KERN_ERR PREFIX "Create sysfs link\n");
 854
 855        }
 856}
 857
 858/*
 859 *  Arg:        
 860 *      device  : video output device (VGA)
 861 *
 862 *  Return Value:
 863 *      None
 864 *
 865 *  Find out all required AML methods defined under the video bus device.
 866 */
 867
 868static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
 869{
 870        acpi_handle h_dummy1;
 871
 872        if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
 873                video->cap._DOS = 1;
 874        }
 875        if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) {
 876                video->cap._DOD = 1;
 877        }
 878        if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) {
 879                video->cap._ROM = 1;
 880        }
 881        if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) {
 882                video->cap._GPD = 1;
 883        }
 884        if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) {
 885                video->cap._SPD = 1;
 886        }
 887        if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) {
 888                video->cap._VPO = 1;
 889        }
 890}
 891
 892/*
 893 * Check whether the video bus device has required AML method to
 894 * support the desired features
 895 */
 896
 897static int acpi_video_bus_check(struct acpi_video_bus *video)
 898{
 899        acpi_status status = -ENOENT;
 900        struct pci_dev *dev;
 901
 902        if (!video)
 903                return -EINVAL;
 904
 905        dev = acpi_get_pci_dev(video->device->handle);
 906        if (!dev)
 907                return -ENODEV;
 908        pci_dev_put(dev);
 909
 910        /* Since there is no HID, CID and so on for VGA driver, we have
 911         * to check well known required nodes.
 912         */
 913
 914        /* Does this device support video switching? */
 915        if (video->cap._DOS || video->cap._DOD) {
 916                if (!video->cap._DOS) {
 917                        printk(KERN_WARNING FW_BUG
 918                                "ACPI(%s) defines _DOD but not _DOS\n",
 919                                acpi_device_bid(video->device));
 920                }
 921                video->flags.multihead = 1;
 922                status = 0;
 923        }
 924
 925        /* Does this device support retrieving a video ROM? */
 926        if (video->cap._ROM) {
 927                video->flags.rom = 1;
 928                status = 0;
 929        }
 930
 931        /* Does this device support configuring which video device to POST? */
 932        if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
 933                video->flags.post = 1;
 934                status = 0;
 935        }
 936
 937        return status;
 938}
 939
 940/* --------------------------------------------------------------------------
 941                                 Driver Interface
 942   -------------------------------------------------------------------------- */
 943
 944/* device interface */
 945static struct acpi_video_device_attrib*
 946acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
 947{
 948        struct acpi_video_enumerated_device *ids;
 949        int i;
 950
 951        for (i = 0; i < video->attached_count; i++) {
 952                ids = &video->attached_array[i];
 953                if ((ids->value.int_val & 0xffff) == device_id)
 954                        return &ids->value.attrib;
 955        }
 956
 957        return NULL;
 958}
 959
 960static int
 961acpi_video_get_device_type(struct acpi_video_bus *video,
 962                           unsigned long device_id)
 963{
 964        struct acpi_video_enumerated_device *ids;
 965        int i;
 966
 967        for (i = 0; i < video->attached_count; i++) {
 968                ids = &video->attached_array[i];
 969                if ((ids->value.int_val & 0xffff) == device_id)
 970                        return ids->value.int_val;
 971        }
 972
 973        return 0;
 974}
 975
 976static int
 977acpi_video_bus_get_one_device(struct acpi_device *device,
 978                              struct acpi_video_bus *video)
 979{
 980        unsigned long long device_id;
 981        int status, device_type;
 982        struct acpi_video_device *data;
 983        struct acpi_video_device_attrib* attribute;
 984
 985        if (!device || !video)
 986                return -EINVAL;
 987
 988        status =
 989            acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
 990        if (ACPI_SUCCESS(status)) {
 991
 992                data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
 993                if (!data)
 994                        return -ENOMEM;
 995
 996                strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
 997                strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
 998                device->driver_data = data;
 999
1000                data->device_id = device_id;
1001                data->video = video;
1002                data->dev = device;
1003
1004                attribute = acpi_video_get_device_attr(video, device_id);
1005
1006                if((attribute != NULL) && attribute->device_id_scheme) {
1007                        switch (attribute->display_type) {
1008                        case ACPI_VIDEO_DISPLAY_CRT:
1009                                data->flags.crt = 1;
1010                                break;
1011                        case ACPI_VIDEO_DISPLAY_TV:
1012                                data->flags.tvout = 1;
1013                                break;
1014                        case ACPI_VIDEO_DISPLAY_DVI:
1015                                data->flags.dvi = 1;
1016                                break;
1017                        case ACPI_VIDEO_DISPLAY_LCD:
1018                                data->flags.lcd = 1;
1019                                break;
1020                        default:
1021                                data->flags.unknown = 1;
1022                                break;
1023                        }
1024                        if(attribute->bios_can_detect)
1025                                data->flags.bios = 1;
1026                } else {
1027                        /* Check for legacy IDs */
1028                        device_type = acpi_video_get_device_type(video,
1029                                                                 device_id);
1030                        /* Ignore bits 16 and 18-20 */
1031                        switch (device_type & 0xffe2ffff) {
1032                        case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
1033                                data->flags.crt = 1;
1034                                break;
1035                        case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:
1036                                data->flags.lcd = 1;
1037                                break;
1038                        case ACPI_VIDEO_DISPLAY_LEGACY_TV:
1039                                data->flags.tvout = 1;
1040                                break;
1041                        default:
1042                                data->flags.unknown = 1;
1043                        }
1044                }
1045
1046                acpi_video_device_bind(video, data);
1047                acpi_video_device_find_cap(data);
1048
1049                status = acpi_install_notify_handler(device->handle,
1050                                                     ACPI_DEVICE_NOTIFY,
1051                                                     acpi_video_device_notify,
1052                                                     data);
1053                if (ACPI_FAILURE(status)) {
1054                        printk(KERN_ERR PREFIX
1055                                          "Error installing notify handler\n");
1056                        if(data->brightness)
1057                                kfree(data->brightness->levels);
1058                        kfree(data->brightness);
1059                        kfree(data);
1060                        return -ENODEV;
1061                }
1062
1063                mutex_lock(&video->device_list_lock);
1064                list_add_tail(&data->entry, &video->video_device_list);
1065                mutex_unlock(&video->device_list_lock);
1066
1067                return 0;
1068        }
1069
1070        return -ENOENT;
1071}
1072
1073/*
1074 *  Arg:
1075 *      video   : video bus device 
1076 *
1077 *  Return:
1078 *      none
1079 *  
1080 *  Enumerate the video device list of the video bus, 
1081 *  bind the ids with the corresponding video devices
1082 *  under the video bus.
1083 */
1084
1085static void acpi_video_device_rebind(struct acpi_video_bus *video)
1086{
1087        struct acpi_video_device *dev;
1088
1089        mutex_lock(&video->device_list_lock);
1090
1091        list_for_each_entry(dev, &video->video_device_list, entry)
1092                acpi_video_device_bind(video, dev);
1093
1094        mutex_unlock(&video->device_list_lock);
1095}
1096
1097/*
1098 *  Arg:
1099 *      video   : video bus device 
1100 *      device  : video output device under the video 
1101 *              bus
1102 *
1103 *  Return:
1104 *      none
1105 *  
1106 *  Bind the ids with the corresponding video devices
1107 *  under the video bus.
1108 */
1109
1110static void
1111acpi_video_device_bind(struct acpi_video_bus *video,
1112                       struct acpi_video_device *device)
1113{
1114        struct acpi_video_enumerated_device *ids;
1115        int i;
1116
1117        for (i = 0; i < video->attached_count; i++) {
1118                ids = &video->attached_array[i];
1119                if (device->device_id == (ids->value.int_val & 0xffff)) {
1120                        ids->bind_info = device;
1121                        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1122                }
1123        }
1124}
1125
1126/*
1127 *  Arg:
1128 *      video   : video bus device 
1129 *
1130 *  Return:
1131 *      < 0     : error
1132 *  
1133 *  Call _DOD to enumerate all devices attached to display adapter
1134 *
1135 */
1136
1137static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1138{
1139        int status;
1140        int count;
1141        int i;
1142        struct acpi_video_enumerated_device *active_list;
1143        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1144        union acpi_object *dod = NULL;
1145        union acpi_object *obj;
1146
1147        status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);
1148        if (!ACPI_SUCCESS(status)) {
1149                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD"));
1150                return status;
1151        }
1152
1153        dod = buffer.pointer;
1154        if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1155                ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1156                status = -EFAULT;
1157                goto out;
1158        }
1159
1160        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1161                          dod->package.count));
1162
1163        active_list = kcalloc(1 + dod->package.count,
1164                              sizeof(struct acpi_video_enumerated_device),
1165                              GFP_KERNEL);
1166        if (!active_list) {
1167                status = -ENOMEM;
1168                goto out;
1169        }
1170
1171        count = 0;
1172        for (i = 0; i < dod->package.count; i++) {
1173                obj = &dod->package.elements[i];
1174
1175                if (obj->type != ACPI_TYPE_INTEGER) {
1176                        printk(KERN_ERR PREFIX
1177                                "Invalid _DOD data in element %d\n", i);
1178                        continue;
1179                }
1180
1181                active_list[count].value.int_val = obj->integer.value;
1182                active_list[count].bind_info = NULL;
1183                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1184                                  (int)obj->integer.value));
1185                count++;
1186        }
1187
1188        kfree(video->attached_array);
1189
1190        video->attached_array = active_list;
1191        video->attached_count = count;
1192
1193 out:
1194        kfree(buffer.pointer);
1195        return status;
1196}
1197
1198static int
1199acpi_video_get_next_level(struct acpi_video_device *device,
1200                          u32 level_current, u32 event)
1201{
1202        int min, max, min_above, max_below, i, l, delta = 255;
1203        max = max_below = 0;
1204        min = min_above = 255;
1205        /* Find closest level to level_current */
1206        for (i = 2; i < device->brightness->count; i++) {
1207                l = device->brightness->levels[i];
1208                if (abs(l - level_current) < abs(delta)) {
1209                        delta = l - level_current;
1210                        if (!delta)
1211                                break;
1212                }
1213        }
1214        /* Ajust level_current to closest available level */
1215        level_current += delta;
1216        for (i = 2; i < device->brightness->count; i++) {
1217                l = device->brightness->levels[i];
1218                if (l < min)
1219                        min = l;
1220                if (l > max)
1221                        max = l;
1222                if (l < min_above && l > level_current)
1223                        min_above = l;
1224                if (l > max_below && l < level_current)
1225                        max_below = l;
1226        }
1227
1228        switch (event) {
1229        case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1230                return (level_current < max) ? min_above : min;
1231        case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1232                return (level_current < max) ? min_above : max;
1233        case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1234                return (level_current > min) ? max_below : min;
1235        case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1236        case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1237                return 0;
1238        default:
1239                return level_current;
1240        }
1241}
1242
1243static int
1244acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1245{
1246        unsigned long long level_current, level_next;
1247        int result = -EINVAL;
1248
1249        /* no warning message if acpi_backlight=vendor is used */
1250        if (!acpi_video_backlight_support())
1251                return 0;
1252
1253        if (!device->brightness)
1254                goto out;
1255
1256        result = acpi_video_device_lcd_get_level_current(device,
1257                                                         &level_current, 0);
1258        if (result)
1259                goto out;
1260
1261        level_next = acpi_video_get_next_level(device, level_current, event);
1262
1263        result = acpi_video_device_lcd_set_level(device, level_next);
1264
1265        if (!result)
1266                backlight_force_update(device->backlight,
1267                                       BACKLIGHT_UPDATE_HOTKEY);
1268
1269out:
1270        if (result)
1271                printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
1272
1273        return result;
1274}
1275
1276int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
1277                        void **edid)
1278{
1279        struct acpi_video_bus *video;
1280        struct acpi_video_device *video_device;
1281        union acpi_object *buffer = NULL;
1282        acpi_status status;
1283        int i, length;
1284
1285        if (!device || !acpi_driver_data(device))
1286                return -EINVAL;
1287
1288        video = acpi_driver_data(device);
1289
1290        for (i = 0; i < video->attached_count; i++) {
1291                video_device = video->attached_array[i].bind_info;
1292                length = 256;
1293
1294                if (!video_device)
1295                        continue;
1296
1297                if (!video_device->cap._DDC)
1298                        continue;
1299
1300                if (type) {
1301                        switch (type) {
1302                        case ACPI_VIDEO_DISPLAY_CRT:
1303                                if (!video_device->flags.crt)
1304                                        continue;
1305                                break;
1306                        case ACPI_VIDEO_DISPLAY_TV:
1307                                if (!video_device->flags.tvout)
1308                                        continue;
1309                                break;
1310                        case ACPI_VIDEO_DISPLAY_DVI:
1311                                if (!video_device->flags.dvi)
1312                                        continue;
1313                                break;
1314                        case ACPI_VIDEO_DISPLAY_LCD:
1315                                if (!video_device->flags.lcd)
1316                                        continue;
1317                                break;
1318                        }
1319                } else if (video_device->device_id != device_id) {
1320                        continue;
1321                }
1322
1323                status = acpi_video_device_EDID(video_device, &buffer, length);
1324
1325                if (ACPI_FAILURE(status) || !buffer ||
1326                    buffer->type != ACPI_TYPE_BUFFER) {
1327                        length = 128;
1328                        status = acpi_video_device_EDID(video_device, &buffer,
1329                                                        length);
1330                        if (ACPI_FAILURE(status) || !buffer ||
1331                            buffer->type != ACPI_TYPE_BUFFER) {
1332                                continue;
1333                        }
1334                }
1335
1336                *edid = buffer->buffer.pointer;
1337                return length;
1338        }
1339
1340        return -ENODEV;
1341}
1342EXPORT_SYMBOL(acpi_video_get_edid);
1343
1344static int
1345acpi_video_bus_get_devices(struct acpi_video_bus *video,
1346                           struct acpi_device *device)
1347{
1348        int status;
1349        struct acpi_device *dev;
1350
1351        status = acpi_video_device_enumerate(video);
1352        if (status)
1353                return status;
1354
1355        list_for_each_entry(dev, &device->children, node) {
1356
1357                status = acpi_video_bus_get_one_device(dev, video);
1358                if (status) {
1359                        printk(KERN_WARNING PREFIX
1360                                        "Can't attach device\n");
1361                        continue;
1362                }
1363        }
1364        return status;
1365}
1366
1367static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1368{
1369        acpi_status status;
1370
1371        if (!device || !device->video)
1372                return -ENOENT;
1373
1374        status = acpi_remove_notify_handler(device->dev->handle,
1375                                            ACPI_DEVICE_NOTIFY,
1376                                            acpi_video_device_notify);
1377        if (ACPI_FAILURE(status)) {
1378                printk(KERN_WARNING PREFIX
1379                       "Can't remove video notify handler\n");
1380        }
1381        if (device->backlight) {
1382                backlight_device_unregister(device->backlight);
1383                device->backlight = NULL;
1384        }
1385        if (device->cooling_dev) {
1386                sysfs_remove_link(&device->dev->dev.kobj,
1387                                  "thermal_cooling");
1388                sysfs_remove_link(&device->cooling_dev->device.kobj,
1389                                  "device");
1390                thermal_cooling_device_unregister(device->cooling_dev);
1391                device->cooling_dev = NULL;
1392        }
1393
1394        return 0;
1395}
1396
1397static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1398{
1399        int status;
1400        struct acpi_video_device *dev, *next;
1401
1402        mutex_lock(&video->device_list_lock);
1403
1404        list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1405
1406                status = acpi_video_bus_put_one_device(dev);
1407                if (ACPI_FAILURE(status))
1408                        printk(KERN_WARNING PREFIX
1409                               "hhuuhhuu bug in acpi video driver.\n");
1410
1411                if (dev->brightness) {
1412                        kfree(dev->brightness->levels);
1413                        kfree(dev->brightness);
1414                }
1415                list_del(&dev->entry);
1416                kfree(dev);
1417        }
1418
1419        mutex_unlock(&video->device_list_lock);
1420
1421        return 0;
1422}
1423
1424/* acpi_video interface */
1425
1426static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1427{
1428        return acpi_video_bus_DOS(video, 0, 0);
1429}
1430
1431static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1432{
1433        return acpi_video_bus_DOS(video, 0, 1);
1434}
1435
1436static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
1437{
1438        struct acpi_video_bus *video = acpi_driver_data(device);
1439        struct input_dev *input;
1440        int keycode = 0;
1441
1442        if (!video)
1443                return;
1444
1445        input = video->input;
1446
1447        switch (event) {
1448        case ACPI_VIDEO_NOTIFY_SWITCH:  /* User requested a switch,
1449                                         * most likely via hotkey. */
1450                acpi_bus_generate_proc_event(device, event, 0);
1451                if (!acpi_notifier_call_chain(device, event, 0))
1452                        keycode = KEY_SWITCHVIDEOMODE;
1453                break;
1454
1455        case ACPI_VIDEO_NOTIFY_PROBE:   /* User plugged in or removed a video
1456                                         * connector. */
1457                acpi_video_device_enumerate(video);
1458                acpi_video_device_rebind(video);
1459                acpi_bus_generate_proc_event(device, event, 0);
1460                keycode = KEY_SWITCHVIDEOMODE;
1461                break;
1462
1463        case ACPI_VIDEO_NOTIFY_CYCLE:   /* Cycle Display output hotkey pressed. */
1464                acpi_bus_generate_proc_event(device, event, 0);
1465                keycode = KEY_SWITCHVIDEOMODE;
1466                break;
1467        case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:     /* Next Display output hotkey pressed. */
1468                acpi_bus_generate_proc_event(device, event, 0);
1469                keycode = KEY_VIDEO_NEXT;
1470                break;
1471        case ACPI_VIDEO_NOTIFY_PREV_OUTPUT:     /* previous Display output hotkey pressed. */
1472                acpi_bus_generate_proc_event(device, event, 0);
1473                keycode = KEY_VIDEO_PREV;
1474                break;
1475
1476        default:
1477                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1478                                  "Unsupported event [0x%x]\n", event));
1479                break;
1480        }
1481
1482        if (event != ACPI_VIDEO_NOTIFY_SWITCH)
1483                acpi_notifier_call_chain(device, event, 0);
1484
1485        if (keycode) {
1486                input_report_key(input, keycode, 1);
1487                input_sync(input);
1488                input_report_key(input, keycode, 0);
1489                input_sync(input);
1490        }
1491
1492        return;
1493}
1494
1495static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1496{
1497        struct acpi_video_device *video_device = data;
1498        struct acpi_device *device = NULL;
1499        struct acpi_video_bus *bus;
1500        struct input_dev *input;
1501        int keycode = 0;
1502
1503        if (!video_device)
1504                return;
1505
1506        device = video_device->dev;
1507        bus = video_device->video;
1508        input = bus->input;
1509
1510        switch (event) {
1511        case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:        /* Cycle brightness */
1512                if (brightness_switch_enabled)
1513                        acpi_video_switch_brightness(video_device, event);
1514                acpi_bus_generate_proc_event(device, event, 0);
1515                keycode = KEY_BRIGHTNESS_CYCLE;
1516                break;
1517        case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:  /* Increase brightness */
1518                if (brightness_switch_enabled)
1519                        acpi_video_switch_brightness(video_device, event);
1520                acpi_bus_generate_proc_event(device, event, 0);
1521                keycode = KEY_BRIGHTNESSUP;
1522                break;
1523        case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:  /* Decrease brightness */
1524                if (brightness_switch_enabled)
1525                        acpi_video_switch_brightness(video_device, event);
1526                acpi_bus_generate_proc_event(device, event, 0);
1527                keycode = KEY_BRIGHTNESSDOWN;
1528                break;
1529        case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */
1530                if (brightness_switch_enabled)
1531                        acpi_video_switch_brightness(video_device, event);
1532                acpi_bus_generate_proc_event(device, event, 0);
1533                keycode = KEY_BRIGHTNESS_ZERO;
1534                break;
1535        case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:     /* display device off */
1536                if (brightness_switch_enabled)
1537                        acpi_video_switch_brightness(video_device, event);
1538                acpi_bus_generate_proc_event(device, event, 0);
1539                keycode = KEY_DISPLAY_OFF;
1540                break;
1541        default:
1542                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1543                                  "Unsupported event [0x%x]\n", event));
1544                break;
1545        }
1546
1547        acpi_notifier_call_chain(device, event, 0);
1548
1549        if (keycode) {
1550                input_report_key(input, keycode, 1);
1551                input_sync(input);
1552                input_report_key(input, keycode, 0);
1553                input_sync(input);
1554        }
1555
1556        return;
1557}
1558
1559static int acpi_video_resume(struct notifier_block *nb,
1560                                unsigned long val, void *ign)
1561{
1562        struct acpi_video_bus *video;
1563        struct acpi_video_device *video_device;
1564        int i;
1565
1566        switch (val) {
1567        case PM_HIBERNATION_PREPARE:
1568        case PM_SUSPEND_PREPARE:
1569        case PM_RESTORE_PREPARE:
1570                return NOTIFY_DONE;
1571        }
1572
1573        video = container_of(nb, struct acpi_video_bus, pm_nb);
1574
1575        dev_info(&video->device->dev, "Restoring backlight state\n");
1576
1577        for (i = 0; i < video->attached_count; i++) {
1578                video_device = video->attached_array[i].bind_info;
1579                if (video_device && video_device->backlight)
1580                        acpi_video_set_brightness(video_device->backlight);
1581        }
1582
1583        return NOTIFY_OK;
1584}
1585
1586static acpi_status
1587acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
1588                        void **return_value)
1589{
1590        struct acpi_device *device = context;
1591        struct acpi_device *sibling;
1592        int result;
1593
1594        if (handle == device->handle)
1595                return AE_CTRL_TERMINATE;
1596
1597        result = acpi_bus_get_device(handle, &sibling);
1598        if (result)
1599                return AE_OK;
1600
1601        if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))
1602                        return AE_ALREADY_EXISTS;
1603
1604        return AE_OK;
1605}
1606
1607static int instance;
1608
1609static int acpi_video_bus_add(struct acpi_device *device)
1610{
1611        struct acpi_video_bus *video;
1612        struct input_dev *input;
1613        int error;
1614        acpi_status status;
1615
1616        status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
1617                                device->parent->handle, 1,
1618                                acpi_video_bus_match, NULL,
1619                                device, NULL);
1620        if (status == AE_ALREADY_EXISTS) {
1621                printk(KERN_WARNING FW_BUG
1622                        "Duplicate ACPI video bus devices for the"
1623                        " same VGA controller, please try module "
1624                        "parameter \"video.allow_duplicates=1\""
1625                        "if the current driver doesn't work.\n");
1626                if (!allow_duplicates)
1627                        return -ENODEV;
1628        }
1629
1630        video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
1631        if (!video)
1632                return -ENOMEM;
1633
1634        /* a hack to fix the duplicate name "VID" problem on T61 */
1635        if (!strcmp(device->pnp.bus_id, "VID")) {
1636                if (instance)
1637                        device->pnp.bus_id[3] = '0' + instance;
1638                instance ++;
1639        }
1640        /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
1641        if (!strcmp(device->pnp.bus_id, "VGA")) {
1642                if (instance)
1643                        device->pnp.bus_id[3] = '0' + instance;
1644                instance++;
1645        }
1646
1647        video->device = device;
1648        strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
1649        strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1650        device->driver_data = video;
1651
1652        acpi_video_bus_find_cap(video);
1653        error = acpi_video_bus_check(video);
1654        if (error)
1655                goto err_free_video;
1656
1657        mutex_init(&video->device_list_lock);
1658        INIT_LIST_HEAD(&video->video_device_list);
1659
1660        error = acpi_video_bus_get_devices(video, device);
1661        if (error)
1662                goto err_free_video;
1663
1664        video->input = input = input_allocate_device();
1665        if (!input) {
1666                error = -ENOMEM;
1667                goto err_put_video;
1668        }
1669
1670        error = acpi_video_bus_start_devices(video);
1671        if (error)
1672                goto err_free_input_dev;
1673
1674        snprintf(video->phys, sizeof(video->phys),
1675                "%s/video/input0", acpi_device_hid(video->device));
1676
1677        input->name = acpi_device_name(video->device);
1678        input->phys = video->phys;
1679        input->id.bustype = BUS_HOST;
1680        input->id.product = 0x06;
1681        input->dev.parent = &device->dev;
1682        input->evbit[0] = BIT(EV_KEY);
1683        set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1684        set_bit(KEY_VIDEO_NEXT, input->keybit);
1685        set_bit(KEY_VIDEO_PREV, input->keybit);
1686        set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
1687        set_bit(KEY_BRIGHTNESSUP, input->keybit);
1688        set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
1689        set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1690        set_bit(KEY_DISPLAY_OFF, input->keybit);
1691
1692        printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s  rom: %s  post: %s)\n",
1693               ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
1694               video->flags.multihead ? "yes" : "no",
1695               video->flags.rom ? "yes" : "no",
1696               video->flags.post ? "yes" : "no");
1697
1698        video->pm_nb.notifier_call = acpi_video_resume;
1699        video->pm_nb.priority = 0;
1700        error = register_pm_notifier(&video->pm_nb);
1701        if (error)
1702                goto err_stop_video;
1703
1704        error = input_register_device(input);
1705        if (error)
1706                goto err_unregister_pm_notifier;
1707
1708        return 0;
1709
1710 err_unregister_pm_notifier:
1711        unregister_pm_notifier(&video->pm_nb);
1712 err_stop_video:
1713        acpi_video_bus_stop_devices(video);
1714 err_free_input_dev:
1715        input_free_device(input);
1716 err_put_video:
1717        acpi_video_bus_put_devices(video);
1718        kfree(video->attached_array);
1719 err_free_video:
1720        kfree(video);
1721        device->driver_data = NULL;
1722
1723        return error;
1724}
1725
1726static int acpi_video_bus_remove(struct acpi_device *device, int type)
1727{
1728        struct acpi_video_bus *video = NULL;
1729
1730
1731        if (!device || !acpi_driver_data(device))
1732                return -EINVAL;
1733
1734        video = acpi_driver_data(device);
1735
1736        unregister_pm_notifier(&video->pm_nb);
1737
1738        acpi_video_bus_stop_devices(video);
1739        acpi_video_bus_put_devices(video);
1740
1741        input_unregister_device(video->input);
1742        kfree(video->attached_array);
1743        kfree(video);
1744
1745        return 0;
1746}
1747
1748static int __init is_i740(struct pci_dev *dev)
1749{
1750        if (dev->device == 0x00D1)
1751                return 1;
1752        if (dev->device == 0x7000)
1753                return 1;
1754        return 0;
1755}
1756
1757static int __init intel_opregion_present(void)
1758{
1759        int opregion = 0;
1760        struct pci_dev *dev = NULL;
1761        u32 address;
1762
1763        for_each_pci_dev(dev) {
1764                if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
1765                        continue;
1766                if (dev->vendor != PCI_VENDOR_ID_INTEL)
1767                        continue;
1768                /* We don't want to poke around undefined i740 registers */
1769                if (is_i740(dev))
1770                        continue;
1771                pci_read_config_dword(dev, 0xfc, &address);
1772                if (!address)
1773                        continue;
1774                opregion = 1;
1775        }
1776        return opregion;
1777}
1778
1779int acpi_video_register(void)
1780{
1781        int result = 0;
1782        if (register_count) {
1783                /*
1784                 * if the function of acpi_video_register is already called,
1785                 * don't register the acpi_vide_bus again and return no error.
1786                 */
1787                return 0;
1788        }
1789
1790        result = acpi_bus_register_driver(&acpi_video_bus);
1791        if (result < 0)
1792                return -ENODEV;
1793
1794        /*
1795         * When the acpi_video_bus is loaded successfully, increase
1796         * the counter reference.
1797         */
1798        register_count = 1;
1799
1800        return 0;
1801}
1802EXPORT_SYMBOL(acpi_video_register);
1803
1804void acpi_video_unregister(void)
1805{
1806        if (!register_count) {
1807                /*
1808                 * If the acpi video bus is already unloaded, don't
1809                 * unload it again and return directly.
1810                 */
1811                return;
1812        }
1813        acpi_bus_unregister_driver(&acpi_video_bus);
1814
1815        register_count = 0;
1816
1817        return;
1818}
1819EXPORT_SYMBOL(acpi_video_unregister);
1820
1821/*
1822 * This is kind of nasty. Hardware using Intel chipsets may require
1823 * the video opregion code to be run first in order to initialise
1824 * state before any ACPI video calls are made. To handle this we defer
1825 * registration of the video class until the opregion code has run.
1826 */
1827
1828static int __init acpi_video_init(void)
1829{
1830        dmi_check_system(video_dmi_table);
1831
1832        if (intel_opregion_present())
1833                return 0;
1834
1835        return acpi_video_register();
1836}
1837
1838static void __exit acpi_video_exit(void)
1839{
1840        acpi_video_unregister();
1841
1842        return;
1843}
1844
1845module_init(acpi_video_init);
1846module_exit(acpi_video_exit);
1847
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.