]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'constify' into release
authorLen Brown <len.brown@intel.com>
Sun, 5 Apr 2009 05:51:16 +0000 (01:51 -0400)
committerLen Brown <len.brown@intel.com>
Sun, 5 Apr 2009 05:51:16 +0000 (01:51 -0400)
1  2 
drivers/acpi/battery.c
drivers/acpi/ec.c
drivers/acpi/processor_thermal.c
drivers/acpi/sbs.c
drivers/acpi/video.c

diff --combined drivers/acpi/battery.c
index 5dfe18bf24cbbea35d1894a78bf14f035eb98fde,4d11b0704d5f9c03480986b39bbcc8654cc1cb59..2abc03668627666ff9322618c750d84655a1177e
@@@ -30,7 -30,6 +30,7 @@@
  #include <linux/init.h>
  #include <linux/types.h>
  #include <linux/jiffies.h>
 +#include <linux/async.h>
  
  #ifdef CONFIG_ACPI_PROCFS_POWER
  #include <linux/proc_fs.h>
@@@ -93,7 -92,7 +93,7 @@@ struct acpi_battery 
  #endif
        struct acpi_device *device;
        unsigned long update_time;
 -      int current_now;
 +      int rate_now;
        int capacity_now;
        int voltage_now;
        int design_capacity;
@@@ -197,8 -196,7 +197,8 @@@ static int acpi_battery_get_property(st
                val->intval = battery->voltage_now * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
 -              val->intval = battery->current_now * 1000;
 +      case POWER_SUPPLY_PROP_POWER_NOW:
 +              val->intval = battery->rate_now * 1000;
                break;
        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
        case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@@ -249,7 -247,6 +249,7 @@@ static enum power_supply_property energ
        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_CURRENT_NOW,
 +      POWER_SUPPLY_PROP_POWER_NOW,
        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
        POWER_SUPPLY_PROP_ENERGY_FULL,
        POWER_SUPPLY_PROP_ENERGY_NOW,
@@@ -276,7 -273,7 +276,7 @@@ struct acpi_offsets 
  
  static struct acpi_offsets state_offsets[] = {
        {offsetof(struct acpi_battery, state), 0},
 -      {offsetof(struct acpi_battery, current_now), 0},
 +      {offsetof(struct acpi_battery, rate_now), 0},
        {offsetof(struct acpi_battery, capacity_now), 0},
        {offsetof(struct acpi_battery, voltage_now), 0},
  };
@@@ -608,11 -605,11 +608,11 @@@ static int acpi_battery_print_state(str
        else
                seq_printf(seq, "charging state:          charged\n");
  
 -      if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
 +      if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "present rate:            unknown\n");
        else
                seq_printf(seq, "present rate:            %d %s\n",
 -                         battery->current_now, acpi_battery_units(battery));
 +                         battery->rate_now, acpi_battery_units(battery));
  
        if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "remaining capacity:      unknown\n");
@@@ -743,7 -740,7 +743,7 @@@ DECLARE_FILE_FUNCTIONS(alarm)
  static struct battery_file {
        struct file_operations ops;
        mode_t mode;
-       char *name;
+       const char *name;
  } acpi_battery_file[] = {
        FILE_DESCRIPTION_RO(info),
        FILE_DESCRIPTION_RO(state),
@@@ -904,27 -901,21 +904,27 @@@ static struct acpi_driver acpi_battery_
                },
  };
  
 -static int __init acpi_battery_init(void)
 +static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
  {
        if (acpi_disabled)
 -              return -ENODEV;
 +              return;
  #ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_battery_dir = acpi_lock_battery_dir();
        if (!acpi_battery_dir)
 -              return -ENODEV;
 +              return;
  #endif
        if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
  #ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_unlock_battery_dir(acpi_battery_dir);
  #endif
 -              return -ENODEV;
 +              return;
        }
 +      return;
 +}
 +
 +static int __init acpi_battery_init(void)
 +{
 +      async_schedule(acpi_battery_init_async, NULL);
        return 0;
  }
  
