]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'ull' into test
authorLen Brown <len.brown@intel.com>
Thu, 23 Oct 2008 03:33:29 +0000 (23:33 -0400)
committerLen Brown <len.brown@intel.com>
Thu, 23 Oct 2008 03:33:29 +0000 (23:33 -0400)
Conflicts:
drivers/acpi/bay.c
drivers/acpi/dock.c
drivers/ata/libata-acpi.c

Signed-off-by: Len Brown <len.brown@intel.com>
24 files changed:
1  2 
drivers/acpi/ac.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/asus_acpi.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/container.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/pci_root.c
drivers/acpi/power.c
drivers/acpi/processor_core.c
drivers/acpi/processor_perflib.c
drivers/acpi/processor_throttling.c
drivers/acpi/sbshc.c
drivers/acpi/sleep/main.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/misc/asus-laptop.c
drivers/misc/eeepc-laptop.c
drivers/misc/fujitsu-laptop.c
drivers/misc/intel_menlow.c
drivers/pci/hotplug/acpiphp_glue.c
include/acpi/acpi_bus.h

diff --combined drivers/acpi/ac.c
index 8b6a84a43b1592a29efd2523bc2168cbd59860d9,5e57a80c6cf11d94bbdbbfab3bfb4d197280c921..d72a1b6c8a943bde5aff998e09b2fbaf1ea9d222
@@@ -85,7 -85,7 +85,7 @@@ struct acpi_ac 
        struct power_supply charger;
  #endif
        struct acpi_device * device;
-       unsigned long state;
+       unsigned long long state;
  };
  
  #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
@@@ -269,7 -269,7 +269,7 @@@ static int acpi_ac_add(struct acpi_devi
        ac->device = device;
        strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_AC_CLASS);
 -      acpi_driver_data(device) = ac;
 +      device->driver_data = ac;
  
        result = acpi_ac_get_state(ac);
        if (result)
index 289d02260f1668fc1df12aaf25f24fd8f23fac47,2b773160e9c2e8be8556102894e02a207be0d713..71d21c51c45f573c6591d224e835843357df5981
@@@ -194,8 -194,7 +194,7 @@@ acpi_memory_get_device(acpi_handle hand
  
  static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
  {
-       unsigned long current_status;
+       unsigned long long current_status;
  
        /* Get device present/absent information from the _STA */
        if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA",
@@@ -264,7 -263,7 +263,7 @@@ static int acpi_memory_powerdown_device
        acpi_status status;
        struct acpi_object_list arg_list;
        union acpi_object arg;
-       unsigned long current_status;
+       unsigned long long current_status;
  
  
        /* Issue the _EJ0 command */
@@@ -403,7 -402,7 +402,7 @@@ static int acpi_memory_device_add(struc
        mem_device->device = device;
        sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
        sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
 -      acpi_driver_data(device) = mem_device;
 +      device->driver_data = mem_device;
  
        /* Get the range from the _CRS */
        result = acpi_memory_get_device_resources(mem_device);
@@@ -454,8 -453,8 +453,8 @@@ static int acpi_memory_device_start (st
                /* call add_memory func */
                result = acpi_memory_enable_device(mem_device);
                if (result)
 -                      ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 -                              "Error in acpi_memory_enable_device\n"));
 +                      printk(KERN_ERR PREFIX
 +                              "Error in acpi_memory_enable_device\n");
        }
        return result;
  }
diff --combined drivers/acpi/asus_acpi.c
index 2377e8b917d7b8d77664f7ab34a627e43b691801,4434209e453e523299092cd9b62950a3f8c8881f..1e74988c7b2d2859871ca335d16af235a3ca7e6f
@@@ -42,7 -42,7 +42,7 @@@
  
  #define ASUS_ACPI_VERSION "0.30"
  
 -#define PROC_ASUS       "asus"        //the directory
 +#define PROC_ASUS       "asus"        /* The directory */
  #define PROC_MLED       "mled"
  #define PROC_WLED       "wled"
  #define PROC_TLED       "tled"
  /*
   * Flags for hotk status
   */
 -#define MLED_ON     0x01      //mail LED
 -#define WLED_ON     0x02      //wireless LED
 -#define TLED_ON     0x04      //touchpad LED
 -#define BT_ON       0x08      //internal Bluetooth
 +#define MLED_ON     0x01      /* Mail LED */
 +#define WLED_ON     0x02      /* Wireless LED */
 +#define TLED_ON     0x04      /* Touchpad LED */
 +#define BT_ON       0x08      /* Internal Bluetooth */
  
  MODULE_AUTHOR("Julien Lerouge, Karol Kozimor");
  MODULE_DESCRIPTION(ACPI_HOTK_NAME);
@@@ -82,28 -82,28 +82,28 @@@ MODULE_PARM_DESC(asus_uid, "UID for ent
  module_param(asus_gid, uint, 0);
  MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus");
  
 -/* For each model, all features implemented, 
 +/* For each model, all features implemented,
   * those marked with R are relative to HOTK, A for absolute */
  struct model_data {
 -      char *name;             //name of the laptop________________A
 -      char *mt_mled;          //method to handle mled_____________R
 -      char *mled_status;      //node to handle mled reading_______A
 -      char *mt_wled;          //method to handle wled_____________R
 -      char *wled_status;      //node to handle wled reading_______A
 -      char *mt_tled;          //method to handle tled_____________R
 -      char *tled_status;      //node to handle tled reading_______A
 -      char *mt_ledd;          //method to handle LED display______R
 -      char *mt_bt_switch;     //method to switch Bluetooth on/off_R
 -      char *bt_status;        //no model currently supports this__?
 -      char *mt_lcd_switch;    //method to turn LCD on/off_________A
 -      char *lcd_status;       //node to read LCD panel state______A
 -      char *brightness_up;    //method to set brightness up_______A
 -      char *brightness_down;  //guess what ?______________________A
 -      char *brightness_set;   //method to set absolute brightness_R
 -      char *brightness_get;   //method to get absolute brightness_R
 -      char *brightness_status;        //node to get brightness____________A
 -      char *display_set;      //method to set video output________R
 -      char *display_get;      //method to get video output________R
 +      char *name;             /* name of the laptop________________A */
 +      char *mt_mled;          /* method to handle mled_____________R */
 +      char *mled_status;      /* node to handle mled reading_______A */
 +      char *mt_wled;          /* method to handle wled_____________R */
 +      char *wled_status;      /* node to handle wled reading_______A */
 +      char *mt_tled;          /* method to handle tled_____________R */
 +      char *tled_status;      /* node to handle tled reading_______A */
 +      char *mt_ledd;          /* method to handle LED display______R */
 +      char *mt_bt_switch;     /* method to switch Bluetooth on/off_R */
 +      char *bt_status;        /* no model currently supports this__? */
 +      char *mt_lcd_switch;    /* method to turn LCD on/off_________A */
 +      char *lcd_status;       /* node to read LCD panel state______A */
 +      char *brightness_up;    /* method to set brightness up_______A */
 +      char *brightness_down;  /* method to set brightness down ____A */
 +      char *brightness_set;   /* method to set absolute brightness_R */
 +      char *brightness_get;   /* method to get absolute brightness_R */
 +      char *brightness_status;/* node to get brightness____________A */
 +      char *display_set;      /* method to set video output________R */
 +      char *display_get;      /* method to get video output________R */
  };
  
  /*
   * about the hotk device
   */
  struct asus_hotk {
 -      struct acpi_device *device;     //the device we are in
 -      acpi_handle handle;     //the handle of the hotk device
 -      char status;            //status of the hotk, for LEDs, ...
 -      u32 ledd_status;        //status of the LED display
 -      struct model_data *methods;     //methods available on the laptop
 -      u8 brightness;          //brightness level
 +      struct acpi_device *device;     /* the device we are in */
 +      acpi_handle handle;             /* the handle of the hotk device */
 +      char status;                    /* status of the hotk, for LEDs */
 +      u32 ledd_status;                /* status of the LED display */
 +      struct model_data *methods;     /* methods available on the laptop */
 +      u8 brightness;                  /* brightness level */
        enum {
 -              A1x = 0,        //A1340D, A1300F
 -              A2x,            //A2500H
 -              A4G,            //A4700G
 -              D1x,            //D1
 -              L2D,            //L2000D
 -              L3C,            //L3800C
 -              L3D,            //L3400D
 -              L3H,            //L3H, L2000E, L5D
 -              L4R,            //L4500R
 -              L5x,            //L5800C 
 -              L8L,            //L8400L
 -              M1A,            //M1300A
 -              M2E,            //M2400E, L4400L
 -              M6N,            //M6800N, W3400N
 -              M6R,            //M6700R, A3000G
 -              P30,            //Samsung P30
 -              S1x,            //S1300A, but also L1400B and M2400A (L84F)
 -              S2x,            //S200 (J1 reported), Victor MP-XP7210
 -              W1N,            //W1000N
 -              W5A,            //W5A
 -              W3V,            //W3030V
 -              xxN,            //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
 -              A4S,            //Z81sp
 -              //(Centrino)
 -              F3Sa,
 +              A1x = 0,        /* A1340D, A1300F */
 +              A2x,            /* A2500H */
 +              A4G,            /* A4700G */
 +              D1x,            /* D1 */
 +              L2D,            /* L2000D */
 +              L3C,            /* L3800C */
 +              L3D,            /* L3400D */
 +              L3H,            /* L3H, L2000E, L5D */
 +              L4R,            /* L4500R */
 +              L5x,            /* L5800C */
 +              L8L,            /* L8400L */
 +              M1A,            /* M1300A */
 +              M2E,            /* M2400E, L4400L */
 +              M6N,            /* M6800N, W3400N */
 +              M6R,            /* M6700R, A3000G */
 +              P30,            /* Samsung P30 */
 +              S1x,            /* S1300A, but also L1400B and M2400A (L84F) */
 +              S2x,            /* S200 (J1 reported), Victor MP-XP7210 */
 +              W1N,            /* W1000N */
 +              W5A,            /* W5A */
 +              W3V,            /* W3030V */
 +              xxN,            /* M2400N, M3700N, M5200N, M6800N,
 +                                                       S1300N, S5200N*/
 +              A4S,            /* Z81sp */
 +              F3Sa,           /* (Centrino) */
                END_MODEL
 -      } model;                //Models currently supported
 -      u16 event_count[128];   //count for each event TODO make this better
 +      } model;                /* Models currently supported */
 +      u16 event_count[128];   /* Count for each event TODO make this better */
  };
  
  /* Here we go */
