Merge branches 'release', 'acpica', 'bugzilla-10224', 'bugzilla-9772', 'bugzilla...
authorLen Brown <len.brown@intel.com>
Wed, 30 Apr 2008 17:58:00 +0000 (13:58 -0400)
committerLen Brown <len.brown@intel.com>
Wed, 30 Apr 2008 17:58:00 +0000 (13:58 -0400)
1  2  3  4  5  6  7  8  9  10  11  12  13 
arch/mips/au1000/common/power.c
arch/x86/kernel/apm_32.c
drivers/acpi/events/evgpe.c
drivers/acpi/processor_idle.c
drivers/acpi/scan.c
drivers/acpi/utilities/utxface.c
drivers/acpi/video.c
drivers/misc/Kconfig
drivers/misc/thinkpad_acpi.c

index 54047d69b820c98195dfa534748019414d8e76ea,54047d69b820c98195dfa534748019414d8e76ea,812a5f8b7d2672ac4cab47eaa4583653d44b7da9,54047d69b820c98195dfa534748019414d8e76ea,54047d69b820c98195dfa534748019414d8e76ea,812a5f8b7d2672ac4cab47eaa4583653d44b7da9,54047d69b820c98195dfa534748019414d8e76ea,812a5f8b7d2672ac4cab47eaa4583653d44b7da9,725a52f364b0042cf794357a603e36e27eb286c9,54047d69b820c98195dfa534748019414d8e76ea,812a5f8b7d2672ac4cab47eaa4583653d44b7da9,812a5f8b7d2672ac4cab47eaa4583653d44b7da9,812a5f8b7d2672ac4cab47eaa4583653d44b7da9..a8cd2c1b9e1b59f313ae98a0c6e8579e0afc6dca
              *  with this program; if not, write  to the Free Software Foundation, Inc.,
              *  675 Mass Ave, Cambridge, MA 02139, USA.
              */
++ ++ + ++   
             #include <linux/init.h>
             #include <linux/pm.h>
             #include <linux/pm_legacy.h>
-- -- - --   #include <linux/slab.h>
             #include <linux/sysctl.h>
             #include <linux/jiffies.h>
             
-- -- - --   #include <asm/string.h>
             #include <asm/uaccess.h>
-- -- - --   #include <asm/io.h>
-- -- - --   #include <asm/system.h>
             #include <asm/cacheflush.h>
             #include <asm/mach-au1x00/au1000.h>
             
             
             #define DEBUG 1
             #ifdef DEBUG
-- -- - --   #  define DPRINTK(fmt, args...)    printk("%s: " fmt, __FUNCTION__ , ## args)
++ ++ + ++   #  define DPRINTK(fmt, args...)    printk("%s: " fmt, __func__, ## args)
             #else
             #  define DPRINTK(fmt, args...)
             #endif
             
             static void au1000_calibrate_delay(void);
             
-- -- - --   extern void set_au1x00_speed(unsigned int new_freq);
-- -- - --   extern unsigned int get_au1x00_speed(void);
-- -- - --   extern unsigned long get_au1x00_uart_baud_base(void);
-- -- - --   extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
             extern unsigned long save_local_and_disable(int controller);
             extern void restore_local_and_enable(int controller, unsigned long mask);
             extern void local_enable_irq(unsigned int irq_nr);
@@@@@@@@@@@@@@ -258,7 -258,7 -251,7 -258,7 -258,7 -251,7 -258,7 -251,7 -258,6 -258,7 -251,7 -251,7 -251,7 +251,6 @@@@@@@@@@@@@@ int au_sleep(void
             static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
                               void __user *buffer, size_t * len, loff_t *ppos)
             {
-------- ----   int retval = 0;
             #ifdef SLEEP_TEST_TIMEOUT
             #define TMPBUFLEN2 16
                char buf[TMPBUFLEN2], *p;
                        p = buf;
                        sleep_ticks = simple_strtoul(p, &p, 0);
             #endif
-------- ----           retval = pm_send_all(PM_SUSPEND, (void *) 2);
-------- ----
-------- ----           if (retval)
-------- ----                   return retval;
             
                        au_sleep();
-- -- -  -              retval = pm_send_all(PM_RESUME, (void *) 0);
-- -- -  -      }
-- -- -  -      return retval;
-- -- -  -   }
-- -- -  -   
-- -- -  -   static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
-- -- -  -                       void __user *buffer, size_t * len, loff_t *ppos)
-- -- -  -   {
-- -- -  -      int retval = 0;
-- -- -  -   
-- -- -  -      if (!write) {
-- -- -  -              *len = 0;
-- -- -  -      } else {
-- -- -  -              retval = pm_send_all(PM_SUSPEND, (void *) 2);
-- -- -  -              if (retval)
-- -- -  -                      return retval;
-- -- -  -              suspend_mode = 1;
-- -- -  -   
-------- ----           retval = pm_send_all(PM_RESUME, (void *) 0);
                }
  -  - -  ---   return retval;
  -  - -  ---}
  -  - -  ---
  -  - -  ---static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
  -  - -  ---                    void __user *buffer, size_t * len, loff_t *ppos)
  -  - -  ---{
  -  - -  ---   int retval = 0;
  -  - -  ---
  -  - -  ---   if (!write) {
  -  - -  ---           *len = 0;
  -  - -  ---   } else {
  -  - -  ---           retval = pm_send_all(PM_SUSPEND, (void *) 2);
  -  - -  ---           if (retval)
  -  - -  ---                   return retval;
  -  - -  ---           suspend_mode = 1;
  -  - -  ---
  -  - -  ---           retval = pm_send_all(PM_RESUME, (void *) 0);
  -  - -  ---   }
-------- ----   return retval;
++++++++ ++++   return 0;
             }
             