diff --combined drivers/acpi/ec.c
index 03107bce03ed424e843fd8ec801de224804148e7,1ec61e52b390bbc0367d5531a2f0fa711cb79270..04e90443eff7b6ea0b53a0fb8c663e3400cb93fa
@@@ -67,7 -67,7 +67,7 @@@ enum ec_command 
  
  #define ACPI_EC_DELAY         500     /* Wait 500ms max. during EC ops */
  #define ACPI_EC_UDELAY_GLK    1000    /* Wait 1ms max. to get global lock */
 -#define ACPI_EC_UDELAY                100     /* Wait 100us before polling EC again */
 +#define ACPI_EC_CDELAY                10      /* Wait 10us before polling EC */
  
  #define ACPI_EC_STORM_THRESHOLD 8     /* number of false interrupts
                                           per one transaction */
@@@ -236,23 -236,13 +236,23 @@@ static int ec_check_sci(struct acpi_ec 
        return 0;
  }
  
 +static void ec_delay(void)
 +{
 +      /* EC in MSI notebooks don't tolerate delays other than 550 usec */
 +      if (EC_FLAGS_MSI)
 +              udelay(ACPI_EC_DELAY);
 +      else
 +              /* Use shortest sleep available */
 +              msleep(1);
 +}
 +
  static int ec_poll(struct acpi_ec *ec)
  {
        unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
 -      udelay(ACPI_EC_UDELAY);
 +      udelay(ACPI_EC_CDELAY);
        while (time_before(jiffies, delay)) {
                gpe_transaction(ec, acpi_ec_read_status(ec));
 -              udelay(ACPI_EC_UDELAY);
 +              ec_delay();
                if (ec_transaction_done(ec))
                        return 0;
        }
@@@ -682,7 -672,7 +682,7 @@@ static int acpi_ec_info_open_fs(struct 
        return single_open(file, acpi_ec_read_info, PDE(inode)->data);
  }
  
- static struct file_operations acpi_ec_info_ops = {
+ static const struct file_operations acpi_ec_info_ops = {
        .open = acpi_ec_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@@ -765,10 -755,6 +765,10 @@@ ec_parse_device(acpi_handle handle, u3
        unsigned long long tmp = 0;
  
        struct acpi_ec *ec = context;
 +
 +      /* clear addr values, ec_parse_io_ports depend on it */
 +      ec->command_addr = ec->data_addr = 0;
 +
        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
                                     ec_parse_io_ports, ec);
        if (ACPI_FAILURE(status))
@@@ -818,11 -804,11 +818,11 @@@ static int acpi_ec_add(struct acpi_devi
                ec = make_acpi_ec();
                if (!ec)
                        return -ENOMEM;
 -              if (ec_parse_device(device->handle, 0, ec, NULL) !=
 -                  AE_CTRL_TERMINATE) {
 +      }
 +      if (ec_parse_device(device->handle, 0, ec, NULL) !=
 +              AE_CTRL_TERMINATE) {
                        kfree(ec);
                        return -EINVAL;
 -              }
        }
  
        ec->handle = device->handle;
@@@ -1000,12 -986,12 +1000,12 @@@ int __init acpi_ec_ecdt_probe(void
                boot_ec->handle = ACPI_ROOT_OBJECT;
                acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
                /* Don't trust ECDT, which comes from ASUSTek */
 -              if (!dmi_name_in_vendors("ASUS"))
 +              if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
                        goto install;
                saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
                if (!saved_ec)
                        return -ENOMEM;
 -              memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
 +              memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
        /* fall through */
        }
        /* This workaround is needed only on some broken machines,
@@@ -1083,10 -1069,13 +1083,10 @@@ static struct acpi_driver acpi_ec_drive
                },
  };
  
 -static int __init acpi_ec_init(void)
 +int __init acpi_ec_init(void)
  {
        int result = 0;
  
 -      if (acpi_disabled)
 -              return 0;
 -
        acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
        if (!acpi_ec_dir)
                return -ENODEV;
        return result;
  }
  
 -subsys_initcall(acpi_ec_init);
 -
  /* EC driver currently not unloadable */
  #if 0
  static void __exit acpi_ec_exit(void)
index 0e47e299a9ac15ee64be0010676fb90f8739a0a8,1f31699359baac765454098dd277e701f4ea7985..39838c66603265bd188f398b07fdd494a0699589
@@@ -373,8 -373,7 +373,8 @@@ static int acpi_processor_max_state(str
        return max_state;
  }
  static int
 -processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
 +processor_get_max_state(struct thermal_cooling_device *cdev,
 +                      unsigned long *state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_processor *pr = acpi_driver_data(device);
        if (!device || !pr)
                return -EINVAL;
  
 -      return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
 +      *state = acpi_processor_max_state(pr);
 +      return 0;
  }
  
  static int
 -processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
 +processor_get_cur_state(struct thermal_cooling_device *cdev,
 +                      unsigned long *cur_state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_processor *pr = acpi_driver_data(device);
 -      int cur_state;
  
        if (!device || !pr)
                return -EINVAL;
  
 -      cur_state = cpufreq_get_cur_state(pr->id);
 +      *cur_state = cpufreq_get_cur_state(pr->id);
        if (pr->flags.throttling)
 -              cur_state += pr->throttling.state;
 -
 -      return sprintf(buf, "%d\n", cur_state);
 +              *cur_state += pr->throttling.state;
 +      return 0;
  }
  
  static int
 -processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
 +processor_set_cur_state(struct thermal_cooling_device *cdev,
 +                      unsigned long state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_processor *pr = acpi_driver_data(device);
@@@ -509,7 -507,7 +509,7 @@@ static ssize_t acpi_processor_write_lim
        return count;
  }
  
- struct file_operations acpi_processor_limit_fops = {
const struct file_operations acpi_processor_limit_fops = {
        .owner = THIS_MODULE,
        .open = acpi_processor_limit_open_fs,
        .read = seq_read,
diff --combined drivers/acpi/sbs.c
index 3963cb6e0f19c75db53572c18081af2846bbc976,1e3cf989196b687e8b537de2a0d02d82f19ffcae..bb8fd1b6054bdf4da4d934064c21915048fabea2
@@@ -102,8 -102,8 +102,8 @@@ struct acpi_battery 
        u16 cycle_count;
        u16 temp_now;
        u16 voltage_now;
 -      s16 current_now;
 -      s16 current_avg;
 +      s16 rate_now;
 +      s16 rate_avg;
        u16 capacity_now;
        u16 state_of_charge;
        u16 state;
@@@ -202,9 -202,9 +202,9 @@@ static int acpi_sbs_battery_get_propert
                return -ENODEV;
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
 -              if (battery->current_now < 0)
 +              if (battery->rate_now < 0)
                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 -              else if (battery->current_now > 0)
 +              else if (battery->rate_now > 0)
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
                else
                        val->intval = POWER_SUPPLY_STATUS_FULL;
                                acpi_battery_vscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
 -              val->intval = abs(battery->current_now) *
 +      case POWER_SUPPLY_PROP_POWER_NOW:
 +              val->intval = abs(battery->rate_now) *
                                acpi_battery_ipscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_AVG:
 -              val->intval = abs(battery->current_avg) *
 +      case POWER_SUPPLY_PROP_POWER_AVG:
 +              val->intval = abs(battery->rate_avg) *
                                acpi_battery_ipscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CAPACITY:
@@@ -295,8 -293,6 +295,8 @@@ static enum power_supply_property sbs_e
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_CURRENT_NOW,
        POWER_SUPPLY_PROP_CURRENT_AVG,
 +      POWER_SUPPLY_PROP_POWER_NOW,
 +      POWER_SUPPLY_PROP_POWER_AVG,
        POWER_SUPPLY_PROP_CAPACITY,
        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
        POWER_SUPPLY_PROP_ENERGY_FULL,
        POWER_SUPPLY_PROP_MODEL_NAME,
        POWER_SUPPLY_PROP_MANUFACTURER,
  };
 +
  #endif
  
  /* --------------------------------------------------------------------------
@@@ -335,8 -330,8 +335,8 @@@ static struct acpi_battery_reader info_
  static struct acpi_battery_reader state_readers[] = {
        {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
        {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
 -      {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
 -      {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
 +      {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
 +      {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
        {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
        {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
        {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@@ -484,9 -479,9 +484,9 @@@ static in
  acpi_sbs_add_fs(struct proc_dir_entry **dir,
                struct proc_dir_entry *parent_dir,
                char *dir_name,
-               struct file_operations *info_fops,
-               struct file_operations *state_fops,
-               struct file_operations *alarm_fops, void *data)
+               const struct file_operations *info_fops,
+               const struct file_operations *state_fops,
+               const struct file_operations *alarm_fops, void *data)
  {
        if (!*dir) {
                *dir = proc_mkdir(dir_name, parent_dir);
@@@ -594,9 -589,9 +594,9 @@@ static int acpi_battery_read_state(stru
        seq_printf(seq, "capacity state:          %s\n",
                   (battery->state & 0x0010) ? "critical" : "ok");
        seq_printf(seq, "charging state:          %s\n",
 -                 (battery->current_now < 0) ? "discharging" :
 -                 ((battery->current_now > 0) ? "charging" : "charged"));
 -      rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
 +                 (battery->rate_now < 0) ? "discharging" :
 +                 ((battery->rate_now > 0) ? "charging" : "charged"));
 +      rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
        rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
                        acpi_battery_vscale(battery)/1000):1;
        seq_printf(seq, "present rate:            %d%s\n", rate,
@@@ -682,7 -677,7 +682,7 @@@ static int acpi_battery_alarm_open_fs(s
        return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
  }
  
- static struct file_operations acpi_battery_info_fops = {
+ static const struct file_operations acpi_battery_info_fops = {
        .open = acpi_battery_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .owner = THIS_MODULE,
  };
  
- static struct file_operations acpi_battery_state_fops = {
+ static const struct file_operations acpi_battery_state_fops = {
        .open = acpi_battery_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .owner = THIS_MODULE,
  };
  
- static struct file_operations acpi_battery_alarm_fops = {
+ static const struct file_operations acpi_battery_alarm_fops = {
        .open = acpi_battery_alarm_open_fs,
        .read = seq_read,
        .write = acpi_battery_write_alarm,
@@@ -730,7 -725,7 +730,7 @@@ static int acpi_ac_state_open_fs(struc
        return single_open(file, acpi_ac_read_state, PDE(inode)->data);
  }
  
- static struct file_operations acpi_ac_state_fops = {
+ static const struct file_operations acpi_ac_state_fops = {
        .open = acpi_ac_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
diff --combined drivers/acpi/video.c
index 100c8eeaa5dd9eea15f92dd142a5167f4fe1c1be,0e7e689634a79e7c0eca28c4a4576791d259676b..d51d6f06c09b2a99f6a555e96e85821560ca4fc7
@@@ -37,8 -37,6 +37,8 @@@
  #include <linux/thermal.h>
  #include <linux/video_output.h>
  #include <linux/sort.h>
 +#include <linux/pci.h>
 +#include <linux/pci_ids.h>
  #include <asm/uaccess.h>
  
  #include <acpi/acpi_bus.h>
@@@ -164,26 -162,16 +164,26 @@@ struct acpi_video_device_cap 
        u8 _BCL:1;              /*Query list of brightness control levels supported */
        u8 _BCM:1;              /*Set the brightness level */
        u8 _BQC:1;              /* Get current brightness level */
 +      u8 _BCQ:1;              /* Some buggy BIOS uses _BCQ instead of _BQC */
        u8 _DDC:1;              /*Return the EDID for this device */
        u8 _DCS:1;              /*Return status of output device */
        u8 _DGS:1;              /*Query graphics state */
        u8 _DSS:1;              /*Device state set */
  };
  
 +struct acpi_video_brightness_flags {
 +      u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
 +      u8 _BCL_reversed:1;             /* _BCL package is in a reversed order*/
 +      u8 _BCL_use_index:1;            /* levels in _BCL are index values */
 +      u8 _BCM_use_index:1;            /* input of _BCM is an index value */
 +      u8 _BQC_use_index:1;            /* _BQC returns an index value */
 +};
 +
  struct acpi_video_device_brightness {
        int curr;
        int count;
        int *levels;
 +      struct acpi_video_brightness_flags flags;
  };
  
  struct acpi_video_device {
  
  /* bus */
  static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
- static struct file_operations acpi_video_bus_info_fops = {
+ static const struct file_operations acpi_video_bus_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_info_open_fs,
        .read = seq_read,
  };
  
  static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
- static struct file_operations acpi_video_bus_ROM_fops = {
+ static const struct file_operations acpi_video_bus_ROM_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_ROM_open_fs,
        .read = seq_read,
  
  static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
                                            struct file *file);
- static struct file_operations acpi_video_bus_POST_info_fops = {
+ static const struct file_operations acpi_video_bus_POST_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_POST_info_open_fs,
        .read = seq_read,
  };
  
  static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
- static struct file_operations acpi_video_bus_POST_fops = {
+ static ssize_t acpi_video_bus_write_POST(struct file *file,
+       const char __user *buffer, size_t count, loff_t *data);
+ static const struct file_operations acpi_video_bus_POST_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_POST_open_fs,
        .read = seq_read,
+       .write = acpi_video_bus_write_POST,
        .llseek = seq_lseek,
        .release = single_release,
  };
  
  static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
- static struct file_operations acpi_video_bus_DOS_fops = {
+ static ssize_t acpi_video_bus_write_DOS(struct file *file,
+       const char __user *buffer, size_t count, loff_t *data);
+ static const struct file_operations acpi_video_bus_DOS_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_DOS_open_fs,
        .read = seq_read,
+       .write = acpi_video_bus_write_DOS,
        .llseek = seq_lseek,
        .release = single_release,
  };
  /* device */
  static int acpi_video_device_info_open_fs(struct inode *inode,
                                          struct file *file);
- static struct file_operations acpi_video_device_info_fops = {
+ static const struct file_operations acpi_video_device_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_info_open_fs,
        .read = seq_read,
  
  static int acpi_video_device_state_open_fs(struct inode *inode,
                                           struct file *file);
- static struct file_operations acpi_video_device_state_fops = {
+ static ssize_t acpi_video_device_write_state(struct file *file,
+       const char __user *buffer, size_t count, loff_t *data);
+ static const struct file_operations acpi_video_device_state_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_state_open_fs,
        .read = seq_read,
+       .write = acpi_video_device_write_state,
        .llseek = seq_lseek,
        .release = single_release,
  };
  
  static int acpi_video_device_brightness_open_fs(struct inode *inode,
                                                struct file *file);
+ static ssize_t acpi_video_device_write_brightness(struct file *file,
+       const char __user *buffer, size_t count, loff_t *data);
  static struct file_operations acpi_video_device_brightness_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_brightness_open_fs,
        .read = seq_read,
+       .write = acpi_video_device_write_brightness,
        .llseek = seq_lseek,
        .release = single_release,
  };
  
  static int acpi_video_device_EDID_open_fs(struct inode *inode,
                                          struct file *file);
- static struct file_operations acpi_video_device_EDID_fops = {
+ static const struct file_operations acpi_video_device_EDID_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_EDID_open_fs,
        .read = seq_read,
        .release = single_release,
  };
  
- static char device_decode[][30] = {
+ static const char device_decode[][30] = {
        "motherboard VGA device",
        "PCI VGA device",
        "AGP VGA device",
@@@ -306,7 -306,7 +318,7 @@@ static int acpi_video_device_lcd_get_le
                        unsigned long long *level);
  static int acpi_video_get_next_level(struct acpi_video_device *device,
                                     u32 level_current, u32 event);
 -static void acpi_video_switch_brightness(struct acpi_video_device *device,
 +static int acpi_video_switch_brightness(struct acpi_video_device *device,
                                         int event);
  static int acpi_video_device_get_state(struct acpi_video_device *device,
                            unsigned long long *state);
@@@ -320,9 -320,7 +332,9 @@@ static int acpi_video_get_brightness(st
        int i;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)bl_get_data(bd);
 -      acpi_video_device_lcd_get_level_current(vd, &cur_level);
 +
 +      if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
 +              return -EINVAL;
        for (i = 2; i < vd->brightness->count; i++) {
                if (vd->brightness->levels[i] == cur_level)
                        /* The first two entries are special - see page 575
  
  static int acpi_video_set_brightness(struct backlight_device *bd)
  {
 -      int request_level = bd->props.brightness+2;
 +      int request_level = bd->props.brightness + 2;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)bl_get_data(bd);
 -      acpi_video_device_lcd_set_level(vd,
 -                                      vd->brightness->levels[request_level]);
 -      return 0;
 +
 +      return acpi_video_device_lcd_set_level(vd,
 +                              vd->brightness->levels[request_level]);
  }
  
  static struct backlight_ops acpi_backlight_ops = {
@@@ -372,37 -370,32 +384,37 @@@ static struct output_properties acpi_ou
  
  
  /* thermal cooling device callbacks */
 -static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
 +static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
 +                             long *state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
  
 -      return sprintf(buf, "%d\n", video->brightness->count - 3);
 +      *state = video->brightness->count - 3;
 +      return 0;
  }
  
 -static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
 +static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
 +                             long *state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
        unsigned long long level;
 -      int state;
 +      int offset;
  
 -      acpi_video_device_lcd_get_level_current(video, &level);
 -      for (state = 2; state < video->brightness->count; state++)
 -              if (level == video->brightness->levels[state])
 -                      return sprintf(buf, "%d\n",
 -                                     video->brightness->count - state - 1);
 +      if (acpi_video_device_lcd_get_level_current(video, &level))
 +              return -EINVAL;
 +      for (offset = 2; offset < video->brightness->count; offset++)
 +              if (level == video->brightness->levels[offset]) {
 +                      *state = video->brightness->count - offset - 1;
 +                      return 0;
 +              }
  
        return -EINVAL;
  }
  
  static int
 -video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
 +video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
@@@ -498,68 -491,34 +510,68 @@@ acpi_video_device_lcd_query_levels(stru
  static int
  acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
  {
 -      int status = AE_OK;
 +      int status;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
        int state;
  
 -
        arg0.integer.value = level;
  
 -      if (device->cap._BCM)
 -              status = acpi_evaluate_object(device->dev->handle, "_BCM",
 -                                            &args, NULL);
 +      status = acpi_evaluate_object(device->dev->handle, "_BCM",
 +                                    &args, NULL);
 +      if (ACPI_FAILURE(status)) {
 +              ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
 +              return -EIO;
 +      }
 +
        device->brightness->curr = level;
        for (state = 2; state < device->brightness->count; state++)
 -              if (level == device->brightness->levels[state])
 -                      device->backlight->props.brightness = state - 2;
 +              if (level == device->brightness->levels[state]) {
 +                      if (device->backlight)
 +                              device->backlight->props.brightness = state - 2;
 +                      return 0;
 +              }
  
 -      return status;
 +      ACPI_ERROR((AE_INFO, "Current brightness invalid"));
 +      return -EINVAL;
  }
  
  static int
  acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
                                        unsigned long long *level)
  {
 -      if (device->cap._BQC)
 -              return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
 -                                           level);
 +      acpi_status status = AE_OK;
 +
 +      if (device->cap._BQC || device->cap._BCQ) {
 +              char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
 +
 +              status = acpi_evaluate_integer(device->dev->handle, buf,
 +                                              NULL, level);
 +              if (ACPI_SUCCESS(status)) {
 +                      if (device->brightness->flags._BQC_use_index) {
 +                              if (device->brightness->flags._BCL_reversed)
 +                                      *level = device->brightness->count
 +                                                               - 3 - (*level);
 +                              *level = device->brightness->levels[*level + 2];
 +
 +                      }
 +                      device->brightness->curr = *level;
 +                      return 0;
 +              } else {
 +                      /* Fixme:
 +                       * should we return an error or ignore this failure?
 +                       * dev->brightness->curr is a cached value which stores
 +                       * the correct current backlight level in most cases.
 +                       * ACPI video backlight still works w/ buggy _BQC.
 +                       * http://bugzilla.kernel.org/show_bug.cgi?id=12233
 +                       */
 +                      ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
 +                      device->cap._BQC = device->cap._BCQ = 0;
 +              }
 +      }
 +
        *level = device->brightness->curr;
 -      return AE_OK;
 +      return 0;
  }
  
  static int
@@@ -708,11 -667,9 +720,11 @@@ static in
  acpi_video_init_brightness(struct acpi_video_device *device)
  {
        union acpi_object *obj = NULL;
 -      int i, max_level = 0, count = 0;
 +      int i, max_level = 0, count = 0, level_ac_battery = 0;
 +      unsigned long long level, level_old;
        union acpi_object *o;
        struct acpi_video_device_brightness *br = NULL;
 +      int result = -EINVAL;
  
        if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
        br = kzalloc(sizeof(*br), GFP_KERNEL);
        if (!br) {
                printk(KERN_ERR "can't allocate memory\n");
 +              result = -ENOMEM;
                goto out;
        }
  
 -      br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
 +      br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
                                GFP_KERNEL);
 -      if (!br->levels)
 +      if (!br->levels) {
 +              result = -ENOMEM;
                goto out_free;
 +      }
  
        for (i = 0; i < obj->package.count; i++) {
                o = (union acpi_object *)&obj->package.elements[i];
                count++;
        }
  
 -      /* don't sort the first two brightness levels */
 -      sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
 -              acpi_video_cmp_level, NULL);
 -
 -      if (count < 2)
 -              goto out_free_levels;
 +      /*
 +       * some buggy BIOS don't export the levels
 +       * when machine is on AC/Battery in _BCL package.
 +       * In this case, the first two elements in _BCL packages
 +       * are also supported brightness levels that OS should take care of.
 +       */
 +      for (i = 2; i < count; i++)
 +              if (br->levels[i] == br->levels[0] ||
 +                  br->levels[i] == br->levels[1])
 +                      level_ac_battery++;
 +
 +      if (level_ac_battery < 2) {
 +              level_ac_battery = 2 - level_ac_battery;
 +              br->flags._BCL_no_ac_battery_levels = 1;
 +              for (i = (count - 1 + level_ac_battery); i >= 2; i--)
 +                      br->levels[i] = br->levels[i - level_ac_battery];
 +              count += level_ac_battery;
 +      } else if (level_ac_battery > 2)
 +              ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
 +
 +      /* Check if the _BCL package is in a reversed order */
 +      if (max_level == br->levels[2]) {
 +              br->flags._BCL_reversed = 1;
 +              sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
 +                      acpi_video_cmp_level, NULL);
 +      } else if (max_level != br->levels[count - 1])
 +              ACPI_ERROR((AE_INFO,
 +                          "Found unordered _BCL package\n"));
  
        br->count = count;
        device->brightness = br;
 -      ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
 +
 +      /* Check the input/output of _BQC/_BCL/_BCM */
 +      if ((max_level < 100) && (max_level <= (count - 2)))
 +              br->flags._BCL_use_index = 1;
 +
 +      /*
 +       * _BCM is always consistent with _BCL,
 +       * at least for all the laptops we have ever seen.
 +       */
 +      br->flags._BCM_use_index = br->flags._BCL_use_index;
 +
 +      /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
 +      br->curr = max_level;
 +      result = acpi_video_device_lcd_get_level_current(device, &level_old);
 +      if (result)
 +              goto out_free_levels;
 +
 +      result = acpi_video_device_lcd_set_level(device, br->curr);
 +      if (result)
 +              goto out_free_levels;
 +
 +      result = acpi_video_device_lcd_get_level_current(device, &level);
 +      if (result)
 +              goto out_free_levels;
 +
 +      if ((level != level_old) && !br->flags._BCM_use_index) {
 +              /* Note:
 +               * This piece of code does not work correctly if the current
 +               * brightness levels is 0.
 +               * But I guess boxes that boot with such a dark screen are rare
 +               * and no more code is needed to cover this specifial case.
 +               */
 +
 +              if (level_ac_battery != 2) {
 +                      /*
 +                       * For now, we don't support the _BCL like this:
 +                       * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
 +                       * because we may mess up the index returned by _BQC.
 +                       * Plus: we have not got a box like this.
 +                       */
 +                      ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
 +              }
 +              br->flags._BQC_use_index = 1;
 +      }
 +
 +      ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 +                        "found %d brightness levels\n", count - 2));
        kfree(obj);
 -      return max_level;
 +      return result;
  
  out_free_levels:
        kfree(br->levels);
