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