@@@ -459,18 -459,18 +459,18 @@@ static struct acpi_driver asus_hotk_dri
                },
  };
  
 -/* 
 +/*
   * This function evaluates an ACPI method, given an int as parameter, the
   * method is searched within the scope of the handle, can be NULL. The output
   * of the method is written is output, which can also be NULL
   *
 - * returns 1 if write is successful, 0 else. 
 + * returns 1 if write is successful, 0 else.
   */
  static int write_acpi_int(acpi_handle handle, const char *method, int val,
                          struct acpi_buffer *output)
  {
 -      struct acpi_object_list params; //list of input parameters (an int here)
 -      union acpi_object in_obj;       //the only param we use
 +      struct acpi_object_list params; /* list of input parameters (int) */
 +      union acpi_object in_obj;       /* the only param we use */
        acpi_status status;
  
        params.count = 1;
@@@ -507,18 -507,18 +507,18 @@@ proc_read_info(char *page, char **start
  {
        int len = 0;
        int temp;
 -      char buf[16];           //enough for all info
 +      char buf[16];           /* enough for all info */
        /*
 -       * We use the easy way, we don't care of off and count, so we don't set eof
 -       * to 1
 +       * We use the easy way, we don't care of off and count,
 +       * so we don't set eof to 1
         */
  
        len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n");
        len += sprintf(page + len, "Model reference    : %s\n",
                       hotk->methods->name);
 -      /* 
 -       * The SFUN method probably allows the original driver to get the list 
 -       * of features supported by a given model. For now, 0x0100 or 0x0800 
 +      /*
 +       * The SFUN method probably allows the original driver to get the list
 +       * of features supported by a given model. For now, 0x0100 or 0x0800
         * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
         * The significance of others is yet to be found.
         */
        /*
         * Another value for userspace: the ASYM method returns 0x02 for
         * battery low and 0x04 for battery critical, its readings tend to be
 -       * more accurate than those provided by _BST. 
 +       * more accurate than those provided by _BST.
         * Note: since not all the laptops provide this method, errors are
         * silently ignored.
         */
@@@ -579,7 -579,7 +579,7 @@@ static int read_led(const char *ledname
        return (hotk->status & ledmask) ? 1 : 0;
  }
  
 -static int parse_arg(const char __user * buf, unsigned long count, int *val)
 +static int parse_arg(const char __user *buf, unsigned long count, int *val)
  {
        char s[32];
        if (!count)
  
  /* FIXME: kill extraneous args so it can be called independently */
  static int
 -write_led(const char __user * buffer, unsigned long count,
 +write_led(const char __user *buffer, unsigned long count,
          char *ledname, int ledmask, int invert)
  {
        int rv, value;
@@@ -631,7 -631,7 +631,7 @@@ proc_read_mled(char *page, char **start
  }
  
  static int
 -proc_write_mled(struct file *file, const char __user * buffer,
 +proc_write_mled(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
  {
        return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1);
@@@ -648,7 -648,7 +648,7 @@@ proc_read_ledd(char *page, char **start
  }
  
  static int
 -proc_write_ledd(struct file *file, const char __user * buffer,
 +proc_write_ledd(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
  {
        int rv, value;
@@@ -677,7 -677,7 +677,7 @@@ proc_read_wled(char *page, char **start
  }
  
  static int
 -proc_write_wled(struct file *file, const char __user * buffer,
 +proc_write_wled(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
  {
        return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0);
@@@ -694,10 -694,10 +694,10 @@@ proc_read_bluetooth(char *page, char **
  }
  
  static int
 -proc_write_bluetooth(struct file *file, const char __user * buffer,
 +proc_write_bluetooth(struct file *file, const char __user *buffer,
                     unsigned long count, void *data)
  {
 -      /* Note: mt_bt_switch controls both internal Bluetooth adapter's 
 +      /* Note: mt_bt_switch controls both internal Bluetooth adapter's
           presence and its LED */
        return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0);
  }
@@@ -714,7 -714,7 +714,7 @@@ proc_read_tled(char *page, char **start
  }
  
  static int
 -proc_write_tled(struct file *file, const char __user * buffer,
 +proc_write_tled(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
  {
        return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0);
@@@ -734,7 -734,7 +734,7 @@@ static int get_lcd_state(void
  
                input.count = 2;
                input.pointer = mt_params;
 -              /* Note: the following values are partly guessed up, but 
 +              /* Note: the following values are partly guessed up, but
                   otherwise they seem to work */
                mt_params[0].type = ACPI_TYPE_INTEGER;
                mt_params[0].integer.value = 0x02;
                        /* That's what the AML code does */
                        lcd = out_obj.integer.value >> 8;
        } else if (hotk->model == F3Sa) {
-               unsigned long tmp;
+               unsigned long long tmp;
                union acpi_object param;
                struct acpi_object_list input;
                acpi_status status;
@@@ -796,13 -796,12 +796,13 @@@ static int set_lcd_state(int value
                            acpi_evaluate_object(NULL,
                                                 hotk->methods->mt_lcd_switch,
                                                 NULL, NULL);
 -              } else {        /* L3H and the like have to be handled differently */
 +              } else {
 +                      /* L3H and the like must be handled differently */
                        if (!write_acpi_int
                            (hotk->handle, hotk->methods->mt_lcd_switch, 0x07,
                             NULL))
                                status = AE_ERROR;
 -                      /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, 
 +                      /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress,
                           the exact behaviour is simulated here */
                }
                if (ACPI_FAILURE(status))
@@@ -820,7 -819,7 +820,7 @@@ proc_read_lcd(char *page, char **start
  }
  
  static int
 -proc_write_lcd(struct file *file, const char __user * buffer,
 +proc_write_lcd(struct file *file, const char __user *buffer,
               unsigned long count, void *data)
  {
        int rv, value;
@@@ -898,7 -897,7 +898,7 @@@ proc_read_brn(char *page, char **start
  }
  
  static int
 -proc_write_brn(struct file *file, const char __user * buffer,
 +proc_write_brn(struct file *file, const char __user *buffer,
               unsigned long count, void *data)
  {
        int rv, value;
@@@ -922,7 -921,7 +922,7 @@@ static void set_display(int value
  }
  
  /*
 - * Now, *this* one could be more user-friendly, but so far, no-one has 
 + * Now, *this* one could be more user-friendly, but so far, no-one has
   * complained. The significance of bits is the same as in proc_write_disp()
   */
  static int
@@@ -934,18 -933,18 +934,18 @@@ proc_read_disp(char *page, char **start
        if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
                printk(KERN_WARNING
                       "Asus ACPI: Error reading display status\n");
 -      value &= 0x07;          /* needed for some models, shouldn't hurt others */
 +      value &= 0x07;  /* needed for some models, shouldn't hurt others */
        return sprintf(page, "%d\n", value);
  }
  
  /*
 - * Experimental support for display switching. As of now: 1 should activate 
 - * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination 
 - * (bitwise) of these will suffice. I never actually tested 3 displays hooked up 
 - * simultaneously, so be warned. See the acpi4asus README for more info.
 + * Experimental support for display switching. As of now: 1 should activate
 + * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination
 + * (bitwise) of these will suffice. I never actually tested 3 displays hooked
 + * up simultaneously, so be warned. See the acpi4asus README for more info.
   */
  static int
 -proc_write_disp(struct file *file, const char __user * buffer,
 +proc_write_disp(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
  {
        int rv, value;
  
  typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
                             int *eof, void *data);
 -typedef int (proc_writefunc) (struct file * file, const char __user * buffer,
 +typedef int (proc_writefunc) (struct file *file, const char __user *buffer,
                              unsigned long count, void *data);
  
  static int
 -asus_proc_add(char *name, proc_writefunc * writefunc,
 -                   proc_readfunc * readfunc, mode_t mode,
 +asus_proc_add(char *name, proc_writefunc *writefunc,
 +                   proc_readfunc *readfunc, mode_t mode,
                     struct acpi_device *device)
  {
        struct proc_dir_entry *proc =
@@@ -1041,9 -1040,9 +1041,9 @@@ static int asus_hotk_add_fs(struct acpi
                              &proc_read_bluetooth, mode, device);
        }
  
 -      /* 
 -       * We need both read node and write method as LCD switch is also accessible
 -       * from keyboard 
 +      /*
 +       * We need both read node and write method as LCD switch is also
 +       * accessible from the keyboard
         */
        if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) {
                asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode,
@@@ -1097,10 -1096,11 +1097,10 @@@ static void asus_hotk_notify(acpi_handl
        if (!hotk)
                return;
  
 -      if ((event & ~((u32) BR_UP)) < 16) {
 +      if ((event & ~((u32) BR_UP)) < 16)
                hotk->brightness = (event & ~((u32) BR_UP));
 -      } else if ((event & ~((u32) BR_DOWN)) < 16) {
 +      else if ((event & ~((u32) BR_DOWN)) < 16)
                hotk->brightness = (event & ~((u32) BR_DOWN));
 -      }
  
        acpi_bus_generate_proc_event(hotk->device, event,
                                hotk->event_count[event % 128]++);
@@@ -1186,8 -1186,8 +1186,8 @@@ static int asus_hotk_get_info(void
        acpi_status status;
  
        /*
 -       * Get DSDT headers early enough to allow for differentiating between 
 -       * models, but late enough to allow acpi_bus_register_driver() to fail 
 +       * Get DSDT headers early enough to allow for differentiating between
 +       * models, but late enough to allow acpi_bus_register_driver() to fail
         * before doing anything ACPI-specific. Should we encounter a machine,
         * which needs special handling (i.e. its hotkey device has a different
         * HID), this bit will be moved. A global variable asus_info contains
  
        /*
         * Try to match the object returned by INIT to the specific model.
 -       * Handle every possible object (or the lack of thereof) the DSDT 
 -       * writers might throw at us. When in trouble, we pass NULL to 
 +       * Handle every possible object (or the lack of thereof) the DSDT
 +       * writers might throw at us. When in trouble, we pass NULL to
         * asus_model_match() and try something completely different.
         */
        if (buffer.pointer) {
                               "default values\n", string);
                        printk(KERN_NOTICE
                               "  send /proc/acpi/dsdt to the developers\n");
 +                      kfree(model);
 +                      return -ENODEV;
                }
                hotk->methods = &model_conf[hotk->model];
                return AE_OK;
        /* Sort of per-model blacklist */
        if (strncmp(string, "L2B", 3) == 0)
                hotk->methods->lcd_status = NULL;
 -      /* L2B is similar enough to L3C to use its settings, with this only 
 +      /* L2B is similar enough to L3C to use its settings, with this only
           exception */
        else if (strncmp(string, "A3G", 3) == 0)
                hotk->methods->lcd_status = "\\BLFG";
@@@ -1323,7 -1321,7 +1323,7 @@@ static int asus_hotk_add(struct acpi_de
        hotk->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_HOTK_CLASS);
 -      acpi_driver_data(device) = hotk;
 +      device->driver_data = hotk;
        hotk->device = device;
  
        result = asus_hotk_check();
        /* LED display is off by default */
        hotk->ledd_status = 0xFFF;
  
 -      end:
 -      if (result) {
 +end:
 +      if (result)
                kfree(hotk);
 -      }
  
        return result;
  }
@@@ -1395,8 -1394,8 +1395,8 @@@ static int asus_hotk_remove(struct acpi
  }
  
  static struct backlight_ops asus_backlight_data = {
 -        .get_brightness = read_brightness,
 -        .update_status  = set_brightness_status,
 +      .get_brightness = read_brightness,
 +      .update_status  = set_brightness_status,
  };
  
  static void asus_acpi_exit(void)
@@@ -1443,15 -1442,15 +1443,15 @@@ static int __init asus_acpi_init(void
                return -ENODEV;
        }
  
 -      asus_backlight_device = backlight_device_register("asus",NULL,NULL,
 +      asus_backlight_device = backlight_device_register("asus", NULL, NULL,
                                                          &asus_backlight_data);
 -        if (IS_ERR(asus_backlight_device)) {
 +      if (IS_ERR(asus_backlight_device)) {
                printk(KERN_ERR "Could not register asus backlight device\n");
                asus_backlight_device = NULL;
                asus_acpi_exit();
                return -ENODEV;
        }
 -        asus_backlight_device->props.max_brightness = 15;
 +      asus_backlight_device->props.max_brightness = 15;
  
        return 0;
  }
diff --combined drivers/acpi/bus.c
index b11400e2f856e28f787ba23160b18a894a93c285,0885fc796fa0ca8442c397a515cbd331c915b5d7..c797c6473f31588cbc6ddf03c25a0770f26ccbe7
@@@ -48,23 -48,6 +48,23 @@@ EXPORT_SYMBOL(acpi_root_dir)
  
  #define STRUCT_TO_INT(s)      (*((int*)&s))
  
 +static int set_power_nocheck(const struct dmi_system_id *id)
 +{
 +      printk(KERN_NOTICE PREFIX "%s detected - "
 +              "disable power check in power transistion\n", id->ident);
 +      acpi_power_nocheck = 1;
 +      return 0;
 +}
 +static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
 +      {
 +      set_power_nocheck, "HP Pavilion 05", {
 +      DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 +      DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
 +      DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
 +      {},
 +};
 +
 +
  /* --------------------------------------------------------------------------
                                  Device Management
     -------------------------------------------------------------------------- */
@@@ -94,7 -77,7 +94,7 @@@ EXPORT_SYMBOL(acpi_bus_get_device)
  int acpi_bus_get_status(struct acpi_device *device)
  {
        acpi_status status = AE_OK;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
  
  
        if (!device)
        }
  
        /*
 -       * Otherwise we assume the status of our parent (unless we don't
 -       * have one, in which case status is implied).
 +       * According to ACPI spec some device can be present and functional
 +       * even if the parent is not present but functional.
 +       * In such conditions the child device should not inherit the status
 +       * from the parent.
         */
 -      else if (device->parent)
 -              device->status = device->parent->status;
        else
                STRUCT_TO_INT(device->status) =
                    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
                    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
  
        if (device->status.functional && !device->status.present) {
 -              printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
 -                     "functional but not present; setting present\n",
 -                     device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
 -              device->status.present = 1;
 +              ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
 +                     "functional but not present;\n",
 +                      device->pnp.bus_id,
 +                      (u32) STRUCT_TO_INT(device->status)));
        }
  
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
@@@ -172,7 -155,7 +172,7 @@@ int acpi_bus_get_power(acpi_handle hand
        int result = 0;
        acpi_status status = 0;
        struct acpi_device *device = NULL;
-       unsigned long psc = 0;
+       unsigned long long psc = 0;
  
  
        result = acpi_bus_get_device(handle, &device);
@@@ -240,19 -223,7 +240,19 @@@ int acpi_bus_set_power(acpi_handle hand
        /*
         * Get device's current power state
         */
 -      acpi_bus_get_power(device->handle, &device->power.state);
 +      if (!acpi_power_nocheck) {
 +              /*
 +               * Maybe the incorrect power state is returned on the bogus
 +               * bios, which is different with the real power state.
 +               * For example: the bios returns D0 state and the real power
 +               * state is D3. OS expects to set the device to D0 state. In
 +               * such case if OS uses the power state returned by the BIOS,
 +               * the device can't be transisted to the correct power state.
 +               * So if the acpi_power_nocheck is set, it is unnecessary to
 +               * get the power state by calling acpi_bus_get_power.
 +               */
 +              acpi_bus_get_power(device->handle, &device->power.state);
 +      }
        if ((state == device->power.state) && !device->flags.force_power_state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
                                  state));
@@@ -525,19 -496,6 +525,19 @@@ static int acpi_bus_check_scope(struct 
        return 0;
  }
  
 +static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
 +int register_acpi_bus_notifier(struct notifier_block *nb)
 +{
 +      return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
 +}
 +EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);
 +
 +void unregister_acpi_bus_notifier(struct notifier_block *nb)
 +{
 +      blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
 +}
 +EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
 +
  /**
   * acpi_bus_notify
   * ---------------
@@@ -548,8 -506,6 +548,8 @@@ static void acpi_bus_notify(acpi_handl
        int result = 0;
        struct acpi_device *device = NULL;
  
 +      blocking_notifier_call_chain(&acpi_bus_notify_list,
 +              type, (void *)handle);
  
        if (acpi_bus_get_device(handle, &device))
                return;
@@@ -793,12 -749,6 +793,12 @@@ static int __init acpi_bus_init(void
                goto error1;
        }
  
 +      /*
 +       * Maybe EC region is required at bus_scan/acpi_get_devices. So it
 +       * is necessary to enable it as early as possible.
 +       */
 +      acpi_boot_ec_enable();
 +
        printk(KERN_INFO PREFIX "Interpreter enabled\n");
  
        /* Initialize sleep structures */
@@@ -868,11 -818,7 +868,11 @@@ static int __init acpi_init(void
                }
        } else
                disable_acpi();
 -
 +      /*
 +       * If the laptop falls into the DMI check table, the power state check
 +       * will be disabled in the course of device power transistion.
 +       */
 +      dmi_check_system(power_nocheck_dmi_table);
        return result;
  }
  
diff --combined drivers/acpi/button.c
index e22033ea2614b8963170e7865b1b569a11699169,baeb661ca953ee561429fd55848d2a254a4d9ef8..9d568d417eaa48e2e76624a0a2e505499c3aedcb
@@@ -145,7 -145,7 +145,7 @@@ static int acpi_button_state_seq_show(s
  {
        struct acpi_button *button = seq->private;
        acpi_status status;
-       unsigned long state;
+       unsigned long long state;
  
        if (!button || !button->device)
                return 0;
@@@ -253,7 -253,7 +253,7 @@@ static int acpi_button_remove_fs(struc
     -------------------------------------------------------------------------- */
  static int acpi_lid_send_state(struct acpi_button *button)
  {
-       unsigned long state;
+       unsigned long long state;
        acpi_status status;
  
        status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
@@@ -384,7 -384,7 +384,7 @@@ static int acpi_button_add(struct acpi_
                return -ENOMEM;
  
        button->device = device;
 -      acpi_driver_data(device) = button;
 +      device->driver_data = button;
  
        button->input = input = input_allocate_device();
        if (!input) {
diff --combined drivers/acpi/container.c
index 03ea8478e393846f7a6aa559f8cfb16faeccce88,cfa5fd68168ade8666df377c7c0060477f7d5e64..134818b265a9fae8ff5aec7af3e443d4cc6d7c59
@@@ -76,7 -76,7 +76,7 @@@ static int is_device_present(acpi_handl
  {
        acpi_handle temp;
        acpi_status status;
-       unsigned long sta;
+       unsigned long long sta;
  
  
        status = acpi_get_handle(handle, "_STA", &temp);
@@@ -108,7 -108,7 +108,7 @@@ static int acpi_container_add(struct ac
        container->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
 -      acpi_driver_data(device) = container;
 +      device->driver_data = container;
  
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
                          acpi_device_name(device), acpi_device_bid(device)));
diff --combined drivers/acpi/dock.c
index 913bb1e89dd60016c09d80bfc2585dc7a1b0f9b8,94857112b64de0afb6608a9fb01c3fc7ac4f0252..5b30b8d91d716126cdd3305d61ee8fd625eea016
@@@ -48,6 -48,7 +48,6 @@@ MODULE_PARM_DESC(immediate_undock, "1 (
        " before undocking");
  
  static struct atomic_notifier_head dock_notifier_list;
 -static struct platform_device *dock_device;
  static char dock_device_name[] = "dock";
  
  static const struct acpi_device_id dock_device_ids[] = {
@@@ -64,29 -65,23 +64,29 @@@ struct dock_station 
        struct mutex hp_lock;
        struct list_head dependent_devices;
        struct list_head hotplug_devices;
 +
 +      struct list_head sibiling;
 +      struct platform_device *dock_device;
  };
 +static LIST_HEAD(dock_stations);
 +static int dock_station_count;
  
  struct dock_dependent_device {
        struct list_head list;
        struct list_head hotplug_list;
        acpi_handle handle;
 -      acpi_notify_handler handler;
 +      struct acpi_dock_ops *ops;
        void *context;
  };
  
  #define DOCK_DOCKING  0x00000001
  #define DOCK_UNDOCKING  0x00000002
 +#define DOCK_IS_DOCK  0x00000010
 +#define DOCK_IS_ATA   0x00000020
 +#define DOCK_IS_BAT   0x00000040
  #define DOCK_EVENT    3
  #define UNDOCK_EVENT  2
  
 -static struct dock_station *dock_station;
 -
  /*****************************************************************************
   *                         Dock Dependent device functions                   *
   *****************************************************************************/
@@@ -204,60 -199,6 +204,60 @@@ static int is_dock(acpi_handle handle
        return 1;
  }
  
 +static int is_ejectable(acpi_handle handle)
 +{
 +      acpi_status status;
 +      acpi_handle tmp;
 +
 +      status = acpi_get_handle(handle, "_EJ0", &tmp);
 +      if (ACPI_FAILURE(status))
 +              return 0;
 +      return 1;
 +}
 +
 +static int is_ata(acpi_handle handle)
 +{
 +      acpi_handle tmp;
 +
 +      if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
 +         (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
 +         (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
 +         (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
 +              return 1;
 +
 +      return 0;
 +}
 +
 +static int is_battery(acpi_handle handle)
 +{
 +      struct acpi_device_info *info;
 +      struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 +      int ret = 1;
 +
 +      if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer)))
 +              return 0;
 +      info = buffer.pointer;
 +      if (!(info->valid & ACPI_VALID_HID))
 +              ret = 0;
 +      else
 +              ret = !strcmp("PNP0C0A", info->hardware_id.value);
 +
 +      kfree(buffer.pointer);
 +      return ret;
 +}
 +
 +static int is_ejectable_bay(acpi_handle handle)
 +{
 +      acpi_handle phandle;
 +      if (!is_ejectable(handle))
 +              return 0;
 +      if (is_battery(handle) || is_ata(handle))
 +              return 1;
 +      if (!acpi_get_parent(handle, &phandle) && is_ata(phandle))
 +              return 1;
 +      return 0;
 +}
 +
  /**
   * is_dock_device - see if a device is on a dock station
   * @handle: acpi handle of the device
   */
  int is_dock_device(acpi_handle handle)
  {
 -      if (!dock_station)
 +      struct dock_station *dock_station;
 +
 +      if (!dock_station_count)
                return 0;
  
 -      if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
 +      if (is_dock(handle))
                return 1;
 +      list_for_each_entry(dock_station, &dock_stations, sibiling) {
 +              if (find_dock_dependent_device(dock_station, handle))
 +                      return 1;
 +      }
  
        return 0;
  }
@@@ -294,7 -229,7 +294,7 @@@ EXPORT_SYMBOL_GPL(is_dock_device)
   */
  static int dock_present(struct dock_station *ds)
  {
-       unsigned long sta;
+       unsigned long long sta;
        acpi_status status;
  
        if (ds) {
@@@ -385,8 -320,8 +385,8 @@@ static void hotplug_dock_devices(struc
         * First call driver specific hotplug functions
         */
        list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
 -              if (dd->handler)
 -                      dd->handler(dd->handle, event, dd->context);
 +              if (dd->ops && dd->ops->handler)
 +                      dd->ops->handler(dd->handle, event, dd->context);
        }
  
        /*
  
  static void dock_event(struct dock_station *ds, u32 event, int num)
  {
 -      struct device *dev = &dock_device->dev;
 +      struct device *dev = &ds->dock_device->dev;
        char event_string[13];
        char *envp[] = { event_string, NULL };
 +      struct dock_dependent_device *dd;
  
        if (num == UNDOCK_EVENT)
                sprintf(event_string, "EVENT=undock");
         * Indicate that the status of the dock station has
         * changed.
         */
 -      kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 +      if (num == DOCK_EVENT)
 +              kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 +
 +      list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
 +              if (dd->ops && dd->ops->uevent)
 +                      dd->ops->uevent(dd->handle, event, dd->context);
 +      if (num != DOCK_EVENT)
 +              kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
  }
  
  /**
@@@ -487,10 -414,9 +487,10 @@@ static void handle_dock(struct dock_sta
        arg.type = ACPI_TYPE_INTEGER;
        arg.integer.value = dock;
        status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
 -      if (ACPI_FAILURE(status))
 -              printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n",
 -                       (char *)name_buffer.pointer);
 +      if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
 +              ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute"
 +                      " _DCK\n", (char *)name_buffer.pointer));
 +
        kfree(buffer.pointer);
        kfree(name_buffer.pointer);
  }
@@@ -526,25 -452,6 +526,25 @@@ static inline void complete_undock(stru
        ds->flags &= ~(DOCK_UNDOCKING);
  }
  
 +static void dock_lock(struct dock_station *ds, int lock)
 +{
 +      struct acpi_object_list arg_list;
 +      union acpi_object arg;
 +      acpi_status status;
 +
 +      arg_list.count = 1;
 +      arg_list.pointer = &arg;
 +      arg.type = ACPI_TYPE_INTEGER;
 +      arg.integer.value = !!lock;
 +      status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL);
 +      if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 +              if (lock)
 +                      printk(KERN_WARNING PREFIX "Locking device failed\n");
 +              else
 +                      printk(KERN_WARNING PREFIX "Unlocking device failed\n");
 +      }
 +}
 +
  /**
   * dock_in_progress - see if we are in the middle of handling a dock event
   * @ds: the dock station
@@@ -572,7 -479,7 +572,7 @@@ static int dock_in_progress(struct dock
   */
  int register_dock_notifier(struct notifier_block *nb)
  {
 -      if (!dock_station)
 +      if (!dock_station_count)
                return -ENODEV;
  
        return atomic_notifier_chain_register(&dock_notifier_list, nb);
@@@ -586,7 -493,7 +586,7 @@@ EXPORT_SYMBOL_GPL(register_dock_notifie
   */
  void unregister_dock_notifier(struct notifier_block *nb)
  {
 -      if (!dock_station)
 +      if (!dock_station_count)
                return;
  
        atomic_notifier_chain_unregister(&dock_notifier_list, nb);
@@@ -597,7 -504,7 +597,7 @@@ EXPORT_SYMBOL_GPL(unregister_dock_notif
  /**
   * register_hotplug_dock_device - register a hotplug function
   * @handle: the handle of the device
 - * @handler: the acpi_notifier_handler to call after docking
 + * @ops: handlers to call after docking
   * @context: device specific data
   *
   * If a driver would like to perform a hotplug operation after a dock
   * the dock driver after _DCK is executed.
   */
  int
 -register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
 +register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
                             void *context)
  {
        struct dock_dependent_device *dd;
 +      struct dock_station *dock_station;
 +      int ret = -EINVAL;
  
 -      if (!dock_station)
 +      if (!dock_station_count)
                return -ENODEV;
  
        /*
         * make sure this handle is for a device dependent on the dock,
         * this would include the dock station itself
         */
 -      dd = find_dock_dependent_device(dock_station, handle);
 -      if (dd) {
 -              dd->handler = handler;
 -              dd->context = context;
 -              dock_add_hotplug_device(dock_station, dd);
 -              return 0;
 +      list_for_each_entry(dock_station, &dock_stations, sibiling) {
 +              /*
 +               * An ATA bay can be in a dock and itself can be ejected
 +               * seperately, so there are two 'dock stations' which need the
 +               * ops
 +               */
 +              dd = find_dock_dependent_device(dock_station, handle);
 +              if (dd) {
 +                      dd->ops = ops;
 +                      dd->context = context;
 +                      dock_add_hotplug_device(dock_station, dd);
 +                      ret = 0;
 +              }
        }
  
 -      return -EINVAL;
 +      return ret;
  }
  
  EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
  void unregister_hotplug_dock_device(acpi_handle handle)
  {
        struct dock_dependent_device *dd;
 +      struct dock_station *dock_station;
  
 -      if (!dock_station)
 +      if (!dock_station_count)
                return;
  
 -      dd = find_dock_dependent_device(dock_station, handle);
 -      if (dd)
 -              dock_del_hotplug_device(dock_station, dd);
 +      list_for_each_entry(dock_station, &dock_stations, sibiling) {
 +              dd = find_dock_dependent_device(dock_station, handle);
 +              if (dd)
 +                      dock_del_hotplug_device(dock_station, dd);
 +      }
  }
  
  EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
@@@ -680,9 -575,13 +680,9 @@@ static int handle_eject_request(struct 
         */
        dock_event(ds, event, UNDOCK_EVENT);
  
 -      if (!dock_present(ds)) {
 -              complete_undock(ds);
 -              return -ENODEV;
 -      }
 -
        hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
        undock(ds);
 +      dock_lock(ds, 0);
        eject_dock(ds);
        if (dock_present(ds)) {
                printk(KERN_ERR PREFIX "Unable to undock!\n");
  static void dock_notify(acpi_handle handle, u32 event, void *data)
  {
        struct dock_station *ds = data;
 +      struct acpi_device *tmp;
 +      int surprise_removal = 0;
 +
 +      /*
 +       * According to acpi spec 3.0a, if a DEVICE_CHECK notification
 +       * is sent and _DCK is present, it is assumed to mean an undock
 +       * request.
 +       */
 +      if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK)
 +              event = ACPI_NOTIFY_EJECT_REQUEST;
  
 +      /*
 +       * dock station: BUS_CHECK - docked or surprise removal
 +       *               DEVICE_CHECK - undocked
 +       * other device: BUS_CHECK/DEVICE_CHECK - added or surprise removal
 +       *
 +       * To simplify event handling, dock dependent device handler always
 +       * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
 +       * ACPI_NOTIFY_EJECT_REQUEST for removal
 +       */
        switch (event) {
        case ACPI_NOTIFY_BUS_CHECK:
 -              if (!dock_in_progress(ds) && dock_present(ds)) {
 +      case ACPI_NOTIFY_DEVICE_CHECK:
 +              if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
 +                 &tmp)) {
                        begin_dock(ds);
                        dock(ds);
                        if (!dock_present(ds)) {
                                printk(KERN_ERR PREFIX "Unable to dock!\n");
 +                              complete_dock(ds);
                                break;
                        }
                        atomic_notifier_call_chain(&dock_notifier_list,
                        hotplug_dock_devices(ds, event);
                        complete_dock(ds);
                        dock_event(ds, event, DOCK_EVENT);
 +                      dock_lock(ds, 1);
 +                      break;
                }
 -              break;
 -      case ACPI_NOTIFY_DEVICE_CHECK:
 -      /*
 -         * According to acpi spec 3.0a, if a DEVICE_CHECK notification
 -         * is sent and _DCK is present, it is assumed to mean an
 -         * undock request.  This notify routine will only be called
 -         * for objects defining _DCK, so we will fall through to eject
 -         * request here.  However, we will pass an eject request through
 -       * to the driver who wish to hotplug.
 -         */
 +              if (dock_present(ds) || dock_in_progress(ds))
 +                      break;
 +              /* This is a surprise removal */
 +              surprise_removal = 1;
 +              event = ACPI_NOTIFY_EJECT_REQUEST;
 +              /* Fall back */
        case ACPI_NOTIFY_EJECT_REQUEST:
                begin_undock(ds);
 -              if (immediate_undock)
 +              if ((immediate_undock && !(ds->flags & DOCK_IS_ATA))
 +                 || surprise_removal)
                        handle_eject_request(ds, event);
                else
                        dock_event(ds, event, UNDOCK_EVENT);
        }
  }
  
 +struct dock_data {
 +      acpi_handle handle;
 +      unsigned long event;
 +      struct dock_station *ds;
 +};
 +
 +static void acpi_dock_deferred_cb(void *context)
 +{
 +      struct dock_data *data = (struct dock_data *)context;
 +
 +      dock_notify(data->handle, data->event, data->ds);
 +      kfree(data);
 +}
 +
 +static int acpi_dock_notifier_call(struct notifier_block *this,
 +      unsigned long event, void *data)
 +{
 +      struct dock_station *dock_station;
 +      acpi_handle handle = (acpi_handle)data;
 +
 +      if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
 +         && event != ACPI_NOTIFY_EJECT_REQUEST)
 +              return 0;
 +      list_for_each_entry(dock_station, &dock_stations, sibiling) {
 +              if (dock_station->handle == handle) {
 +                      struct dock_data *dock_data;
 +
 +                      dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL);
 +                      if (!dock_data)
 +                              return 0;
 +                      dock_data->handle = handle;
 +                      dock_data->event = event;
 +                      dock_data->ds = dock_station;
 +                      acpi_os_hotplug_execute(acpi_dock_deferred_cb,
 +                              dock_data);
 +                      return 0 ;
 +              }
 +      }
 +      return 0;
 +}
 +
 +static struct notifier_block dock_acpi_notifier = {
 +      .notifier_call = acpi_dock_notifier_call,
 +};
 +
  /**
   * find_dock_devices - find devices on the dock station
   * @handle: the handle of the device we are examining
@@@ -855,8 -688,6 +855,8 @@@ fdd_out
  static ssize_t show_docked(struct device *dev,
                           struct device_attribute *attr, char *buf)
  {
 +      struct dock_station *dock_station = *((struct dock_station **)
 +              dev->platform_data);
        return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
  
  }
@@@ -868,8 -699,6 +868,8 @@@ static DEVICE_ATTR(docked, S_IRUGO, sho
  static ssize_t show_flags(struct device *dev,
                          struct device_attribute *attr, char *buf)
  {
 +      struct dock_station *dock_station = *((struct dock_station **)
 +              dev->platform_data);
        return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
  
  }
@@@ -882,8 -711,6 +882,8 @@@ static ssize_t write_undock(struct devi
                           const char *buf, size_t count)
  {
        int ret;
 +      struct dock_station *dock_station = *((struct dock_station **)
 +              dev->platform_data);
  
        if (!count)
                return -EINVAL;
@@@ -900,38 -727,16 +900,38 @@@ static DEVICE_ATTR(undock, S_IWUSR, NUL
  static ssize_t show_dock_uid(struct device *dev,
                             struct device_attribute *attr, char *buf)
  {
-       unsigned long lbuf;
+       unsigned long long lbuf;
 +      struct dock_station *dock_station = *((struct dock_station **)
 +              dev->platform_data);
        acpi_status status = acpi_evaluate_integer(dock_station->handle,
                                        "_UID", NULL, &lbuf);
        if (ACPI_FAILURE(status))
            return 0;
  
-       return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf);
+       return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf);
  }
  static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
  
 +static ssize_t show_dock_type(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct dock_station *dock_station = *((struct dock_station **)
 +              dev->platform_data);
 +      char *type;
 +
 +      if (dock_station->flags & DOCK_IS_DOCK)
 +              type = "dock_station";
 +      else if (dock_station->flags & DOCK_IS_ATA)
 +              type = "ata_bay";
 +      else if (dock_station->flags & DOCK_IS_BAT)
 +              type = "battery_bay";
 +      else
 +              type = "unknown";
 +
 +      return snprintf(buf, PAGE_SIZE, "%s\n", type);
 +}
 +static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL);
 +
  /**
   * dock_add - add a new dock station
   * @handle: the dock station handle
  static int dock_add(acpi_handle handle)
  {
        int ret;
 -      acpi_status status;
        struct dock_dependent_device *dd;
 +      struct dock_station *dock_station;
 +      struct platform_device *dock_device;
  
        /* allocate & initialize the dock_station private data */
        dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
        dock_station->last_dock_time = jiffies - HZ;
        INIT_LIST_HEAD(&dock_station->dependent_devices);
        INIT_LIST_HEAD(&dock_station->hotplug_devices);
 +      INIT_LIST_HEAD(&dock_station->sibiling);
        spin_lock_init(&dock_station->dd_lock);
        mutex_init(&dock_station->hp_lock);
        ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
  
        /* initialize platform device stuff */
 -      dock_device =
 -              platform_device_register_simple(dock_device_name, 0, NULL, 0);
 +      dock_station->dock_device =
 +              platform_device_register_simple(dock_device_name,
 +                      dock_station_count, NULL, 0);
 +      dock_device = dock_station->dock_device;
        if (IS_ERR(dock_device)) {
                kfree(dock_station);
                dock_station = NULL;
                return PTR_ERR(dock_device);
        }
 +      platform_device_add_data(dock_device, &dock_station,
 +              sizeof(struct dock_station *));
  
        /* we want the dock device to send uevents */
        dock_device->dev.uevent_suppress = 0;
  
 +      if (is_dock(handle))
 +              dock_station->flags |= DOCK_IS_DOCK;
 +      if (is_ata(handle))
 +              dock_station->flags |= DOCK_IS_ATA;
 +      if (is_battery(handle))
 +              dock_station->flags |= DOCK_IS_BAT;
 +
        ret = device_create_file(&dock_device->dev, &dev_attr_docked);
        if (ret) {
                printk("Error %d adding sysfs file\n", ret);
                dock_station = NULL;
                return ret;
        }
 +      ret = device_create_file(&dock_device->dev, &dev_attr_type);
 +      if (ret)
 +              printk(KERN_ERR"Error %d adding sysfs file\n", ret);
  
        /* Find dependent devices */
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
        }
        add_dock_dependent_device(dock_station, dd);
  
 -      /* register for dock events */
 -      status = acpi_install_notify_handler(dock_station->handle,
 -                                           ACPI_SYSTEM_NOTIFY,
 -                                           dock_notify, dock_station);
 -
 -      if (ACPI_FAILURE(status)) {
 -              printk(KERN_ERR PREFIX "Error installing notify handler\n");
 -              ret = -ENODEV;
 -              goto dock_add_err;
 -      }
 -
 -      printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION);
 -
 +      dock_station_count++;
 +      list_add(&dock_station->sibiling, &dock_stations);
        return 0;
  
 -dock_add_err:
 -      kfree(dd);
  dock_add_err_unregister:
 +      device_remove_file(&dock_device->dev, &dev_attr_type);
        device_remove_file(&dock_device->dev, &dev_attr_docked);
        device_remove_file(&dock_device->dev, &dev_attr_undock);
        device_remove_file(&dock_device->dev, &dev_attr_uid);
  /**
   * dock_remove - free up resources related to the dock station
   */
 -static int dock_remove(void)
 +static int dock_remove(struct dock_station *dock_station)
  {
        struct dock_dependent_device *dd, *tmp;
 -      acpi_status status;
 +      struct platform_device *dock_device = dock_station->dock_device;
  
 -      if (!dock_station)
 +      if (!dock_station_count)
                return 0;
  
        /* remove dependent devices */
                                 list)
            kfree(dd);
  
 -      /* remove dock notify handler */
 -      status = acpi_remove_notify_handler(dock_station->handle,
 -                                          ACPI_SYSTEM_NOTIFY,
 -                                          dock_notify);
 -      if (ACPI_FAILURE(status))
 -              printk(KERN_ERR "Error removing notify handler\n");
 -
        /* cleanup sysfs */
 +      device_remove_file(&dock_device->dev, &dev_attr_type);
        device_remove_file(&dock_device->dev, &dev_attr_docked);
        device_remove_file(&dock_device->dev, &dev_attr_undock);
        device_remove_file(&dock_device->dev, &dev_attr_uid);
  static acpi_status
  find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
  {
 -      int *count = context;
        acpi_status status = AE_OK;
  
        if (is_dock(handle)) {
                if (dock_add(handle) >= 0) {
 -                      (*count)++;
                        status = AE_CTRL_TERMINATE;
                }
        }
        return status;
  }
  
 -static int __init dock_init(void)
 +static acpi_status
 +find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
  {
 -      int num = 0;
 -
 -      dock_station = NULL;
 +      /* If bay is a dock, it's already handled */
 +      if (is_ejectable_bay(handle) && !is_dock(handle))
 +              dock_add(handle);
 +      return AE_OK;
 +}
  
 +static int __init dock_init(void)
 +{
        if (acpi_disabled)
                return 0;
  
        /* look for a dock station */
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 -                          ACPI_UINT32_MAX, find_dock, &num, NULL);
 +                          ACPI_UINT32_MAX, find_dock, NULL, NULL);
  
 -      if (!num)
 -              printk(KERN_INFO "No dock devices found.\n");
 +      /* look for bay */
 +      acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 +                      ACPI_UINT32_MAX, find_bay, NULL, NULL);
 +      if (!dock_station_count) {
 +              printk(KERN_INFO PREFIX "No dock devices found.\n");
 +              return 0;
 +      }
  
 +      register_acpi_bus_notifier(&dock_acpi_notifier);
 +      printk(KERN_INFO PREFIX "%s: %d docks/bays found\n",
 +              ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
        return 0;
  }
  
  static void __exit dock_exit(void)
  {
 -      dock_remove();
 +      struct dock_station *dock_station;
 +
 +      unregister_acpi_bus_notifier(&dock_acpi_notifier);
 +      list_for_each_entry(dock_station, &dock_stations, sibiling)
 +              dock_remove(dock_station);
  }
  
 -postcore_initcall(dock_init);
 +/*
 + * Must be called before drivers of devices in dock, otherwise we can't know
 + * which devices are in a dock
 + */
 +subsys_initcall(dock_init);
  module_exit(dock_exit);
diff --combined drivers/acpi/ec.c
index 40fefba6264edfb3afd3b8915591a98278c3a13f,638a68679a420e876987cd67f8f050a7a4c18fce..ef42316f89f52452f69192d89894ca9ba64f46ee
@@@ -1,7 -1,7 +1,7 @@@
  /*
 - *  ec.c - ACPI Embedded Controller Driver (v2.0)
 + *  ec.c - ACPI Embedded Controller Driver (v2.1)
   *
 - *  Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
 + *  Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de>
   *  Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
   *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
@@@ -26,7 -26,7 +26,7 @@@
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   */
  
 -/* Uncomment next line to get verbose print outs*/
 +/* Uncomment next line to get verbose printout */
  /* #define DEBUG */
  
  #include <linux/kernel.h>
@@@ -38,7 -38,6 +38,7 @@@
  #include <linux/seq_file.h>
  #include <linux/interrupt.h>
  #include <linux/list.h>
 +#include <linux/spinlock.h>
  #include <asm/io.h>
  #include <acpi/acpi_bus.h>
  #include <acpi/acpi_drivers.h>
@@@ -66,21 -65,22 +66,21 @@@ enum ec_command 
        ACPI_EC_COMMAND_QUERY = 0x84,
  };
  
 -/* EC events */
 -enum ec_event {
 -      ACPI_EC_EVENT_OBF_1 = 1,        /* Output buffer full */
 -      ACPI_EC_EVENT_IBF_0,            /* Input buffer empty */
 -};
 -
  #define ACPI_EC_DELAY         500     /* Wait 500ms max. during EC ops */
  #define ACPI_EC_UDELAY_GLK    1000    /* Wait 1ms max. to get global lock */
  #define ACPI_EC_UDELAY                100     /* Wait 100us before polling EC again */
  
 +#define ACPI_EC_STORM_THRESHOLD 20    /* number of false interrupts
 +                                         per one transaction */
 +
  enum {
 -      EC_FLAGS_WAIT_GPE = 0,          /* Don't check status until GPE arrives */
        EC_FLAGS_QUERY_PENDING,         /* Query is pending */
 -      EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent for status change */
 +      EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent
 +                                       * for status change */
        EC_FLAGS_NO_GPE,                /* Don't use GPE mode */
 -      EC_FLAGS_RESCHEDULE_POLL        /* Re-schedule poll */
 +      EC_FLAGS_GPE_STORM,             /* GPE storm detected */
 +      EC_FLAGS_HANDLERS_INSTALLED     /* Handlers for GPE and
 +                                       * OpReg are installed */
  };
  
  /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@@ -95,15 -95,6 +95,15 @@@ struct acpi_ec_query_handler 
        u8 query_bit;
  };
  
 +struct transaction {
 +      const u8 *wdata;
 +      u8 *rdata;
 +      unsigned short irq_count;
 +      u8 command;
 +      u8 wlen;
 +      u8 rlen;
 +};
 +
  static struct acpi_ec {
        acpi_handle handle;
        unsigned long gpe;
        struct mutex lock;
        wait_queue_head_t wait;
        struct list_head list;
 -      struct delayed_work work;
 -      atomic_t irq_count;
 -      u8 handlers_installed;
 +      struct transaction *curr;
 +      spinlock_t curr_lock;
  } *boot_ec, *first_ec;
  
  /* 
@@@ -158,7 -150,7 +158,7 @@@ static inline u8 acpi_ec_read_data(stru
  {
        u8 x = inb(ec->data_addr);
        pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
 -      return inb(ec->data_addr);
 +      return x;
  }
  
  static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
@@@ -173,172 -165,158 +173,172 @@@ static inline void acpi_ec_write_data(s
        outb(data, ec->data_addr);
  }
  
 -static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
 +static int ec_transaction_done(struct acpi_ec *ec)
  {
 -      if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
 -              return 0;
 -      if (event == ACPI_EC_EVENT_OBF_1) {
 -              if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
 -                      return 1;
 -      } else if (event == ACPI_EC_EVENT_IBF_0) {
 -              if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
 -                      return 1;
 -      }
 -
 -      return 0;
 +      unsigned long flags;
 +      int ret = 0;
 +      spin_lock_irqsave(&ec->curr_lock, flags);
 +      if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
 +              ret = 1;
 +      spin_unlock_irqrestore(&ec->curr_lock, flags);
 +      return ret;
  }
  
 -static void ec_schedule_ec_poll(struct acpi_ec *ec)
 +static void gpe_transaction(struct acpi_ec *ec, u8 status)
  {
 -      if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
 -              schedule_delayed_work(&ec->work,
 -                                    msecs_to_jiffies(ACPI_EC_DELAY));
 +      unsigned long flags;
 +      spin_lock_irqsave(&ec->curr_lock, flags);
 +      if (!ec->curr)
 +              goto unlock;
 +      if (ec->curr->wlen > 0) {
 +              if ((status & ACPI_EC_FLAG_IBF) == 0) {
 +                      acpi_ec_write_data(ec, *(ec->curr->wdata++));
 +                      --ec->curr->wlen;
 +              } else
 +                      /* false interrupt, state didn't change */
 +                      ++ec->curr->irq_count;
 +
 +      } else if (ec->curr->rlen > 0) {
 +              if ((status & ACPI_EC_FLAG_OBF) == 1) {
 +                      *(ec->curr->rdata++) = acpi_ec_read_data(ec);
 +                      --ec->curr->rlen;
 +              } else
 +                      /* false interrupt, state didn't change */
 +                      ++ec->curr->irq_count;
 +      }
 +unlock:
 +      spin_unlock_irqrestore(&ec->curr_lock, flags);
  }
  
 -static void ec_switch_to_poll_mode(struct acpi_ec *ec)
 +static int acpi_ec_wait(struct acpi_ec *ec)
  {
 +      if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
 +                             msecs_to_jiffies(ACPI_EC_DELAY)))
 +              return 0;
 +      /* missing GPEs, switch back to poll mode */
 +      if (printk_ratelimit())
 +              pr_info(PREFIX "missing confirmations, "
 +                              "switch off interrupt mode.\n");
        set_bit(EC_FLAGS_NO_GPE, &ec->flags);
        clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 -      acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 -      set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
 +      return 1;
  }
  
 -static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
 +static void acpi_ec_gpe_query(void *ec_cxt);
 +
 +static int ec_check_sci(struct acpi_ec *ec, u8 state)
  {
 -      atomic_set(&ec->irq_count, 0);
 -      if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
 -          likely(!force_poll)) {
 -              if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
 -                                     msecs_to_jiffies(ACPI_EC_DELAY)))
 -                      return 0;
 -              clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
 -              if (acpi_ec_check_status(ec, event)) {
 -                      /* missing GPEs, switch back to poll mode */
 -                      if (printk_ratelimit())
 -                              pr_info(PREFIX "missing confirmations, "
 -                                              "switch off interrupt mode.\n");
 -                      ec_switch_to_poll_mode(ec);
 -                      ec_schedule_ec_poll(ec);
 -                      return 0;
 -              }
 -      } else {
 -              unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
 -              clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
 -              while (time_before(jiffies, delay)) {
 -                      if (acpi_ec_check_status(ec, event))
 -                              return 0;
 -                      msleep(1);
 -              }
 -              if (acpi_ec_check_status(ec,event))
 +      if (state & ACPI_EC_FLAG_SCI) {
 +              if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
 +                      return acpi_os_execute(OSL_EC_BURST_HANDLER,
 +                              acpi_ec_gpe_query, ec);
 +      }
 +      return 0;
 +}
 +
 +static int ec_poll(struct acpi_ec *ec)
 +{
 +      unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
 +      msleep(1);
 +      while (time_before(jiffies, delay)) {
 +              gpe_transaction(ec, acpi_ec_read_status(ec));
 +              msleep(1);
 +              if (ec_transaction_done(ec))
                        return 0;
        }
 -      pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
 -              acpi_ec_read_status(ec),
 -              (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
        return -ETIME;
  }
  
 -static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
 -                                      const u8 * wdata, unsigned wdata_len,
 -                                      u8 * rdata, unsigned rdata_len,
 +static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 +                                      struct transaction *t,
                                        int force_poll)
  {
 -      int result = 0;
 -      set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
 +      unsigned long tmp;
 +      int ret = 0;
        pr_debug(PREFIX "transaction start\n");
 -      acpi_ec_write_cmd(ec, command);
 -      for (; wdata_len > 0; --wdata_len) {
 -              result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
 -              if (result) {
 -                      pr_err(PREFIX
 -                             "write_cmd timeout, command = %d\n", command);
 -                      goto end;
 -              }
 -              set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
 -              acpi_ec_write_data(ec, *(wdata++));
 +      /* disable GPE during transaction if storm is detected */
 +      if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
 +              clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 +              acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
        }
 -
 -      if (!rdata_len) {
 -              result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
 -              if (result) {
 -                      pr_err(PREFIX
 -                             "finish-write timeout, command = %d\n", command);
 -                      goto end;
 -              }
 -      } else if (command == ACPI_EC_COMMAND_QUERY)
 +      /* start transaction */
 +      spin_lock_irqsave(&ec->curr_lock, tmp);
 +      /* following two actions should be kept atomic */
 +      t->irq_count = 0;
 +      ec->curr = t;
 +      acpi_ec_write_cmd(ec, ec->curr->command);
 +      if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
                clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 -
 -      for (; rdata_len > 0; --rdata_len) {
 -              result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
 -              if (result) {
 -                      pr_err(PREFIX "read timeout, command = %d\n", command);
 -                      goto end;
 -              }
 -              /* Don't expect GPE after last read */
 -              if (rdata_len > 1)
 -                      set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
 -              *(rdata++) = acpi_ec_read_data(ec);
 -      }
 -      end:
 +      spin_unlock_irqrestore(&ec->curr_lock, tmp);
 +      /* if we selected poll mode or failed in GPE-mode do a poll loop */
 +      if (force_poll ||
 +          !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
 +          acpi_ec_wait(ec))
 +              ret = ec_poll(ec);
        pr_debug(PREFIX "transaction end\n");
 -      return result;
 +      spin_lock_irqsave(&ec->curr_lock, tmp);
 +      ec->curr = NULL;
 +      spin_unlock_irqrestore(&ec->curr_lock, tmp);
 +      if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
 +              /* check if we received SCI during transaction */
 +              ec_check_sci(ec, acpi_ec_read_status(ec));
 +              /* it is safe to enable GPE outside of transaction */
 +              acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 +      } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
 +                 t->irq_count > ACPI_EC_STORM_THRESHOLD) {
 +              pr_debug(PREFIX "GPE storm detected\n");
 +              set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
 +      }
 +      return ret;
 +}
 +
 +static int ec_check_ibf0(struct acpi_ec *ec)
 +{
 +      u8 status = acpi_ec_read_status(ec);
 +      return (status & ACPI_EC_FLAG_IBF) == 0;
  }
  
 -static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
 -                             const u8 * wdata, unsigned wdata_len,
 -                             u8 * rdata, unsigned rdata_len,
 +static int ec_wait_ibf0(struct acpi_ec *ec)
 +{
 +      unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
 +      /* interrupt wait manually if GPE mode is not active */
 +      unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ?
 +              msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1);
 +      while (time_before(jiffies, delay))
 +              if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout))
 +                      return 0;
 +      return -ETIME;
 +}
 +
 +static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
                               int force_poll)
  {
        int status;
        u32 glk;
 -
 -      if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
 +      if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
                return -EINVAL;
 -
 -      if (rdata)
 -              memset(rdata, 0, rdata_len);
 -
 +      if (t->rdata)
 +              memset(t->rdata, 0, t->rlen);
        mutex_lock(&ec->lock);
        if (ec->global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status)) {
 -                      mutex_unlock(&ec->lock);
 -                      return -ENODEV;
 +                      status = -ENODEV;
 +                      goto unlock;
                }
        }
 -
 -      status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
 -      if (status) {
 +      if (ec_wait_ibf0(ec)) {
                pr_err(PREFIX "input buffer is not empty, "
                                "aborting transaction\n");
 +              status = -ETIME;
                goto end;
        }
 -
 -      status = acpi_ec_transaction_unlocked(ec, command,
 -                                            wdata, wdata_len,
 -                                            rdata, rdata_len,
 -                                            force_poll);
 -
 -      end:
 -
 +      status = acpi_ec_transaction_unlocked(ec, t, force_poll);
 +end:
        if (ec->global_lock)
                acpi_release_global_lock(glk);
 +unlock:
        mutex_unlock(&ec->lock);
 -
        return status;
  }
  
  int acpi_ec_burst_enable(struct acpi_ec *ec)
  {
        u8 d;
 -      return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1, 0);
 +      struct transaction t = {.command = ACPI_EC_BURST_ENABLE,
 +                              .wdata = NULL, .rdata = &d,
 +                              .wlen = 0, .rlen = 1};
 +
 +      return acpi_ec_transaction(ec, &t, 0);
  }
  
  int acpi_ec_burst_disable(struct acpi_ec *ec)
  {
 -      return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0, 0);
 +      struct transaction t = {.command = ACPI_EC_BURST_DISABLE,
 +                              .wdata = NULL, .rdata = NULL,
 +                              .wlen = 0, .rlen = 0};
 +
 +      return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
 +                              acpi_ec_transaction(ec, &t, 0) : 0;
  }
  
  static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
  {
        int result;
        u8 d;
 +      struct transaction t = {.command = ACPI_EC_COMMAND_READ,
 +                              .wdata = &address, .rdata = &d,
 +                              .wlen = 1, .rlen = 1};
  
 -      result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
 -                                   &address, 1, &d, 1, 0);
 +      result = acpi_ec_transaction(ec, &t, 0);
        *data = d;
        return result;
  }
  static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
  {
        u8 wdata[2] = { address, data };
 -      return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
 -                                 wdata, 2, NULL, 0, 0);
 +      struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
 +                              .wdata = wdata, .rdata = NULL,
 +                              .wlen = 2, .rlen = 0};
 +
 +      return acpi_ec_transaction(ec, &t, 0);
  }
  
  /*
@@@ -448,13 -412,12 +448,13 @@@ int ec_transaction(u8 command
                   u8 * rdata, unsigned rdata_len,
                   int force_poll)
  {
 +      struct transaction t = {.command = command,
 +                              .wdata = wdata, .rdata = rdata,
 +                              .wlen = wdata_len, .rlen = rdata_len};
        if (!first_ec)
                return -ENODEV;
  
 -      return acpi_ec_transaction(first_ec, command, wdata,
 -                                 wdata_len, rdata, rdata_len,
 -                                 force_poll);
 +      return acpi_ec_transaction(first_ec, &t, force_poll);
  }
  
  EXPORT_SYMBOL(ec_transaction);
@@@ -463,9 -426,7 +463,9 @@@ static int acpi_ec_query(struct acpi_e
  {
        int result;
        u8 d;
 -
 +      struct transaction t = {.command = ACPI_EC_COMMAND_QUERY,
 +                              .wdata = NULL, .rdata = &d,
 +                              .wlen = 0, .rlen = 1};
        if (!ec || !data)
                return -EINVAL;
  
         * bit to be cleared (and thus clearing the interrupt source).
         */
  
 -      result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1, 0);
 +      result = acpi_ec_transaction(ec, &t, 0);
        if (result)
                return result;
  
@@@ -552,26 -513,46 +552,26 @@@ static void acpi_ec_gpe_query(void *ec_
  
  static u32 acpi_ec_gpe_handler(void *data)
  {
 -      acpi_status status = AE_OK;
        struct acpi_ec *ec = data;
 -      u8 state = acpi_ec_read_status(ec);
 +      u8 status;
  
        pr_debug(PREFIX "~~~> interrupt\n");
 -      atomic_inc(&ec->irq_count);
 -      if (atomic_read(&ec->irq_count) > 5) {
 -              pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
 -              ec_switch_to_poll_mode(ec);
 -              goto end;
 -      }
 -      clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
 -      if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
 +      status = acpi_ec_read_status(ec);
 +
 +      gpe_transaction(ec, status);
 +      if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
                wake_up(&ec->wait);
  
 -      if (state & ACPI_EC_FLAG_SCI) {
 -              if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
 -                      status = acpi_os_execute(OSL_EC_BURST_HANDLER,
 -                              acpi_ec_gpe_query, ec);
 -      } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
 -                 !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
 -                 in_interrupt()) {
 +      ec_check_sci(ec, status);
 +      if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
 +          !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
                /* this is non-query, must be confirmation */
                if (printk_ratelimit())
                        pr_info(PREFIX "non-query interrupt received,"
                                " switching to interrupt mode\n");
                set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 -              clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
        }
 -end:
 -      ec_schedule_ec_poll(ec);
 -      return ACPI_SUCCESS(status) ?
 -          ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 -}
 -
 -static void do_ec_poll(struct work_struct *work)
 -{
 -      struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
 -      atomic_set(&ec->irq_count, 0);
 -      (void)acpi_ec_gpe_handler(ec);
 +      return ACPI_INTERRUPT_HANDLED;
  }
  
  /* --------------------------------------------------------------------------
@@@ -715,7 -696,8 +715,7 @@@ static struct acpi_ec *make_acpi_ec(voi
        mutex_init(&ec->lock);
        init_waitqueue_head(&ec->wait);
        INIT_LIST_HEAD(&ec->list);
 -      INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
 -      atomic_set(&ec->irq_count, 0);
 +      spin_lock_init(&ec->curr_lock);
        return ec;
  }
  
@@@ -736,6 -718,7 +736,7 @@@ static acpi_statu
  ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
  {
        acpi_status status;
+       unsigned long long tmp;
  
        struct acpi_ec *ec = context;
        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
  
        /* Get GPE bit assignment (EC events). */
        /* TODO: Add support for _GPE returning a package */
-       status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
+       status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
        if (ACPI_FAILURE(status))
                return status;
+       ec->gpe = tmp;
        /* Use the global lock for all EC transactions? */
-       acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+       acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
+       ec->global_lock = tmp;
        ec->handle = handle;
        return AE_CTRL_TERMINATE;
  }
  
 -static void ec_poll_stop(struct acpi_ec *ec)
 -{
 -      clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
 -      cancel_delayed_work(&ec->work);
 -}
 -
  static void ec_remove_handlers(struct acpi_ec *ec)
  {
 -      ec_poll_stop(ec);
        if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
                                ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
                pr_err(PREFIX "failed to remove space handler\n");
        if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
                                &acpi_ec_gpe_handler)))
                pr_err(PREFIX "failed to remove gpe handler\n");
 -      ec->handlers_installed = 0;
 +      clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
  }
  
  static int acpi_ec_add(struct acpi_device *device)
  
        if (!first_ec)
                first_ec = ec;
 -      acpi_driver_data(device) = ec;
 +      device->driver_data = ec;
        acpi_ec_add_fs(device);
        pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
                          ec->gpe, ec->command_addr, ec->data_addr);
@@@ -824,7 -816,7 +827,7 @@@ static int acpi_ec_remove(struct acpi_d
        }
        mutex_unlock(&ec->lock);
        acpi_ec_remove_fs(device);
 -      acpi_driver_data(device) = NULL;
 +      device->driver_data = NULL;
        if (ec == first_ec)
                first_ec = NULL;
        kfree(ec);
@@@ -857,36 -849,27 +860,36 @@@ ec_parse_io_ports(struct acpi_resource 
  static int ec_install_handlers(struct acpi_ec *ec)
  {
        acpi_status status;
 -      if (ec->handlers_installed)
 +      if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags))
                return 0;
        status = acpi_install_gpe_handler(NULL, ec->gpe,
 -                                        ACPI_GPE_EDGE_TRIGGERED,
 -                                        &acpi_ec_gpe_handler, ec);
 +                                ACPI_GPE_EDGE_TRIGGERED,
 +                                &acpi_ec_gpe_handler, ec);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 -
        acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
        acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 -
        status = acpi_install_address_space_handler(ec->handle,
                                                    ACPI_ADR_SPACE_EC,
                                                    &acpi_ec_space_handler,
                                                    NULL, ec);
        if (ACPI_FAILURE(status)) {
 -              acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
 -              return -ENODEV;
 +              if (status == AE_NOT_FOUND) {
 +                      /*
 +                       * Maybe OS fails in evaluating the _REG object.
 +                       * The AE_NOT_FOUND error will be ignored and OS
 +                       * continue to initialize EC.
 +                       */
 +                      printk(KERN_ERR "Fail in evaluating the _REG object"
 +                              " of EC device. Broken bios is suspected.\n");
 +              } else {
 +                      acpi_remove_gpe_handler(NULL, ec->gpe,
 +                              &acpi_ec_gpe_handler);
 +                      return -ENODEV;
 +              }
        }
  
 -      ec->handlers_installed = 1;
 +      set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
        return 0;
  }
  
@@@ -907,6 -890,7 +910,6 @@@ static int acpi_ec_start(struct acpi_de
  
        /* EC is fully operational, allow queries */
        clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 -      ec_schedule_ec_poll(ec);
        return ret;
  }
  
@@@ -925,7 -909,7 +928,7 @@@ static int acpi_ec_stop(struct acpi_dev
  
  int __init acpi_boot_ec_enable(void)
  {
 -      if (!boot_ec || boot_ec->handlers_installed)
 +      if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags))
                return 0;
        if (!ec_install_handlers(boot_ec)) {
                first_ec = boot_ec;
diff --combined drivers/acpi/osl.c
index 6234d3e7acd33e1e4e5f5e31c1c97446454f2abd,f58fcbbc810df05e90b32e1a2ab47beccd22d2ff..4be252145cb45320cf82b14c4e579c525bf2776e
@@@ -608,7 -608,7 +608,7 @@@ static void acpi_os_derive_pci_id_2(acp
        acpi_handle handle;
        struct acpi_pci_id *pci_id = *id;
        acpi_status status;
-       unsigned long temp;
+       unsigned long long temp;
        acpi_object_type type;
  
        acpi_get_parent(chandle, &handle);
                if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
                        return;
  
-               status =
-                   acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
+               status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
                                          &temp);
                if (ACPI_SUCCESS(status)) {
                        u32 val;
@@@ -682,22 -681,6 +681,22 @@@ static void acpi_os_execute_deferred(st
        return;
  }
  
 +static void acpi_os_execute_hp_deferred(struct work_struct *work)
 +{
 +      struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
 +      if (!dpc) {
 +              printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
 +              return;
 +      }
 +
 +      acpi_os_wait_events_complete(NULL);
 +
 +      dpc->function(dpc->context);
 +      kfree(dpc);
 +
 +      return;
 +}
 +
  /*******************************************************************************
   *
   * FUNCTION:    acpi_os_execute
   *
   ******************************************************************************/
  
 -acpi_status acpi_os_execute(acpi_execute_type type,
 -                          acpi_osd_exec_callback function, void *context)
 +static acpi_status __acpi_os_execute(acpi_execute_type type,
 +      acpi_osd_exec_callback function, void *context, int hp)
  {
        acpi_status status = AE_OK;
        struct acpi_os_dpc *dpc;
        struct workqueue_struct *queue;
 +      int ret;
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                          "Scheduling function [%p(%p)] for deferred execution.\n",
                          function, context));
        dpc->function = function;
        dpc->context = context;
  
 -      INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 -      queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
 -      if (!queue_work(queue, &dpc->work)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 -                        "Call to queue_work() failed.\n"));
 +      if (!hp) {
 +              INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 +              queue = (type == OSL_NOTIFY_HANDLER) ?
 +                      kacpi_notify_wq : kacpid_wq;
 +              ret = queue_work(queue, &dpc->work);
 +      } else {
 +              INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred);
 +              ret = schedule_work(&dpc->work);
 +      }
 +
 +      if (!ret) {
 +              printk(KERN_ERR PREFIX
 +                        "Call to queue_work() failed.\n");
                status = AE_ERROR;
                kfree(dpc);
        }
        return_ACPI_STATUS(status);
  }
  
 +acpi_status acpi_os_execute(acpi_execute_type type,
 +                          acpi_osd_exec_callback function, void *context)
 +{
 +      return __acpi_os_execute(type, function, context, 0);
 +}
  EXPORT_SYMBOL(acpi_os_execute);
  
 +acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
 +      void *context)
 +{
 +      return __acpi_os_execute(0, function, context, 1);
 +}
 +
  void acpi_os_wait_events_complete(void *context)
  {
        flush_workqueue(kacpid_wq);
diff --combined drivers/acpi/pci_root.c
index add1a19bbbfe8ecba3b0e5e6ce63962196c65a92,18ff4e5c8d814c515d1a6bd1c5466186a00bfdec..1b8f67d21d539c427f29ef2b60b34c922e780abd
@@@ -190,7 -190,7 +190,7 @@@ static int __devinit acpi_pci_root_add(
        struct acpi_pci_root *root = NULL;
        struct acpi_pci_root *tmp;
        acpi_status status = AE_OK;
-       unsigned long value = 0;
+       unsigned long long value = 0;
        acpi_handle handle = NULL;
        struct acpi_device *child;
  
        root->device = device;
        strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
 -      acpi_driver_data(device) = root;
 +      device->driver_data = root;
  
        device->ops.bind = acpi_pci_bind;
  
diff --combined drivers/acpi/power.c
index e88edc008668b14a8ac6216b8bf98a45a89932e1,89e5d2a8c33a00e16272b676f9007d93c81a6fea..a1718e56103b33b5da9909b23727c4474611f90f
@@@ -54,14 -54,6 +54,14 @@@ ACPI_MODULE_NAME("power")
  #define ACPI_POWER_RESOURCE_STATE_OFF 0x00
  #define ACPI_POWER_RESOURCE_STATE_ON  0x01
  #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 +
 +#ifdef MODULE_PARAM_PREFIX
 +#undef MODULE_PARAM_PREFIX
 +#endif
 +#define MODULE_PARAM_PREFIX "acpi."
 +int acpi_power_nocheck;
 +module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
 +
  static int acpi_power_add(struct acpi_device *device);
  static int acpi_power_remove(struct acpi_device *device, int type);
  static int acpi_power_resume(struct acpi_device *device);
@@@ -136,16 -128,16 +136,16 @@@ acpi_power_get_context(acpi_handle hand
        return 0;
  }
  
 -static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
 +static int acpi_power_get_state(acpi_handle handle, int *state)
  {
        acpi_status status = AE_OK;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
  
  
 -      if (!resource || !state)
 +      if (!handle || !state)
                return -EINVAL;
  
 -      status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
 +      status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
                              ACPI_POWER_RESOURCE_STATE_OFF;
  
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
 -                        resource->name, state ? "on" : "off"));
 +                        acpi_ut_get_node_name(handle), state ? "on" : "off"));
  
        return 0;
  }
  static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
  {
        int result = 0, state1;
 -      struct acpi_power_resource *resource = NULL;
        u32 i = 0;
  
  
                return -EINVAL;
  
        /* The state of the list is 'on' IFF all resources are 'on'. */
 +      /* */
  
        for (i = 0; i < list->count; i++) {
 -              result = acpi_power_get_context(list->handles[i], &resource);
 -              if (result)
 -                      return result;
 -              result = acpi_power_get_state(resource, &state1);
 +              /*
 +               * The state of the power resource can be obtained by
 +               * using the ACPI handle. In such case it is unnecessary to
 +               * get the Power resource first and then get its state again.
 +               */
 +              result = acpi_power_get_state(list->handles[i], &state1);
                if (result)
                        return result;
  
@@@ -236,18 -226,12 +236,18 @@@ static int acpi_power_on(acpi_handle ha
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
 -      result = acpi_power_get_state(resource, &state);
 -      if (result)
 -              return result;
 -      if (state != ACPI_POWER_RESOURCE_STATE_ON)
 -              return -ENOEXEC;
 -
 +      if (!acpi_power_nocheck) {
 +              /*
 +               * If acpi_power_nocheck is set, it is unnecessary to check
 +               * the power state after power transition.
 +               */
 +              result = acpi_power_get_state(resource->device->handle,
 +                              &state);
 +              if (result)
 +                      return result;
 +              if (state != ACPI_POWER_RESOURCE_STATE_ON)
 +                      return -ENOEXEC;
 +      }
        /* Update the power resource's _device_ power state */
        resource->device->power.state = ACPI_STATE_D0;
  
@@@ -293,17 -277,11 +293,17 @@@ static int acpi_power_off_device(acpi_h
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
 -      result = acpi_power_get_state(resource, &state);
 -      if (result)
 -              return result;
 -      if (state != ACPI_POWER_RESOURCE_STATE_OFF)
 -              return -ENOEXEC;
 +      if (!acpi_power_nocheck) {
 +              /*
 +               * If acpi_power_nocheck is set, it is unnecessary to check
 +               * the power state after power transition.
 +               */
 +              result = acpi_power_get_state(handle, &state);
 +              if (result)
 +                      return result;
 +              if (state != ACPI_POWER_RESOURCE_STATE_OFF)
 +                      return -ENOEXEC;
 +      }
  
        /* Update the power resource's _device_ power state */
        resource->device->power.state = ACPI_STATE_D3;
@@@ -577,7 -555,7 +577,7 @@@ static int acpi_power_seq_show(struct s
        if (!resource)
                goto end;
  
 -      result = acpi_power_get_state(resource, &state);
 +      result = acpi_power_get_state(resource->device->handle, &state);
        if (result)
                goto end;
  
@@@ -679,7 -657,7 +679,7 @@@ static int acpi_power_add(struct acpi_d
        strcpy(resource->name, device->pnp.bus_id);
        strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
 -      acpi_driver_data(device) = resource;
 +      device->driver_data = resource;
  
        /* Evalute the object to get the system level and resource order. */
        status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
        resource->system_level = acpi_object.power_resource.system_level;
        resource->order = acpi_object.power_resource.resource_order;
  
 -      result = acpi_power_get_state(resource, &state);
 +      result = acpi_power_get_state(device->handle, &state);
        if (result)
                goto end;
  
@@@ -755,9 -733,9 +755,9 @@@ static int acpi_power_resume(struct acp
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      resource = (struct acpi_power_resource *)acpi_driver_data(device);
 +      resource = acpi_driver_data(device);
  
 -      result = acpi_power_get_state(resource, &state);
 +      result = acpi_power_get_state(device->handle, &state);
        if (result)
                return result;
  
index 289461649196b7e2cf5cf1b34d0683aadfe901ee,8a2787141f80e0d5af852a73f3ce2fad44f04b7a..24a362f8034c49a722005efec417714560b5b9cf
@@@ -563,7 -563,7 +563,7 @@@ static int acpi_processor_get_info(stru
  
        /* Check if it is a Device with HID and UID */
        if (has_uid) {
-               unsigned long value;
+               unsigned long long value;
                status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
                                                NULL, &value);
                if (ACPI_FAILURE(status)) {
@@@ -818,7 -818,7 +818,7 @@@ static int acpi_processor_add(struct ac
        pr->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
 -      acpi_driver_data(device) = pr;
 +      device->driver_data = pr;
  
        return 0;
  }
@@@ -875,7 -875,7 +875,7 @@@ static int acpi_processor_remove(struc
  static int is_processor_present(acpi_handle handle)
  {
        acpi_status status;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
  
  
        status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
index b0614f3794705c0286a3d6e8381db1a7c1809857,f8129c7277f1840582a4b4e8d84aefd221edb000..dc98f7a6f2c49bfb701716f330fc70dff13012a5
@@@ -38,7 -38,6 +38,7 @@@
  
  #include <asm/uaccess.h>
  #endif
 +#include <asm/cpufeature.h>
  
  #include <acpi/acpi_bus.h>
  #include <acpi/processor.h>
@@@ -127,7 -126,7 +127,7 @@@ static struct notifier_block acpi_ppc_n
  static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
  {
        acpi_status status = 0;
-       unsigned long ppc = 0;
+       unsigned long long ppc = 0;
  
  
        if (!pr)
@@@ -335,6 -334,7 +335,6 @@@ static int acpi_processor_get_performan
        acpi_status status = AE_OK;
        acpi_handle handle = NULL;
  
 -
        if (!pr || !pr->performance || !pr->handle)
                return -EINVAL;
  
  
        result = acpi_processor_get_performance_control(pr);
        if (result)
 -              return result;
 +              goto update_bios;
  
        result = acpi_processor_get_performance_states(pr);
        if (result)
 -              return result;
 +              goto update_bios;
  
        return 0;
 +
 +      /*
 +       * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
 +       * the BIOS is older than the CPU and does not know its frequencies
 +       */
 + update_bios:
 +      if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
 +              if(boot_cpu_has(X86_FEATURE_EST))
 +                      printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
 +                             "frequency support\n");
 +      }
 +      return result;
  }
  
  int acpi_processor_notify_smm(struct module *calling_module)
@@@ -536,13 -524,13 +536,13 @@@ static int acpi_processor_get_psd(struc
  
        psd = buffer.pointer;
        if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
 +              printk(KERN_ERR PREFIX "Invalid _PSD data\n");
                result = -EFAULT;
                goto end;
        }
  
        if (psd->package.count != 1) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
 +              printk(KERN_ERR PREFIX "Invalid _PSD data\n");
                result = -EFAULT;
                goto end;
        }
        status = acpi_extract_package(&(psd->package.elements[0]),
                &format, &state);
        if (ACPI_FAILURE(status)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
 +              printk(KERN_ERR PREFIX "Invalid _PSD data\n");
                result = -EFAULT;
                goto end;
        }
  
        if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n"));
 +              printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
                result = -EFAULT;
                goto end;
        }
  
        if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n"));
 +              printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
                result = -EFAULT;
                goto end;
        }
index e89a25824f2a1244eff5bdb7c5e00467b2f48a5d,3097b752003d44a92053a18af05e9edf645f19e2..3da2df93d924ddf534af4e24d16fd635f3c6ef3c
@@@ -274,7 -274,7 +274,7 @@@ static int acpi_processor_throttling_no
  static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
  {
        acpi_status status = 0;
-       unsigned long tpc = 0;
+       unsigned long long tpc = 0;
  
        if (!pr)
                return -EINVAL;
@@@ -528,13 -528,13 +528,13 @@@ static int acpi_processor_get_tsd(struc
  
        tsd = buffer.pointer;
        if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
 +              printk(KERN_ERR PREFIX "Invalid _TSD data\n");
                result = -EFAULT;
                goto end;
        }
  
        if (tsd->package.count != 1) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
 +              printk(KERN_ERR PREFIX "Invalid _TSD data\n");
                result = -EFAULT;
                goto end;
        }
        status = acpi_extract_package(&(tsd->package.elements[0]),
                                      &format, &state);
        if (ACPI_FAILURE(status)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
 +              printk(KERN_ERR PREFIX "Invalid _TSD data\n");
                result = -EFAULT;
                goto end;
        }
  
        if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n"));
 +              printk(KERN_ERR PREFIX "Unknown _TSD:num_entries\n");
                result = -EFAULT;
                goto end;
        }
  
        if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n"));
 +              printk(KERN_ERR PREFIX "Unknown _TSD:revision\n");
                result = -EFAULT;
                goto end;
        }
diff --combined drivers/acpi/sbshc.c
index 001d9143a2cb18923b2f56695e2a6fc6681cdcb7,81d23d38ec915d0161881342bf4634ccf8ccf657..e53e590252c01346e09ab317d6595cc218d3a72f
@@@ -258,7 -258,7 +258,7 @@@ extern int acpi_ec_add_query_handler(st
  static int acpi_smbus_hc_add(struct acpi_device *device)
  {
        int status;
-       unsigned long val;
+       unsigned long long val;
        struct acpi_smb_hc *hc;
  
        if (!device)
        hc->ec = acpi_driver_data(device->parent);
        hc->offset = (val >> 8) & 0xff;
        hc->query_bit = val & 0xff;
 -      acpi_driver_data(device) = hc;
 +      device->driver_data = hc;
  
        acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
        printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
@@@ -303,7 -303,7 +303,7 @@@ static int acpi_smbus_hc_remove(struct 
        hc = acpi_driver_data(device);
        acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
        kfree(hc);
 -      acpi_driver_data(device) = NULL;
 +      device->driver_data = NULL;
        return 0;
  }
  
index cc344d4252c94d4da031480a4f8ee88448b75458,b32ba565e69edcfbf9d7a5db26d1a12b3ae78c1b..76037883cd13d25a8b3d8e7446c8fa8bb1ad12fd
@@@ -15,7 -15,6 +15,7 @@@
  #include <linux/dmi.h>
  #include <linux/device.h>
  #include <linux/suspend.h>
 +#include <linux/reboot.h>
  
  #include <asm/io.h>
  
  #include "sleep.h"
  
  u8 sleep_states[ACPI_S_STATE_COUNT];
 +static u32 acpi_target_sleep_state = ACPI_STATE_S0;
 +
 +static void acpi_sleep_tts_switch(u32 acpi_state)
 +{
 +      union acpi_object in_arg = { ACPI_TYPE_INTEGER };
 +      struct acpi_object_list arg_list = { 1, &in_arg };
 +      acpi_status status = AE_OK;
 +
 +      in_arg.integer.value = acpi_state;
 +      status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL);
 +      if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 +              /*
 +               * OS can't evaluate the _TTS object correctly. Some warning
 +               * message will be printed. But it won't break anything.
 +               */
 +              printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
 +      }
 +}
 +
 +static int tts_notify_reboot(struct notifier_block *this,
 +                      unsigned long code, void *x)
 +{
 +      acpi_sleep_tts_switch(ACPI_STATE_S5);
 +      return NOTIFY_DONE;
 +}
 +
 +static struct notifier_block tts_notifier = {
 +      .notifier_call  = tts_notify_reboot,
 +      .next           = NULL,
 +      .priority       = 0,
 +};
  
  static int acpi_sleep_prepare(u32 acpi_state)
  {
@@@ -77,7 -45,9 +77,7 @@@
        return 0;
  }
  
 -#ifdef CONFIG_PM_SLEEP
 -static u32 acpi_target_sleep_state = ACPI_STATE_S0;
 -
 +#ifdef CONFIG_ACPI_SLEEP
  /*
   * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
   * user to request that behavior by using the 'acpi_old_suspend_ordering'
@@@ -161,9 -131,8 +161,9 @@@ static void acpi_pm_end(void
         * failing transition to a sleep state.
         */
        acpi_target_sleep_state = ACPI_STATE_S0;
 +      acpi_sleep_tts_switch(acpi_target_sleep_state);
  }
 -#endif /* CONFIG_PM_SLEEP */
 +#endif /* CONFIG_ACPI_SLEEP */
  
  #ifdef CONFIG_SUSPEND
  extern void do_suspend_lowlevel(void);
@@@ -186,7 -155,6 +186,7 @@@ static int acpi_suspend_begin(suspend_s
  
        if (sleep_states[acpi_state]) {
                acpi_target_sleep_state = acpi_state;
 +              acpi_sleep_tts_switch(acpi_target_sleep_state);
        } else {
                printk(KERN_ERR "ACPI does not support this state: %d\n",
                        pm_state);
@@@ -232,8 -200,6 +232,8 @@@ static int acpi_suspend_enter(suspend_s
                break;
        }
  
 +      /* If ACPI is not enabled by the BIOS, we need to enable it here. */
 +      acpi_enable();
        /* Reprogram control registers and execute _BFS */
        acpi_leave_sleep_state_prep(acpi_state);
  
@@@ -330,14 -296,6 +330,14 @@@ static struct dmi_system_id __initdata 
                DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
                },
        },
 +      {
 +      .callback = init_old_suspend_ordering,
 +      .ident = "HP xw4600 Workstation",
 +      .matches = {
 +              DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 +              DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
 +              },
 +      },
        {},
  };
  #endif /* CONFIG_SUSPEND */
@@@ -355,7 -313,6 +355,7 @@@ void __init acpi_no_s4_hw_signature(voi
  static int acpi_hibernation_begin(void)
  {
        acpi_target_sleep_state = ACPI_STATE_S4;
 +      acpi_sleep_tts_switch(acpi_target_sleep_state);
        return 0;
  }
  
@@@ -419,15 -376,7 +419,15 @@@ static struct platform_hibernation_ops 
   */
  static int acpi_hibernation_begin_old(void)
  {
 -      int error = acpi_sleep_prepare(ACPI_STATE_S4);
 +      int error;
 +      /*
 +       * The _TTS object should always be evaluated before the _PTS object.
 +       * When the old_suspended_ordering is true, the _PTS object is
 +       * evaluated in the acpi_sleep_prepare.
 +       */
 +      acpi_sleep_tts_switch(ACPI_STATE_S4);
 +
 +      error = acpi_sleep_prepare(ACPI_STATE_S4);
  
        if (!error)
                acpi_target_sleep_state = ACPI_STATE_S4;
@@@ -495,7 -444,7 +495,7 @@@ int acpi_pm_device_sleep_state(struct d
        acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
        struct acpi_device *adev;
        char acpi_method[] = "_SxD";
-       unsigned long d_min, d_max;
+       unsigned long long d_min, d_max;
  
        if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
                printk(KERN_DEBUG "ACPI handle has no context!\n");
@@@ -647,10 -596,5 +647,10 @@@ int __init acpi_sleep_init(void
                pm_power_off = acpi_power_off;
        }
        printk(")\n");
 +      /*
 +       * Register the tts_notifier to reboot notifier list so that the _TTS
 +       * object can also be evaluated when the system enters S5.
 +       */
 +      register_reboot_notifier(&tts_notifier);
        return 0;
  }
diff --combined drivers/acpi/thermal.c
index f26c6463a09eca4d6d94506402a5628faca41b50,47abb94bdfb96c2ac0140f44eb4ac922f30d460f..ad6cae938f0b8cabfff04f305c577f0970bd1cb8
@@@ -246,18 -246,18 +246,18 @@@ static const struct file_operations acp
  static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
  {
        acpi_status status = AE_OK;
+       unsigned long long tmp;
  
        if (!tz)
                return -EINVAL;
  
        tz->last_temperature = tz->temperature;
  
-       status =
-           acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature);
+       status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
+       tz->temperature = tmp;
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
                          tz->temperature));
  
  static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
  {
        acpi_status status = AE_OK;
+       unsigned long long tmp;
  
        if (!tz)
                return -EINVAL;
  
-       status =
-           acpi_evaluate_integer(tz->device->handle, "_TZP", NULL,
-                                 &tz->polling_frequency);
+       status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
+       tz->polling_frequency = tmp;
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
                          tz->polling_frequency));
  
@@@ -356,6 -355,7 +355,7 @@@ do {       
  static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
  {
        acpi_status status = AE_OK;
+       unsigned long long tmp;
        struct acpi_handle_list devices;
        int valid = 0;
        int i;
        /* Critical Shutdown (required) */
        if (flag & ACPI_TRIPS_CRITICAL) {
                status = acpi_evaluate_integer(tz->device->handle,
-                               "_CRT", NULL, &tz->trips.critical.temperature);
+                               "_CRT", NULL, &tmp);
+               tz->trips.critical.temperature = tmp;
                /*
                 * Treat freezing temperatures as invalid as well; some
                 * BIOSes return really low values and cause reboots at startup.
                        } else if (crt > 0) {
                                unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
                                /*
 -                               * Allow override to lower critical threshold
 +                               * Allow override critical threshold
                                 */
 -                              if (crt_k < tz->trips.critical.temperature)
 -                                      tz->trips.critical.temperature = crt_k;
 +                              if (crt_k > tz->trips.critical.temperature)
 +                                      printk(KERN_WARNING PREFIX
 +                                              "Critical threshold %d C\n", crt);
 +                              tz->trips.critical.temperature = crt_k;
                        }
                }
        }
        /* Critical Sleep (optional) */
        if (flag & ACPI_TRIPS_HOT) {
                status = acpi_evaluate_integer(tz->device->handle,
-                               "_HOT", NULL, &tz->trips.hot.temperature);
+                               "_HOT", NULL, &tmp);
                if (ACPI_FAILURE(status)) {
                        tz->trips.hot.flags.valid = 0;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                        "No hot threshold\n"));
                } else {
+                       tz->trips.hot.temperature = tmp;
                        tz->trips.hot.flags.valid = 1;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                        "Found hot threshold [%lu]\n",
                if (psv == -1) {
                        status = AE_SUPPORT;
                } else if (psv > 0) {
-                       tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv);
+                       tmp = CELSIUS_TO_KELVIN(psv);
                        status = AE_OK;
                } else {
                        status = acpi_evaluate_integer(tz->device->handle,
-                               "_PSV", NULL, &tz->trips.passive.temperature);
+                               "_PSV", NULL, &tmp);
                }
  
                if (ACPI_FAILURE(status))
                        tz->trips.passive.flags.valid = 0;
                else {
+                       tz->trips.passive.temperature = tmp;
                        tz->trips.passive.flags.valid = 1;
                        if (flag == ACPI_TRIPS_INIT) {
                                status = acpi_evaluate_integer(
                                                tz->device->handle, "_TC1",
-                                               NULL, &tz->trips.passive.tc1);
+                                               NULL, &tmp);
                                if (ACPI_FAILURE(status))
                                        tz->trips.passive.flags.valid = 0;
+                               else
+                                       tz->trips.passive.tc1 = tmp;
                                status = acpi_evaluate_integer(
                                                tz->device->handle, "_TC2",
-                                               NULL, &tz->trips.passive.tc2);
+                                               NULL, &tmp);
                                if (ACPI_FAILURE(status))
                                        tz->trips.passive.flags.valid = 0;