@@@ -838,7 -724,7 +850,7 @@@ out_free
  out:
        device->brightness = NULL;
        kfree(obj);
 -      return 0;
 +      return result;
  }
  
  /*
  static void acpi_video_device_find_cap(struct acpi_video_device *device)
  {
        acpi_handle h_dummy1;
 -      u32 max_level = 0;
  
  
        memset(&device->cap, 0, sizeof(device->cap));
        }
        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
                device->cap._BQC = 1;
 +      else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
 +                              &h_dummy1))) {
 +              printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
 +              device->cap._BCQ = 1;
 +      }
 +
        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
                device->cap._DDC = 1;
        }
                device->cap._DSS = 1;
        }
  
 -      if (acpi_video_backlight_support())
 -              max_level = acpi_video_init_brightness(device);
 -
 -      if (device->cap._BCL && device->cap._BCM && max_level > 0) {
 +      if (acpi_video_backlight_support()) {
                int result;
                static int count = 0;
                char *name;
 +
 +              result = acpi_video_init_brightness(device);
 +              if (result)
 +                      return;
                name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
                if (!name)
                        return;
                device->backlight = backlight_device_register(name,
                        NULL, device, &acpi_backlight_ops);
                device->backlight->props.max_brightness = device->brightness->count-3;
 -              /*
 -               * If there exists the _BQC object, the _BQC object will be
 -               * called to get the current backlight brightness. Otherwise
 -               * the brightness will be set to the maximum.
 -               */
 -              if (device->cap._BQC)
 -                      device->backlight->props.brightness =
 -                              acpi_video_get_brightness(device->backlight);
 -              else
 -                      device->backlight->props.brightness =
 -                              device->backlight->props.max_brightness;
 -              backlight_update_status(device->backlight);
                kfree(name);
  
                device->cdev = thermal_cooling_device_register("LCD",
@@@ -1181,12 -1073,13 +1193,12 @@@ acpi_video_device_write_brightness(stru
        /* validate through the list of available levels */
        for (i = 2; i < dev->brightness->count; i++)
                if (level == dev->brightness->levels[i]) {
 -                      if (ACPI_SUCCESS
 -                          (acpi_video_device_lcd_set_level(dev, level)))
 -                              dev->brightness->curr = level;
 +                      if (!acpi_video_device_lcd_set_level(dev, level))
 +                              return count;
                        break;
                }
  
 -      return count;
 +      return -EINVAL;
  }
  
  static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@@ -1253,7 -1146,6 +1265,6 @@@ static int acpi_video_device_add_fs(str
                goto err_remove_dir;
  
        /* 'state' [R/W] */
-       acpi_video_device_state_fops.write = acpi_video_device_write_state;
        entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_device_state_fops,
                goto err_remove_info;
  
        /* 'brightness' [R/W] */
-       acpi_video_device_brightness_fops.write =
-               acpi_video_device_write_brightness;
        entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_device_brightness_fops,
@@@ -1546,7 -1436,6 +1555,6 @@@ static int acpi_video_bus_add_fs(struc
                goto err_remove_rom;
  
        /* 'POST' [R/W] */
-       acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
        entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_bus_POST_fops,
                goto err_remove_post_info;
  
        /* 'DOS' [R/W] */
-       acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
        entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_bus_DOS_fops,
@@@ -1868,29 -1756,15 +1875,29 @@@ acpi_video_get_next_level(struct acpi_v
        }
  }
  
 -static void
 +static int
  acpi_video_switch_brightness(struct acpi_video_device *device, int event)
  {
        unsigned long long level_current, level_next;
 +      int result = -EINVAL;
 +
        if (!device->brightness)
 -              return;
 -      acpi_video_device_lcd_get_level_current(device, &level_current);
 +              goto out;
 +
 +      result = acpi_video_device_lcd_get_level_current(device,
 +                                                       &level_current);
 +      if (result)
 +              goto out;
 +
        level_next = acpi_video_get_next_level(device, level_current, event);
 -      acpi_video_device_lcd_set_level(device, level_next);
 +
 +      result = acpi_video_device_lcd_set_level(device, level_next);
 +
 +out:
 +      if (result)
 +              printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
 +
 +      return result;
  }
  
  static int
@@@ -2257,27 -2131,7 +2264,27 @@@ static int acpi_video_bus_remove(struc
        return 0;
  }
  
 -static int __init acpi_video_init(void)
 +static int __init intel_opregion_present(void)
 +{
 +#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
 +      struct pci_dev *dev = NULL;
 +      u32 address;
 +
 +      for_each_pci_dev(dev) {
 +              if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
 +                      continue;
 +              if (dev->vendor != PCI_VENDOR_ID_INTEL)
 +                      continue;
 +              pci_read_config_dword(dev, 0xfc, &address);
 +              if (!address)
 +                      continue;
 +              return 1;
 +      }
 +#endif
 +      return 0;
 +}
 +
 +int acpi_video_register(void)
  {
        int result = 0;
  
  
        return 0;
  }
 +EXPORT_SYMBOL(acpi_video_register);
 +
 +/*
 + * This is kind of nasty. Hardware using Intel chipsets may require
 + * the video opregion code to be run first in order to initialise
 + * state before any ACPI video calls are made. To handle this we defer
 + * registration of the video class until the opregion code has run.
 + */
 +
 +static int __init acpi_video_init(void)
 +{
 +      if (intel_opregion_present())
 +              return 0;
 +
 +      return acpi_video_register();
 +}
  
  static void __exit acpi_video_exit(void)
  {