-------- ----
             static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
                              void __user *buffer, size_t * len, loff_t *ppos)
             {
             
             
             static struct ctl_table pm_table[] = {
-------- ----   {
-------- ----           .ctl_name       = CTL_UNNUMBERED,
-------- ----           .procname       = "suspend",
-------- ----           .data           = NULL,
-------- ----           .maxlen         = 0,
-------- ----           .mode           = 0600,
-------- ----           .proc_handler   = &pm_do_suspend
-------- ----   },
                {
                        .ctl_name       = CTL_UNNUMBERED,
                        .procname       = "sleep",
diff --combined arch/x86/kernel/apm_32.c
index d4438ef296d8a607f7a703a845040715a8335fd9,d4438ef296d8a607f7a703a845040715a8335fd9,e4ea362e84800a6c28bf8056ec340aff5fea4bad,f0030a0999c74f01785c4acd7a499778de58a4ff,d4438ef296d8a607f7a703a845040715a8335fd9,e4ea362e84800a6c28bf8056ec340aff5fea4bad,d4438ef296d8a607f7a703a845040715a8335fd9,e4ea362e84800a6c28bf8056ec340aff5fea4bad,bc8b57d119a1d546a64d1e4f260df39c56809e73,d4438ef296d8a607f7a703a845040715a8335fd9,e4ea362e84800a6c28bf8056ec340aff5fea4bad,e4ea362e84800a6c28bf8056ec340aff5fea4bad,e4ea362e84800a6c28bf8056ec340aff5fea4bad..bf9290e290136a36d6006d032c1ca4fe392f84bd
                                original_pm_idle();
                        else
                                default_idle();
++ ++ + ++              local_irq_disable();
                        jiffies_since_last_check = jiffies - last_jiffies;
                        if (jiffies_since_last_check > idle_period)
                                goto recalc;
             
                if (apm_idle_done)
                        apm_do_busy();
++ ++ + ++   
++ ++ + ++      local_irq_enable();
             }
             
             /**
@@@@@@@@@@@@@@ -1189,19 -1189,19 -1192,19 -1189,19 -1189,19 -1192,19 -1189,19 -1192,19 -1189,6 -1189,19 -1192,19 -1192,19 -1192,19 +1192,6 @@@@@@@@@@@@@@ static int suspend(int vetoable
                int err;
                struct apm_user *as;
             
-------- ----   if (pm_send_all(PM_SUSPEND, (void *)3)) {
-------- ----           /* Vetoed */
-------- ----           if (vetoable) {
-------- ----                   if (apm_info.connection_version > 0x100)
-------- ----                           set_system_power_state(APM_STATE_REJECT);
-------- ----                   err = -EBUSY;
-------- ----                   ignore_sys_suspend = 0;
-------- ----                   printk(KERN_WARNING "apm: suspend was vetoed.\n");
-------- ----                   goto out;
-------- ----           }
-------- ----           printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
-------- ----   }
-------- ----
                device_suspend(PMSG_SUSPEND);
                local_irq_disable();
                device_power_down(PMSG_SUSPEND);
                device_power_up();
                local_irq_enable();
                device_resume();
-------- ----   pm_send_all(PM_RESUME, (void *)0);
                queue_event(APM_NORMAL_RESUME, NULL);
-------- ---- out:
                spin_lock(&user_list_lock);
                for (as = user_list; as != NULL; as = as->next) {
                        as->suspend_wait = 0;
@@@@@@@@@@@@@@ -1337,7 -1337,7 -1340,7 -1337,7 -1337,7 -1340,7 -1337,7 -1340,7 -1322,6 -1337,7 -1340,7 -1340,7 -1340,7 +1325,6 @@@@@@@@@@@@@@ static void check_events(void
                                if ((event != APM_NORMAL_RESUME)
                                    || (ignore_normal_resume == 0)) {
                                        device_resume();
-------- ----                           pm_send_all(PM_RESUME, (void *)0);
                                        queue_event(event, NULL);
                                }
                                ignore_normal_resume = 0;
@@@@@@@@@@@@@@ -2217,7 -2217,7 -2220,6 -2217,6 -2217,7 -2220,6 -2217,7 -2220,6 -2201,7 -2217,7 -2220,6 -2220,6 -2220,6 +2204,6 @@@@@@@@@@@@@@ static struct dmi_system_id __initdata 
              */
             static int __init apm_init(void)
             {
--  - - --      struct proc_dir_entry *apm_proc;
                struct desc_struct *gdt;
                int err;
             
                set_base(gdt[APM_DS >> 3],
                         __va((unsigned long)apm_info.bios.dseg << 4));
             
--  - - --      apm_proc = create_proc_entry("apm", 0, NULL);
--  - - --      if (apm_proc)
--  - - --              apm_proc->proc_fops = &apm_file_ops;
++  + + ++      proc_create("apm", 0, NULL, &apm_file_ops);
             
                kapmd_task = kthread_create(apm, NULL, "kapmd");
                if (IS_ERR(kapmd_task)) {
index f55e1fd9e0b8dcb2ce60192d2c2794bb81e6acb9,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,cd06170e7871a3eecfa08c018f5f2ff51cedfe81,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b,0dadd2adc8001a109669b4ae62c673da60f4747b..5354be44f87678beda3531645527a8e95a02edaf
@@@@@@@@@@@@@@ -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 +5,7 @@@@@@@@@@@@@@
              *****************************************************************************/
             
             /*
 ------------ * Copyright (C) 2000 - 2007, R. Byron Moore
 ++++++++++++ * Copyright (C) 2000 - 2008, Intel Corp.
              * All rights reserved.
              *
              * Redistribution and use in source and binary forms, with or without
@@@@@@@@@@@@@@ -248,10 -248,10 -248,10 -248,6 -248,10 -248,10 -248,10 -248,10 -248,10 -248,10 -248,10 -248,10 -248,10 +248,6 @@@@@@@@@@@@@@ acpi_status acpi_ev_disable_gpe(struct 
             
                ACPI_FUNCTION_TRACE(ev_disable_gpe);
             
--- ---------   if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
--- ---------           return_ACPI_STATUS(AE_OK);
--- ---------   }
--- ---------
                /* Make sure HW enable masks are updated */
             
                status =
index 788da9781f80ffb5311b396cd3557b0786376dcd,788da9781f80ffb5311b396cd3557b0786376dcd,0d90ff5fd1172440b724f161b1ad51657511eb3a,788da9781f80ffb5311b396cd3557b0786376dcd,e8e2d88692368f5ea4903485aa7ca6a6b783e493,0d90ff5fd1172440b724f161b1ad51657511eb3a,47b167c731a04764dda30a33b38fd55c81e3c0cc,0d90ff5fd1172440b724f161b1ad51657511eb3a,788da9781f80ffb5311b396cd3557b0786376dcd,6f3b217699e94a4d47f5b3863c4ffe68ff24938f,0d90ff5fd1172440b724f161b1ad51657511eb3a,0d90ff5fd1172440b724f161b1ad51657511eb3a,0d90ff5fd1172440b724f161b1ad51657511eb3a..55d69dce47c4e2da1090a80ab7c36235a5c9ded8
@@@@@@@@@@@@@@ -216,10 -216,10 -216,10 -216,10 -216,10 -216,10 -216,10 -216,10 -216,10 -216,8 -216,10 -216,10 -216,10 +216,10 @@@@@@@@@@@@@@ static void acpi_safe_halt(void
                 * test NEED_RESCHED:
                 */
                smp_mb();
         -      if (!need_resched())
         +      if (!need_resched()) {
                        safe_halt();
         +              local_irq_disable();
         +      }
                current_thread_info()->status |= TS_POLLING;
             }
             
@@@@@@@@@@@@@@ -418,14 -418,14 -418,13 -418,14 -418,14 -418,13 -418,14 -418,13 -418,14 -416,12 -418,13 -418,13 -418,13 +418,13 @@@@@@@@@@@@@@ static void acpi_processor_idle(void
             
                cx = pr->power.state;
                if (!cx || acpi_idle_suspend) {
-- -- - --              if (pm_idle_save)
-- -- - --                      pm_idle_save();
-- -- - --              else
++ ++ + ++              if (pm_idle_save) {
++ ++ + ++                      pm_idle_save(); /* enables IRQs */
++ ++ + ++              } else {
                                acpi_safe_halt();
-- -- - -    
-- -- - -               if (irqs_disabled())
         +                      local_irq_enable();
++ ++ + ++              }
             
         -              local_irq_enable();
                        return;
                }
             
                         * Use the appropriate idle routine, the one that would
                         * be used without acpi C-states.
                         */
-- -- - --              if (pm_idle_save)
-- -- - --                      pm_idle_save();
-- -- - --              else
++ ++ + ++              if (pm_idle_save) {
++ ++ + ++                      pm_idle_save(); /* enables IRQs */
++ ++ + ++              } else {
                                acpi_safe_halt();
++ ++ + ++                      local_irq_enable();
++ ++ + ++              }
             
                        /*
                         * TBD: Can't get time duration while in C1, as resumes
                         *       skew otherwise.
                         */
                        sleep_ticks = 0xFFFFFFFF;
-- -- - -               if (irqs_disabled())
-- -- - -                       local_irq_enable();
         -              local_irq_enable();
         +   
                        break;
             
                case ACPI_STATE_C2:
@@@@@@@@@@@@@@ -848,6 -848,6 -847,6 -848,6 -848,6 -847,6 -848,7 -847,6 -848,6 -842,6 -847,6 -847,6 -847,6 +847,7 @@@@@@@@@@@@@@ static int acpi_processor_get_power_inf
                        /* all processors need to support C1 */
                        pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
                        pr->power.states[ACPI_STATE_C1].valid = 1;
++++++ ++++++           pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
                }
                /* the C0 state only exists as a filler in our array */
                pr->power.states[ACPI_STATE_C0].valid = 1;
@@@@@@@@@@@@@@ -960,6 -960,6 -959,6 -960,6 -960,6 -959,6 -961,9 -959,6 -960,6 -954,6 -959,6 -959,6 -959,6 +960,9 @@@@@@@@@@@@@@ static int acpi_processor_get_power_inf
                                         cx.address);
                        }
             
++++++ ++++++           if (cx.type == ACPI_STATE_C1) {
++++++ ++++++                   cx.valid = 1;
++++++ ++++++           }
             
                        obj = &(element->package.elements[2]);
                        if (obj->type != ACPI_TYPE_INTEGER)
@@@@@@@@@@@@@@ -1295,6 -1295,6 -1294,6 -1295,6 -1295,6 -1294,6 -1299,8 -1294,6 -1295,6 -1289,6 -1294,6 -1294,6 -1294,6 +1298,8 @@@@@@@@@@@@@@ int acpi_processor_cst_has_changed(stru
             {
                int result = 0;
             
++++++ ++++++   if (boot_option_idle_override)
++++++ ++++++           return 0;
             
                if (!pr)
                        return -EINVAL;
@@@@@@@@@@@@@@ -1487,6 -1487,6 -1486,6 -1487,6 -1487,7 -1486,6 -1493,6 -1486,6 -1487,6 -1481,7 -1486,6 -1486,6 -1486,6 +1492,6 @@@@@@@@@@@@@@ static int acpi_idle_enter_simple(struc
                        return 0;
                }
             
    -    -      acpi_unlazy_tlb(smp_processor_id());
                /*
                 * Must be done before busmaster disable as we might need to
                 * access HPET !
@@@@@@@@@@@@@@ -1576,8 -1576,8 -1575,8 -1576,8 -1577,6 -1575,8 -1582,8 -1575,8 -1576,8 -1571,6 -1575,8 -1575,8 -1575,8 +1581,8 @@@@@@@@@@@@@@ static int acpi_idle_enter_bm(struct cp
                        return 0;
                }
             
    +    +      acpi_unlazy_tlb(smp_processor_id());
    +    +   
                /* Tell the scheduler that we are going deep-idle: */
                sched_clock_idle_sleep_event();
                /*
@@@@@@@@@@@@@@ -1693,9 -1693,9 -1692,9 -1693,9 -1692,7 -1692,9 -1699,9 -1692,9 -1693,9 -1686,7 -1692,9 -1692,9 -1692,9 +1698,9 @@@@@@@@@@@@@@ static int acpi_processor_setup_cpuidle
                        switch (cx->type) {
                                case ACPI_STATE_C1:
                                state->flags |= CPUIDLE_FLAG_SHALLOW;
    -    -                      state->flags |= CPUIDLE_FLAG_TIME_VALID;
    +    +                      if (cx->entry_method == ACPI_CSTATE_FFH)
    +    +                              state->flags |= CPUIDLE_FLAG_TIME_VALID;
    +    +   
                                state->enter = acpi_idle_enter_c1;
                                dev->safe_state = state;
                                break;
@@@@@@@@@@@@@@ -1734,6 -1734,6 -1733,6 -1734,6 -1731,6 -1733,6 -1740,9 -1733,6 -1734,6 -1725,6 -1733,6 -1733,6 -1733,6 +1739,9 @@@@@@@@@@@@@@ int acpi_processor_cst_has_changed(stru
             {
                int ret;
             
++++++ ++++++   if (boot_option_idle_override)
++++++ ++++++           return 0;
++++++ ++++++
                if (!pr)
                        return -EINVAL;
             
@@@@@@@@@@@@@@ -1764,6 -1764,6 -1763,6 -1764,6 -1761,6 -1763,6 -1773,8 -1763,6 -1764,6 -1755,6 -1763,6 -1763,6 -1763,6 +1772,8 @@@@@@@@@@@@@@ int __cpuinit acpi_processor_power_init
                struct proc_dir_entry *entry = NULL;
                unsigned int i;
             
++++++ ++++++   if (boot_option_idle_override)
++++++ ++++++           return 0;
             
                if (!first_run) {
                        dmi_check_system(processor_power_dmi_table);
                 * Note that we use previously set idle handler will be used on
                 * platforms that only support C1.
                 */
------ ------   if ((pr->flags.power) && (!boot_option_idle_override)) {
++++++ ++++++   if (pr->flags.power) {
             #ifdef CONFIG_CPU_IDLE
                        acpi_processor_setup_cpuidle(pr);
                        pr->power.dev.cpu = pr->id;
             int acpi_processor_power_exit(struct acpi_processor *pr,
                                      struct acpi_device *device)
             {
++++++ ++++++   if (boot_option_idle_override)
++++++ ++++++           return 0;
++++++ ++++++
             #ifdef CONFIG_CPU_IDLE
------ ------   if ((pr->flags.power) && (!boot_option_idle_override))
++++++ ++++++   if (pr->flags.power)
                        cpuidle_unregister_device(&pr->power.dev);
             #endif
                pr->flags.power_setup_done = 0;
diff --combined drivers/acpi/scan.c
index 464ee6ea8c61ad0efe22039773ef3fceb72fc439,bd32351854ac19343bd99b5034bed0a2b4a64fb3,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,57570ac47803f4d590da5f8254547119ab10aec3,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,3fac011f9cf964082b463ef20913542ca9bce173,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,e6ce262b5d449673932c6c49fa1f41bbc8cb8436,6b1999b1cd34046a6a86d7f2424890f0e8a44537..6d85289f1c12ad50fdf46ddd72a863c00d1070db
@@@@@@@@@@@@@@ -39,26 -39,26 -39,26 -39,26 -39,20 -39,26 -39,26 -39,26 -39,26 -39,20 -39,26 -39,26 -39,26 +39,26 @@@@@@@@@@@@@@ static int create_modalias(struct acpi_
                                   int size)
             {
                int len;
    +    +      int count;
             
    -    -      if (!acpi_dev->flags.hardware_id)
    +    +      if (!acpi_dev->flags.hardware_id && !acpi_dev->flags.compatible_ids)
                        return -ENODEV;
             
    -    -      len = snprintf(modalias, size, "acpi:%s:",
    -    -                     acpi_dev->pnp.hardware_id);
    -    -      if (len < 0 || len >= size)
    -    -              return -EINVAL;
    +    +      len = snprintf(modalias, size, "acpi:");
                size -= len;
             
    +    +      if (acpi_dev->flags.hardware_id) {
    +    +              count = snprintf(&modalias[len], size, "%s:",
    +    +                               acpi_dev->pnp.hardware_id);
    +    +              if (count < 0 || count >= size)
    +    +                      return -EINVAL;
    +    +              len += count;
    +    +              size -= count;
    +    +      }
    +    +   
                if (acpi_dev->flags.compatible_ids) {
                        struct acpi_compatible_id_list *cid_list;
                        int i;
    -    -              int count;
             
                        cid_list = acpi_dev->pnp.cid_list;
                        for (i = 0; i < cid_list->count; i++) {
@@@@@@@@@@@@@@ -615,8 -615,8 -615,8 -615,8 -609,8 -615,8 -615,8 -615,8 -615,8 -609,7 -615,8 -615,8 -615,8 +615,8 @@@@@@@@@@@@@@ acpi_bus_get_ejd(acpi_handle handle, ac
                status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
                if (ACPI_SUCCESS(status)) {
                        obj = buffer.pointer;
         -              status = acpi_get_handle(NULL, obj->string.pointer, ejd);
         +              status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer,
         +                                       ejd);
                        kfree(buffer.pointer);
                }
                return status;
@@@@@@@@@@@@@@ -677,8 -677,9 -677,9 -677,9 -671,9 -677,9 -677,9 -677,9 -677,9 -670,9 -677,9 -677,9 -677,9 +677,8 @@@@@@@@@@@@@@ acpi_bus_extract_wakeup_device_power_pa
                device->wakeup.resources.count = package->package.count - 2;
                for (i = 0; i < device->wakeup.resources.count; i++) {
                        element = &(package->package.elements[i + 2]);
 ------------           if (element->type != ACPI_TYPE_ANY) {
 ++++++++++++           if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
                                return AE_BAD_DATA;
 ------------           }
             
                        device->wakeup.resources.handles[i] = element->reference.handle;
                }
@@@@@@@@@@@@@@ -691,6 -692,9 -692,6 -692,6 -686,6 -692,6 -692,6 -692,6 -692,6 -685,6 -692,6 -692,6 -692,6 +691,9 @@@@@@@@@@@@@@ static int acpi_bus_get_wakeup_device_f
                acpi_status status = 0;
                struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
                union acpi_object *package = NULL;
+ +++++++++++   union acpi_object in_arg[3];
+ +++++++++++   struct acpi_object_list arg_list = { 3, in_arg };
+ +++++++++++   acpi_status psw_status = AE_OK;
             
                struct acpi_device_id button_device_ids[] = {
                        {"PNP0C0D", 0},
                        {"", 0},
                };
             
- -----------
                /* _PRW */
                status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
                if (ACPI_FAILURE(status)) {
                kfree(buffer.pointer);
             
                device->wakeup.flags.valid = 1;
+ +++++++++++   /* Call _PSW/_DSW object to disable its ability to wake the sleeping
+ +++++++++++    * system for the ACPI device with the _PRW object.
+ +++++++++++    * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
+ +++++++++++    * So it is necessary to call _DSW object first. Only when it is not
+ +++++++++++    * present will the _PSW object used.
+ +++++++++++    */
+ +++++++++++   /*
+ +++++++++++    * Three agruments are needed for the _DSW object.
+ +++++++++++    * Argument 0: enable/disable the wake capabilities
+ +++++++++++    * When _DSW object is called to disable the wake capabilities, maybe
+ +++++++++++    * the first argument is filled. The value of the other two agruments
+ +++++++++++    * is meaningless.
+ +++++++++++    */
+ +++++++++++   in_arg[0].type = ACPI_TYPE_INTEGER;
+ +++++++++++   in_arg[0].integer.value = 0;
+ +++++++++++   in_arg[1].type = ACPI_TYPE_INTEGER;
+ +++++++++++   in_arg[1].integer.value = 0;
+ +++++++++++   in_arg[2].type = ACPI_TYPE_INTEGER;
+ +++++++++++   in_arg[2].integer.value = 0;
+ +++++++++++   psw_status = acpi_evaluate_object(device->handle, "_DSW",
+ +++++++++++                                           &arg_list, NULL);
+ +++++++++++   if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
+ +++++++++++           ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n"));
+ +++++++++++   /*
+ +++++++++++    * When the _DSW object is not present, OSPM will call _PSW object.
+ +++++++++++    */
+ +++++++++++   if (psw_status == AE_NOT_FOUND) {
+ +++++++++++           /*
+ +++++++++++            * Only one agruments is required for the _PSW object.
+ +++++++++++            * agrument 0: enable/disable the wake capabilities
+ +++++++++++            */
+ +++++++++++           arg_list.count = 1;
+ +++++++++++           in_arg[0].integer.value = 0;
+ +++++++++++           psw_status = acpi_evaluate_object(device->handle, "_PSW",
+ +++++++++++                                           &arg_list, NULL);
+ +++++++++++           if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
+ +++++++++++                   ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in "
+ +++++++++++                                           "evaluate _PSW\n"));
+ +++++++++++   }
                /* Power button, Lid switch always enable wakeup */
                if (!acpi_match_device_ids(device, button_device_ids))
                        device->wakeup.flags.run_wake = 1;
@@@@@@@@@@@@@@ -881,10 -923,10 -882,10 -882,10 -876,10 -882,10 -882,10 -882,10 -882,10 -875,10 -882,10 -882,10 -882,7 +922,7 @@@@@@@@@@@@@@ static void acpi_device_get_busid(struc
             static int
             acpi_video_bus_match(struct acpi_device *device)
             {
------------    acpi_handle h_dummy1;
------------    acpi_handle h_dummy2;
------------    acpi_handle h_dummy3;
------------ 
++++++++++++    acpi_handle h_dummy;
             
                if (!device)
                        return -EINVAL;
                 */
             
                /* Does this device able to support video switching ? */
------------    if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
------------        ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
++++++++++++    if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
++++++++++++        ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
                        return 0;
             
                /* Does this device able to retrieve a video ROM ? */
------------    if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
++++++++++++    if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
                        return 0;
             
                /* Does this device able to configure which video head to be POSTed ? */
------------    if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
------------        ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
------------        ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
++++++++++++    if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
++++++++++++        ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
++++++++++++        ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
                        return 0;
             
                return -ENODEV;
@@@@@@@@@@@@@@ -972,7 -1014,7 -973,7 -973,7 -967,7 -973,7 -973,7 -973,7 -973,7 -966,7 -973,7 -973,7 -970,7 +1010,7 @@@@@@@@@@@@@@ static void acpi_device_set_id(struct a
                case ACPI_BUS_TYPE_DEVICE:
                        status = acpi_get_object_info(handle, &buffer);
                        if (ACPI_FAILURE(status)) {
         -                      printk(KERN_ERR PREFIX "%s: Error reading device info\n", __FUNCTION__);
         +                      printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
                                return;
                        }
             
index a92d91277ef9dc537eb079568eb5a3205a850b54,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,df41312733c219aaa8fa48b96447f1faeb53183d,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253,2d496918b3cda4593d383b36cce08f18e2535253..f8bdadf3c32fffba99a72c5e4d905d9634331fdc
@@@@@@@@@@@@@@ -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 -5,7 +5,7 @@@@@@@@@@@@@@
              *****************************************************************************/
             
             /*
 ------------ * Copyright (C) 2000 - 2007, R. Byron Moore
 ++++++++++++ * Copyright (C) 2000 - 2008, Intel Corp.
              * All rights reserved.
              *
              * Redistribution and use in source and binary forms, with or without
             #define _COMPONENT          ACPI_UTILITIES
             ACPI_MODULE_NAME("utxface")
             
 ++++++++++++#ifndef ACPI_ASL_COMPILER
             /*******************************************************************************
              *
              * FUNCTION:    acpi_initialize_subsystem
@@@@@@@@@@@@@@ -193,24 -192,24 -192,24 -192,6 -192,24 -192,24 -192,24 -192,24 -192,24 -192,24 -192,24 -192,24 -192,24 +193,6 @@@@@@@@@@@@@@ acpi_status acpi_enable_subsystem(u32 f
                        }
                }
             
--- ---------   /*
--- ---------    * Complete the GPE initialization for the GPE blocks defined in the FADT
--- ---------    * (GPE block 0 and 1).
--- ---------    *
--- ---------    * Note1: This is where the _PRW methods are executed for the GPEs. These
--- ---------    * methods can only be executed after the SCI and Global Lock handlers are
--- ---------    * installed and initialized.
--- ---------    *
--- ---------    * Note2: Currently, there seems to be no need to run the _REG methods
--- ---------    * before execution of the _PRW methods and enabling of the GPEs.
--- ---------    */
--- ---------   if (!(flags & ACPI_NO_EVENT_INIT)) {
--- ---------           status = acpi_ev_install_fadt_gpes();
--- ---------           if (ACPI_FAILURE(status)) {
--- ---------                   return (status);
--- ---------           }
--- ---------   }
--- ---------
                return_ACPI_STATUS(status);
             }
             
@@@@@@@@@@@@@@ -280,6 -279,6 -279,6 -261,23 -279,6 -279,6 -279,6 -279,6 -279,6 -279,6 -279,6 -279,6 -279,6 +262,23 @@@@@@@@@@@@@@ acpi_status acpi_initialize_objects(u3
                        }
                }
             
+++ +++++++++   /*
+++ +++++++++    * Complete the GPE initialization for the GPE blocks defined in the FADT
+++ +++++++++    * (GPE block 0 and 1).
+++ +++++++++    *
+++ +++++++++    * Note1: This is where the _PRW methods are executed for the GPEs. These
+++ +++++++++    * methods can only be executed after the SCI and Global Lock handlers are
+++ +++++++++    * installed and initialized.
+++ +++++++++    *
+++ +++++++++    * Note2: Currently, there seems to be no need to run the _REG methods
+++ +++++++++    * before execution of the _PRW methods and enabling of the GPEs.
+++ +++++++++    */
+++ +++++++++   if (!(flags & ACPI_NO_EVENT_INIT)) {
+++ +++++++++           status = acpi_ev_install_fadt_gpes();
+++ +++++++++           if (ACPI_FAILURE(status))
+++ +++++++++                   return (status);
+++ +++++++++   }
+++ +++++++++
                /*
                 * Empty the caches (delete the cached objects) on the assumption that
                 * the table load filled them up more than they will be at runtime --
             
             ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
             
 ++++++++++++#endif
             /*******************************************************************************
              *
              * FUNCTION:    acpi_terminate
@@@@@@@@@@@@@@ -337,7 -335,6 -335,6 -334,6 -335,6 -335,6 -335,6 -335,6 -335,6 -335,6 -335,6 -335,6 -335,6 +336,7 @@@@@@@@@@@@@@ acpi_status acpi_terminate(void
             }
             
             ACPI_EXPORT_SYMBOL(acpi_terminate)
 ++++++++++++#ifndef ACPI_ASL_COMPILER
             #ifdef ACPI_FUTURE_USAGE
             /*******************************************************************************
              *
@@@@@@@@@@@@@@ -493,4 -490,3 -490,3 -489,3 -490,3 -490,3 -490,3 -490,3 -490,3 -490,3 -490,3 -490,3 -490,3 +492,4 @@@@@@@@@@@@@@ acpi_status acpi_purge_cached_objects(v
             }
             
             ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
 ++++++++++++#endif
diff --combined drivers/acpi/video.c
index 980a74188781eba10b5372934de94bef0e2a2ea2,980a74188781eba10b5372934de94bef0e2a2ea2,980a74188781eba10b5372934de94bef0e2a2ea2,980a74188781eba10b5372934de94bef0e2a2ea2,12fb44f16766f5979be78b031cd16225161e23d3,980a74188781eba10b5372934de94bef0e2a2ea2,980a74188781eba10b5372934de94bef0e2a2ea2,980a74188781eba10b5372934de94bef0e2a2ea2,980a74188781eba10b5372934de94bef0e2a2ea2,12cce69b5441e98a7bd8da23031dc250daaa88f1,55c09561937910ebfbd50fb922d0444881fb617c,980a74188781eba10b5372934de94bef0e2a2ea2,c24a1d743257e835523d2ac25e9e2474ee421df1..33c502e560269e0678ab726508f36f13de9c6a6d
             #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS  0x88
             #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF              0x89
             
------------ #define ACPI_VIDEO_HEAD_INVALID            (~0u - 1)
------------ #define ACPI_VIDEO_HEAD_END                (~0u)
             #define MAX_NAME_LEN       20
             
             #define ACPI_VIDEO_DISPLAY_CRT     1
@@@@@@@@@@@@@@ -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -713,7 -711,7 +711,7 @@@@@@@@@@@@@@ static void acpi_video_device_find_cap(
             
                kfree(obj);
             
    -           if (device->cap._BCL && device->cap._BCM && max_level > 0) {
    +           if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
                        int result;
                        static int count = 0;
                        char *name;
                        if (IS_ERR(device->cdev))
                                return;
             
---------- --           if (device->cdev) {
---------- --                   printk(KERN_INFO PREFIX
---------- --                           "%s is registered as cooling_device%d\n",
---------- --                           device->dev->dev.bus_id, device->cdev->id);
---------- --                   result = sysfs_create_link(&device->dev->dev.kobj,
---------- --                                     &device->cdev->device.kobj,
---------- --                                     "thermal_cooling");
---------- --                   if (result)
---------- --                           printk(KERN_ERR PREFIX "Create sysfs link\n");
---------- --                   result = sysfs_create_link(&device->cdev->device.kobj,
---------- --                                     &device->dev->dev.kobj,
---------- --                                     "device");
---------- --                        if (result)
---------- --                           printk(KERN_ERR PREFIX "Create sysfs link\n");
---------- --           }
++++++++++ ++           printk(KERN_INFO PREFIX
++++++++++ ++                   "%s is registered as cooling_device%d\n",
++++++++++ ++                   device->dev->dev.bus_id, device->cdev->id);
++++++++++ ++           result = sysfs_create_link(&device->dev->dev.kobj,
++++++++++ ++                           &device->cdev->device.kobj,
++++++++++ ++                           "thermal_cooling");
++++++++++ ++           if (result)
++++++++++ ++                   printk(KERN_ERR PREFIX "Create sysfs link\n");
++++++++++ ++           result = sysfs_create_link(&device->cdev->device.kobj,
++++++++++ ++                           &device->dev->dev.kobj, "device");
++++++++++ ++           if (result)
++++++++++ ++                   printk(KERN_ERR PREFIX "Create sysfs link\n");
++++++++++ ++
                }
                if (device->cap._DCS && device->cap._DSS){
                        static int count = 0;
@@@@@@@@@@@@@@ -807,11 -807,11 -807,11 -807,11 -807,11 -807,11 -807,11 -807,11 -807,11 -807,40 -805,11 -807,11 -805,11 +803,11 @@@@@@@@@@@@@@ static void acpi_video_bus_find_cap(str
             static int acpi_video_bus_check(struct acpi_video_bus *video)
             {
                acpi_status status = -ENOENT;
         -      long device_id;
         -      struct device *dev;
         -      struct acpi_device *device;
         +   
             
                if (!video)
                        return -EINVAL;
             
         -      device = video->device;
         -   
         -      status =
         -          acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
         -   
         -      if (!ACPI_SUCCESS(status))
         -              return -ENODEV;
         -   
         -      /* We need to attempt to determine whether the _ADR refers to a
         -         PCI device or not. There's no terribly good way to do this,
         -         so the best we can hope for is to assume that there'll never
         -         be a video device in the host bridge */
         -      if (device_id >= 0x10000) {
         -              /* It looks like a PCI device. Does it exist? */
         -              dev = acpi_get_physical_device(device->handle);
         -      } else {
         -              /* It doesn't look like a PCI device. Does its parent
         -                 exist? */
         -              acpi_handle phandle;
         -              if (acpi_get_parent(device->handle, &phandle))
         -                      return -ENODEV;
         -              dev = acpi_get_physical_device(phandle);
         -      }
         -      if (!dev)
         -              return -ENODEV;
         -      put_device(dev);
         -   
                /* Since there is no HID, CID and so on for VGA driver, we have
                 * to check well known required nodes.
                 */
@@@@@@@@@@@@@@ -1050,87 -1050,87 -1050,87 -1050,87 -1050,87 -1050,87 -1050,87 -1050,87 -1050,87 -1079,87 -1048,87 -1050,87 -1048,90 +1046,90 @@@@@@@@@@@@@@ acpi_video_device_EDID_open_fs(struct i
             
             static int acpi_video_device_add_fs(struct acpi_device *device)
             {
------------    struct proc_dir_entry *entry = NULL;
++++++++++++    struct proc_dir_entry *entry, *device_dir;
                struct acpi_video_device *vid_dev;
             
------------ 
------------    if (!device)
------------            return -ENODEV;
------------ 
                vid_dev = acpi_driver_data(device);
                if (!vid_dev)
                        return -ENODEV;
             
------------    if (!acpi_device_dir(device)) {
------------            acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
------------                                                 vid_dev->video->dir);
------------            if (!acpi_device_dir(device))
------------                    return -ENODEV;
------------            acpi_device_dir(device)->owner = THIS_MODULE;
------------    }
++++++++++++    device_dir = proc_mkdir(acpi_device_bid(device),
++++++++++++                            vid_dev->video->dir);
++++++++++++    if (!device_dir)
++++++++++++            return -ENOMEM;
++++++++++++ 
++++++++++++    device_dir->owner = THIS_MODULE;
             
                /* 'info' [R] */
------------    entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("info", S_IRUGO, device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            entry->proc_fops = &acpi_video_device_info_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_dir;
++++++++++++ 
++++++++++++    entry->proc_fops = &acpi_video_device_info_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'state' [R/W] */
------------    entry =
------------        create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
------------                          acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
++++++++++++                              device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            acpi_video_device_state_fops.write = acpi_video_device_write_state;
------------            entry->proc_fops = &acpi_video_device_state_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_info;
++++++++++++ 
++++++++++++    acpi_video_device_state_fops.write = acpi_video_device_write_state;
++++++++++++    entry->proc_fops = &acpi_video_device_state_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'brightness' [R/W] */
------------    entry =
------------        create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR,
------------                          acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR,
++++++++++++                              device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness;
------------            entry->proc_fops = &acpi_video_device_brightness_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_state;
++++++++++++ 
++++++++++++    acpi_video_device_brightness_fops.write =
++++++++++++                    acpi_video_device_write_brightness;
++++++++++++    entry->proc_fops = &acpi_video_device_brightness_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'EDID' [R] */
------------    entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("EDID", S_IRUGO, device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            entry->proc_fops = &acpi_video_device_EDID_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_brightness;
             
++++++++++++    entry->proc_fops = &acpi_video_device_EDID_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
++++++++++++ 
++++++++++++    acpi_device_dir(device) = device_dir;
                return 0;
++++++++++++ 
++++++++++++  err_remove_brightness:
++++++++++++    remove_proc_entry("brightness", device_dir);
++++++++++++  err_remove_state:
++++++++++++    remove_proc_entry("state", device_dir);
++++++++++++  err_remove_info:
++++++++++++    remove_proc_entry("info", device_dir);
++++++++++++  err_remove_dir:
++++++++++++    remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
++++++++++++    return -ENOMEM;
             }
             
             static int acpi_video_device_remove_fs(struct acpi_device *device)
             {
                struct acpi_video_device *vid_dev;
++++++++++++    struct proc_dir_entry *device_dir;
             
                vid_dev = acpi_driver_data(device);
                if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
                        return -ENODEV;
             
------------    if (acpi_device_dir(device)) {
------------            remove_proc_entry("info", acpi_device_dir(device));
------------            remove_proc_entry("state", acpi_device_dir(device));
------------            remove_proc_entry("brightness", acpi_device_dir(device));
------------            remove_proc_entry("EDID", acpi_device_dir(device));
++++++++++++    device_dir = acpi_device_dir(device);
++++++++++++    if (device_dir) {
++++++++++++            remove_proc_entry("info", device_dir);
++++++++++++            remove_proc_entry("state", device_dir);
++++++++++++            remove_proc_entry("brightness", device_dir);
++++++++++++            remove_proc_entry("EDID", device_dir);
                        remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
                        acpi_device_dir(device) = NULL;
                }
@@@@@@@@@@@@@@ -1172,7 -1172,7 -1172,7 -1172,7 -1172,7 -1172,7 -1172,7 -1172,7 -1172,7 -1201,7 -1170,7 -1172,7 -1173,7 +1171,7 @@@@@@@@@@@@@@ static int acpi_video_bus_ROM_seq_show(
                if (!video)
                        goto end;
             
         -      printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__);
         +      printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
                seq_printf(seq, "<TODO>\n");
             
                   end:
@@@@@@@@@@@@@@ -1337,94 -1337,94 -1337,94 -1337,94 -1337,94 -1337,94 -1337,94 -1337,94 -1337,94 -1366,123 -1335,94 -1337,94 -1338,91 +1336,91 @@@@@@@@@@@@@@ acpi_video_bus_write_DOS(struct file *f
             
             static int acpi_video_bus_add_fs(struct acpi_device *device)
             {
         -      long device_id;
         -      int status;
------------    struct proc_dir_entry *entry = NULL;
------------    struct acpi_video_bus *video;
--------- -- 
         -      struct device *dev;
++++++++++++    struct acpi_video_bus *video = acpi_driver_data(device);
++++++++++++    struct proc_dir_entry *device_dir;
++++++++++++    struct proc_dir_entry *entry;
             
--------- --    video = acpi_driver_data(device);
         -      status =
         -          acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
++++++++++++    device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
++++++++++++    if (!device_dir)
++++++++++++            return -ENOMEM;
             
         -      if (!ACPI_SUCCESS(status))
         -              return -ENODEV;
         -   
         -      /* We need to attempt to determine whether the _ADR refers to a
         -         PCI device or not. There's no terribly good way to do this,
         -         so the best we can hope for is to assume that there'll never
         -         be a video device in the host bridge */
         -      if (device_id >= 0x10000) {
         -              /* It looks like a PCI device. Does it exist? */
         -              dev = acpi_get_physical_device(device->handle);
         -      } else {
         -              /* It doesn't look like a PCI device. Does its parent
         -                 exist? */
         -              acpi_handle phandle;
         -              if (acpi_get_parent(device->handle, &phandle))
         -                      return -ENODEV;
         -              dev = acpi_get_physical_device(phandle);
         -      }
         -      if (!dev)
         -              return -ENODEV;
         -      put_device(dev);
         -   
         -   
         -   
         -      video = acpi_driver_data(device);
         -   
------------    if (!acpi_device_dir(device)) {
------------            acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
------------                                                 acpi_video_dir);
------------            if (!acpi_device_dir(device))
------------                    return -ENODEV;
------------            video->dir = acpi_device_dir(device);
------------            acpi_device_dir(device)->owner = THIS_MODULE;
------------    }
++++++++++++    device_dir->owner = THIS_MODULE;
             
                /* 'info' [R] */
------------    entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("info", S_IRUGO, device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            entry->proc_fops = &acpi_video_bus_info_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_dir;
++++++++++++ 
++++++++++++    entry->proc_fops = &acpi_video_bus_info_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'ROM' [R] */
------------    entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("ROM", S_IRUGO, device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            entry->proc_fops = &acpi_video_bus_ROM_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_info;
++++++++++++ 
++++++++++++    entry->proc_fops = &acpi_video_bus_ROM_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'POST_info' [R] */
------------    entry =
------------        create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("POST_info", S_IRUGO, device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            entry->proc_fops = &acpi_video_bus_POST_info_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_rom;
++++++++++++ 
++++++++++++    entry->proc_fops = &acpi_video_bus_POST_info_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'POST' [R/W] */
------------    entry =
------------        create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR,
------------                          acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("POST", S_IFREG | S_IRUGO | S_IWUSR,
++++++++++++                              device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
------------            entry->proc_fops = &acpi_video_bus_POST_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_post_info;
++++++++++++ 
++++++++++++    acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
++++++++++++    entry->proc_fops = &acpi_video_bus_POST_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
             
                /* 'DOS' [R/W] */
------------    entry =
------------        create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR,
------------                          acpi_device_dir(device));
++++++++++++    entry = create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IWUSR,
++++++++++++                          device_dir);
                if (!entry)
------------            return -ENODEV;
------------    else {
------------            acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
------------            entry->proc_fops = &acpi_video_bus_DOS_fops;
------------            entry->data = acpi_driver_data(device);
------------            entry->owner = THIS_MODULE;
------------    }
++++++++++++            goto err_remove_post;
++++++++++ + 
++++++++++++    acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
++++++++++++    entry->proc_fops = &acpi_video_bus_DOS_fops;
++++++++++++    entry->data = acpi_driver_data(device);
++++++++++++    entry->owner = THIS_MODULE;
          +  
++++++++++++    video->dir = acpi_device_dir(device) = device_dir;
                return 0;
++++++++++++ 
++++++++++++  err_remove_post:
++++++++++++    remove_proc_entry("POST", device_dir);
++++++++++++  err_remove_post_info:
++++++++++++    remove_proc_entry("POST_info", device_dir);
++++++++++++  err_remove_rom:
++++++++++++    remove_proc_entry("ROM", device_dir);
++++++++++++  err_remove_info:
++++++++++++    remove_proc_entry("info", device_dir);
++++++++++++  err_remove_dir:
++++++++++++    remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
++++++++++++    return -ENOMEM;
             }
             
             static int acpi_video_bus_remove_fs(struct acpi_device *device)
             {
------------    struct acpi_video_bus *video;
------------ 
------------ 
------------    video = acpi_driver_data(device);
------------ 
------------    if (acpi_device_dir(device)) {
------------            remove_proc_entry("info", acpi_device_dir(device));
------------            remove_proc_entry("ROM", acpi_device_dir(device));
------------            remove_proc_entry("POST_info", acpi_device_dir(device));
------------            remove_proc_entry("POST", acpi_device_dir(device));
------------            remove_proc_entry("DOS", acpi_device_dir(device));
++++++++++++    struct proc_dir_entry *device_dir = acpi_device_dir(device);
++++++++++++ 
++++++++++++    if (device_dir) {
++++++++++++            remove_proc_entry("info", device_dir);
++++++++++++            remove_proc_entry("ROM", device_dir);
++++++++++++            remove_proc_entry("POST_info", device_dir);
++++++++++++            remove_proc_entry("POST", device_dir);
++++++++++++            remove_proc_entry("DOS", device_dir);
                        remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
                        acpi_device_dir(device) = NULL;
                }
             static struct acpi_video_device_attrib*
             acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
             {
------------    int count;
++++++++++++    struct acpi_video_enumerated_device *ids;
++++++++++++    int i;
++++++++++++ 
++++++++++++    for (i = 0; i < video->attached_count; i++) {
++++++++++++            ids = &video->attached_array[i];
++++++++++++            if ((ids->value.int_val & 0xffff) == device_id)
++++++++++++                    return &ids->value.attrib;
++++++++++++    }
             
------------    for(count = 0; count < video->attached_count; count++)
------------            if((video->attached_array[count].value.int_val & 0xffff) == device_id)
------------                    return &(video->attached_array[count].value.attrib);
                return NULL;
             }
             
             acpi_video_device_bind(struct acpi_video_bus *video,
                               struct acpi_video_device *device)
             {
++++++++++++    struct acpi_video_enumerated_device *ids;
                int i;
             
------------ #define IDS_VAL(i) video->attached_array[i].value.int_val
------------ #define IDS_BIND(i) video->attached_array[i].bind_info
------------ 
------------    for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID &&
------------         i < video->attached_count; i++) {
------------            if (device->device_id == (IDS_VAL(i) & 0xffff)) {
------------                    IDS_BIND(i) = device;
++++++++++++    for (i = 0; i < video->attached_count; i++) {
++++++++++++            ids = &video->attached_array[i];
++++++++++++            if (device->device_id == (ids->value.int_val & 0xffff)) {
++++++++++++                    ids->bind_info = device;
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
                        }
                }
------------ #undef IDS_VAL
------------ #undef IDS_BIND
             }
             
             /*
@@@@@@@@@@@@@@ -1603,7 -1603,7 -1603,7 -1603,7 -1603,7 -1603,7 -1603,7 -1603,7 -1603,7 -1661,7 -1601,7 -1603,7 -1601,7 +1599,7 @@@@@@@@@@@@@@ static int acpi_video_device_enumerate(
                int status;
                int count;
                int i;
------------    struct acpi_video_enumerated_device *active_device_list;
++++++++++++    struct acpi_video_enumerated_device *active_list;
                struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
                union acpi_object *dod = NULL;
                union acpi_object *obj;
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
                                  dod->package.count));
             
------------    active_device_list = kmalloc((1 +
------------                                  dod->package.count) *
------------                                 sizeof(struct
------------                                        acpi_video_enumerated_device),
------------                                 GFP_KERNEL);
------------ 
------------    if (!active_device_list) {
++++++++++++    active_list = kcalloc(1 + dod->package.count,
++++++++++++                          sizeof(struct acpi_video_enumerated_device),
++++++++++++                          GFP_KERNEL);
++++++++++++    if (!active_list) {
                        status = -ENOMEM;
                        goto out;
                }
                        obj = &dod->package.elements[i];
             
                        if (obj->type != ACPI_TYPE_INTEGER) {
------------                    printk(KERN_ERR PREFIX "Invalid _DOD data\n");
------------                    active_device_list[i].value.int_val =
------------                        ACPI_VIDEO_HEAD_INVALID;
++++++++++++                    printk(KERN_ERR PREFIX
++++++++++++                            "Invalid _DOD data in element %d\n", i);
++++++++++++                    continue;
                        }
------------            active_device_list[i].value.int_val = obj->integer.value;
------------            active_device_list[i].bind_info = NULL;
++++++++++++ 
++++++++++++            active_list[count].value.int_val = obj->integer.value;
++++++++++++            active_list[count].bind_info = NULL;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
                                          (int)obj->integer.value));
                        count++;
                }
------------    active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
             
                kfree(video->attached_array);
             
------------    video->attached_array = active_device_list;
++++++++++++    video->attached_array = active_list;
                video->attached_count = count;
------------       out:
++++++++++++ 
++++++++++++  out:
                kfree(buffer.pointer);
                return status;
             }
diff --combined drivers/misc/Kconfig
index 962817e49fba02e063dc164a3d0971e221eaa3a7,962817e49fba02e063dc164a3d0971e221eaa3a7,297a48f8544679dda2af4bd435cb32feff65b661,297a48f8544679dda2af4bd435cb32feff65b661,962817e49fba02e063dc164a3d0971e221eaa3a7,7a4869a9db868939deb741c6be64135c7c2bacae,962817e49fba02e063dc164a3d0971e221eaa3a7,38cce4d1e2fbf11991faacea848cc0c267174429,962817e49fba02e063dc164a3d0971e221eaa3a7,982e27b86d101a15ebb2f579652a67d4ae08f806,08f35d76dcd9003960c395f59e6aafe5f919b55e,2e217947d971529f1e4afb5ffc78f1af996a4cba,297a48f8544679dda2af4bd435cb32feff65b661..636af2862308fab614b4f9f9b2395ce0a24c7e4f
@@@@@@@@@@@@@@ -22,6 -22,6 -22,39 -22,39 -22,6 -22,39 -22,6 -22,39 -22,6 -22,6 -22,39 -22,39 -22,39 +22,39 @@@@@@@@@@@@@@ config ATMEL_PW
                  purposes including software controlled power-efficent backlights
                  on LCD displays, motor control, and waveform generation.
             
++  + + ++   config ATMEL_TCLIB
++  + + ++      bool "Atmel AT32/AT91 Timer/Counter Library"
++  + + ++      depends on (AVR32 || ARCH_AT91)
++  + + ++      help
++  + + ++        Select this if you want a library to allocate the Timer/Counter
++  + + ++        blocks found on many Atmel processors.  This facilitates using
++  + + ++        these blocks by different drivers despite processor differences.
++  + + ++   
++  + + ++   config ATMEL_TCB_CLKSRC
++  + + ++      bool "TC Block Clocksource"
++  + + ++      depends on ATMEL_TCLIB && GENERIC_TIME
++  + + ++      default y
++  + + ++      help
++  + + ++        Select this to get a high precision clocksource based on a
++  + + ++        TC block with a 5+ MHz base clock rate.  Two timer channels
++  + + ++        are combined to make a single 32-bit timer.
++  + + ++   
++  + + ++        When GENERIC_CLOCKEVENTS is defined, the third timer channel
++  + + ++        may be used as a clock event device supporting oneshot mode
++  + + ++        (delays of up to two seconds) based on the 32 KiHz clock.
++  + + ++   
++  + + ++   config ATMEL_TCB_CLKSRC_BLOCK
++  + + ++      int
++  + + ++      depends on ATMEL_TCB_CLKSRC
++  + + ++      prompt "TC Block" if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || CPU_AT32AP700X
++  + + ++      default 0
++  + + ++      range 0 1
++  + + ++      help
++  + + ++        Some chips provide more than one TC block, so you have the
++  + + ++        choice of which one to use for the clock framework.  The other
++  + + ++        TC can be used for other purposes, such as PWM generation and
++  + + ++        interval timing.
++  + + ++   
             config IBM_ASM
                tristate "Device driver for IBM RSA service processor"
                depends on X86 && PCI && INPUT && EXPERIMENTAL
@@@@@@@@@@@@@@ -107,8 -107,8 -140,8 -140,8 -107,8 -140,8 -107,8 -140,9 -107,8 -107,7 -140,8 -140,8 -140,8 +140,9 @@@@@@@@@@@@@@ config ACER_WM
                depends on EXPERIMENTAL
                depends on ACPI
                depends on LEDS_CLASS
+++++++ +++++   depends on NEW_LEDS
                depends on BACKLIGHT_CLASS_DEVICE
         +      depends on SERIO_I8042
                select ACPI_WMI
                ---help---
                  This is a driver for newer Acer (and Wistron) laptops. It adds
@@@@@@@@@@@@@@ -127,6 -127,6 -160,6 -160,6 -127,6 -160,6 -127,6 -161,7 -127,6 -126,6 -160,6 -160,6 -160,6 +161,7 @@@@@@@@@@@@@@ config ASUS_LAPTO
                     depends on ACPI
                depends on EXPERIMENTAL && !ACPI_ASUS
                depends on LEDS_CLASS
+++++++ +++++   depends on NEW_LEDS
                depends on BACKLIGHT_CLASS_DEVICE
                     ---help---
                  This is the new Linux driver for Asus laptops. It may also support some
             config THINKPAD_ACPI
                tristate "ThinkPad ACPI Laptop Extras"
                depends on X86 && ACPI
+++++++++++ +   select BACKLIGHT_LCD_SUPPORT
                select BACKLIGHT_CLASS_DEVICE
                select HWMON
                select NVRAM
----------- -   depends on INPUT
+++++++++++ +   select INPUT
+++++++++++ +   select NEW_LEDS
+++++++++++ +   select LEDS_CLASS
                ---help---
                  This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
                  support for Fn-Fx key combinations, Bluetooth control, video
@@@@@@@@@@@@@@ -311,6 -311,6 -344,6 -344,6 -311,6 -344,6 -311,6 -346,6 -311,6 -310,6 -344,7 -347,6 -344,6 +349,7 @@@@@@@@@@@@@@ config ATMEL_SS
             config INTEL_MENLOW
                tristate "Thermal Management driver for Intel menlow platform"
                depends on ACPI_THERMAL
++++++++++ ++   select THERMAL
                depends on X86
                ---help---
                  ACPI thermal management enhancement driver on
             
                  If unsure, say N.
             
+++++ +++++++config EEEPC_LAPTOP
+++++ +++++++   tristate "Eee PC Hotkey Driver (EXPERIMENTAL)"
+++++ +++++++   depends on X86
+++++ +++++++   depends on ACPI
+++++ +++++++   depends on BACKLIGHT_CLASS_DEVICE
+++++ +++++++   depends on HWMON
+++++ +++++++   depends on EXPERIMENTAL
+++++ +++++++   ---help---
+++++ +++++++     This driver supports the Fn-Fx keys on Eee PC laptops.
+++++ +++++++     It also adds the ability to switch camera/wlan on/off.
+++++ +++++++
+++++ +++++++     If you have an Eee PC laptop, say Y or M here.
+++++ +++++++
             config ENCLOSURE_SERVICES
                tristate "Enclosure Services"
                default n
                  driver (SCSI/ATA) which supports enclosures
                  or a SCSI enclosure device (SES) to use these services.
             
++  + + ++   config SGI_XP
++  + + ++      tristate "Support communication between SGI SSIs"
++  + + ++      depends on IA64_GENERIC || IA64_SGI_SN2
++  + + ++      select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
++  + + ++      select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
++  + + ++      ---help---
++  + + ++        An SGI machine can be divided into multiple Single System
++  + + ++        Images which act independently of each other and have
++  + + ++        hardware based memory protection from the others.  Enabling
++  + + ++        this feature will allow for direct communication between SSIs
++  + + ++        based on a network adapter and DMA messaging.
++  + + ++   
             endif # MISC_DEVICES
index 6cb781262f947611a20916bf6b996c9ff3e713cb,6cb781262f947611a20916bf6b996c9ff3e713cb,6cb781262f947611a20916bf6b996c9ff3e713cb,6cb781262f947611a20916bf6b996c9ff3e713cb,6cb781262f947611a20916bf6b996c9ff3e713cb,6cb781262f947611a20916bf6b996c9ff3e713cb,6cb781262f947611a20916bf6b996c9ff3e713cb,31115c9cfb345154b8a5c7d90027940a0111b7c4,6cb781262f947611a20916bf6b996c9ff3e713cb,bb269d0c677edbc4cadd268dc634e90b6120a80e,6cb781262f947611a20916bf6b996c9ff3e713cb,d29ad2e4afc23a73a083c2ea5c8fc7b96af64001,6cb781262f947611a20916bf6b996c9ff3e713cb..3f28f6eabdbffcca3868b0b688b4a0516da91347
              *  02110-1301, USA.
              */
             
----------- -#define TPACPI_VERSION "0.19"
+++++++++++ +#define TPACPI_VERSION "0.20"
             #define TPACPI_SYSFS_VERSION 0x020200
             
             /*
             #include <linux/hwmon.h>
             #include <linux/hwmon-sysfs.h>
             #include <linux/input.h>
+++++++++++ +#include <linux/leds.h>
             #include <asm/uaccess.h>
             
             #include <linux/dmi.h>
             #define TP_CMOS_VOLUME_MUTE        2
             #define TP_CMOS_BRIGHTNESS_UP      4
             #define TP_CMOS_BRIGHTNESS_DOWN    5
+++++++++++ +#define TP_CMOS_THINKLIGHT_ON      12
+++++++++++ +#define TP_CMOS_THINKLIGHT_OFF     13
             
             /* NVRAM Addresses */
             enum tp_nvram_addr {
             #define TPACPI_PROC_DIR "ibm"
             #define TPACPI_ACPI_EVENT_PREFIX "ibm"
             #define TPACPI_DRVR_NAME TPACPI_FILE
+++++++++++ +#define TPACPI_DRVR_SHORTNAME "tpacpi"
             #define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
             
+++++++++++ +#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
+++++++++++ +#define TPACPI_WORKQUEUE_NAME "ktpacpid"
+++++++++++ +
             #define TPACPI_MAX_ACPI_ARGS 3
             
             /* Debugging */
@@@@@@@@@@@@@@ -225,6 -225,6 -225,6 -225,6 -225,6 -225,6 -225,6 -225,6 -225,6 -225,6 -225,6 -232,7 -225,6 +232,7 @@@@@@@@@@@@@@ static struct 
                u32 light:1;
                u32 light_status:1;
                u32 bright_16levels:1;
+++++++++++ +   u32 bright_acpimode:1;
                u32 wan:1;
                u32 fan_ctrl_status_undef:1;
                u32 input_device_registered:1;
                u32 hotkey_poll_active:1;
             } tp_features;
             
+++++++++++ +static struct {
+++++++++++ +   u16 hotkey_mask_ff:1;
+++++++++++ +   u16 bright_cmos_ec_unsync:1;
+++++++++++ +} tp_warned;
+++++++++++ +
             struct thinkpad_id_data {
                unsigned int vendor;    /* ThinkPad vendor:
                                         * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
                u16 bios_model;         /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
                u16 ec_model;
             
----------- -   char *model_str;
+++++++++++ +   char *model_str;        /* ThinkPad T43 */
+++++++++++ +   char *nummodel_str;     /* 9384A9C for a 9384-A9C model */
             };
             static struct thinkpad_id_data thinkpad_id;
             
@@@@@@@@@@@@@@ -259,6 -259,6 -259,6 -259,6 -259,6 -259,6 -259,6 -259,6 -259,6 -259,6 -259,6 -273,16 -259,6 +273,16 @@@@@@@@@@@@@@ static enum 
             static int experimental;
             static u32 dbg_level;
             
+++++++++++ +static struct workqueue_struct *tpacpi_wq;
+++++++++++ +
+++++++++++ +/* Special LED class that can defer work */
+++++++++++ +struct tpacpi_led_classdev {
+++++++++++ +   struct led_classdev led_classdev;
+++++++++++ +   struct work_struct work;
+++++++++++ +   enum led_brightness new_brightness;
+++++++++++ +   unsigned int led;
+++++++++++ +};
+++++++++++ +
             /****************************************************************************
              ****************************************************************************
              *
@@@@@@@@@@@@@@ -807,6 -807,6 -807,6 -807,6 -807,6 -807,6 -807,6 -807,6 -807,6 -807,6 -807,6 -831,80 -807,6 +831,80 @@@@@@@@@@@@@@ static int parse_strtoul(const char *bu
                return 0;
             }
             
+++++++++++ +static int __init tpacpi_query_bcl_levels(acpi_handle handle)
+++++++++++ +{
+++++++++++ +   struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+++++++++++ +   union acpi_object *obj;
+++++++++++ +   int rc;
+++++++++++ +
+++++++++++ +   if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
+++++++++++ +           obj = (union acpi_object *)buffer.pointer;
+++++++++++ +           if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
+++++++++++ +                   printk(TPACPI_ERR "Unknown _BCL data, "
+++++++++++ +                          "please report this to %s\n", TPACPI_MAIL);
+++++++++++ +                   rc = 0;
+++++++++++ +           } else {
+++++++++++ +                   rc = obj->package.count;
+++++++++++ +           }
+++++++++++ +   } else {
+++++++++++ +           return 0;
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   kfree(buffer.pointer);
+++++++++++ +   return rc;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
+++++++++++ +                                   u32 lvl, void *context, void **rv)
+++++++++++ +{
+++++++++++ +   char name[ACPI_PATH_SEGMENT_LENGTH];
+++++++++++ +   struct acpi_buffer buffer = { sizeof(name), &name };
+++++++++++ +
+++++++++++ +   if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
+++++++++++ +       !strncmp("_BCL", name, sizeof(name) - 1)) {
+++++++++++ +           BUG_ON(!rv || !*rv);
+++++++++++ +           **(int **)rv = tpacpi_query_bcl_levels(handle);
+++++++++++ +           return AE_CTRL_TERMINATE;
+++++++++++ +   } else {
+++++++++++ +           return AE_OK;
+++++++++++ +   }
+++++++++++ +}
+++++++++++ +
+++++++++++ +/*
+++++++++++ + * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
+++++++++++ + */
+++++++++++ +static int __init tpacpi_check_std_acpi_brightness_support(void)
+++++++++++ +{
+++++++++++ +   int status;
+++++++++++ +   int bcl_levels = 0;
+++++++++++ +   void *bcl_ptr = &bcl_levels;
+++++++++++ +
+++++++++++ +   if (!vid_handle) {
+++++++++++ +           TPACPI_ACPIHANDLE_INIT(vid);
+++++++++++ +   }
+++++++++++ +   if (!vid_handle)
+++++++++++ +           return 0;
+++++++++++ +
+++++++++++ +   /*
+++++++++++ +    * Search for a _BCL method, and execute it.  This is safe on all
+++++++++++ +    * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
+++++++++++ +    * BIOS in ACPI backlight control mode.  We do NOT have to care
+++++++++++ +    * about calling the _BCL method in an enabled video device, any
+++++++++++ +    * will do for our purposes.
+++++++++++ +    */
+++++++++++ +
+++++++++++ +   status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
+++++++++++ +                                tpacpi_acpi_walk_find_bcl, NULL,
+++++++++++ +                                &bcl_ptr);
+++++++++++ +
+++++++++++ +   if (ACPI_SUCCESS(status) && bcl_levels > 2) {
+++++++++++ +           tp_features.bright_acpimode = 1;
+++++++++++ +           return (bcl_levels - 2);
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   return 0;
+++++++++++ +}
+++++++++++ +
             /*************************************************************************
              * thinkpad-acpi driver attributes
              */
@@@@@@@@@@@@@@ -909,12 -909,12 -909,12 -909,12 -909,12 -909,12 -909,12 -909,12 -909,12 -909,12 -909,12 -1007,14 -909,12 +1007,14 @@@@@@@@@@@@@@ static int __init thinkpad_acpi_driver_
                                thinkpad_id.ec_version_str : "unknown");
             
                if (thinkpad_id.vendor && thinkpad_id.model_str)
----------- -           printk(TPACPI_INFO "%s %s\n",
+++++++++++ +           printk(TPACPI_INFO "%s %s, model %s\n",
                                (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
                                        "IBM" : ((thinkpad_id.vendor ==
                                                        PCI_VENDOR_ID_LENOVO) ?
                                                "Lenovo" : "Unknown vendor"),
----------- -                   thinkpad_id.model_str);
+++++++++++ +                   thinkpad_id.model_str,
+++++++++++ +                   (thinkpad_id.nummodel_str) ?
+++++++++++ +                           thinkpad_id.nummodel_str : "unknown");
             
                return 0;
             }
@@@@@@@@@@@@@@ -1078,8 -1078,8 -1078,8 -1078,8 -1078,8 -1078,8 -1078,8 -1078,8 -1078,8 -1078,7 -1078,8 -1178,8 -1078,8 +1178,8 @@@@@@@@@@@@@@ static int hotkey_get_tablet_mode(int *
                if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
                        return -EIO;
             
         -      return ((s & TP_HOTKEY_TABLET_MASK) != 0);
         +      *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);
         +      return 0;
             }
             
             /*
@@@@@@@@@@@@@@ -1107,6 -1107,6 -1107,6 -1107,6 -1107,6 -1107,6 -1107,6 -1107,6 -1107,6 -1106,6 -1107,6 -1207,19 -1107,6 +1207,19 @@@@@@@@@@@@@@ static int hotkey_mask_set(u32 mask
                int rc = 0;
             
                if (tp_features.hotkey_mask) {
+++++++++++ +           if (!tp_warned.hotkey_mask_ff &&
+++++++++++ +               (mask == 0xffff || mask == 0xffffff ||
+++++++++++ +                mask == 0xffffffff)) {
+++++++++++ +                   tp_warned.hotkey_mask_ff = 1;
+++++++++++ +                   printk(TPACPI_NOTICE
+++++++++++ +                          "setting the hotkey mask to 0x%08x is likely "
+++++++++++ +                          "not the best way to go about it\n", mask);
+++++++++++ +                   printk(TPACPI_NOTICE
+++++++++++ +                          "please consider using the driver defaults, "
+++++++++++ +                          "and refer to up-to-date thinkpad-acpi "
+++++++++++ +                          "documentation\n");
+++++++++++ +           }
+++++++++++ +
                        HOTKEY_CONFIG_CRITICAL_START
                        for (i = 0; i < 32; i++) {
                                u32 m = 1 << i;
@@@@@@@@@@@@@@ -1427,8 -1427,8 -1427,8 -1427,8 -1427,8 -1427,8 -1427,8 -1427,8 -1427,8 -1426,8 -1427,8 -1540,7 -1427,8 +1540,7 @@@@@@@@@@@@@@ static void hotkey_poll_setup(int may_w
                    (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) {
                        if (!tpacpi_hotkey_task) {
                                tpacpi_hotkey_task = kthread_run(hotkey_kthread,
----------- -                                                    NULL,
----------- -                                                    TPACPI_FILE "d");
+++++++++++ +                                   NULL, TPACPI_NVRAM_KTHREAD_NAME);
                                if (IS_ERR(tpacpi_hotkey_task)) {
                                        tpacpi_hotkey_task = NULL;
                                        printk(TPACPI_ERR
@@@@@@@@@@@@@@ -1887,6 -1887,6 -1887,6 -1887,6 -1887,6 -1887,6 -1887,6 -1887,6 -1887,6 -1886,6 -1887,6 -1999,9 -1887,6 +1999,9 @@@@@@@@@@@@@@ static int __init hotkey_init(struct ib
                        KEY_UNKNOWN,    /* 0x0D: FN+INSERT */
                        KEY_UNKNOWN,    /* 0x0E: FN+DELETE */
             
+++++++++++ +           /* These either have to go through ACPI video, or
+++++++++++ +            * act like in the IBM ThinkPads, so don't ever
+++++++++++ +            * enable them by default */
                        KEY_RESERVED,   /* 0x0F: FN+HOME (brightness up) */
                        KEY_RESERVED,   /* 0x10: FN+END (brightness down) */
             
                                set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
                        }
             
+++++++++++ +           /* Do not issue duplicate brightness change events to
+++++++++++ +            * userspace */
+++++++++++ +           if (!tp_features.bright_acpimode)
+++++++++++ +                   /* update bright_acpimode... */
+++++++++++ +                   tpacpi_check_std_acpi_brightness_support();
+++++++++++ +
+++++++++++ +           if (tp_features.bright_acpimode) {
+++++++++++ +                   printk(TPACPI_INFO
+++++++++++ +                          "This ThinkPad has standard ACPI backlight "
+++++++++++ +                          "brightness control, supported by the ACPI "
+++++++++++ +                          "video driver\n");
+++++++++++ +                   printk(TPACPI_NOTICE
+++++++++++ +                          "Disabling thinkpad-acpi brightness events "
+++++++++++ +                          "by default...\n");
+++++++++++ +
+++++++++++ +                   /* The hotkey_reserved_mask change below is not
+++++++++++ +                    * necessary while the keys are at KEY_RESERVED in the
+++++++++++ +                    * default map, but better safe than sorry, leave it
+++++++++++ +                    * here as a marker of what we have to do, especially
+++++++++++ +                    * when we finally become able to set this at runtime
+++++++++++ +                    * on response to X.org requests */
+++++++++++ +                   hotkey_reserved_mask |=
+++++++++++ +                           (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
+++++++++++ +                           | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
+++++++++++ +           }
+++++++++++ +
                        dbg_printk(TPACPI_DBG_INIT,
                                        "enabling hot key handling\n");
                        res = hotkey_status_set(1);
@@@@@@@@@@@@@@ -3110,13 -3110,13 -3110,13 -3110,13 -3110,13 -3110,13 -3110,13 -3110,13 -3110,13 -3109,13 -3110,13 -3251,82 -3110,13 +3251,82 @@@@@@@@@@@@@@ static struct ibm_struct video_driver_d
             TPACPI_HANDLE(lght, root, "\\LGHT");       /* A21e, A2xm/p, T20-22, X20-21 */
             TPACPI_HANDLE(ledb, ec, "LEDB");           /* G4x */
             
+++++++++++ +static int light_get_status(void)
+++++++++++ +{
+++++++++++ +   int status = 0;
+++++++++++ +
+++++++++++ +   if (tp_features.light_status) {
+++++++++++ +           if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
+++++++++++ +                   return -EIO;
+++++++++++ +           return (!!status);
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   return -ENXIO;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static int light_set_status(int status)
+++++++++++ +{
+++++++++++ +   int rc;
+++++++++++ +
+++++++++++ +   if (tp_features.light) {
+++++++++++ +           if (cmos_handle) {
+++++++++++ +                   rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",
+++++++++++ +                                   (status)?
+++++++++++ +                                           TP_CMOS_THINKLIGHT_ON :
+++++++++++ +                                           TP_CMOS_THINKLIGHT_OFF);
+++++++++++ +           } else {
+++++++++++ +                   rc = acpi_evalf(lght_handle, NULL, NULL, "vd",
+++++++++++ +                                   (status)? 1 : 0);
+++++++++++ +           }
+++++++++++ +           return (rc)? 0 : -EIO;
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   return -ENXIO;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void light_set_status_worker(struct work_struct *work)
+++++++++++ +{
+++++++++++ +   struct tpacpi_led_classdev *data =
+++++++++++ +                   container_of(work, struct tpacpi_led_classdev, work);
+++++++++++ +
+++++++++++ +   if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
+++++++++++ +           light_set_status((data->new_brightness != LED_OFF));
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void light_sysfs_set(struct led_classdev *led_cdev,
+++++++++++ +                   enum led_brightness brightness)
+++++++++++ +{
+++++++++++ +   struct tpacpi_led_classdev *data =
+++++++++++ +           container_of(led_cdev,
+++++++++++ +                        struct tpacpi_led_classdev,
+++++++++++ +                        led_classdev);
+++++++++++ +   data->new_brightness = brightness;
+++++++++++ +   queue_work(tpacpi_wq, &data->work);
+++++++++++ +}
+++++++++++ +
+++++++++++ +static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
+++++++++++ +{
+++++++++++ +   return (light_get_status() == 1)? LED_FULL : LED_OFF;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static struct tpacpi_led_classdev tpacpi_led_thinklight = {
+++++++++++ +   .led_classdev = {
+++++++++++ +           .name           = "tpacpi::thinklight",
+++++++++++ +           .brightness_set = &light_sysfs_set,
+++++++++++ +           .brightness_get = &light_sysfs_get,
+++++++++++ +   }
+++++++++++ +};
+++++++++++ +
             static int __init light_init(struct ibm_init_struct *iibm)
             {
+++++++++++ +   int rc = 0;
+++++++++++ +
                vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
             
                TPACPI_ACPIHANDLE_INIT(ledb);
                TPACPI_ACPIHANDLE_INIT(lght);
                TPACPI_ACPIHANDLE_INIT(cmos);
+++++++++++ +   INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
             
                /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
                tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
                vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
                        str_supported(tp_features.light));
             
----------- -   return (tp_features.light)? 0 : 1;
+++++++++++ +   if (tp_features.light) {
+++++++++++ +           rc = led_classdev_register(&tpacpi_pdev->dev,
+++++++++++ +                                      &tpacpi_led_thinklight.led_classdev);
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   if (rc < 0) {
+++++++++++ +           tp_features.light = 0;
+++++++++++ +           tp_features.light_status = 0;
+++++++++++ +   } else {
+++++++++++ +           rc = (tp_features.light)? 0 : 1;
+++++++++++ +   }
+++++++++++ +   return rc;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void light_exit(void)
+++++++++++ +{
+++++++++++ +   led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
+++++++++++ +   if (work_pending(&tpacpi_led_thinklight.work))
+++++++++++ +           flush_workqueue(tpacpi_wq);
             }
             
             static int light_read(char *p)
             {
                int len = 0;
----------- -   int status = 0;
+++++++++++ +   int status;
             
                if (!tp_features.light) {
                        len += sprintf(p + len, "status:\t\tnot supported\n");
                        len += sprintf(p + len, "status:\t\tunknown\n");
                        len += sprintf(p + len, "commands:\ton, off\n");
                } else {
----------- -           if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
----------- -                   return -EIO;
+++++++++++ +           status = light_get_status();
+++++++++++ +           if (status < 0)
+++++++++++ +                   return status;
                        len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
                        len += sprintf(p + len, "commands:\ton, off\n");
                }
             
             static int light_write(char *buf)
             {
----------- -   int cmos_cmd, lght_cmd;
                char *cmd;
----------- -   int success;
+++++++++++ +   int newstatus = 0;
             
                if (!tp_features.light)
                        return -ENODEV;
             
                while ((cmd = next_cmd(&buf))) {
                        if (strlencmp(cmd, "on") == 0) {
----------- -                   cmos_cmd = 0x0c;
----------- -                   lght_cmd = 1;
+++++++++++ +                   newstatus = 1;
                        } else if (strlencmp(cmd, "off") == 0) {
----------- -                   cmos_cmd = 0x0d;
----------- -                   lght_cmd = 0;
+++++++++++ +                   newstatus = 0;
                        } else
                                return -EINVAL;
----------- -
----------- -           success = cmos_handle ?
----------- -               acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
----------- -               acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
----------- -           if (!success)
----------- -                   return -EIO;
                }
             
----------- -   return 0;
+++++++++++ +   return light_set_status(newstatus);
             }
             
             static struct ibm_struct light_driver_data = {
                .name = "light",
                .read = light_read,
                .write = light_write,
+++++++++++ +   .exit = light_exit,
             };
             
             /*************************************************************************
@@@@@@@@@@@@@@ -3583,6 -3583,6 -3583,6 -3583,6 -3583,6 -3583,6 -3583,6 -3583,6 -3583,6 -3582,6 -3583,6 -3804,12 -3583,6 +3804,12 @@@@@@@@@@@@@@ enum {  /* For TPACPI_LED_OLD *
                TPACPI_LED_EC_HLMS = 0x0e,      /* EC reg to select led to command */
             };
             
+++++++++++ +enum led_status_t {
+++++++++++ +   TPACPI_LED_OFF = 0,
+++++++++++ +   TPACPI_LED_ON,
+++++++++++ +   TPACPI_LED_BLINK,
+++++++++++ +};
+++++++++++ +
             static enum led_access_mode led_supported;
             
             TPACPI_HANDLE(led, ec, "SLED",     /* 570 */
                   "LED",               /* all others */
                   );                   /* R30, R31 */
             
+++++++++++ +#define TPACPI_LED_NUMLEDS 8
+++++++++++ +static struct tpacpi_led_classdev *tpacpi_leds;
+++++++++++ +static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
+++++++++++ +static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
+++++++++++ +   /* there's a limit of 19 chars + NULL before 2.6.26 */
+++++++++++ +   "tpacpi::power",
+++++++++++ +   "tpacpi:orange:batt",
+++++++++++ +   "tpacpi:green:batt",
+++++++++++ +   "tpacpi::dock_active",
+++++++++++ +   "tpacpi::bay_active",
+++++++++++ +   "tpacpi::dock_batt",
+++++++++++ +   "tpacpi::unknown_led",
+++++++++++ +   "tpacpi::standby",
+++++++++++ +};
+++++++++++ +
+++++++++++ +static int led_get_status(unsigned int led)
+++++++++++ +{
+++++++++++ +   int status;
+++++++++++ +   enum led_status_t led_s;
+++++++++++ +
+++++++++++ +   switch (led_supported) {
+++++++++++ +   case TPACPI_LED_570:
+++++++++++ +           if (!acpi_evalf(ec_handle,
+++++++++++ +                           &status, "GLED", "dd", 1 << led))
+++++++++++ +                   return -EIO;
+++++++++++ +           led_s = (status == 0)?
+++++++++++ +                           TPACPI_LED_OFF :
+++++++++++ +                           ((status == 1)?
+++++++++++ +                                   TPACPI_LED_ON :
+++++++++++ +                                   TPACPI_LED_BLINK);
+++++++++++ +           tpacpi_led_state_cache[led] = led_s;
+++++++++++ +           return led_s;
+++++++++++ +   default:
+++++++++++ +           return -ENXIO;
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   /* not reached */
+++++++++++ +}
+++++++++++ +
+++++++++++ +static int led_set_status(unsigned int led, enum led_status_t ledstatus)
+++++++++++ +{
+++++++++++ +   /* off, on, blink. Index is led_status_t */
+++++++++++ +   static const int const led_sled_arg1[] = { 0, 1, 3 };
+++++++++++ +   static const int const led_exp_hlbl[] = { 0, 0, 1 };    /* led# * */
+++++++++++ +   static const int const led_exp_hlcl[] = { 0, 1, 1 };    /* led# * */
+++++++++++ +   static const int const led_led_arg1[] = { 0, 0x80, 0xc0 };
+++++++++++ +
+++++++++++ +   int rc = 0;
+++++++++++ +
+++++++++++ +   switch (led_supported) {
+++++++++++ +   case TPACPI_LED_570:
+++++++++++ +                   /* 570 */
+++++++++++ +                   led = 1 << led;
+++++++++++ +                   if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+++++++++++ +                                   led, led_sled_arg1[ledstatus]))
+++++++++++ +                           rc = -EIO;
+++++++++++ +                   break;
+++++++++++ +   case TPACPI_LED_OLD:
+++++++++++ +                   /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
+++++++++++ +                   led = 1 << led;
+++++++++++ +                   rc = ec_write(TPACPI_LED_EC_HLMS, led);
+++++++++++ +                   if (rc >= 0)
+++++++++++ +                           rc = ec_write(TPACPI_LED_EC_HLBL,
+++++++++++ +                                         led * led_exp_hlbl[ledstatus]);
+++++++++++ +                   if (rc >= 0)
+++++++++++ +                           rc = ec_write(TPACPI_LED_EC_HLCL,
+++++++++++ +                                         led * led_exp_hlcl[ledstatus]);
+++++++++++ +                   break;
+++++++++++ +   case TPACPI_LED_NEW:
+++++++++++ +                   /* all others */
+++++++++++ +                   if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
+++++++++++ +                                   led, led_led_arg1[ledstatus]))
+++++++++++ +                           rc = -EIO;
+++++++++++ +                   break;
+++++++++++ +   default:
+++++++++++ +           rc = -ENXIO;
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   if (!rc)
+++++++++++ +           tpacpi_led_state_cache[led] = ledstatus;
+++++++++++ +
+++++++++++ +   return rc;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void led_sysfs_set_status(unsigned int led,
+++++++++++ +                            enum led_brightness brightness)
+++++++++++ +{
+++++++++++ +   led_set_status(led,
+++++++++++ +                   (brightness == LED_OFF) ?
+++++++++++ +                   TPACPI_LED_OFF :
+++++++++++ +                   (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
+++++++++++ +                           TPACPI_LED_BLINK : TPACPI_LED_ON);
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void led_set_status_worker(struct work_struct *work)
+++++++++++ +{
+++++++++++ +   struct tpacpi_led_classdev *data =
+++++++++++ +           container_of(work, struct tpacpi_led_classdev, work);
+++++++++++ +
+++++++++++ +   if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
+++++++++++ +           led_sysfs_set_status(data->led, data->new_brightness);
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void led_sysfs_set(struct led_classdev *led_cdev,
+++++++++++ +                   enum led_brightness brightness)
+++++++++++ +{
+++++++++++ +   struct tpacpi_led_classdev *data = container_of(led_cdev,
+++++++++++ +                        struct tpacpi_led_classdev, led_classdev);
+++++++++++ +
+++++++++++ +   data->new_brightness = brightness;
+++++++++++ +   queue_work(tpacpi_wq, &data->work);
+++++++++++ +}
+++++++++++ +
+++++++++++ +static int led_sysfs_blink_set(struct led_classdev *led_cdev,
+++++++++++ +                   unsigned long *delay_on, unsigned long *delay_off)
+++++++++++ +{
+++++++++++ +   struct tpacpi_led_classdev *data = container_of(led_cdev,
+++++++++++ +                        struct tpacpi_led_classdev, led_classdev);
+++++++++++ +
+++++++++++ +   /* Can we choose the flash rate? */
+++++++++++ +   if (*delay_on == 0 && *delay_off == 0) {
+++++++++++ +           /* yes. set them to the hardware blink rate (1 Hz) */
+++++++++++ +           *delay_on = 500; /* ms */
+++++++++++ +           *delay_off = 500; /* ms */
+++++++++++ +   } else if ((*delay_on != 500) || (*delay_off != 500))
+++++++++++ +           return -EINVAL;
+++++++++++ +
+++++++++++ +   data->new_brightness = TPACPI_LED_BLINK;
+++++++++++ +   queue_work(tpacpi_wq, &data->work);
+++++++++++ +
+++++++++++ +   return 0;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
+++++++++++ +{
+++++++++++ +   int rc;
+++++++++++ +
+++++++++++ +   struct tpacpi_led_classdev *data = container_of(led_cdev,
+++++++++++ +                        struct tpacpi_led_classdev, led_classdev);
+++++++++++ +
+++++++++++ +   rc = led_get_status(data->led);
+++++++++++ +
+++++++++++ +   if (rc == TPACPI_LED_OFF || rc < 0)
+++++++++++ +           rc = LED_OFF;   /* no error handling in led class :( */
+++++++++++ +   else
+++++++++++ +           rc = LED_FULL;
+++++++++++ +
+++++++++++ +   return rc;
+++++++++++ +}
+++++++++++ +
+++++++++++ +static void led_exit(void)
+++++++++++ +{
+++++++++++ +   unsigned int i;
+++++++++++ +
+++++++++++ +   for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
+++++++++++ +           if (tpacpi_leds[i].led_classdev.name)
+++++++++++ +                   led_classdev_unregister(&tpacpi_leds[i].led_classdev);
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   kfree(tpacpi_leds);
+++++++++++ +   tpacpi_leds = NULL;
+++++++++++ +}
+++++++++++ +
             static int __init led_init(struct ibm_init_struct *iibm)
             {
+++++++++++ +   unsigned int i;
+++++++++++ +   int rc;
+++++++++++ +
                vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
             
                TPACPI_ACPIHANDLE_INIT(led);
                vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
                        str_supported(led_supported), led_supported);
             
+++++++++++ +   tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
+++++++++++ +                         GFP_KERNEL);
+++++++++++ +   if (!tpacpi_leds) {
+++++++++++ +           printk(TPACPI_ERR "Out of memory for LED data\n");
+++++++++++ +           return -ENOMEM;
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
+++++++++++ +           tpacpi_leds[i].led = i;
+++++++++++ +
+++++++++++ +           tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
+++++++++++ +           tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
+++++++++++ +           if (led_supported == TPACPI_LED_570)
+++++++++++ +                   tpacpi_leds[i].led_classdev.brightness_get =
+++++++++++ +                                                   &led_sysfs_get;
+++++++++++ +
+++++++++++ +           tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
+++++++++++ +
+++++++++++ +           INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
+++++++++++ +
+++++++++++ +           rc = led_classdev_register(&tpacpi_pdev->dev,
+++++++++++ +                                      &tpacpi_leds[i].led_classdev);
+++++++++++ +           if (rc < 0) {
+++++++++++ +                   tpacpi_leds[i].led_classdev.name = NULL;
+++++++++++ +                   led_exit();
+++++++++++ +                   return rc;
+++++++++++ +           }
+++++++++++ +   }
+++++++++++ +
                return (led_supported != TPACPI_LED_NONE)? 0 : 1;
             }
             
----------- -#define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking"))
+++++++++++ +#define str_led_status(s) \
+++++++++++ +   ((s) == TPACPI_LED_OFF ? "off" : \
+++++++++++ +           ((s) == TPACPI_LED_ON ? "on" : "blinking"))
             
             static int led_read(char *p)
             {
                        /* 570 */
                        int i, status;
                        for (i = 0; i < 8; i++) {
----------- -                   if (!acpi_evalf(ec_handle,
----------- -                                   &status, "GLED", "dd", 1 << i))
+++++++++++ +                   status = led_get_status(i);
+++++++++++ +                   if (status < 0)
                                        return -EIO;
                                len += sprintf(p + len, "%d:\t\t%s\n",
----------- -                                  i, led_status(status));
+++++++++++ +                                  i, str_led_status(status));
                        }
                }
             
                return len;
             }
             
----------- -/* off, on, blink */
----------- -static const int led_sled_arg1[] = { 0, 1, 3 };
----------- -static const int led_exp_hlbl[] = { 0, 0, 1 };     /* led# * */
----------- -static const int led_exp_hlcl[] = { 0, 1, 1 };     /* led# * */
----------- -static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
----------- -
             static int led_write(char *buf)
             {
                char *cmd;
----------- -   int led, ind, ret;
+++++++++++ +   int led, rc;
+++++++++++ +   enum led_status_t s;
             
                if (!led_supported)
                        return -ENODEV;
                                return -EINVAL;
             
                        if (strstr(cmd, "off")) {
----------- -                   ind = 0;
+++++++++++ +                   s = TPACPI_LED_OFF;
                        } else if (strstr(cmd, "on")) {
----------- -                   ind = 1;
+++++++++++ +                   s = TPACPI_LED_ON;
                        } else if (strstr(cmd, "blink")) {
----------- -                   ind = 2;
----------- -           } else
----------- -                   return -EINVAL;
----------- -
----------- -           if (led_supported == TPACPI_LED_570) {
----------- -                   /* 570 */
----------- -                   led = 1 << led;
----------- -                   if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
----------- -                                   led, led_sled_arg1[ind]))
----------- -                           return -EIO;
----------- -           } else if (led_supported == TPACPI_LED_OLD) {
----------- -                   /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
----------- -                   led = 1 << led;
----------- -                   ret = ec_write(TPACPI_LED_EC_HLMS, led);
----------- -                   if (ret >= 0)
----------- -                           ret = ec_write(TPACPI_LED_EC_HLBL,
----------- -                                           led * led_exp_hlbl[ind]);
----------- -                   if (ret >= 0)
----------- -                           ret = ec_write(TPACPI_LED_EC_HLCL,
----------- -                                           led * led_exp_hlcl[ind]);
----------- -                   if (ret < 0)
----------- -                           return ret;
+++++++++++ +                   s = TPACPI_LED_BLINK;
                        } else {
----------- -                   /* all others */
----------- -                   if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
----------- -                                   led, led_led_arg1[ind]))
----------- -                           return -EIO;
+++++++++++ +                   return -EINVAL;
                        }
+++++++++++ +
+++++++++++ +           rc = led_set_status(led, s);
+++++++++++ +           if (rc < 0)
+++++++++++ +                   return rc;
                }
             
                return 0;
@@@@@@@@@@@@@@ -3706,6 -3706,6 -3706,6 -3706,6 -3706,6 -3706,6 -3706,6 -3706,6 -3706,6 -3705,6 -3706,6 -4105,7 -3706,6 +4105,7 @@@@@@@@@@@@@@ static struct ibm_struct led_driver_dat
                .name = "led",
                .read = led_read,
                .write = led_write,
+++++++++++ +   .exit = led_exit,
             };
             
             /*************************************************************************
@@@@@@@@@@@@@@ -4170,8 -4170,8 -4170,8 -4170,8 -4170,8 -4170,8 -4170,8 -4170,8 -4170,8 -4169,8 -4170,8 -4570,16 -4170,8 +4570,16 @@@@@@@@@@@@@@ static struct ibm_struct ecdump_driver_
             
             #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
             
+++++++++++ +enum {
+++++++++++ +   TP_EC_BACKLIGHT = 0x31,
+++++++++++ +
+++++++++++ +   /* TP_EC_BACKLIGHT bitmasks */
+++++++++++ +   TP_EC_BACKLIGHT_LVLMSK = 0x1F,
+++++++++++ +   TP_EC_BACKLIGHT_CMDMSK = 0xE0,
+++++++++++ +   TP_EC_BACKLIGHT_MAPSW = 0x20,
+++++++++++ +};
+++++++++++ +
             static struct backlight_device *ibm_backlight_device;
----------- -static int brightness_offset = 0x31;
             static int brightness_mode;
             static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
             
@@@@@@@@@@@@@@ -4180,16 -4180,16 -4180,16 -4180,16 -4180,16 -4180,16 -4180,16 -4180,16 -4180,16 -4179,16 -4180,16 -4588,24 -4180,16 +4588,24 @@@@@@@@@@@@@@ static struct mutex brightness_mutex
             /*
              * ThinkPads can read brightness from two places: EC 0x31, or
              * CMOS NVRAM byte 0x5E, bits 0-3.
+++++++++++ + *
+++++++++++ + * EC 0x31 has the following layout
+++++++++++ + *   Bit 7: unknown function
+++++++++++ + *   Bit 6: unknown function
+++++++++++ + *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
+++++++++++ + *   Bit 4: must be set to zero to avoid problems
+++++++++++ + *   Bit 3-0: backlight brightness level
+++++++++++ + *
+++++++++++ + * brightness_get_raw returns status data in the EC 0x31 layout
              */
----------- -static int brightness_get(struct backlight_device *bd)
+++++++++++ +static int brightness_get_raw(int *status)
             {
                u8 lec = 0, lcmos = 0, level = 0;
             
                if (brightness_mode & 1) {
----------- -           if (!acpi_ec_read(brightness_offset, &lec))
+++++++++++ +           if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
                                return -EIO;
----------- -           lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
----------- -           level = lec;
+++++++++++ +           level = lec & TP_EC_BACKLIGHT_LVLMSK;
                };
                if (brightness_mode & 2) {
                        lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
                        level = lcmos;
                }
             
----------- -   if (brightness_mode == 3 && lec != lcmos) {
----------- -           printk(TPACPI_ERR
----------- -                   "CMOS NVRAM (%u) and EC (%u) do not agree "
----------- -                   "on display brightness level\n",
----------- -                   (unsigned int) lcmos,
----------- -                   (unsigned int) lec);
----------- -           return -EIO;
+++++++++++ +   if (brightness_mode == 3) {
+++++++++++ +           *status = lec;  /* Prefer EC, CMOS is just a backing store */
+++++++++++ +           lec &= TP_EC_BACKLIGHT_LVLMSK;
+++++++++++ +           if (lec == lcmos)
+++++++++++ +                   tp_warned.bright_cmos_ec_unsync = 0;
+++++++++++ +           else {
+++++++++++ +                   if (!tp_warned.bright_cmos_ec_unsync) {
+++++++++++ +                           printk(TPACPI_ERR
+++++++++++ +                                   "CMOS NVRAM (%u) and EC (%u) do not "
+++++++++++ +                                   "agree on display brightness level\n",
+++++++++++ +                                   (unsigned int) lcmos,
+++++++++++ +                                   (unsigned int) lec);
+++++++++++ +                           tp_warned.bright_cmos_ec_unsync = 1;
+++++++++++ +                   }
+++++++++++ +                   return -EIO;
+++++++++++ +           }
+++++++++++ +   } else {
+++++++++++ +           *status = level;
                }
             
----------- -   return level;
+++++++++++ +   return 0;
             }
             
             /* May return EINTR which can always be mapped to ERESTARTSYS */
@@@@@@@@@@@@@@ -4216,19 -4216,19 -4216,19 -4216,19 -4216,19 -4216,19 -4216,19 -4216,19 -4216,19 -4215,19 -4216,19 -4643,22 -4216,19 +4643,22 @@@@@@@@@@@@@@ static int brightness_set(int value
             {
                int cmos_cmd, inc, i, res;
                int current_value;
+++++++++++ +   int command_bits;
             
----------- -   if (value > ((tp_features.bright_16levels)? 15 : 7))
+++++++++++ +   if (value > ((tp_features.bright_16levels)? 15 : 7) ||
+++++++++++ +       value < 0)
                        return -EINVAL;
             
                res = mutex_lock_interruptible(&brightness_mutex);
                if (res < 0)
                        return res;
             
----------- -   current_value = brightness_get(NULL);
----------- -   if (current_value < 0) {
----------- -           res = current_value;
+++++++++++ +   res = brightness_get_raw(&current_value);
+++++++++++ +   if (res < 0)
                        goto errout;
----------- -   }
+++++++++++ +
+++++++++++ +   command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
+++++++++++ +   current_value &= TP_EC_BACKLIGHT_LVLMSK;
             
                cmos_cmd = value > current_value ?
                                TP_CMOS_BRIGHTNESS_UP :
                                goto errout;
                        }
                        if ((brightness_mode & 1) &&
----------- -               !acpi_ec_write(brightness_offset, i + inc)) {
+++++++++++ +               !acpi_ec_write(TP_EC_BACKLIGHT,
+++++++++++ +                              (i + inc) | command_bits)) {
                                res = -EIO;
                                goto errout;;
                        }
@@@@@@@@@@@@@@ -4266,106 -4266,106 -4266,106 -4266,106 -4266,106 -4266,106 -4266,106 -4266,106 -4266,106 -4265,106 -4266,106 -4697,23 -4266,106 +4697,23 @@@@@@@@@@@@@@ static int brightness_update_status(str
                                        bd->props.brightness : 0);
             }
             
----------- -static struct backlight_ops ibm_backlight_data = {
----------- -   .get_brightness = brightness_get,
----------- -   .update_status  = brightness_update_status,
----------- -};
----------- -
----------- -/* --------------------------------------------------------------------- */
----------- -
----------- -static int __init tpacpi_query_bcll_levels(acpi_handle handle)
----------- -{
----------- -   struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
----------- -   union acpi_object *obj;
----------- -   int rc;
----------- -
----------- -   if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
----------- -           obj = (union acpi_object *)buffer.pointer;
----------- -           if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
----------- -                   printk(TPACPI_ERR "Unknown BCLL data, "
----------- -                          "please report this to %s\n", TPACPI_MAIL);
----------- -                   rc = 0;
----------- -           } else {
----------- -                   rc = obj->package.count;
----------- -           }
----------- -   } else {
----------- -           return 0;
----------- -   }
----------- -
----------- -   kfree(buffer.pointer);
----------- -   return rc;
----------- -}
----------- -
----------- -static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
----------- -                                   void *context, void **rv)
--------- - -{
--------- - -   char name[ACPI_PATH_SEGMENT_LENGTH];
--------- - -   struct acpi_buffer buffer = { sizeof(name), &name };
--------- - -
--------- - -   if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
--------- - -       !strncmp("BCLL", name, sizeof(name) - 1)) {
--------- - -           if (tpacpi_query_bcll_levels(handle) == 16) {
--------- - -                   *rv = handle;
--------- - -                   return AE_CTRL_TERMINATE;
--------- - -           } else {
--------- - -                   return AE_OK;
--------- - -           }
--------- - -   } else {
--------- - -           return AE_OK;
--------- - -   }
--------- - -}
--------- - -
--------- - -static int __init brightness_check_levels(void)
+++++++++++ +static int brightness_get(struct backlight_device *bd)
             {
--------- - -   int status;
--------- - -   void *found_node = NULL;
         -      char name[ACPI_PATH_SEGMENT_LENGTH];
         -      struct acpi_buffer buffer = { sizeof(name), &name };
+++++++++++ +   int status, res;
             
         -      if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
         -          !strncmp("BCLL", name, sizeof(name) - 1)) {
         -              if (tpacpi_query_bcll_levels(handle) == 16) {
         -                      *rv = handle;
         -                      return AE_CTRL_TERMINATE;
         -              } else {
         -                      return AE_OK;
         -              }
         -      } else {
         -              return AE_OK;
         -      }
         -   }
         -   
         -   static int __init brightness_check_levels(void)
         -   {
         -      int status;
         -      void *found_node = NULL;
         -   
----------- -   if (!vid_handle) {
----------- -           TPACPI_ACPIHANDLE_INIT(vid);
----------- -   }
----------- -   if (!vid_handle)
----------- -           return 0;
----------- -
----------- -   /* Search for a BCLL package with 16 levels */
----------- -   status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
----------- -                                   brightness_find_bcll, NULL,
----------- -                                   &found_node);
----------- -
----------- -   return (ACPI_SUCCESS(status) && found_node != NULL);
----------- -}
----------- -
----------- -static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
----------- -                                   void *context, void **rv)
----------- -{
----------- -   char name[ACPI_PATH_SEGMENT_LENGTH];
----------- -   struct acpi_buffer buffer = { sizeof(name), &name };
+++++++++++ +   res = brightness_get_raw(&status);
+++++++++++ +   if (res < 0)
+++++++++++ +           return 0; /* FIXME: teach backlight about error handling */
             
----------- -   if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
----------- -       !strncmp("_BCL", name, sizeof(name) - 1)) {
----------- -           *rv = handle;
----------- -           return AE_CTRL_TERMINATE;
----------- -   } else {
----------- -           return AE_OK;
----------- -   }
+++++++++++ +   return status & TP_EC_BACKLIGHT_LVLMSK;
             }
             
----------- -static int __init brightness_check_std_acpi_support(void)
----------- -{
----------- -   int status;
----------- -   void *found_node = NULL;
----------- -
----------- -   if (!vid_handle) {
----------- -           TPACPI_ACPIHANDLE_INIT(vid);
----------- -   }
----------- -   if (!vid_handle)
----------- -           return 0;
----------- -
----------- -   /* Search for a _BCL method, but don't execute it */
----------- -   status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
----------- -                                brightness_find_bcl, NULL, &found_node);
+++++++++++ +static struct backlight_ops ibm_backlight_data = {
+++++++++++ +   .get_brightness = brightness_get,
+++++++++++ +   .update_status  = brightness_update_status,
+++++++++++ +};
             
----------- -   return (ACPI_SUCCESS(status) && found_node != NULL);
----------- -}
+++++++++++ +/* --------------------------------------------------------------------- */
             
             static int __init brightness_init(struct ibm_init_struct *iibm)
             {
             
                mutex_init(&brightness_mutex);
             
----------- -   if (!brightness_enable) {
----------- -           dbg_printk(TPACPI_DBG_INIT,
----------- -                      "brightness support disabled by "
----------- -                      "module parameter\n");
----------- -           return 1;
----------- -   } else if (brightness_enable > 1) {
----------- -           if (brightness_check_std_acpi_support()) {
+++++++++++ +   /*
+++++++++++ +    * We always attempt to detect acpi support, so as to switch
+++++++++++ +    * Lenovo Vista BIOS to ACPI brightness mode even if we are not
+++++++++++ +    * going to publish a backlight interface
+++++++++++ +    */
+++++++++++ +   b = tpacpi_check_std_acpi_brightness_support();
+++++++++++ +   if (b > 0) {
+++++++++++ +           if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
+++++++++++ +                   printk(TPACPI_NOTICE
+++++++++++ +                          "Lenovo BIOS switched to ACPI backlight "
+++++++++++ +                          "control mode\n");
+++++++++++ +           }
+++++++++++ +           if (brightness_enable > 1) {
                                printk(TPACPI_NOTICE
                                       "standard ACPI backlight interface "
                                       "available, not loading native one...\n");
                        }
                }
             
+++++++++++ +   if (!brightness_enable) {
+++++++++++ +           dbg_printk(TPACPI_DBG_INIT,
+++++++++++ +                      "brightness support disabled by "
+++++++++++ +                      "module parameter\n");
+++++++++++ +           return 1;
+++++++++++ +   }
+++++++++++ +
+++++++++++ +   if (b > 16) {
+++++++++++ +           printk(TPACPI_ERR
+++++++++++ +                  "Unsupported brightness interface, "
+++++++++++ +                  "please contact %s\n", TPACPI_MAIL);
+++++++++++ +           return 1;
+++++++++++ +   }
+++++++++++ +   if (b == 16)
+++++++++++ +           tp_features.bright_16levels = 1;
+++++++++++ +
                if (!brightness_mode) {
                        if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
                                brightness_mode = 2;
                if (brightness_mode > 3)
                        return -EINVAL;
             
----------- -   tp_features.bright_16levels =
----------- -                   thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
----------- -                   brightness_check_levels();
----------- -
----------- -   b = brightness_get(NULL);
----------- -   if (b < 0)
+++++++++++ +   if (brightness_get_raw(&b) < 0)
                        return 1;
             
                if (tp_features.bright_16levels)
             
                ibm_backlight_device->props.max_brightness =
                                        (tp_features.bright_16levels)? 15 : 7;
----------- -   ibm_backlight_device->props.brightness = b;
+++++++++++ +   ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
                backlight_update_status(ibm_backlight_device);
             
                return 0;
@@@@@@@@@@@@@@ -5046,11 -5046,11 -5046,11 -5046,11 -5046,11 -5046,11 -5046,11 -5046,11 -5046,11 -5045,11 -5046,11 -5411,11 -5046,11 +5411,11 @@@@@@@@@@@@@@ static void fan_watchdog_reset(void
                if (fan_watchdog_maxinterval > 0 &&
                    tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
                        fan_watchdog_active = 1;
----------- -           if (!schedule_delayed_work(&fan_watchdog_task,
+++++++++++ +           if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
                                        msecs_to_jiffies(fan_watchdog_maxinterval
                                                         * 1000))) {
                                printk(TPACPI_ERR
----------- -                          "failed to schedule the fan watchdog, "
+++++++++++ +                          "failed to queue the fan watchdog, "
                                       "watchdog will not trigger\n");
                        }
                } else
@@@@@@@@@@@@@@ -5420,7 -5420,7 -5420,7 -5420,7 -5420,7 -5420,7 -5420,7 -5420,7 -5420,7 -5419,7 -5420,7 -5785,7 -5420,7 +5785,7 @@@@@@@@@@@@@@ static void fan_exit(void
                                   &driver_attr_fan_watchdog);
             
                cancel_delayed_work(&fan_watchdog_task);
----------- -   flush_scheduled_work();
+++++++++++ +   flush_workqueue(tpacpi_wq);
             }
             
             static int fan_read(char *p)
@@@@@@@@@@@@@@ -5826,10 -5826,10 -5826,10 -5826,10 -5826,10 -5826,10 -5826,10 -5826,10 -5826,10 -5825,10 -5826,10 -6191,13 -5826,10 +6191,13 @@@@@@@@@@@@@@ static void __init get_thinkpad_model_d
             
                tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
                                                GFP_KERNEL);
------- -----   if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
+++++++ +++++   if (tp->model_str && strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
                        kfree(tp->model_str);
                        tp->model_str = NULL;
                }
+++++++++++ +
+++++++++++ +   tp->nummodel_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_NAME),
+++++++++++ +                                   GFP_KERNEL);
             }
             
             static int __init probe_for_thinkpad(void)
@@@@@@@@@@@@@@ -6071,6 -6071,6 -6071,6 -6071,6 -6071,6 -6071,6 -6071,6 -6071,6 -6071,6 -6070,6 -6071,6 -6439,9 -6071,6 +6439,9 @@@@@@@@@@@@@@ static void thinkpad_acpi_module_exit(v
                if (proc_dir)
                        remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
             
+++++++++++ +   if (tpacpi_wq)
+++++++++++ +           destroy_workqueue(tpacpi_wq);
+++++++++++ +
                kfree(thinkpad_id.bios_version_str);
                kfree(thinkpad_id.ec_version_str);
                kfree(thinkpad_id.model_str);
@@@@@@@@@@@@@@ -6101,6 -6101,6 -6101,6 -6101,6 -6101,6 -6101,6 -6101,6 -6101,6 -6101,6 -6100,6 -6101,6 -6472,12 -6101,6 +6472,12 @@@@@@@@@@@@@@ static int __init thinkpad_acpi_module_
                TPACPI_ACPIHANDLE_INIT(ecrd);
                TPACPI_ACPIHANDLE_INIT(ecwr);
             
+++++++++++ +   tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
+++++++++++ +   if (!tpacpi_wq) {
+++++++++++ +           thinkpad_acpi_module_exit();
+++++++++++ +           return -ENOMEM;
+++++++++++ +   }
+++++++++++ +
                proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
                if (!proc_dir) {
                        printk(TPACPI_ERR
             /* Please remove this in year 2009 */
             MODULE_ALIAS("ibm_acpi");
             
+++++++++++ +MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
+++++++++++ +
             /*
              * DMI matching for module autoloading
              *