+                               else
+                                       tz->trips.passive.tc2 = tmp;
                                status = acpi_evaluate_integer(
                                                tz->device->handle, "_TSP",
-                                               NULL, &tz->trips.passive.tsp);
+                                               NULL, &tmp);
                                if (ACPI_FAILURE(status))
                                        tz->trips.passive.flags.valid = 0;
+                               else
+                                       tz->trips.passive.tsp = tmp;
                        }
                }
        }
  
                if (flag & ACPI_TRIPS_ACTIVE) {
                        status = acpi_evaluate_integer(tz->device->handle,
-                               name, NULL, &tz->trips.active[i].temperature);
+                                                       name, NULL, &tmp);
                        if (ACPI_FAILURE(status)) {
                                tz->trips.active[i].flags.valid = 0;
                                if (i == 0)
                                                tz->trips.active[i - 2].temperature :
                                                CELSIUS_TO_KELVIN(act));
                                break;
-                       } else
+                       } else {
+                               tz->trips.active[i].temperature = tmp;
                                tz->trips.active[i].flags.valid = 1;
+                       }
                }
  
                name[2] = 'L';
@@@ -1215,8 -1224,8 +1226,8 @@@ static int acpi_thermal_register_therma
                                  acpi_bus_private_data_handler,
                                  tz->thermal_zone);
        if (ACPI_FAILURE(status)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 -                              "Error attaching device data\n"));
 +              printk(KERN_ERR PREFIX
 +                              "Error attaching device data\n");
                return -ENODEV;
        }
  
@@@ -1649,7 -1658,7 +1660,7 @@@ static int acpi_thermal_add(struct acpi
        strcpy(tz->name, device->pnp.bus_id);
        strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
 -      acpi_driver_data(device) = tz;
 +      device->driver_data = tz;
        mutex_init(&tz->lock);
  
  
diff --combined drivers/acpi/video.c
index 59fd299bb3d758a23f3b1c7b0d9da9fa5189de13,79409c9d2ad6f5e3499ac3ccfc533731ccd73444..a29b0ccac65aa05c8e739526a27ea2b6e09e31b9
@@@ -291,20 -291,20 +291,20 @@@ static int acpi_video_device_lcd_set_le
                        int level);
  static int acpi_video_device_lcd_get_level_current(
                        struct acpi_video_device *device,
-                       unsigned long *level);
+                       unsigned long long *level);
  static int acpi_video_get_next_level(struct acpi_video_device *device,
                                     u32 level_current, u32 event);
  static void acpi_video_switch_brightness(struct acpi_video_device *device,
                                         int event);
  static int acpi_video_device_get_state(struct acpi_video_device *device,
-                           unsigned long *state);
+                           unsigned long long *state);
  static int acpi_video_output_get(struct output_device *od);
  static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
  
  /*backlight device sysfs support*/
  static int acpi_video_get_brightness(struct backlight_device *bd)
  {
-       unsigned long cur_level;
+       unsigned long long cur_level;
        int i;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)bl_get_data(bd);
@@@ -336,7 -336,7 +336,7 @@@ static struct backlight_ops acpi_backli
  /*video output device sysfs support*/
  static int acpi_video_output_get(struct output_device *od)
  {
-       unsigned long state;
+       unsigned long long state;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)dev_get_drvdata(&od->dev);
        acpi_video_device_get_state(vd, &state);
@@@ -370,7 -370,7 +370,7 @@@ static int video_get_cur_state(struct t
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
-       unsigned long level;
+       unsigned long long level;
        int state;
  
        acpi_video_device_lcd_get_level_current(video, &level);
@@@ -410,7 -410,7 +410,7 @@@ static struct thermal_cooling_device_op
  /* device */
  
  static int
- acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
+ acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state)
  {
        int status;
  
  
  static int
  acpi_video_device_get_state(struct acpi_video_device *device,
-                           unsigned long *state)
+                           unsigned long long *state)
  {
        int status;
  
@@@ -436,7 -436,7 +436,7 @@@ acpi_video_device_set_state(struct acpi
        int status;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
-       unsigned long ret;
+       unsigned long long ret;
  
  
        arg0.integer.value = state;
@@@ -495,7 -495,7 +495,7 @@@ acpi_video_device_lcd_set_level(struct 
  
  static int
  acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
-                                       unsigned long *level)
+                                       unsigned long long *level)
  {
        if (device->cap._BQC)
                return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
@@@ -549,7 -549,7 +549,7 @@@ static in
  acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
  {
        int status;
-       unsigned long tmp;
+       unsigned long long tmp;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
  
  }
  
  static int
- acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
+ acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
  {
        int status;
  
  
  static int
  acpi_video_bus_POST_options(struct acpi_video_bus *video,
-                           unsigned long *options)
+                           unsigned long long *options)
  {
        int status;
  
@@@ -918,7 -918,7 +918,7 @@@ static int acpi_video_device_state_seq_
  {
        int status;
        struct acpi_video_device *dev = seq->private;
-       unsigned long state;
+       unsigned long long state;
  
  
        if (!dev)
        status = acpi_video_device_get_state(dev, &state);
        seq_printf(seq, "state:     ");
        if (ACPI_SUCCESS(status))
-               seq_printf(seq, "0x%02lx\n", state);
+               seq_printf(seq, "0x%02llx\n", state);
        else
                seq_printf(seq, "<not supported>\n");
  
        status = acpi_video_device_query(dev, &state);
        seq_printf(seq, "query:     ");
        if (ACPI_SUCCESS(status))
-               seq_printf(seq, "0x%02lx\n", state);
+               seq_printf(seq, "0x%02llx\n", state);
        else
                seq_printf(seq, "<not supported>\n");
  
@@@ -1217,7 -1217,7 +1217,7 @@@ static int acpi_video_bus_ROM_open_fs(s
  static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
  {
        struct acpi_video_bus *video = seq->private;
-       unsigned long options;
+       unsigned long long options;
        int status;
  
  
                        printk(KERN_WARNING PREFIX
                               "This indicates a BIOS bug. Please contact the manufacturer.\n");
                }
-               printk("%lx\n", options);
+               printk("%llx\n", options);
                seq_printf(seq, "can POST: <integrated video>");
                if (options & 2)
                        seq_printf(seq, " <PCI video>");
@@@ -1256,7 -1256,7 +1256,7 @@@ static int acpi_video_bus_POST_seq_show
  {
        struct acpi_video_bus *video = seq->private;
        int status;
-       unsigned long id;
+       unsigned long long id;
  
  
        if (!video)
@@@ -1303,7 -1303,7 +1303,7 @@@ acpi_video_bus_write_POST(struct file *
        struct seq_file *m = file->private_data;
        struct acpi_video_bus *video = m->private;
        char str[12] = { 0 };
-       unsigned long opt, options;
+       unsigned long long opt, options;
  
  
        if (!video || count + 1 > sizeof str)
@@@ -1473,7 -1473,7 +1473,7 @@@ static in
  acpi_video_bus_get_one_device(struct acpi_device *device,
                              struct acpi_video_bus *video)
  {
-       unsigned long device_id;
+       unsigned long long device_id;
        int status;
        struct acpi_video_device *data;
        struct acpi_video_device_attrib* attribute;
  
                strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
                strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
 -              acpi_driver_data(device) = data;
 +              device->driver_data = data;
  
                data->device_id = device_id;
                data->video = video;
                                                     acpi_video_device_notify,
                                                     data);
                if (ACPI_FAILURE(status)) {
 -                      ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 -                                        "Error installing notify handler\n"));
 +                      printk(KERN_ERR PREFIX
 +                                        "Error installing notify handler\n");
                        if(data->brightness)
                                kfree(data->brightness->levels);
                        kfree(data->brightness);
@@@ -1724,7 -1724,7 +1724,7 @@@ acpi_video_get_next_level(struct acpi_v
  static void
  acpi_video_switch_brightness(struct acpi_video_device *device, int event)
  {
-       unsigned long level_current, level_next;
+       unsigned long long level_current, level_next;
        if (!device->brightness)
                return;
        acpi_video_device_lcd_get_level_current(device, &level_current);
@@@ -1745,8 -1745,8 +1745,8 @@@ acpi_video_bus_get_devices(struct acpi_
  
                status = acpi_video_bus_get_one_device(dev, video);
                if (ACPI_FAILURE(status)) {
 -                      ACPI_DEBUG_PRINT((ACPI_DB_WARN,
 -                                      "Cant attach device"));
 +                      printk(KERN_WARNING PREFIX
 +                                      "Cant attach device");
                        continue;
                }
        }
@@@ -1982,7 -1982,7 +1982,7 @@@ static int acpi_video_bus_add(struct ac
        video->device = device;
        strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
        strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
 -      acpi_driver_data(device) = video;
 +      device->driver_data = video;
  
        acpi_video_bus_find_cap(video);
        error = acpi_video_bus_check(video);
                                             ACPI_DEVICE_NOTIFY,
                                             acpi_video_bus_notify, video);
        if (ACPI_FAILURE(status)) {
 -              ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 -                                "Error installing notify handler\n"));
 +              printk(KERN_ERR PREFIX
 +                                "Error installing notify handler\n");
                error = -ENODEV;
                goto err_stop_video;
        }
        acpi_video_bus_remove_fs(device);
   err_free_video:
        kfree(video);
 -      acpi_driver_data(device) = NULL;
 +      device->driver_data = NULL;
  
        return error;
  }
index 57d81c713eab24e59e4981212fb21b1422055dab,967ecec825772a0771b8e6f6056e2539def8c81c..a9d5228724a6950d6e7cc42d70ab8ddfab2bdd05
@@@ -139,7 -139,6 +139,7 @@@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBR
            "\\_SB.PCI0.PX40.ECD0._Q10",        /* L3C */
            "\\_SB.PCI0.PX40.EC0.Q10",  /* M1A */
            "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */
 +          "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
            "\\_SB.PCI0.PX40.Q10",      /* S1x */
            "\\Q10");           /* A2x, L2D, L3D, M2E */
  
@@@ -281,7 -280,7 +281,7 @@@ static int write_acpi_int(acpi_handle h
  
  static int read_wireless_status(int mask)
  {
-       ulong status;
+       unsigned long long status;
        acpi_status rv = AE_OK;
  
        if (!wireless_status_handle)
  
  static int read_gps_status(void)
  {
-       ulong status;
+       unsigned long long status;
        acpi_status rv = AE_OK;
  
        rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status);
@@@ -351,7 -350,7 +351,7 @@@ static void write_status(acpi_handle ha
        static void object##_led_set(struct led_classdev *led_cdev,     \
                                     enum led_brightness value)         \
        {                                                               \
 -              object##_led_wk = value;                                \
 +              object##_led_wk = (value > 0) ? 1 : 0;                  \
                queue_work(led_workqueue, &object##_led_work);          \
        }                                                               \
        static void object##_led_update(struct work_struct *ignored)    \
@@@ -405,7 -404,7 +405,7 @@@ static void lcd_blank(int blank
  
  static int read_brightness(struct backlight_device *bd)
  {
-       ulong value;
+       unsigned long long value;
        acpi_status rv = AE_OK;
  
        rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
@@@ -456,7 -455,7 +456,7 @@@ static ssize_t show_infos(struct devic
                          struct device_attribute *attr, char *page)
  {
        int len = 0;
-       ulong temp;
+       unsigned long long temp;
        char buf[16];           //enough for all info
        acpi_status rv = AE_OK;
  
@@@ -604,7 -603,7 +604,7 @@@ static void set_display(int value
  
  static int read_display(void)
  {
-       ulong value = 0;
+       unsigned long long value = 0;
        acpi_status rv = AE_OK;
  
        /* In most of the case, we know how to set the display, but sometime
@@@ -850,7 -849,7 +850,7 @@@ static int asus_hotk_get_info(void
  {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *model = NULL;
-       ulong bsts_result, hwrs_result;
+       unsigned long long bsts_result, hwrs_result;
        char *string = NULL;
        acpi_status status;
  
@@@ -997,7 -996,7 +997,7 @@@ static int asus_hotk_add(struct acpi_de
        hotk->handle = device->handle;
        strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
        strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
 -      acpi_driver_data(device) = hotk;
 +      device->driver_data = hotk;
        hotk->device = device;
  
        result = asus_hotk_check();
index 7b39e0f0f1be6cac4d8b33903e834d07ec240a96,616bcbd8def6d3064db1022665330d7309b9ad4b..9ef98b2d5039e76bd52054e47be358909c60f58e
@@@ -28,8 -28,6 +28,8 @@@
  #include <acpi/acpi_drivers.h>
  #include <acpi/acpi_bus.h>
  #include <linux/uaccess.h>
 +#include <linux/input.h>
 +#include <linux/rfkill.h>
  
  #define EEEPC_LAPTOP_VERSION  "0.1"
  
@@@ -127,10 -125,6 +127,10 @@@ struct eeepc_hotk 
                                           by this BIOS */
        uint init_flag;                 /* Init flags */
        u16 event_count[128];           /* count for each event */
 +      struct input_dev *inputdev;
 +      u16 *keycode_map;
 +      struct rfkill *eeepc_wlan_rfkill;
 +      struct rfkill *eeepc_bluetooth_rfkill;
  };
  
  /* The actual device the driver binds to */
@@@ -146,27 -140,6 +146,27 @@@ static struct platform_driver platform_
  
  static struct platform_device *platform_device;
  
 +struct key_entry {
 +      char type;
 +      u8 code;
 +      u16 keycode;
 +};
 +
 +enum { KE_KEY, KE_END };
 +
 +static struct key_entry eeepc_keymap[] = {
 +      /* Sleep already handled via generic ACPI code */
 +      {KE_KEY, 0x10, KEY_WLAN },
 +      {KE_KEY, 0x12, KEY_PROG1 },
 +      {KE_KEY, 0x13, KEY_MUTE },
 +      {KE_KEY, 0x14, KEY_VOLUMEDOWN },
 +      {KE_KEY, 0x15, KEY_VOLUMEUP },
 +      {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
 +      {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
 +      {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
 +      {KE_END, 0},
 +};
 +
  /*
   * The hotkey driver declaration
   */
@@@ -231,7 -204,7 +231,7 @@@ static int write_acpi_int(acpi_handle h
  static int read_acpi_int(acpi_handle handle, const char *method, int *val)
  {
        acpi_status status;
-       ulong result;
+       unsigned long long result;
  
        status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
        if (ACPI_FAILURE(status)) {
@@@ -287,44 -260,6 +287,44 @@@ static int update_bl_status(struct back
        return set_brightness(bd, bd->props.brightness);
  }
  
 +/*
 + * Rfkill helpers
 + */
 +
 +static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state)
 +{
 +      if (state == RFKILL_STATE_SOFT_BLOCKED)
 +              return set_acpi(CM_ASL_WLAN, 0);
 +      else
 +              return set_acpi(CM_ASL_WLAN, 1);
 +}
 +
 +static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
 +{
 +      if (get_acpi(CM_ASL_WLAN) == 1)
 +              *state = RFKILL_STATE_UNBLOCKED;
 +      else
 +              *state = RFKILL_STATE_SOFT_BLOCKED;
 +      return 0;
 +}
 +
 +static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state)
 +{
 +      if (state == RFKILL_STATE_SOFT_BLOCKED)
 +              return set_acpi(CM_ASL_BLUETOOTH, 0);
 +      else
 +              return set_acpi(CM_ASL_BLUETOOTH, 1);
 +}
 +
 +static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state)
 +{
 +      if (get_acpi(CM_ASL_BLUETOOTH) == 1)
 +              *state = RFKILL_STATE_UNBLOCKED;
 +      else
 +              *state = RFKILL_STATE_SOFT_BLOCKED;
 +      return 0;
 +}
 +
  /*
   * Sys helpers
   */
@@@ -376,11 -311,13 +376,11 @@@ static ssize_t show_sys_acpi(int cm, ch
  EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
  EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
  EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
 -EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN);
  
  static struct attribute *platform_attributes[] = {
        &dev_attr_camera.attr,
        &dev_attr_cardr.attr,
        &dev_attr_disp.attr,
 -      &dev_attr_wlan.attr,
        NULL
  };
  
@@@ -391,64 -328,8 +391,64 @@@ static struct attribute_group platform_
  /*
   * Hotkey functions
   */
 +static struct key_entry *eepc_get_entry_by_scancode(int code)
 +{
 +      struct key_entry *key;
 +
 +      for (key = eeepc_keymap; key->type != KE_END; key++)
 +              if (code == key->code)
 +                      return key;
 +
 +      return NULL;
 +}
 +
 +static struct key_entry *eepc_get_entry_by_keycode(int code)
 +{
 +      struct key_entry *key;
 +
 +      for (key = eeepc_keymap; key->type != KE_END; key++)
 +              if (code == key->keycode && key->type == KE_KEY)
 +                      return key;
 +
 +      return NULL;
 +}
 +
 +static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
 +{
 +      struct key_entry *key = eepc_get_entry_by_scancode(scancode);
 +
 +      if (key && key->type == KE_KEY) {
 +              *keycode = key->keycode;
 +              return 0;
 +      }
 +
 +      return -EINVAL;
 +}
 +
 +static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
 +{
 +      struct key_entry *key;
 +      int old_keycode;
 +
 +      if (keycode < 0 || keycode > KEY_MAX)
 +              return -EINVAL;
 +
 +      key = eepc_get_entry_by_scancode(scancode);
 +      if (key && key->type == KE_KEY) {
 +              old_keycode = key->keycode;
 +              key->keycode = keycode;
 +              set_bit(keycode, dev->keybit);
 +              if (!eepc_get_entry_by_keycode(old_keycode))
 +                      clear_bit(old_keycode, dev->keybit);
 +              return 0;
 +      }
 +
 +      return -EINVAL;
 +}
 +
  static int eeepc_hotk_check(void)
  {
 +      const struct key_entry *key;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        int result;
  
                               "Get control methods supported: 0x%x\n",
                               ehotk->cm_supported);
                }
 +              ehotk->inputdev = input_allocate_device();
 +              if (!ehotk->inputdev) {
 +                      printk(EEEPC_INFO "Unable to allocate input device\n");
 +                      return 0;
 +              }
 +              ehotk->inputdev->name = "Asus EeePC extra buttons";
 +              ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
 +              ehotk->inputdev->id.bustype = BUS_HOST;
 +              ehotk->inputdev->getkeycode = eeepc_getkeycode;
 +              ehotk->inputdev->setkeycode = eeepc_setkeycode;
 +
 +              for (key = eeepc_keymap; key->type != KE_END; key++) {
 +                      switch (key->type) {
 +                      case KE_KEY:
 +                              set_bit(EV_KEY, ehotk->inputdev->evbit);
 +                              set_bit(key->keycode, ehotk->inputdev->keybit);
 +                              break;
 +                      }
 +              }
 +              result = input_register_device(ehotk->inputdev);
 +              if (result) {
 +                      printk(EEEPC_INFO "Unable to register input device\n");
 +                      input_free_device(ehotk->inputdev);
 +                      return 0;
 +              }
        } else {
                printk(EEEPC_ERR "Hotkey device not present, aborting\n");
                return -EINVAL;
        return 0;
  }
  
 -static void notify_wlan(u32 *event)
 -{
 -      /* if DISABLE_ASL_WLAN is set, the notify code for fn+f2
 -         will always be 0x10 */
 -      if (ehotk->cm_supported & (0x1 << CM_ASL_WLAN)) {
 -              const char *method = cm_getv[CM_ASL_WLAN];
 -              int value;
 -              if (read_acpi_int(ehotk->handle, method, &value))
 -                      printk(EEEPC_WARNING "Error reading %s\n",
 -                             method);
 -              else if (value == 1)
 -                      *event = 0x11;
 -      }
 -}
 -
  static void notify_brn(void)
  {
        struct backlight_device *bd = eeepc_backlight_device;
  
  static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
  {
 +      static struct key_entry *key;
        if (!ehotk)
                return;
 -      if (event == NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & ehotk->init_flag))
 -              notify_wlan(&event);
        if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
                notify_brn();
        acpi_bus_generate_proc_event(ehotk->device, event,
                                     ehotk->event_count[event % 128]++);
 +      if (ehotk->inputdev) {
 +              key = eepc_get_entry_by_scancode(event);
 +              if (key) {
 +                      switch (key->type) {
 +                      case KE_KEY:
 +                              input_report_key(ehotk->inputdev, key->keycode,
 +                                               1);
 +                              input_sync(ehotk->inputdev);
 +                              input_report_key(ehotk->inputdev, key->keycode,
 +                                               0);
 +                              input_sync(ehotk->inputdev);
 +                              break;
 +                      }
 +              }
 +      }
  }
  
  static int eeepc_hotk_add(struct acpi_device *device)
        ehotk->handle = device->handle;
        strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
        strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
 -      acpi_driver_data(device) = ehotk;
 +      device->driver_data = ehotk;
        ehotk->device = device;
        result = eeepc_hotk_check();
        if (result)
                                             eeepc_hotk_notify, ehotk);
        if (ACPI_FAILURE(status))
                printk(EEEPC_ERR "Error installing notify handler\n");
 +
 +      if (get_acpi(CM_ASL_WLAN) != -1) {
 +              ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
 +                                                         RFKILL_TYPE_WLAN);
 +
 +              if (!ehotk->eeepc_wlan_rfkill)
 +                      goto end;
 +
 +              ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
 +              ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
 +              ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
 +              if (get_acpi(CM_ASL_WLAN) == 1)
 +                      ehotk->eeepc_wlan_rfkill->state =
 +                              RFKILL_STATE_UNBLOCKED;
 +              else
 +                      ehotk->eeepc_wlan_rfkill->state =
 +                              RFKILL_STATE_SOFT_BLOCKED;
 +              rfkill_register(ehotk->eeepc_wlan_rfkill);
 +      }
 +
 +      if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
 +              ehotk->eeepc_bluetooth_rfkill =
 +                      rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
 +
 +              if (!ehotk->eeepc_bluetooth_rfkill)
 +                      goto end;
 +
 +              ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
 +              ehotk->eeepc_bluetooth_rfkill->toggle_radio =
 +                      eeepc_bluetooth_rfkill_set;
 +              ehotk->eeepc_bluetooth_rfkill->get_state =
 +                      eeepc_bluetooth_rfkill_state;
 +              if (get_acpi(CM_ASL_BLUETOOTH) == 1)
 +                      ehotk->eeepc_bluetooth_rfkill->state =
 +                              RFKILL_STATE_UNBLOCKED;
 +              else
 +                      ehotk->eeepc_bluetooth_rfkill->state =
 +                              RFKILL_STATE_SOFT_BLOCKED;
 +              rfkill_register(ehotk->eeepc_bluetooth_rfkill);
 +      }
 +
   end:
        if (result) {
                kfree(ehotk);
@@@ -737,12 -553,6 +737,12 @@@ static void eeepc_backlight_exit(void
  {
        if (eeepc_backlight_device)
                backlight_device_unregister(eeepc_backlight_device);
 +      if (ehotk->inputdev)
 +              input_unregister_device(ehotk->inputdev);
 +      if (ehotk->eeepc_wlan_rfkill)
 +              rfkill_unregister(ehotk->eeepc_wlan_rfkill);
 +      if (ehotk->eeepc_bluetooth_rfkill)
 +              rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
        eeepc_backlight_device = NULL;
  }
  
index 8555a17f00ef95507ef3986636b973dd06490d48,efd395a64720cfcd91afe77fa64ac28e04e6a020..d2cf0bfe31638f4de679f47a73c13097d527f3d4
@@@ -44,9 -44,8 +44,9 @@@
   * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are
   * also supported by this driver.
   *
 - * This driver has been tested on a Fujitsu Lifebook S6410 and S7020.  It
 - * should work on most P-series and S-series Lifebooks, but YMMV.
 + * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and
 + * P8010.  It should work on most P-series and S-series Lifebooks, but
 + * YMMV.
   *
   * The module parameter use_alt_lcd_levels switches between different ACPI
   * brightness controls which are used by different Fujitsu laptops.  In most
@@@ -66,7 -65,7 +66,7 @@@
  #include <linux/video_output.h>
  #include <linux/platform_device.h>
  
 -#define FUJITSU_DRIVER_VERSION "0.4.2"
 +#define FUJITSU_DRIVER_VERSION "0.4.3"
  
  #define FUJITSU_LCD_N_LEVELS 8
  
  #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS     0x87
  
  /* Hotkey details */
 -#define LOCK_KEY      0x410   /* codes for the keys in the GIRB register */
 -#define DISPLAY_KEY   0x411   /* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */
 -#define ENERGY_KEY    0x412   /* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */
 -#define REST_KEY      0x413   /* KEY_SUSPEND (R key) */
 +#define KEY1_CODE     0x410   /* codes for the keys in the GIRB register */
 +#define KEY2_CODE     0x411
 +#define KEY3_CODE     0x412
 +#define KEY4_CODE     0x413
  
  #define MAX_HOTKEY_RINGBUFFER_SIZE 100
  #define RINGBUFFERSIZE 40
@@@ -124,7 -123,6 +124,7 @@@ struct fujitsu_t 
        char phys[32];
        struct backlight_device *bl_device;
        struct platform_device *pf_device;
 +      int keycode1, keycode2, keycode3, keycode4;
  
        unsigned int max_brightness;
        unsigned int brightness_changed;
@@@ -226,7 -224,7 +226,7 @@@ static int set_lcd_level_alt(int level
  
  static int get_lcd_level(void)
  {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
  
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");
  
  static int get_max_brightness(void)
  {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
  
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");
  
  static int get_lcd_level_alt(void)
  {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
  
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n");
@@@ -386,7 -384,7 +386,7 @@@ static ssize_t store_lcd_level(struct d
  
  static int get_irb(void)
  {
-       unsigned long state = 0;
+       unsigned long long state = 0;
        acpi_status status = AE_OK;
  
        vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n");
@@@ -432,7 -430,7 +432,7 @@@ static struct platform_driver fujitsupf
                   }
  };
  
 -static int dmi_check_cb_s6410(const struct dmi_system_id *id)
 +static void dmi_check_cb_common(const struct dmi_system_id *id)
  {
        acpi_handle handle;
        int have_blnf;
                            "auto-detecting disable_adjust\n");
                disable_brightness_adjust = have_blnf ? 0 : 1;
        }
 +}
 +
 +static int dmi_check_cb_s6410(const struct dmi_system_id *id)
 +{
 +      dmi_check_cb_common(id);
 +      fujitsu->keycode1 = KEY_SCREENLOCK;     /* "Lock" */
 +      fujitsu->keycode2 = KEY_HELP;   /* "Mobility Center" */
 +      return 0;
 +}
 +
 +static int dmi_check_cb_p8010(const struct dmi_system_id *id)
 +{
 +      dmi_check_cb_common(id);
 +      fujitsu->keycode1 = KEY_HELP;   /* "Support" */
 +      fujitsu->keycode3 = KEY_SWITCHVIDEOMODE;        /* "Presentation" */
 +      fujitsu->keycode4 = KEY_WWW;    /* "Internet" */
        return 0;
  }
  
  static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
        {
 -       .ident = "Fujitsu Siemens",
 +       .ident = "Fujitsu Siemens S6410",
         .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
                     DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
                     },
         .callback = dmi_check_cb_s6410},
        {
 -       .ident = "FUJITSU LifeBook P8010",
 +       .ident = "Fujitsu LifeBook P8010",
         .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
                     DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"),
 -                  },
 -       .callback = dmi_check_cb_s6410},
 +                   },
 +       .callback = dmi_check_cb_p8010},
        {}
  };
  
@@@ -508,7 -490,7 +508,7 @@@ static int acpi_fujitsu_add(struct acpi
        fujitsu->acpi_handle = device->handle;
        sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
        sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
 -      acpi_driver_data(device) = fujitsu;
 +      device->driver_data = fujitsu;
  
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_DEVICE_NOTIFY,
        }
  
        /* do config (detect defaults) */
 -      dmi_check_system(fujitsu_dmi_table);
        use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0;
        disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0;
        disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0;
@@@ -640,17 -623,17 +640,17 @@@ static void acpi_fujitsu_notify(acpi_ha
                        keycode = 0;
                        if (disable_brightness_keys != 1) {
                                if (oldb == 0) {
 -                                      acpi_bus_generate_proc_event(fujitsu->
 -                                              dev,
 -                                              ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
 -                                              0);
 +                                      acpi_bus_generate_proc_event
 +                                          (fujitsu->dev,
 +                                           ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
 +                                           0);
                                        keycode = KEY_BRIGHTNESSDOWN;
                                } else if (oldb ==
                                           (fujitsu->max_brightness) - 1) {
 -                                      acpi_bus_generate_proc_event(fujitsu->
 -                                              dev,
 -                                              ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
 -                                              0);
 +                                      acpi_bus_generate_proc_event
 +                                          (fujitsu->dev,
 +                                           ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
 +                                           0);
                                        keycode = KEY_BRIGHTNESSUP;
                                }
                        }
                        }
                        if (disable_brightness_keys != 1) {
                                acpi_bus_generate_proc_event(fujitsu->dev,
 -                                      ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
 -                                      0);
 +                                      ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0);
                                keycode = KEY_BRIGHTNESSUP;
                        }
                } else if (oldb > newb) {
                        }
                        if (disable_brightness_keys != 1) {
                                acpi_bus_generate_proc_event(fujitsu->dev,
 -                                      ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
 -                                      0);
 +                                      ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0);
                                keycode = KEY_BRIGHTNESSDOWN;
                        }
                } else {
@@@ -718,7 -703,7 +718,7 @@@ static int acpi_fujitsu_hotkey_add(stru
        sprintf(acpi_device_name(device), "%s",
                ACPI_FUJITSU_HOTKEY_DEVICE_NAME);
        sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
 -      acpi_driver_data(device) = fujitsu_hotkey;
 +      device->driver_data = fujitsu_hotkey;
  
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_DEVICE_NOTIFY,
        input->id.product = 0x06;
        input->dev.parent = &device->dev;
        input->evbit[0] = BIT(EV_KEY);
 -      set_bit(KEY_SCREENLOCK, input->keybit);
 -      set_bit(KEY_MEDIA, input->keybit);
 -      set_bit(KEY_EMAIL, input->keybit);
 -      set_bit(KEY_SUSPEND, input->keybit);
 +      set_bit(fujitsu->keycode1, input->keybit);
 +      set_bit(fujitsu->keycode2, input->keybit);
 +      set_bit(fujitsu->keycode3, input->keybit);
 +      set_bit(fujitsu->keycode4, input->keybit);
        set_bit(KEY_UNKNOWN, input->keybit);
  
        error = input_register_device(input);
@@@ -848,24 -833,24 +848,24 @@@ static void acpi_fujitsu_hotkey_notify(
                                    irb);
  
                        switch (irb & 0x4ff) {
 -                      case LOCK_KEY:
 -                              keycode = KEY_SCREENLOCK;
 +                      case KEY1_CODE:
 +                              keycode = fujitsu->keycode1;
                                break;
 -                      case DISPLAY_KEY:
 -                              keycode = KEY_MEDIA;
 +                      case KEY2_CODE:
 +                              keycode = fujitsu->keycode2;
                                break;
 -                      case ENERGY_KEY:
 -                              keycode = KEY_EMAIL;
 +                      case KEY3_CODE:
 +                              keycode = fujitsu->keycode3;
                                break;
 -                      case REST_KEY:
 -                              keycode = KEY_SUSPEND;
 +                      case KEY4_CODE:
 +                              keycode = fujitsu->keycode4;
                                break;
                        case 0:
                                keycode = 0;
                                break;
                        default:
                                vdbg_printk(FUJLAPTOP_DBG_WARN,
 -                                      "Unknown GIRB result [%x]\n", irb);
 +                                          "Unknown GIRB result [%x]\n", irb);
                                keycode = -1;
                                break;
                        }
                                        "Push keycode into ringbuffer [%d]\n",
                                        keycode);
                                status = kfifo_put(fujitsu_hotkey->fifo,
 -                                              (unsigned char *)&keycode,
 -                                              sizeof(keycode));
 +                                                 (unsigned char *)&keycode,
 +                                                 sizeof(keycode));
                                if (status != sizeof(keycode)) {
                                        vdbg_printk(FUJLAPTOP_DBG_WARN,
 -                                              "Could not push keycode [0x%x]\n",
 -                                              keycode);
 +                                          "Could not push keycode [0x%x]\n",
 +                                          keycode);
                                } else {
                                        input_report_key(input, keycode, 1);
                                        input_sync(input);
                                        input_report_key(input, keycode_r, 0);
                                        input_sync(input);
                                        vdbg_printk(FUJLAPTOP_DBG_TRACE,
 -                                                  "Pop keycode from ringbuffer [%d]\n",
 -                                                  keycode_r);
 +                                        "Pop keycode from ringbuffer [%d]\n",
 +                                        keycode_r);
                                }
                        }
                }
@@@ -958,11 -943,6 +958,11 @@@ static int __init fujitsu_init(void
        if (!fujitsu)
                return -ENOMEM;
        memset(fujitsu, 0, sizeof(struct fujitsu_t));
 +      fujitsu->keycode1 = KEY_PROG1;
 +      fujitsu->keycode2 = KEY_PROG2;
 +      fujitsu->keycode3 = KEY_PROG3;
 +      fujitsu->keycode4 = KEY_PROG4;
 +      dmi_check_system(fujitsu_dmi_table);
  
        result = acpi_bus_register_driver(&acpi_fujitsu_driver);
        if (result < 0) {
@@@ -1096,14 -1076,15 +1096,14 @@@ MODULE_DESCRIPTION("Fujitsu laptop extr
  MODULE_VERSION(FUJITSU_DRIVER_VERSION);
  MODULE_LICENSE("GPL");
  
 -MODULE_ALIAS
 -    ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
 -MODULE_ALIAS
 -    ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
 +MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
 +MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
  
  static struct pnp_device_id pnp_ids[] = {
 -      { .id = "FUJ02bf" },
 -      { .id = "FUJ02B1" },
 -      { .id = "FUJ02E3" },
 -      { .id = "" }
 +      {.id = "FUJ02bf"},
 +      {.id = "FUJ02B1"},
 +      {.id = "FUJ02E3"},
 +      {.id = ""}
  };
 +
  MODULE_DEVICE_TABLE(pnp, pnp_ids);
index cd3ea7faa5b6bd4cf55d3bd2ec2c2c0436f0ae41,bd372ea11b0a514e87f13b7d0405e6b94edaaf1c..a78274385d546f9b8c8cd74917a504f679e78452
@@@ -57,7 -57,7 +57,7 @@@ static int memory_get_int_max_bandwidth
  {
        struct acpi_device *device = cdev->devdata;
        acpi_handle handle = device->handle;
-       unsigned long value;
+       unsigned long long value;
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status = AE_OK;
@@@ -90,7 -90,7 +90,7 @@@ static int memory_get_cur_bandwidth(str
  {
        struct acpi_device *device = cdev->devdata;
        acpi_handle handle = device->handle;
-       unsigned long value;
+       unsigned long long value;
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status = AE_OK;
@@@ -115,7 -115,7 +115,7 @@@ static int memory_set_cur_bandwidth(str
        struct acpi_object_list arg_list;
        union acpi_object arg;
        acpi_status status;
-       int temp;
+       unsigned long long temp;
        unsigned long max_state;
  
        if (memory_get_int_max_bandwidth(cdev, &max_state))
  
        status =
            acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list,
-                                 (unsigned long *)&temp);
+                                 &temp);
  
        printk(KERN_INFO
               "Bandwidth value was %d: status is %d\n", state, status);
@@@ -175,7 -175,7 +175,7 @@@ static int intel_menlow_memory_add(stru
                goto end;
        }
  
 -      acpi_driver_data(device) = cdev;
 +      device->driver_data = cdev;
        result = sysfs_create_link(&device->dev.kobj,
                                &cdev->device.kobj, "thermal_cooling");
        if (result)
@@@ -252,7 -252,8 +252,8 @@@ static DEFINE_MUTEX(intel_menlow_attr_l
   * @auxtype : AUX0/AUX1
   * @buf: syfs buffer
   */
- static int sensor_get_auxtrip(acpi_handle handle, int index, int *value)
+ static int sensor_get_auxtrip(acpi_handle handle, int index,
+                                                       unsigned long long *value)
  {
        acpi_status status;
  
                return -EINVAL;
  
        status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0,
-                                      NULL, (unsigned long *)value);
+                                      NULL, value);
        if (ACPI_FAILURE(status))
                return -EIO;
  
@@@ -282,13 -283,13 +283,13 @@@ static int sensor_set_auxtrip(acpi_hand
        struct acpi_object_list args = {
                1, &arg
        };
-       int temp;
+       unsigned long long temp;
  
        if (index != 0 && index != 1)
                return -EINVAL;
  
        status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1,
-                                      NULL, (unsigned long *)&temp);
+                                      NULL, &temp);
        if (ACPI_FAILURE(status))
                return -EIO;
        if ((index && value < temp) || (!index && value > temp))
  
        arg.integer.value = value;
        status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0,
-                                      &args, (unsigned long *)&temp);
+                                      &args, &temp);
        if (ACPI_FAILURE(status))
                return -EIO;
  
@@@ -312,7 -313,7 +313,7 @@@ static ssize_t aux0_show(struct device 
                         struct device_attribute *dev_attr, char *buf)
  {
        struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
-       int value;
+       unsigned long long value;
        int result;
  
        result = sensor_get_auxtrip(attr->handle, 0, &value);
@@@ -324,7 -325,7 +325,7 @@@ static ssize_t aux1_show(struct device 
                         struct device_attribute *dev_attr, char *buf)
  {
        struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr);
-       int value;
+       unsigned long long value;
        int result;
  
        result = sensor_get_auxtrip(attr->handle, 1, &value);
@@@ -376,7 -377,7 +377,7 @@@ static ssize_t bios_enabled_show(struc
                                 struct device_attribute *attr, char *buf)
  {
        acpi_status status;
-       unsigned long bios_enabled;
+       unsigned long long bios_enabled;
  
        status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled);
        if (ACPI_FAILURE(status))
@@@ -492,7 -493,7 +493,7 @@@ static int __init intel_menlow_module_i
  {
        int result = -ENODEV;
        acpi_status status;
-       unsigned long enable;
+       unsigned long long enable;
  
        if (acpi_disabled)
                return result;
index db54c5ef2aa58311afed0c624e78842179becb36,3baee56fa81aec137931d24af4457efa7197f8b8..955aae4071f7a64eeb5cb716aaacf8ebb26c7a11
@@@ -169,9 -169,7 +169,9 @@@ static int post_dock_fixups(struct noti
  }
  
  
 -
 +static struct acpi_dock_ops acpiphp_dock_ops = {
 +      .handler = handle_hotplug_event_func,
 +};
  
  /* callback routine to register each ACPI PCI slot object */
  static acpi_status
@@@ -182,7 -180,7 +182,7 @@@ register_slot(acpi_handle handle, u32 l
        struct acpiphp_func *newfunc;
        acpi_handle tmp;
        acpi_status status = AE_OK;
-       unsigned long adr, sun;
+       unsigned long long adr, sun;
        int device, function, retval;
  
        status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
                 */
                newfunc->flags &= ~FUNC_HAS_EJ0;
                if (register_hotplug_dock_device(handle,
 -                      handle_hotplug_event_func, newfunc))
 +                      &acpiphp_dock_ops, newfunc))
                        dbg("failed to register dock device\n");
  
                /* we need to be notified when dock events happen
@@@ -530,7 -528,7 +530,7 @@@ find_p2p_bridge(acpi_handle handle, u3
  {
        acpi_status status;
        acpi_handle dummy_handle;
-       unsigned long tmp;
+       unsigned long long tmp;
        int device, function;
        struct pci_dev *dev;
        struct pci_bus *pci_bus = context;
  static int add_bridge(acpi_handle handle)
  {
        acpi_status status;
-       unsigned long tmp;
+       unsigned long long tmp;
        int seg, bus;
        acpi_handle dummy_handle;
        struct pci_bus *pci_bus;
@@@ -769,7 -767,7 +769,7 @@@ static int get_gsi_base(acpi_handle han
  {
        acpi_status status;
        int result = -1;
-       unsigned long gsb;
+       unsigned long long gsb;
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
        union acpi_object *obj;
        void *table;
@@@ -810,7 -808,7 +810,7 @@@ static acpi_statu
  ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
  {
        acpi_status status;
-       unsigned long sta;
+       unsigned long long sta;
        acpi_handle tmp;
        struct pci_dev *pdev;
        u32 gsi_base;
@@@ -874,7 -872,7 +874,7 @@@ static acpi_statu
  ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv)
  {
        acpi_status status;
-       unsigned long sta;
+       unsigned long long sta;
        acpi_handle tmp;
        u32 gsi_base;
        struct acpiphp_ioapic *pos, *n, *ioapic = NULL;
@@@ -1266,7 -1264,7 +1266,7 @@@ static int disable_device(struct acpiph
  static unsigned int get_slot_status(struct acpiphp_slot *slot)
  {
        acpi_status status;
-       unsigned long sta = 0;
+       unsigned long long sta = 0;
        u32 dvid;
        struct list_head *l;
        struct acpiphp_func *func;
diff --combined include/acpi/acpi_bus.h
index c1b5556c985d23893106768de6758c6c1a1a16e5,c52f10dee367b7a199d972fd81de28684be34bd4..54a279e44c9a4eb42dc0e83c836cfcc275d79c73
@@@ -46,7 -46,7 +46,7 @@@ acpi_extract_package(union acpi_object 
  acpi_status
  acpi_evaluate_integer(acpi_handle handle,
                      acpi_string pathname,
-                     struct acpi_object_list *arguments, unsigned long *data);
+                     struct acpi_object_list *arguments, unsigned long long *data);
  acpi_status
  acpi_evaluate_reference(acpi_handle handle,
                        acpi_string pathname,
@@@ -300,11 -300,7 +300,11 @@@ struct acpi_device 
        enum acpi_bus_removal_type removal_type;        /* indicate for different removal type */
  };
  
 -#define acpi_driver_data(d)   ((d)->driver_data)
 +static inline void *acpi_driver_data(struct acpi_device *d)
 +{
 +      return d->driver_data;
 +}
 +
  #define to_acpi_device(d)     container_of(d, struct acpi_device, dev)
  #define to_acpi_driver(d)     container_of(d, struct acpi_driver, drv)
  
@@@ -331,9 -327,6 +331,9 @@@ int acpi_bus_get_private_data(acpi_hand
  extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
  extern int register_acpi_notifier(struct notifier_block *);
  extern int unregister_acpi_notifier(struct notifier_block *);
 +
 +extern int register_acpi_bus_notifier(struct notifier_block *nb);
 +extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
  /*
   * External Functions
   */