Pull sysfs into test branch
authorLen Brown <len.brown@intel.com>
Sat, 3 Feb 2007 06:14:35 +0000 (01:14 -0500)
committerLen Brown <len.brown@intel.com>
Sat, 3 Feb 2007 06:14:35 +0000 (01:14 -0500)
Conflicts:

Documentation/feature-removal-schedule.txt
include/acpi/acpi_drivers.h

Signed-off-by: Len Brown <len.brown@intel.com>
17 files changed:
1  2 
Documentation/feature-removal-schedule.txt
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/container.c
drivers/acpi/fan.c
drivers/acpi/motherboard.c
drivers/acpi/pci_root.c
drivers/acpi/processor_core.c
drivers/acpi/scan.c
drivers/acpi/system.c
drivers/acpi/thermal.c
drivers/acpi/video.c
include/acpi/acpi_bus.h
include/acpi/acpi_drivers.h

@@@ -226,23 -226,6 +226,23 @@@ Who:     Jean Delvare <khali@linux-fr.org
  
  ---------------------------
  
 +What: i2c_adapter.dev
 +      i2c_adapter.list
 +When: July 2007
 +Why:  Superfluous, given i2c_adapter.class_dev:
 +        * The "dev" was a stand-in for the physical device node that legacy
 +          drivers would not have; but now it's almost always present.  Any
 +          remaining legacy drivers must upgrade (they now trigger warnings).
 +        * The "list" duplicates class device children.
 +      The delay in removing this is so upgraded lm_sensors and libsensors
 +      can get deployed.  (Removal causes minor changes in the sysfs layout,
 +      notably the location of the adapter type name and parenting the i2c
 +      client hardware directly from their controller.)
 +Who:  Jean Delvare <khali@linux-fr.org>,
 +      David Brownell <dbrownell@users.sourceforge.net>
 +
 +---------------------------
 +
  What: IPv4 only connection tracking/NAT/helpers
  When: 2.6.22
  Why:  The new layer 3 independant connection tracking replaces the old
@@@ -274,54 -257,11 +274,62 @@@ Who:    Venkatesh Pallipadi <venkatesh.pal
  
  ---------------------------
  
++<<<<<<< test:Documentation/feature-removal-schedule.txt
 +What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
 +When: 2.6.21
 +Why:  hotkey.c was an attempt to consolidate multiple drivers that use
 +      ACPI to implement hotkeys.  However, hotkeys are not documented
 +      in the ACPI specification, so the drivers used undocumented
 +      vendor-specific hooks and turned out to be more different than
 +      the same.
 +
 +      Further, the keys and the features supplied by each platform
 +      are different, so there will always be a need for
 +      platform-specific drivers.
 +
 +      So the new plan is to delete hotkey.c and instead, work on the
 +      platform specific drivers to try to make them look the same
 +      to the user when they supply the same features.
 +
 +      hotkey.c has always depended on CONFIG_EXPERIMENTAL
 +
 +Who:  Len Brown <len.brown@intel.com>
 +
 +---------------------------
 +
 +What: /sys/firmware/acpi/namespace
 +When: 2.6.21
 +Why:  The ACPI namespace is effectively the symbol list for
 +      the BIOS.  The device names are completely arbitrary
 +      and have no place being exposed to user-space.
 +
 +      For those interested in the BIOS ACPI namespace,
 +      the BIOS can be extracted and disassembled with acpidump
 +      and iasl as documented in the pmtools package here:
 +      http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
 +Who:  Len Brown <len.brown@intel.com>
 +
 +---------------------------
 +
+ What: ACPI procfs interface
+ When: July 2007
+ Why:  After ACPI sysfs conversion, ACPI attributes will be duplicated
+       in sysfs and the ACPI procfs interface should be removed.
+ Who:  Zhang Rui <rui.zhang@intel.com>
+ ---------------------------
 +What: /proc/acpi/button
 +When: August 2007
 +Why:  /proc/acpi/button has been replaced by events to the input layer
 +      since 2.6.20.
 +Who:  Len Brown <len.brown@intel.com>
 +
 +---------------------------
 +
 +What: JFFS (version 1)
 +When: 2.6.21
 +Why:  Unmaintained for years, superceded by JFFS2 for years.
 +Who:  Jeff Garzik <jeff@garzik.org>
 +
 +---------------------------
diff --combined drivers/acpi/Kconfig
@@@ -11,7 -11,7 +11,7 @@@ config ACP
        bool "ACPI Support"
        depends on IA64 || X86
        depends on PCI
 -      select PM
 +      depends on PM
        default y
        ---help---
          Advanced Configuration and Power Interface (ACPI) support for 
@@@ -77,6 -77,20 +77,20 @@@ config ACPI_SLEEP_PROC_SLEE
          Create /proc/acpi/sleep
          Deprecated by /sys/power/state
  
+ config ACPI_PROCFS
+       bool "Procfs interface (deprecated)"
+       depends on ACPI
+       default y
+       ---help---
+         Procfs interface for ACPI is made optional for back-compatible.
+         As the same functions are duplicated in sysfs interface
+         and this proc interface will be removed some time later,
+         it's marked as deprecated.
+         ( /proc/acpi/debug_layer && debug_level are deprecated by
+           /sys/module/acpi/parameters/debug_layer && debug_level.
+           /proc/acpi/info is deprecated by
+           /sys/module/acpi/parameters/acpica_version )
  config ACPI_AC
        tristate "AC Adapter"
        depends on X86
@@@ -97,7 -111,6 +111,7 @@@ config ACPI_BATTER
  
  config ACPI_BUTTON
        tristate "Button"
 +      depends on INPUT
        default y
        help
          This driver handles events on the power, sleep and lid buttons.
  
  config ACPI_VIDEO
        tristate "Video"
 -      depends on X86
 +      depends on X86 && BACKLIGHT_CLASS_DEVICE
        help
          This driver implement the ACPI Extensions For Display Adapters
          for integrated graphics devices on motherboard, as specified in
@@@ -139,13 -152,6 +153,13 @@@ config ACPI_DOC
        help
          This driver adds support for ACPI controlled docking stations
  
 +config ACPI_BAY
 +      tristate "Removable Drive Bay (EXPERIMENTAL)"
 +      depends on EXPERIMENTAL
 +      help
 +        This driver adds support for ACPI controlled removable drive
 +        bays such as the IBM ultrabay or the Dell Module Bay.
 +
  config ACPI_PROCESSOR
        tristate "Processor"
        default y
@@@ -180,7 -186,6 +194,7 @@@ config ACPI_NUM
  config ACPI_ASUS
          tristate "ASUS/Medion Laptop Extras"
        depends on X86
 +      select BACKLIGHT_CLASS_DEVICE
          ---help---
            This driver provides support for extra features of ACPI-compatible
            ASUS laptops. As some of Medion laptops are made by ASUS, it may also
  config ACPI_IBM
        tristate "IBM ThinkPad Laptop Extras"
        depends on X86
 +      select BACKLIGHT_CLASS_DEVICE
        ---help---
          This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
          support for Fn-Fx key combinations, Bluetooth control, video
@@@ -235,7 -239,6 +249,7 @@@ config ACPI_IBM_DOC
  config ACPI_TOSHIBA
        tristate "Toshiba Laptop Extras"
        depends on X86
 +      select BACKLIGHT_CLASS_DEVICE
        ---help---
          This driver adds support for access to certain system settings
          on "legacy free" Toshiba laptops.  These laptops can be recognized by
diff --combined drivers/acpi/Makefile
@@@ -37,14 -37,14 +37,15 @@@ endi
  
  obj-y                         += sleep/
  obj-y                         += bus.o glue.o
+ obj-y                         += scan.o motherboard.o
  obj-$(CONFIG_ACPI_AC)                 += ac.o
  obj-$(CONFIG_ACPI_BATTERY)    += battery.o
  obj-$(CONFIG_ACPI_BUTTON)     += button.o
  obj-$(CONFIG_ACPI_EC)         += ec.o
  obj-$(CONFIG_ACPI_FAN)                += fan.o
  obj-$(CONFIG_ACPI_DOCK)               += dock.o
 -obj-$(CONFIG_ACPI_VIDEO)      += video.o 
 +obj-$(CONFIG_ACPI_BAY)                += bay.o
 +obj-$(CONFIG_ACPI_VIDEO)      += video.o
  obj-$(CONFIG_ACPI_HOTKEY)     += hotkey.o
  obj-y                         += pci_root.o pci_link.o pci_irq.o pci_bind.o
  obj-$(CONFIG_ACPI_POWER)      += power.o
@@@ -57,7 -57,6 +58,6 @@@ obj-$(CONFIG_ACPI_NUMA)               += numa.
  obj-$(CONFIG_ACPI_ASUS)               += asus_acpi.o
  obj-$(CONFIG_ACPI_IBM)                += ibm_acpi.o
  obj-$(CONFIG_ACPI_TOSHIBA)    += toshiba_acpi.o
- obj-y                         += scan.o motherboard.o
  obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)     += acpi_memhotplug.o
  obj-y                         += cm_sbs.o
  obj-$(CONFIG_ACPI_SBS)                += i2c_ec.o sbs.o
diff --combined drivers/acpi/battery.c
@@@ -64,7 -64,7 +64,7 @@@ extern void *acpi_unlock_battery_dir(st
  
  static int acpi_battery_add(struct acpi_device *device);
  static int acpi_battery_remove(struct acpi_device *device, int type);
- static int acpi_battery_resume(struct acpi_device *device, int status);
+ static int acpi_battery_resume(struct acpi_device *device);
  
  static struct acpi_driver acpi_battery_driver = {
        .name = ACPI_BATTERY_DRIVER_NAME,
@@@ -149,7 -149,7 +149,7 @@@ acpi_battery_get_info(struct acpi_batte
                return -ENODEV;
        }
  
 -      package = (union acpi_object *)buffer.pointer;
 +      package = buffer.pointer;
  
        /* Extract Package Data */
  
                goto end;
        }
  
 -      data.pointer = kmalloc(data.length, GFP_KERNEL);
 +      data.pointer = kzalloc(data.length, GFP_KERNEL);
        if (!data.pointer) {
                result = -ENOMEM;
                goto end;
        }
 -      memset(data.pointer, 0, data.length);
  
        status = acpi_extract_package(package, &format, &data);
        if (ACPI_FAILURE(status)) {
        kfree(buffer.pointer);
  
        if (!result)
 -              (*bif) = (struct acpi_battery_info *)data.pointer;
 +              (*bif) = data.pointer;
  
        return result;
  }
@@@ -208,7 -209,7 +208,7 @@@ acpi_battery_get_status(struct acpi_bat
                return -ENODEV;
        }
  
 -      package = (union acpi_object *)buffer.pointer;
 +      package = buffer.pointer;
  
        /* Extract Package Data */
  
                goto end;
        }
  
 -      data.pointer = kmalloc(data.length, GFP_KERNEL);
 +      data.pointer = kzalloc(data.length, GFP_KERNEL);
        if (!data.pointer) {
                result = -ENOMEM;
                goto end;
        }
 -      memset(data.pointer, 0, data.length);
  
        status = acpi_extract_package(package, &format, &data);
        if (ACPI_FAILURE(status)) {
        kfree(buffer.pointer);
  
        if (!result)
 -              (*bst) = (struct acpi_battery_status *)data.pointer;
 +              (*bst) = data.pointer;
  
        return result;
  }
@@@ -332,7 -334,7 +332,7 @@@ static struct proc_dir_entry *acpi_batt
  static int acpi_battery_read_info(struct seq_file *seq, void *offset)
  {
        int result = 0;
 -      struct acpi_battery *battery = (struct acpi_battery *)seq->private;
 +      struct acpi_battery *battery = seq->private;
        struct acpi_battery_info *bif = NULL;
        char *units = "?";
  
@@@ -416,7 -418,7 +416,7 @@@ static int acpi_battery_info_open_fs(st
  static int acpi_battery_read_state(struct seq_file *seq, void *offset)
  {
        int result = 0;
 -      struct acpi_battery *battery = (struct acpi_battery *)seq->private;
 +      struct acpi_battery *battery = seq->private;
        struct acpi_battery_status *bst = NULL;
        char *units = "?";
  
@@@ -492,7 -494,7 +492,7 @@@ static int acpi_battery_state_open_fs(s
  
  static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
  {
 -      struct acpi_battery *battery = (struct acpi_battery *)seq->private;
 +      struct acpi_battery *battery = seq->private;
        char *units = "?";
  
  
@@@ -529,8 -531,8 +529,8 @@@ acpi_battery_write_alarm(struct file *f
  {
        int result = 0;
        char alarm_string[12] = { '\0' };
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_battery *battery = (struct acpi_battery *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_battery *battery = m->private;
  
  
        if (!battery || (count > sizeof(alarm_string) - 1))
@@@ -656,7 -658,7 +656,7 @@@ static int acpi_battery_remove_fs(struc
  
  static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct acpi_battery *battery = (struct acpi_battery *)data;
 +      struct acpi_battery *battery = data;
        struct acpi_device *device = NULL;
  
  
@@@ -692,9 -694,10 +692,9 @@@ static int acpi_battery_add(struct acpi
        if (!device)
                return -EINVAL;
  
 -      battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL);
 +      battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
        if (!battery)
                return -ENOMEM;
 -      memset(battery, 0, sizeof(struct acpi_battery));
  
        battery->device = device;
        strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
@@@ -739,7 -742,7 +739,7 @@@ static int acpi_battery_remove(struct a
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      battery = (struct acpi_battery *)acpi_driver_data(device);
 +      battery = acpi_driver_data(device);
  
        status = acpi_remove_notify_handler(device->handle,
                                            ACPI_ALL_NOTIFY,
  }
  
  /* this is needed to learn about changes made in suspended state */
- static int acpi_battery_resume(struct acpi_device *device, int state)
+ static int acpi_battery_resume(struct acpi_device *device)
  {
        struct acpi_battery *battery;
  
diff --combined drivers/acpi/bus.c
@@@ -44,6 -44,9 +44,6 @@@ ACPI_MODULE_NAME("acpi_bus"
  extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
  #endif
  
 -struct fadt_descriptor acpi_fadt;
 -EXPORT_SYMBOL(acpi_fadt);
 -
  struct acpi_device *acpi_root;
  struct proc_dir_entry *acpi_root_dir;
  EXPORT_SYMBOL(acpi_root_dir);
@@@ -192,7 -195,7 +192,7 @@@ int acpi_bus_set_power(acpi_handle hand
  
        if (!device->flags.power_manageable) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
-                               device->kobj.name));
+                               device->dev.kobj.name));
                return -ENODEV;
        }
        /*
@@@ -558,9 -561,6 +558,9 @@@ static int __init acpi_bus_init_irq(voi
        case ACPI_IRQ_MODEL_IOSAPIC:
                message = "IOSAPIC";
                break;
 +      case ACPI_IRQ_MODEL_PLATFORM:
 +              message = "platform specific model";
 +              break;
        default:
                printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
                return -ENODEV;
        return 0;
  }
  
 +acpi_native_uint acpi_gbl_permanent_mmap;
 +
 +
  void __init acpi_early_init(void)
  {
        acpi_status status = AE_OK;
 -      struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
 -
  
        if (acpi_disabled)
                return;
        if (!acpi_strict)
                acpi_gbl_enable_interpreter_slack = TRUE;
  
 +      acpi_gbl_permanent_mmap = 1;
 +
 +      status = acpi_reallocate_root_table();
 +      if (ACPI_FAILURE(status)) {
 +              printk(KERN_ERR PREFIX
 +                     "Unable to reallocate ACPI tables\n");
 +              goto error0;
 +      }
 +
        status = acpi_initialize_subsystem();
        if (ACPI_FAILURE(status)) {
                printk(KERN_ERR PREFIX
                goto error0;
        }
  
 -      /*
 -       * Get a separate copy of the FADT for use by other drivers.
 -       */
 -      status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer);
 -      if (ACPI_FAILURE(status)) {
 -              printk(KERN_ERR PREFIX "Unable to get the FADT\n");
 -              goto error0;
 -      }
  #ifdef CONFIG_X86
        if (!acpi_ioapic) {
 -              extern acpi_interrupt_flags acpi_sci_flags;
 +              extern u8 acpi_sci_flags;
  
                /* compatible (0) means level (3) */
 -              if (acpi_sci_flags.trigger == 0)
 -                      acpi_sci_flags.trigger = 3;
 -
 +              if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
 +                      acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
 +                      acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
 +              }
                /* Set PIC-mode SCI trigger type */
 -              acpi_pic_sci_set_trigger(acpi_fadt.sci_int,
 -                                       acpi_sci_flags.trigger);
 +              acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
 +                                       (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
        } else {
                extern int acpi_sci_override_gsi;
                /*
 -               * now that acpi_fadt is initialized,
 +               * now that acpi_gbl_FADT is initialized,
                 * update it with result from INT_SRC_OVR parsing
                 */
 -              acpi_fadt.sci_int = acpi_sci_override_gsi;
 +              acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
        }
  #endif
  
diff --combined drivers/acpi/button.c
@@@ -29,7 -29,6 +29,7 @@@
  #include <linux/types.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
 +#include <linux/input.h>
  #include <acpi/acpi_bus.h>
  #include <acpi/acpi_drivers.h>
  
@@@ -63,7 -62,7 +63,7 @@@
  #define _COMPONENT            ACPI_BUTTON_COMPONENT
  ACPI_MODULE_NAME("acpi_button")
  
 -    MODULE_AUTHOR("Paul Diefenbaugh");
 +MODULE_AUTHOR("Paul Diefenbaugh");
  MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
  MODULE_LICENSE("GPL");
  
@@@ -75,18 -74,16 +75,18 @@@ static int acpi_button_state_open_fs(st
  static struct acpi_driver acpi_button_driver = {
        .name = ACPI_BUTTON_DRIVER_NAME,
        .class = ACPI_BUTTON_CLASS,
-       .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E",
+       .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
        .ops = {
                .add = acpi_button_add,
                .remove = acpi_button_remove,
 -              },
 +      },
  };
  
  struct acpi_button {
        struct acpi_device *device;     /* Fixed button kludge */
 -      u8 type;
 +      unsigned int type;
 +      struct input_dev *input;
 +      char phys[32];                  /* for input device */
        unsigned long pushed;
  };
  
@@@ -112,7 -109,8 +112,7 @@@ static struct proc_dir_entry *acpi_butt
  
  static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_button *button = (struct acpi_button *)seq->private;
 -
 +      struct acpi_button *button = seq->private;
  
        if (!button || !button->device)
                return 0;
@@@ -130,17 -128,22 +130,17 @@@ static int acpi_button_info_open_fs(str
  
  static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_button *button = (struct acpi_button *)seq->private;
 +      struct acpi_button *button = seq->private;
        acpi_status status;
        unsigned long state;
  
 -
        if (!button || !button->device)
                return 0;
  
        status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
 -      if (ACPI_FAILURE(status)) {
 -              seq_printf(seq, "state:      unsupported\n");
 -      } else {
 -              seq_printf(seq, "state:      %s\n",
 -                         (state ? "open" : "closed"));
 -      }
 -
 +      seq_printf(seq, "state:      %s\n",
 +                 ACPI_FAILURE(status) ? "unsupported" :
 +                      (state ? "open" : "closed"));
        return 0;
  }
  
@@@ -156,7 -159,8 +156,7 @@@ static struct proc_dir_entry *acpi_lid_
  static int acpi_button_add_fs(struct acpi_device *device)
  {
        struct proc_dir_entry *entry = NULL;
 -      struct acpi_button *button = NULL;
 -
 +      struct acpi_button *button;
  
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
  static int acpi_button_remove_fs(struct acpi_device *device)
  {
 -      struct acpi_button *button = NULL;
 -
 +      struct acpi_button *button = acpi_driver_data(device);
  
 -      button = acpi_driver_data(device);
        if (acpi_device_dir(device)) {
                if (button->type == ACPI_BUTTON_TYPE_LID)
                        remove_proc_entry(ACPI_BUTTON_FILE_STATE,
  
  static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct acpi_button *button = (struct acpi_button *)data;
 -
 +      struct acpi_button *button = data;
 +      struct input_dev *input;
  
        if (!button || !button->device)
                return;
  
        switch (event) {
        case ACPI_BUTTON_NOTIFY_STATUS:
 +              input = button->input;
 +
 +              if (button->type == ACPI_BUTTON_TYPE_LID) {
 +                      struct acpi_handle *handle = button->device->handle;
 +                      unsigned long state;
 +
 +                      if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
 +                                                              NULL, &state)))
 +                              input_report_switch(input, SW_LID, !state);
 +
 +              } else {
 +                      int keycode = test_bit(KEY_SLEEP, input->keybit) ?
 +                                              KEY_SLEEP : KEY_POWER;
 +
 +                      input_report_key(input, keycode, 1);
 +                      input_sync(input);
 +                      input_report_key(input, keycode, 0);
 +              }
 +              input_sync(input);
 +
                acpi_bus_generate_event(button->device, event,
                                        ++button->pushed);
                break;
  
  static acpi_status acpi_button_notify_fixed(void *data)
  {
 -      struct acpi_button *button = (struct acpi_button *)data;
 -
 +      struct acpi_button *button = data;
  
        if (!button)
                return AE_BAD_PARAMETER;
        return AE_OK;
  }
  
 -static int acpi_button_add(struct acpi_device *device)
 +static int acpi_button_install_notify_handlers(struct acpi_button *button)
  {
 -      int result = 0;
 -      acpi_status status = AE_OK;
 -      struct acpi_button *button = NULL;
 +      acpi_status status;
  
 +      switch (button->type) {
 +      case ACPI_BUTTON_TYPE_POWERF:
 +              status =
 +                  acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
 +                                                   acpi_button_notify_fixed,
 +                                                   button);
 +              break;
 +      case ACPI_BUTTON_TYPE_SLEEPF:
 +              status =
 +                  acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
 +                                                   acpi_button_notify_fixed,
 +                                                   button);
 +              break;
 +      default:
 +              status = acpi_install_notify_handler(button->device->handle,
 +                                                   ACPI_DEVICE_NOTIFY,
 +                                                   acpi_button_notify,
 +                                                   button);
 +              break;
 +      }
 +
 +      return ACPI_FAILURE(status) ? -ENODEV : 0;
 +}
 +
 +static void acpi_button_remove_notify_handlers(struct acpi_button *button)
 +{
 +      switch (button->type) {
 +      case ACPI_BUTTON_TYPE_POWERF:
 +              acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
 +                                              acpi_button_notify_fixed);
 +              break;
 +      case ACPI_BUTTON_TYPE_SLEEPF:
 +              acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
 +                                              acpi_button_notify_fixed);
 +              break;
 +      default:
 +              acpi_remove_notify_handler(button->device->handle,
 +                                         ACPI_DEVICE_NOTIFY,
 +                                         acpi_button_notify);
 +              break;
 +      }
 +}
 +
 +static int acpi_button_add(struct acpi_device *device)
 +{
 +      int error;
 +      struct acpi_button *button;
 +      struct input_dev *input;
  
        if (!device)
                return -EINVAL;
  
 -      button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL);
 +      button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
        if (!button)
                return -ENOMEM;
 -      memset(button, 0, sizeof(struct acpi_button));
  
        button->device = device;
        acpi_driver_data(device) = button;
  
 +      button->input = input = input_allocate_device();
 +      if (!input) {
 +              error = -ENOMEM;
 +              goto err_free_button;
 +      }
 +
        /*
         * Determine the button type (via hid), as fixed-feature buttons
         * need to be handled a bit differently than generic-space.
        } else {
                printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
                            acpi_device_hid(device));
 -              result = -ENODEV;
 -              goto end;
 +              error = -ENODEV;
 +              goto err_free_input;
        }
  
 -      result = acpi_button_add_fs(device);
 -      if (result)
 -              goto end;
 +      error = acpi_button_add_fs(device);
 +      if (error)
 +              goto err_free_input;
 +
 +      error = acpi_button_install_notify_handlers(button);
 +      if (error)
 +              goto err_remove_fs;
 +
 +      snprintf(button->phys, sizeof(button->phys),
 +               "%s/button/input0", acpi_device_hid(device));
 +
 +      input->name = acpi_device_name(device);
 +      input->phys = button->phys;
 +      input->id.bustype = BUS_HOST;
 +      input->id.product = button->type;
  
        switch (button->type) {
 +      case ACPI_BUTTON_TYPE_POWER:
        case ACPI_BUTTON_TYPE_POWERF:
 -              status =
 -                  acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
 -                                                   acpi_button_notify_fixed,
 -                                                   button);
 +              input->evbit[0] = BIT(EV_KEY);
 +              set_bit(KEY_POWER, input->keybit);
                break;
 +
 +      case ACPI_BUTTON_TYPE_SLEEP:
        case ACPI_BUTTON_TYPE_SLEEPF:
 -              status =
 -                  acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
 -                                                   acpi_button_notify_fixed,
 -                                                   button);
 +              input->evbit[0] = BIT(EV_KEY);
 +              set_bit(KEY_SLEEP, input->keybit);
                break;
 -      default:
 -              status = acpi_install_notify_handler(device->handle,
 -                                                   ACPI_DEVICE_NOTIFY,
 -                                                   acpi_button_notify,
 -                                                   button);
 +
 +      case ACPI_BUTTON_TYPE_LID:
 +              input->evbit[0] = BIT(EV_SW);
 +              set_bit(SW_LID, input->swbit);
                break;
        }
  
 -      if (ACPI_FAILURE(status)) {
 -              result = -ENODEV;
 -              goto end;
 -      }
 +      error = input_register_device(input);
 +      if (error)
 +              goto err_remove_handlers;
  
        if (device->wakeup.flags.valid) {
                /* Button's GPE is run-wake GPE */
        printk(KERN_INFO PREFIX "%s [%s]\n",
               acpi_device_name(device), acpi_device_bid(device));
  
 -      end:
 -      if (result) {
 -              acpi_button_remove_fs(device);
 -              kfree(button);
 -      }
 +      return 0;
  
 -      return result;
 + err_remove_handlers:
 +      acpi_button_remove_notify_handlers(button);
 + err_remove_fs:
 +      acpi_button_remove_fs(device);
 + err_free_input:
 +      input_free_device(input);
 + err_free_button:
 +      kfree(button);
 +      return error;
  }
  
  static int acpi_button_remove(struct acpi_device *device, int type)
  {
 -      acpi_status status = 0;
 -      struct acpi_button *button = NULL;
 -
 +      struct acpi_button *button;
  
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
        button = acpi_driver_data(device);
  
 -      /* Unregister for device notifications. */
 -      switch (button->type) {
 -      case ACPI_BUTTON_TYPE_POWERF:
 -              status =
 -                  acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
 -                                                  acpi_button_notify_fixed);
 -              break;
 -      case ACPI_BUTTON_TYPE_SLEEPF:
 -              status =
 -                  acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
 -                                                  acpi_button_notify_fixed);
 -              break;
 -      default:
 -              status = acpi_remove_notify_handler(device->handle,
 -                                                  ACPI_DEVICE_NOTIFY,
 -                                                  acpi_button_notify);
 -              break;
 -      }
 -
 +      acpi_button_remove_notify_handlers(button);
        acpi_button_remove_fs(device);
 -
 +      input_unregister_device(button->input);
        kfree(button);
  
        return 0;
  
  static int __init acpi_button_init(void)
  {
 -      int result = 0;
 -
 +      int result;
  
        acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
        if (!acpi_button_dir)
  
  static void __exit acpi_button_exit(void)
  {
 -
        acpi_bus_unregister_driver(&acpi_button_driver);
  
        if (acpi_power_dir)
        if (acpi_lid_dir)
                remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
        remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
 -
 -      return;
  }
  
  module_init(acpi_button_init);
diff --combined drivers/acpi/container.c
@@@ -96,10 -96,11 +96,10 @@@ static int acpi_container_add(struct ac
                return -EINVAL;
        }
  
 -      container = kmalloc(sizeof(struct acpi_container), GFP_KERNEL);
 +      container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
        if (!container)
                return -ENOMEM;
  
 -      memset(container, 0, sizeof(struct acpi_container));
        container->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
@@@ -116,7 -117,7 +116,7 @@@ static int acpi_container_remove(struc
        acpi_status status = AE_OK;
        struct acpi_container *pc = NULL;
  
 -      pc = (struct acpi_container *)acpi_driver_data(device);
 +      pc = acpi_driver_data(device);
        kfree(pc);
        return status;
  }
@@@ -167,7 -168,7 +167,7 @@@ static void container_notify_cb(acpi_ha
                        if (ACPI_FAILURE(status) || !device) {
                                result = container_device_add(&device, handle);
                                if (!result)
-                                       kobject_uevent(&device->kobj,
+                                       kobject_uevent(&device->dev.kobj,
                                                       KOBJ_ONLINE);
                                else
                                        printk("Failed to add container\n");
                } else {
                        if (ACPI_SUCCESS(status)) {
                                /* device exist and this is a remove request */
-                               kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+                               kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
                        }
                }
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
                if (!acpi_bus_get_device(handle, &device) && device) {
-                       kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+                       kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
                }
                break;
        default:
diff --combined drivers/acpi/fan.c
@@@ -48,8 -48,8 +48,8 @@@ MODULE_LICENSE("GPL")
  
  static int acpi_fan_add(struct acpi_device *device);
  static int acpi_fan_remove(struct acpi_device *device, int type);
- static int acpi_fan_suspend(struct acpi_device *device, int state);
- static int acpi_fan_resume(struct acpi_device *device, int state);
+ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
+ static int acpi_fan_resume(struct acpi_device *device);
  
  static struct acpi_driver acpi_fan_driver = {
        .name = ACPI_FAN_DRIVER_NAME,
@@@ -99,8 -99,8 +99,8 @@@ acpi_fan_write_state(struct file *file
                     size_t count, loff_t * ppos)
  {
        int result = 0;
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_fan *fan = (struct acpi_fan *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_fan *fan = m->private;
        char state_string[12] = { '\0' };
  
  
@@@ -186,9 -186,10 +186,9 @@@ static int acpi_fan_add(struct acpi_dev
        if (!device)
                return -EINVAL;
  
 -      fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL);
 +      fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL);
        if (!fan)
                return -ENOMEM;
 -      memset(fan, 0, sizeof(struct acpi_fan));
  
        fan->device = device;
        strcpy(acpi_device_name(device), "Fan");
@@@ -228,7 -229,7 +228,7 @@@ static int acpi_fan_remove(struct acpi_
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      fan = (struct acpi_fan *)acpi_driver_data(device);
 +      fan = acpi_driver_data(device);
  
        acpi_fan_remove_fs(device);
  
        return 0;
  }
  
- static int acpi_fan_suspend(struct acpi_device *device, int state)
+ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
  {
        if (!device)
                return -EINVAL;
        return AE_OK;
  }
  
- static int acpi_fan_resume(struct acpi_device *device, int state)
+ static int acpi_fan_resume(struct acpi_device *device)
  {
        int result = 0;
        int power_state = 0;
@@@ -33,8 -33,7 +33,7 @@@
  ACPI_MODULE_NAME("acpi_motherboard")
  
  /* Dell use PNP0C01 instead of PNP0C02 */
- #define ACPI_MB_HID1                  "PNP0C01"
- #define ACPI_MB_HID2                  "PNP0C02"
+ #define ACPI_MB_HID                   "PNP0C01,PNP0C02"
  /**
   * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
   * Doesn't care about the failure of 'request_region', since other may reserve
@@@ -110,19 -109,10 +109,10 @@@ static int acpi_motherboard_add(struct 
        return 0;
  }
  
- static struct acpi_driver acpi_motherboard_driver1 = {
+ static struct acpi_driver acpi_motherboard_driver = {
        .name = "motherboard",
        .class = "",
-       .ids = ACPI_MB_HID1,
-       .ops = {
-               .add = acpi_motherboard_add,
-               },
- };
- static struct acpi_driver acpi_motherboard_driver2 = {
-       .name = "motherboard",
-       .class = "",
-       .ids = ACPI_MB_HID2,
+       .ids = ACPI_MB_HID,
        .ops = {
                .add = acpi_motherboard_add,
                },
@@@ -134,47 -124,46 +124,46 @@@ static void __init acpi_request_region 
        if (!addr->address || !length)
                return;
  
 -      if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_IO)
 +      if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
                request_region(addr->address, length, desc);
 -      else if (addr->address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 +      else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
                request_mem_region(addr->address, length, desc);
  }
  
  static void __init acpi_reserve_resources(void)
  {
 -      acpi_request_region(&acpi_gbl_FADT->xpm1a_evt_blk,
 -                             acpi_gbl_FADT->pm1_evt_len, "ACPI PM1a_EVT_BLK");
 +      acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block,
 +                             acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK");
  
 -      acpi_request_region(&acpi_gbl_FADT->xpm1b_evt_blk,
 -                             acpi_gbl_FADT->pm1_evt_len, "ACPI PM1b_EVT_BLK");
 +      acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block,
 +                             acpi_gbl_FADT.pm1_event_length, "ACPI PM1b_EVT_BLK");
  
 -      acpi_request_region(&acpi_gbl_FADT->xpm1a_cnt_blk,
 -                             acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1a_CNT_BLK");
 +      acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block,
 +                             acpi_gbl_FADT.pm1_control_length, "ACPI PM1a_CNT_BLK");
  
 -      acpi_request_region(&acpi_gbl_FADT->xpm1b_cnt_blk,
 -                             acpi_gbl_FADT->pm1_cnt_len, "ACPI PM1b_CNT_BLK");
 +      acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block,
 +                             acpi_gbl_FADT.pm1_control_length, "ACPI PM1b_CNT_BLK");
  
 -      if (acpi_gbl_FADT->pm_tm_len == 4)
 -              acpi_request_region(&acpi_gbl_FADT->xpm_tmr_blk, 4, "ACPI PM_TMR");
 +      if (acpi_gbl_FADT.pm_timer_length == 4)
 +              acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
  
 -      acpi_request_region(&acpi_gbl_FADT->xpm2_cnt_blk,
 -                             acpi_gbl_FADT->pm2_cnt_len, "ACPI PM2_CNT_BLK");
 +      acpi_request_region(&acpi_gbl_FADT.xpm2_control_block,
 +                             acpi_gbl_FADT.pm2_control_length, "ACPI PM2_CNT_BLK");
  
        /* Length of GPE blocks must be a non-negative multiple of 2 */
  
 -      if (!(acpi_gbl_FADT->gpe0_blk_len & 0x1))
 -              acpi_request_region(&acpi_gbl_FADT->xgpe0_blk,
 -                             acpi_gbl_FADT->gpe0_blk_len, "ACPI GPE0_BLK");
 +      if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
 +              acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
 +                             acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
  
 -      if (!(acpi_gbl_FADT->gpe1_blk_len & 0x1))
 -              acpi_request_region(&acpi_gbl_FADT->xgpe1_blk,
 -                             acpi_gbl_FADT->gpe1_blk_len, "ACPI GPE1_BLK");
 +      if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
 +              acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
 +                             acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
  }
  
  static int __init acpi_motherboard_init(void)
  {
-       acpi_bus_register_driver(&acpi_motherboard_driver1);
-       acpi_bus_register_driver(&acpi_motherboard_driver2);
+       acpi_bus_register_driver(&acpi_motherboard_driver);
        /*
         * Guarantee motherboard IO reservation first
         * This module must run after scan.c
diff --combined drivers/acpi/pci_root.c
@@@ -98,12 -98,11 +98,12 @@@ void acpi_pci_unregister_driver(struct 
  
        struct acpi_pci_driver **pptr = &sub_driver;
        while (*pptr) {
 -              if (*pptr != driver)
 -                      continue;
 -              *pptr = (*pptr)->next;
 -              break;
 +              if (*pptr == driver)
 +                      break;
 +              pptr = &(*pptr)->next;
        }
 +      BUG_ON(!*pptr);
 +      *pptr = (*pptr)->next;
  
        if (!driver->remove)
                return;
  
  EXPORT_SYMBOL(acpi_pci_unregister_driver);
  
 +acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
 +{
 +      struct acpi_pci_root *tmp;
 +      
 +      list_for_each_entry(tmp, &acpi_pci_roots, node) {
 +              if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus))
 +                      return tmp->device->handle;
 +      }
 +      return NULL;            
 +}
 +
 +EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
 +
  static acpi_status
  get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
  {
 -      int *busnr = (int *)data;
 +      int *busnr = data;
        struct acpi_resource_address64 address;
  
        if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@@ -165,6 -151,21 +165,21 @@@ static acpi_status try_get_root_bridge_
        return AE_OK;
  }
  
+ static void acpi_pci_bridge_scan(struct acpi_device *device)
+ {
+       int status;
+       struct acpi_device *child = NULL;
+       if (device->flags.bus_address)
+               if (device->parent && device->parent->ops.bind) {
+                       status = device->parent->ops.bind(device);
+                       if (!status) {
+                               list_for_each_entry(child, &device->children, node)
+                                       acpi_pci_bridge_scan(child);
+                       }
+               }
+ }
  static int acpi_pci_root_add(struct acpi_device *device)
  {
        int result = 0;
        acpi_status status = AE_OK;
        unsigned long value = 0;
        acpi_handle handle = NULL;
+       struct acpi_device *child;
  
  
        if (!device)
                return -EINVAL;
  
 -      root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
 +      root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
        if (!root)
                return -ENOMEM;
 -      memset(root, 0, sizeof(struct acpi_pci_root));
        INIT_LIST_HEAD(&root->node);
  
        root->device = device;
        strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
        acpi_driver_data(device) = root;
  
-       /*
-        * TBD: Doesn't the bus driver automatically set this?
-        */
        device->ops.bind = acpi_pci_bind;
  
        /* 
                result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
                                              root->id.bus);
  
+       /*
+        * Scan and bind all _ADR-Based Devices
+        */
+       list_for_each_entry(child, &device->children, node)
+               acpi_pci_bridge_scan(child);
        end:
        if (result) {
                if (!list_empty(&root->node))
@@@ -344,7 -350,7 +363,7 @@@ static int acpi_pci_root_remove(struct 
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      root = (struct acpi_pci_root *)acpi_driver_data(device);
 +      root = acpi_driver_data(device);
  
        kfree(root);
  
@@@ -277,7 -277,7 +277,7 @@@ static struct proc_dir_entry *acpi_proc
  
  static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_processor *pr = (struct acpi_processor *)seq->private;
 +      struct acpi_processor *pr = seq->private;
  
  
        if (!pr)
@@@ -375,126 -375,30 +375,126 @@@ static int acpi_processor_remove_fs(str
  }
  
  /* Use the acpiid in MADT to map cpus in case of SMP */
 +
  #ifndef CONFIG_SMP
 -#define convert_acpiid_to_cpu(acpi_id) (-1)
 +static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;}
  #else
  
 +static struct acpi_table_madt *madt;
 +
 +static int map_lapic_id(struct acpi_subtable_header *entry,
 +               u32 acpi_id, int *apic_id)
 +{
 +      struct acpi_madt_local_apic *lapic =
 +              (struct acpi_madt_local_apic *)entry;
 +      if ((lapic->lapic_flags & ACPI_MADT_ENABLED) &&
 +          lapic->processor_id == acpi_id) {
 +              *apic_id = lapic->id;
 +              return 1;
 +      }
 +      return 0;
 +}
 +
 +static int map_lsapic_id(struct acpi_subtable_header *entry,
 +                u32 acpi_id, int *apic_id)
 +{
 +      struct acpi_madt_local_sapic *lsapic =
 +              (struct acpi_madt_local_sapic *)entry;
 +      /* Only check enabled APICs*/
 +      if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
 +              /* First check against id */
 +              if (lsapic->processor_id == acpi_id) {
 +                      *apic_id = lsapic->id;
 +                      return 1;
 +              /* Check against optional uid */
 +              } else if (entry->length >= 16 &&
 +                      lsapic->uid == acpi_id) {
 +                      *apic_id = lsapic->uid;
 +                      return 1;
 +              }
 +      }
 +      return 0;
 +}
 +
  #ifdef CONFIG_IA64
 -#define arch_acpiid_to_apicid         ia64_acpiid_to_sapicid
  #define arch_cpu_to_apicid    ia64_cpu_to_sapicid
 -#define ARCH_BAD_APICID               (0xffff)
  #else
 -#define arch_acpiid_to_apicid         x86_acpiid_to_apicid
  #define arch_cpu_to_apicid    x86_cpu_to_apicid
 -#define ARCH_BAD_APICID               (0xff)
  #endif
  
 -static int convert_acpiid_to_cpu(u8 acpi_id)
 +static int map_madt_entry(u32 acpi_id)
 +{
 +      unsigned long madt_end, entry;
 +      int apic_id = -1;
 +
 +      if (!madt)
 +              return apic_id;
 +
 +      entry = (unsigned long)madt;
 +      madt_end = entry + madt->header.length;
 +
 +      /* Parse all entries looking for a match. */
 +
 +      entry += sizeof(struct acpi_table_madt);
 +      while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
 +              struct acpi_subtable_header *header =
 +                      (struct acpi_subtable_header *)entry;
 +              if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
 +                      if (map_lapic_id(header, acpi_id, &apic_id))
 +                              break;
 +              } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 +                      if (map_lsapic_id(header, acpi_id, &apic_id))
 +                              break;
 +              }
 +              entry += header->length;
 +      }
 +      return apic_id;
 +}
 +
 +static int map_mat_entry(acpi_handle handle, u32 acpi_id)
 +{
 +      struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 +      union acpi_object *obj;
 +      struct acpi_subtable_header *header;
 +      int apic_id = -1;
 +
 +      if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
 +              goto exit;
 +
 +      if (!buffer.length || !buffer.pointer)
 +              goto exit;
 +
 +      obj = buffer.pointer;
 +      if (obj->type != ACPI_TYPE_BUFFER ||
 +          obj->buffer.length < sizeof(struct acpi_subtable_header)) {
 +              goto exit;
 +      }
 +
 +      header = (struct acpi_subtable_header *)obj->buffer.pointer;
 +      if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
 +              map_lapic_id(header, acpi_id, &apic_id);
 +      } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 +              map_lsapic_id(header, acpi_id, &apic_id);
 +      }
 +
 +exit:
 +      if (buffer.pointer)
 +              kfree(buffer.pointer);
 +      return apic_id;
 +}
 +
 +static int get_cpu_id(acpi_handle handle, u32 acpi_id)
  {
 -      u16 apic_id;
        int i;
 +      int apic_id = -1;
  
 -      apic_id = arch_acpiid_to_apicid[acpi_id];
 -      if (apic_id == ARCH_BAD_APICID)
 -              return -1;
 +      apic_id = map_mat_entry(handle, acpi_id);
 +      if (apic_id == -1)
 +              apic_id = map_madt_entry(acpi_id);
 +      if (apic_id == -1)
 +              return apic_id;
  
 -      for (i = 0; i < NR_CPUS; i++) {
 +      for (i = 0; i < NR_CPUS; ++i) {
                if (arch_cpu_to_apicid[i] == apic_id)
                        return i;
        }
                                   Driver Interface
     -------------------------------------------------------------------------- */
  
 -static int acpi_processor_get_info(struct acpi_processor *pr)
 +static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
  {
        acpi_status status = 0;
        union acpi_object object = { 0 };
         * Check to see if we have bus mastering arbitration control.  This
         * is required for proper C3 usage (to maintain cache coherency).
         */
 -      if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) {
 +      if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
                pr->flags.bm_control = 1;
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Bus mastering arbitration control present\n"));
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "No bus mastering arbitration control\n"));
  
 -      /*
 -       * Evalute the processor object.  Note that it is common on SMP to
 -       * have the first (boot) processor with a valid PBLK address while
 -       * all others have a NULL address.
 -       */
 -      status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
 -      if (ACPI_FAILURE(status)) {
 -              printk(KERN_ERR PREFIX "Evaluating processor object\n");
 -              return -ENODEV;
 -      }
 -
 -      /*
 -       * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
 -       *      >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
 -       */
 -      pr->acpi_id = object.processor.proc_id;
 +      /* Check if it is a Device with HID and UID */
 +      if (has_uid) {
 +              unsigned long value;
 +              status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
 +                                              NULL, &value);
 +              if (ACPI_FAILURE(status)) {
 +                      printk(KERN_ERR PREFIX "Evaluating processor _UID\n");
 +                      return -ENODEV;
 +              }
 +              pr->acpi_id = value;
 +      } else {
 +              /*
 +              * Evalute the processor object.  Note that it is common on SMP to
 +              * have the first (boot) processor with a valid PBLK address while
 +              * all others have a NULL address.
 +              */
 +              status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
 +              if (ACPI_FAILURE(status)) {
 +                      printk(KERN_ERR PREFIX "Evaluating processor object\n");
 +                      return -ENODEV;
 +              }
  
 -      cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
 +              /*
 +              * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
 +              *      >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
 +              */
 +              pr->acpi_id = object.processor.proc_id;
 +      }
 +      cpu_index = get_cpu_id(pr->handle, pr->acpi_id);
  
        /* Handle UP system running SMP kernel, with no LAPIC in MADT */
        if (!cpu0_initialized && (cpu_index == -1) &&
         *  less than the max # of CPUs. They should be ignored _iff
         *  they are physically not present.
         */
 -      if (cpu_index == -1) {
 +      if (pr->id == -1) {
                if (ACPI_FAILURE
                    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
 -                      printk(KERN_ERR PREFIX
 -                                  "Getting cpuindex for acpiid 0x%x\n",
 -                                  pr->acpi_id);
                        return -ENODEV;
                }
        }
                            object.processor.pblk_length);
        else {
                pr->throttling.address = object.processor.pblk_address;
 -              pr->throttling.duty_offset = acpi_fadt.duty_offset;
 -              pr->throttling.duty_width = acpi_fadt.duty_width;
 +              pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
 +              pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
  
                pr->pblk = object.processor.pblk_address;
  
@@@ -632,7 -528,7 +632,7 @@@ static int __cpuinit acpi_processor_sta
  
        pr = acpi_driver_data(device);
  
 -      result = acpi_processor_get_info(pr);
 +      result = acpi_processor_get_info(pr, device->flags.unique_id);
        if (result) {
                /* Processor is physically not present */
                return 0;
         * Don't trust it blindly
         */
        if (processor_device_array[pr->id] != NULL &&
 -          processor_device_array[pr->id] != (void *)device) {
 +          processor_device_array[pr->id] != device) {
                printk(KERN_WARNING "BIOS reported wrong ACPI id"
                        "for the processor\n");
                return -ENODEV;
        }
 -      processor_device_array[pr->id] = (void *)device;
 +      processor_device_array[pr->id] = device;
  
        processors[pr->id] = pr;
  
  
  static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct acpi_processor *pr = (struct acpi_processor *)data;
 +      struct acpi_processor *pr = data;
        struct acpi_device *device = NULL;
  
  
@@@ -719,9 -615,10 +719,9 @@@ static int acpi_processor_add(struct ac
        if (!device)
                return -EINVAL;
  
 -      pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
 +      pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
        if (!pr)
                return -ENOMEM;
 -      memset(pr, 0, sizeof(struct acpi_processor));
  
        pr->handle = device->handle;
        strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
@@@ -740,7 -637,7 +740,7 @@@ static int acpi_processor_remove(struc
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      pr = (struct acpi_processor *)acpi_driver_data(device);
 +      pr = acpi_driver_data(device);
  
        if (pr->id >= NR_CPUS) {
                kfree(pr);
@@@ -814,7 -711,7 +814,7 @@@ int acpi_processor_device_add(acpi_hand
                return -ENODEV;
  
        if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
-               kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
+               kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
        }
        return 0;
  }
@@@ -852,13 -749,13 +852,13 @@@ acpi_processor_hotplug_notify(acpi_hand
                }
  
                if (pr->id >= 0 && (pr->id < NR_CPUS)) {
-                       kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+                       kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
                        break;
                }
  
                result = acpi_processor_start(device);
                if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
-                       kobject_uevent(&device->kobj, KOBJ_ONLINE);
+                       kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
                } else {
                        printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
                                    acpi_device_bid(device));
                }
  
                if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
-                       kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+                       kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
                break;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@@ -1002,21 -899,15 +1002,21 @@@ static int __init acpi_processor_init(v
        memset(&processors, 0, sizeof(processors));
        memset(&errata, 0, sizeof(errata));
  
 +#ifdef CONFIG_SMP
 +      if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
 +                              (struct acpi_table_header **)&madt)))
 +              madt = 0;
 +#endif
 +
        acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
        if (!acpi_processor_dir)
 -              return 0;
 +              return -ENOMEM;
        acpi_processor_dir->owner = THIS_MODULE;
  
        result = acpi_bus_register_driver(&acpi_processor_driver);
        if (result < 0) {
                remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 -              return 0;
 +              return result;
        }
  
        acpi_processor_install_hotplug_notify();
diff --combined drivers/acpi/scan.c
@@@ -21,470 -21,408 +21,408 @@@ extern struct acpi_device *acpi_root
  #define ACPI_BUS_DEVICE_NAME          "System Bus"
  
  static LIST_HEAD(acpi_device_list);
+ static LIST_HEAD(acpi_bus_id_list);
  DEFINE_SPINLOCK(acpi_device_lock);
  LIST_HEAD(acpi_wakeup_device_list);
  
- static void acpi_device_release(struct kobject *kobj)
- {
-       struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
-       kfree(dev->pnp.cid_list);
-       kfree(dev);
- }
- struct acpi_device_attribute {
-       struct attribute attr;
-        ssize_t(*show) (struct acpi_device *, char *);
-        ssize_t(*store) (struct acpi_device *, const char *, size_t);
+ struct acpi_device_bus_id{
+       char bus_id[15];
+       unsigned int instance_no;
+       struct list_head node;
  };
- typedef void acpi_device_sysfs_files(struct kobject *,
-                                    const struct attribute *);
- static void setup_sys_fs_device_files(struct acpi_device *dev,
-                                     acpi_device_sysfs_files * func);
- #define create_sysfs_device_files(dev)        \
-       setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file)
- #define remove_sysfs_device_files(dev)        \
-       setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file)
- #define to_acpi_device(n) container_of(n, struct acpi_device, kobj)
- #define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr);
- static ssize_t acpi_device_attr_show(struct kobject *kobj,
-                                    struct attribute *attr, char *buf)
- {
-       struct acpi_device *device = to_acpi_device(kobj);
-       struct acpi_device_attribute *attribute = to_handle_attr(attr);
-       return attribute->show ? attribute->show(device, buf) : -EIO;
- }
- static ssize_t acpi_device_attr_store(struct kobject *kobj,
-                                     struct attribute *attr, const char *buf,
-                                     size_t len)
+ static int acpi_eject_operation(acpi_handle handle, int lockable)
  {
-       struct acpi_device *device = to_acpi_device(kobj);
-       struct acpi_device_attribute *attribute = to_handle_attr(attr);
-       return attribute->store ? attribute->store(device, buf, len) : -EIO;
- }
- static struct sysfs_ops acpi_device_sysfs_ops = {
-       .show = acpi_device_attr_show,
-       .store = acpi_device_attr_store,
- };
+       struct acpi_object_list arg_list;
+       union acpi_object arg;
+       acpi_status status = AE_OK;
  
- static struct kobj_type ktype_acpi_ns = {
-       .sysfs_ops = &acpi_device_sysfs_ops,
-       .release = acpi_device_release,
- };
+       /*
+        * TBD: evaluate _PS3?
+        */
  
- static int namespace_uevent(struct kset *kset, struct kobject *kobj,
-                            char **envp, int num_envp, char *buffer,
-                            int buffer_size)
- {
-       struct acpi_device *dev = to_acpi_device(kobj);
-       int i = 0;
-       int len = 0;
+       if (lockable) {
+               arg_list.count = 1;
+               arg_list.pointer = &arg;
+               arg.type = ACPI_TYPE_INTEGER;
+               arg.integer.value = 0;
+               acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
+       }
  
-       if (!dev->driver)
-               return 0;
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+       arg.type = ACPI_TYPE_INTEGER;
+       arg.integer.value = 1;
  
-       if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
-                          "PHYSDEVDRIVER=%s", dev->driver->name))
-               return -ENOMEM;
+       /*
+        * TBD: _EJD support.
+        */
  
-       envp[i] = NULL;
+       status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
+       if (ACPI_FAILURE(status)) {
+               return (-ENODEV);
+       }
  
-       return 0;
+       return (0);
  }
  
- static struct kset_uevent_ops namespace_uevent_ops = {
-       .uevent = &namespace_uevent,
- };
+ static ssize_t
+ acpi_eject_store(struct device *d, struct device_attribute *attr,
+               const char *buf, size_t count)
+ {
+       int result;
+       int ret = count;
+       int islockable;
+       acpi_status status;
+       acpi_handle handle;
+       acpi_object_type type = 0;
+       struct acpi_device *acpi_device = to_acpi_device(d);
  
- static struct kset acpi_namespace_kset = {
-       .kobj = {
-                .name = "namespace",
-                },
-       .subsys = &acpi_subsys,
-       .ktype = &ktype_acpi_ns,
-       .uevent_ops = &namespace_uevent_ops,
- };
+       if ((!count) || (buf[0] != '1')) {
+               return -EINVAL;
+       }
+ #ifndef FORCE_EJECT
+       if (acpi_device->driver == NULL) {
+               ret = -ENODEV;
+               goto err;
+       }
+ #endif
+       status = acpi_get_type(acpi_device->handle, &type);
+       if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
+               ret = -ENODEV;
+               goto err;
+       }
  
- static void acpi_device_register(struct acpi_device *device,
-                                struct acpi_device *parent)
- {
-       int err;
+       islockable = acpi_device->flags.lockable;
+       handle = acpi_device->handle;
  
-       /*
-        * Linkage
-        * -------
-        * Link this device to its parent and siblings.
-        */
-       INIT_LIST_HEAD(&device->children);
-       INIT_LIST_HEAD(&device->node);
-       INIT_LIST_HEAD(&device->g_list);
-       INIT_LIST_HEAD(&device->wakeup_list);
+       result = acpi_bus_trim(acpi_device, 1);
  
-       spin_lock(&acpi_device_lock);
-       if (device->parent) {
-               list_add_tail(&device->node, &device->parent->children);
-               list_add_tail(&device->g_list, &device->parent->g_list);
-       } else
-               list_add_tail(&device->g_list, &acpi_device_list);
-       if (device->wakeup.flags.valid)
-               list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
-       spin_unlock(&acpi_device_lock);
+       if (!result)
+               result = acpi_eject_operation(handle, islockable);
  
-       strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN);
-       if (parent)
-               device->kobj.parent = &parent->kobj;
-       device->kobj.ktype = &ktype_acpi_ns;
-       device->kobj.kset = &acpi_namespace_kset;
-       err = kobject_register(&device->kobj);
-       if (err < 0)
-               printk(KERN_WARNING "%s: kobject_register error: %d\n",
-                       __FUNCTION__, err);
-       create_sysfs_device_files(device);
+       if (result) {
+               ret = -EBUSY;
+       }
+       err:
+       return ret;
  }
  
- static void acpi_device_unregister(struct acpi_device *device, int type)
- {
-       spin_lock(&acpi_device_lock);
-       if (device->parent) {
-               list_del(&device->node);
-               list_del(&device->g_list);
-       } else
-               list_del(&device->g_list);
-       list_del(&device->wakeup_list);
+ static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
  
-       spin_unlock(&acpi_device_lock);
+ static ssize_t
+ acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
  
-       acpi_detach_data(device->handle, acpi_bus_data_handler);
-       remove_sysfs_device_files(device);
-       kobject_unregister(&device->kobj);
+       return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
  }
+ static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
  
- void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
- {
+ static ssize_t
+ acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
+       int result;
  
-       /* TBD */
+       result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
+       if(result)
+               goto end;
  
-       return;
+       result = sprintf(buf, "%s\n", (char*)path.pointer);
+       kfree(path.pointer);
+   end:
+       return result;
  }
+ static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
  
- static int acpi_bus_get_power_flags(struct acpi_device *device)
+ static int acpi_device_setup_files(struct acpi_device *dev)
  {
-       acpi_status status = 0;
-       acpi_handle handle = NULL;
-       u32 i = 0;
-       /*
-        * Power Management Flags
-        */
-       status = acpi_get_handle(device->handle, "_PSC", &handle);
-       if (ACPI_SUCCESS(status))
-               device->power.flags.explicit_get = 1;
-       status = acpi_get_handle(device->handle, "_IRC", &handle);
-       if (ACPI_SUCCESS(status))
-               device->power.flags.inrush_current = 1;
+       acpi_status status;
+       acpi_handle temp;
+       int result = 0;
  
        /*
-        * Enumerate supported power management states
+        * Devices gotten from FADT don't have a "path" attribute
         */
-       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
-               struct acpi_device_power_state *ps = &device->power.states[i];
-               char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
-               /* Evaluate "_PRx" to se if power resources are referenced */
-               acpi_evaluate_reference(device->handle, object_name, NULL,
-                                       &ps->resources);
-               if (ps->resources.count) {
-                       device->power.flags.power_resources = 1;
-                       ps->flags.valid = 1;
-               }
-               /* Evaluate "_PSx" to see if we can do explicit sets */
-               object_name[2] = 'S';
-               status = acpi_get_handle(device->handle, object_name, &handle);
-               if (ACPI_SUCCESS(status)) {
-                       ps->flags.explicit_set = 1;
-                       ps->flags.valid = 1;
-               }
-               /* State is valid if we have some power control */
-               if (ps->resources.count || ps->flags.explicit_set)
-                       ps->flags.valid = 1;
-               ps->power = -1; /* Unknown - driver assigned */
-               ps->latency = -1;       /* Unknown - driver assigned */
+       if(dev->handle) {
+               result = device_create_file(&dev->dev, &dev_attr_path);
+               if(result)
+                       goto end;
        }
  
-       /* Set defaults for D0 and D3 states (always valid) */
-       device->power.states[ACPI_STATE_D0].flags.valid = 1;
-       device->power.states[ACPI_STATE_D0].power = 100;
-       device->power.states[ACPI_STATE_D3].flags.valid = 1;
-       device->power.states[ACPI_STATE_D3].power = 0;
-       /* TBD: System wake support and resource requirements. */
-       device->power.state = ACPI_STATE_UNKNOWN;
+       if(dev->flags.hardware_id) {
+               result = device_create_file(&dev->dev, &dev_attr_hid);
+               if(result)
+                       goto end;
+       }
  
-       return 0;
+         /*
+          * If device has _EJ0, 'eject' file is created that is used to trigger
+          * hot-removal function from userland.
+          */
+       status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+       if (ACPI_SUCCESS(status))
+               result = device_create_file(&dev->dev, &dev_attr_eject);
+   end:
+       return result;
  }
  
int acpi_match_ids(struct acpi_device *device, char *ids)
static void acpi_device_remove_files(struct acpi_device *dev)
  {
-       if (device->flags.hardware_id)
-               if (strstr(ids, device->pnp.hardware_id))
-                       return 0;
+       acpi_status status;
+       acpi_handle temp;
  
-       if (device->flags.compatible_ids) {
-               struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
-               int i;
+       /*
+        * If device has _EJ0, 'eject' file is created that is used to trigger
+        * hot-removal function from userland.
+        */
+       status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+       if (ACPI_SUCCESS(status))
+               device_remove_file(&dev->dev, &dev_attr_eject);
  
-               /* compare multiple _CID entries against driver ids */
-               for (i = 0; i < cid_list->count; i++) {
-                       if (strstr(ids, cid_list->id[i].value))
-                               return 0;
-               }
-       }
-       return -ENOENT;
+       if(dev->flags.hardware_id)
+               device_remove_file(&dev->dev, &dev_attr_hid);
+       if(dev->handle)
+               device_remove_file(&dev->dev, &dev_attr_path);
  }
static acpi_status
- acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
                                           union acpi_object *package)
+ /* --------------------------------------------------------------------------
                      ACPI Bus operations
+    -------------------------------------------------------------------------- */
static void acpi_device_release(struct device *dev)
  {
-       int i = 0;
-       union acpi_object *element = NULL;
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
  
-       if (!device || !package || (package->package.count < 2))
-               return AE_BAD_PARAMETER;
-       element = &(package->package.elements[0]);
-       if (!element)
-               return AE_BAD_PARAMETER;
-       if (element->type == ACPI_TYPE_PACKAGE) {
-               if ((element->package.count < 2) ||
-                   (element->package.elements[0].type !=
-                    ACPI_TYPE_LOCAL_REFERENCE)
-                   || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
-                       return AE_BAD_DATA;
-               device->wakeup.gpe_device =
-                   element->package.elements[0].reference.handle;
-               device->wakeup.gpe_number =
-                   (u32) element->package.elements[1].integer.value;
-       } else if (element->type == ACPI_TYPE_INTEGER) {
-               device->wakeup.gpe_number = element->integer.value;
-       } else
-               return AE_BAD_DATA;
-       element = &(package->package.elements[1]);
-       if (element->type != ACPI_TYPE_INTEGER) {
-               return AE_BAD_DATA;
-       }
-       device->wakeup.sleep_state = element->integer.value;
-       if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
-               return AE_NO_MEMORY;
-       }
-       device->wakeup.resources.count = package->package.count - 2;
-       for (i = 0; i < device->wakeup.resources.count; i++) {
-               element = &(package->package.elements[i + 2]);
-               if (element->type != ACPI_TYPE_ANY) {
-                       return AE_BAD_DATA;
-               }
-               device->wakeup.resources.handles[i] = element->reference.handle;
-       }
-       return AE_OK;
+       kfree(acpi_dev->pnp.cid_list);
+       kfree(acpi_dev);
  }
  
- static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
+ static int acpi_device_suspend(struct device *dev, pm_message_t state)
  {
-       acpi_status status = 0;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       union acpi_object *package = NULL;
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_driver *acpi_drv = acpi_dev->driver;
  
+       if (acpi_drv && acpi_drv->ops.suspend)
+               return acpi_drv->ops.suspend(acpi_dev, state);
+       return 0;
+ }
  
-       /* _PRW */
-       status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
-               goto end;
-       }
-       package = (union acpi_object *)buffer.pointer;
-       status = acpi_bus_extract_wakeup_device_power_package(device, package);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
-               goto end;
-       }
-       kfree(buffer.pointer);
-       device->wakeup.flags.valid = 1;
-       /* Power button, Lid switch always enable wakeup */
-       if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
-               device->wakeup.flags.run_wake = 1;
+ static int acpi_device_resume(struct device *dev)
+ {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_driver *acpi_drv = acpi_dev->driver;
  
-       end:
-       if (ACPI_FAILURE(status))
-               device->flags.wake_capable = 0;
+       if (acpi_drv && acpi_drv->ops.resume)
+               return acpi_drv->ops.resume(acpi_dev);
        return 0;
  }
  
- /* --------------------------------------------------------------------------
-               ACPI sysfs device file support
-    -------------------------------------------------------------------------- */
- static ssize_t acpi_eject_store(struct acpi_device *device,
-                               const char *buf, size_t count);
- #define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
- static struct acpi_device_attribute acpi_device_attr_##_name = \
-               __ATTR(_name, _mode, _show, _store)
+ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
+ {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_driver *acpi_drv = to_acpi_driver(drv);
  
- ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
+       return !acpi_match_ids(acpi_dev, acpi_drv->ids);
+ }
  
- /**
-  * setup_sys_fs_device_files - sets up the device files under device namespace
-  * @dev:      acpi_device object
-  * @func:     function pointer to create or destroy the device file
-  */
- static void
- setup_sys_fs_device_files(struct acpi_device *dev,
-                         acpi_device_sysfs_files * func)
+ static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
+       char *buffer, int buffer_size)
  {
-       acpi_status status;
-       acpi_handle temp = NULL;
-       /*
-        * If device has _EJ0, 'eject' file is created that is used to trigger
-        * hot-removal function from userland.
-        */
-       status = acpi_get_handle(dev->handle, "_EJ0", &temp);
-       if (ACPI_SUCCESS(status))
-               (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr);
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       int i = 0, length = 0, ret = 0;
+       if (acpi_dev->flags.hardware_id)
+               ret = add_uevent_var(envp, num_envp, &i,
+                       buffer, buffer_size, &length,
+                       "HWID=%s", acpi_dev->pnp.hardware_id);
+       if (ret)
+               return -ENOMEM;
+       if (acpi_dev->flags.compatible_ids) {
+               int j;
+               struct acpi_compatible_id_list *cid_list;
+               cid_list = acpi_dev->pnp.cid_list;
+               for (j = 0; j < cid_list->count; j++) {
+                       ret = add_uevent_var(envp, num_envp, &i, buffer,
+                               buffer_size, &length, "COMPTID=%s",
+                               cid_list->id[j].value);
+                       if (ret)
+                               return -ENOMEM;
+               }
+       }
+       envp[i] = NULL;
+       return 0;
  }
  
- static int acpi_eject_operation(acpi_handle handle, int lockable)
+ static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
+ static int acpi_start_single_object(struct acpi_device *);
+ static int acpi_device_probe(struct device * dev)
  {
-       struct acpi_object_list arg_list;
-       union acpi_object arg;
-       acpi_status status = AE_OK;
-       /*
-        * TBD: evaluate _PS3?
-        */
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
+       int ret;
+       ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
+       if (!ret) {
+               if (acpi_dev->bus_ops.acpi_op_start)
+                       acpi_start_single_object(acpi_dev);
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                       "Found driver [%s] for device [%s]\n",
+                       acpi_drv->name, acpi_dev->pnp.bus_id));
+               get_device(dev);
+       }
+       return ret;
+ }
  
-       if (lockable) {
-               arg_list.count = 1;
-               arg_list.pointer = &arg;
-               arg.type = ACPI_TYPE_INTEGER;
-               arg.integer.value = 0;
-               acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
+ static int acpi_device_remove(struct device * dev)
+ {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_driver *acpi_drv = acpi_dev->driver;
+       if (acpi_drv) {
+               if (acpi_drv->ops.stop)
+                       acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
+               if (acpi_drv->ops.remove)
+                       acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
        }
+       acpi_dev->driver = NULL;
+       acpi_driver_data(dev) = NULL;
  
-       arg_list.count = 1;
-       arg_list.pointer = &arg;
-       arg.type = ACPI_TYPE_INTEGER;
-       arg.integer.value = 1;
+       put_device(dev);
+       return 0;
+ }
  
-       /*
-        * TBD: _EJD support.
-        */
+ static void acpi_device_shutdown(struct device *dev)
+ {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       struct acpi_driver *acpi_drv = acpi_dev->driver;
  
-       status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
-       if (ACPI_FAILURE(status)) {
-               return (-ENODEV);
-       }
+       if (acpi_drv && acpi_drv->ops.shutdown)
+               acpi_drv->ops.shutdown(acpi_dev);
  
-       return (0);
+       return ;
  }
  
- static ssize_t
- acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
+ static struct bus_type acpi_bus_type = {
+       .name           = "acpi",
+       .suspend        = acpi_device_suspend,
+       .resume         = acpi_device_resume,
+       .shutdown       = acpi_device_shutdown,
+       .match          = acpi_bus_match,
+       .probe          = acpi_device_probe,
+       .remove         = acpi_device_remove,
+       .uevent         = acpi_device_uevent,
+ };
+ static int acpi_device_register(struct acpi_device *device,
+                                struct acpi_device *parent)
  {
        int result;
-       int ret = count;
-       int islockable;
-       acpi_status status;
-       acpi_handle handle;
-       acpi_object_type type = 0;
+       struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
+       int found = 0;
+       /*
+        * Linkage
+        * -------
+        * Link this device to its parent and siblings.
+        */
+       INIT_LIST_HEAD(&device->children);
+       INIT_LIST_HEAD(&device->node);
+       INIT_LIST_HEAD(&device->g_list);
+       INIT_LIST_HEAD(&device->wakeup_list);
  
-       if ((!count) || (buf[0] != '1')) {
-               return -EINVAL;
+       new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
+       if (!new_bus_id) {
+               printk(KERN_ERR PREFIX "Memory allocation error\n");
+               return -ENOMEM;
        }
- #ifndef FORCE_EJECT
-       if (device->driver == NULL) {
-               ret = -ENODEV;
-               goto err;
+       spin_lock(&acpi_device_lock);
+       /*
+        * Find suitable bus_id and instance number in acpi_bus_id_list
+        * If failed, create one and link it into acpi_bus_id_list
+        */
+       list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
+               if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) {
+                       acpi_device_bus_id->instance_no ++;
+                       found = 1;
+                       kfree(new_bus_id);
+                       break;
+               }
        }
- #endif
-       status = acpi_get_type(device->handle, &type);
-       if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
-               ret = -ENODEV;
-               goto err;
+       if(!found) {
+               acpi_device_bus_id = new_bus_id;
+               strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device");
+               acpi_device_bus_id->instance_no = 0;
+               list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
        }
+       sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
  
-       islockable = device->flags.lockable;
-       handle = device->handle;
-       result = acpi_bus_trim(device, 1);
-       if (!result)
-               result = acpi_eject_operation(handle, islockable);
+       if (device->parent) {
+               list_add_tail(&device->node, &device->parent->children);
+               list_add_tail(&device->g_list, &device->parent->g_list);
+       } else
+               list_add_tail(&device->g_list, &acpi_device_list);
+       if (device->wakeup.flags.valid)
+               list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
+       spin_unlock(&acpi_device_lock);
  
-       if (result) {
-               ret = -EBUSY;
+       if (device->parent)
+               device->dev.parent = &parent->dev;
+       device->dev.bus = &acpi_bus_type;
+       device_initialize(&device->dev);
+       device->dev.release = &acpi_device_release;
+       result = device_add(&device->dev);
+       if(result) {
+               printk("Error adding device %s", device->dev.bus_id);
+               goto end;
        }
-       err:
-       return ret;
- }
  
- /* --------------------------------------------------------------------------
-                               Performance Management
-    -------------------------------------------------------------------------- */
+       result = acpi_device_setup_files(device);
+       if(result)
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
  
- static int acpi_bus_get_perf_flags(struct acpi_device *device)
- {
-       device->performance.state = ACPI_STATE_UNKNOWN;
+       device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
        return 0;
+   end:
+       spin_lock(&acpi_device_lock);
+       if (device->parent) {
+               list_del(&device->node);
+               list_del(&device->g_list);
+       } else
+               list_del(&device->g_list);
+       list_del(&device->wakeup_list);
+       spin_unlock(&acpi_device_lock);
+       return result;
  }
  
- /* --------------------------------------------------------------------------
-                                  Driver Management
-    -------------------------------------------------------------------------- */
+ static void acpi_device_unregister(struct acpi_device *device, int type)
+ {
+       spin_lock(&acpi_device_lock);
+       if (device->parent) {
+               list_del(&device->node);
+               list_del(&device->g_list);
+       } else
+               list_del(&device->g_list);
  
- static LIST_HEAD(acpi_bus_drivers);
+       list_del(&device->wakeup_list);
+       spin_unlock(&acpi_device_lock);
  
- /**
-  * acpi_bus_match - match device IDs to driver's supported IDs
-  * @device: the device that we are trying to match to a driver
-  * @driver: driver whose device id table is being checked
-  *
-  * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
-  * matches the specified driver's criteria.
-  */
- static int
- acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
- {
-       if (driver && driver->ops.match)
-               return driver->ops.match(device, driver);
-       return acpi_match_ids(device, driver->ids);
+       acpi_detach_data(device->handle, acpi_bus_data_handler);
+       acpi_device_remove_files(device);
+       device_unregister(&device->dev);
  }
  
+ /* --------------------------------------------------------------------------
+                                  Driver Management
+    -------------------------------------------------------------------------- */
  /**
   * acpi_bus_driver_init - add a device to a driver
   * @device: the device to add and initialize
   * @driver: driver for the device
   *
   * Used to initialize a device via its device driver.  Called whenever a 
-  * driver is bound to a device.  Invokes the driver's add() and start() ops.
+  * driver is bound to a device.  Invokes the driver's add() ops.
   */
  static int
  acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
@@@ -535,162 -473,246 +473,246 @@@ static int acpi_start_single_object(str
        return result;
  }
  
- static void acpi_driver_attach(struct acpi_driver *drv)
+ /**
+  * acpi_bus_register_driver - register a driver with the ACPI bus
+  * @driver: driver being registered
+  *
+  * Registers a driver with the ACPI bus.  Searches the namespace for all
+  * devices that match the driver's criteria and binds.  Returns zero for
+  * success or a negative error status for failure.
+  */
+ int acpi_bus_register_driver(struct acpi_driver *driver)
  {
-       struct list_head *node, *next;
+       int ret;
  
+       if (acpi_disabled)
+               return -ENODEV;
+       driver->drv.name = driver->name;
+       driver->drv.bus = &acpi_bus_type;
+       driver->drv.owner = driver->owner;
  
-       spin_lock(&acpi_device_lock);
-       list_for_each_safe(node, next, &acpi_device_list) {
-               struct acpi_device *dev =
-                   container_of(node, struct acpi_device, g_list);
+       ret = driver_register(&driver->drv);
+       return ret;
+ }
  
-               if (dev->driver || !dev->status.present)
-                       continue;
-               spin_unlock(&acpi_device_lock);
-               if (!acpi_bus_match(dev, drv)) {
-                       if (!acpi_bus_driver_init(dev, drv)) {
-                               acpi_start_single_object(dev);
-                               atomic_inc(&drv->references);
-                               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                                 "Found driver [%s] for device [%s]\n",
-                                                 drv->name, dev->pnp.bus_id));
-                       }
+ EXPORT_SYMBOL(acpi_bus_register_driver);
+ /**
+  * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
+  * @driver: driver to unregister
+  *
+  * Unregisters a driver with the ACPI bus.  Searches the namespace for all
+  * devices that match the driver's criteria and unbinds.
+  */
+ void acpi_bus_unregister_driver(struct acpi_driver *driver)
+ {
+       driver_unregister(&driver->drv);
+ }
+ EXPORT_SYMBOL(acpi_bus_unregister_driver);
+ /* --------------------------------------------------------------------------
+                                  Device Enumeration
+    -------------------------------------------------------------------------- */
+ acpi_status
+ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
+ {
+       acpi_status status;
+       acpi_handle tmp;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object *obj;
+       status = acpi_get_handle(handle, "_EJD", &tmp);
+       if (ACPI_FAILURE(status))
+               return status;
+       status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
+       if (ACPI_SUCCESS(status)) {
+               obj = buffer.pointer;
+               status = acpi_get_handle(NULL, obj->string.pointer, ejd);
+               kfree(buffer.pointer);
+       }
+       return status;
+ }
+ EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
+ void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
+ {
+       /* TBD */
+       return;
+ }
+ int acpi_match_ids(struct acpi_device *device, char *ids)
+ {
+       if (device->flags.hardware_id)
+               if (strstr(ids, device->pnp.hardware_id))
+                       return 0;
+       if (device->flags.compatible_ids) {
+               struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+               int i;
+               /* compare multiple _CID entries against driver ids */
+               for (i = 0; i < cid_list->count; i++) {
+                       if (strstr(ids, cid_list->id[i].value))
+                               return 0;
+               }
+       }
+       return -ENOENT;
+ }
+ static int acpi_bus_get_perf_flags(struct acpi_device *device)
+ {
+       device->performance.state = ACPI_STATE_UNKNOWN;
+       return 0;
+ }
+ static acpi_status
+ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
+                                            union acpi_object *package)
+ {
+       int i = 0;
+       union acpi_object *element = NULL;
+       if (!device || !package || (package->package.count < 2))
+               return AE_BAD_PARAMETER;
+       element = &(package->package.elements[0]);
+       if (!element)
+               return AE_BAD_PARAMETER;
+       if (element->type == ACPI_TYPE_PACKAGE) {
+               if ((element->package.count < 2) ||
+                   (element->package.elements[0].type !=
+                    ACPI_TYPE_LOCAL_REFERENCE)
+                   || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
+                       return AE_BAD_DATA;
+               device->wakeup.gpe_device =
+                   element->package.elements[0].reference.handle;
+               device->wakeup.gpe_number =
+                   (u32) element->package.elements[1].integer.value;
+       } else if (element->type == ACPI_TYPE_INTEGER) {
+               device->wakeup.gpe_number = element->integer.value;
+       } else
+               return AE_BAD_DATA;
+       element = &(package->package.elements[1]);
+       if (element->type != ACPI_TYPE_INTEGER) {
+               return AE_BAD_DATA;
+       }
+       device->wakeup.sleep_state = element->integer.value;
+       if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
+               return AE_NO_MEMORY;
+       }
+       device->wakeup.resources.count = package->package.count - 2;
+       for (i = 0; i < device->wakeup.resources.count; i++) {
+               element = &(package->package.elements[i + 2]);
+               if (element->type != ACPI_TYPE_ANY) {
+                       return AE_BAD_DATA;
                }
-               spin_lock(&acpi_device_lock);
+               device->wakeup.resources.handles[i] = element->reference.handle;
        }
-       spin_unlock(&acpi_device_lock);
+       return AE_OK;
  }
  
- static void acpi_driver_detach(struct acpi_driver *drv)
+ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
  {
-       struct list_head *node, *next;
+       acpi_status status = 0;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *package = NULL;
  
  
-       spin_lock(&acpi_device_lock);
-       list_for_each_safe(node, next, &acpi_device_list) {
-               struct acpi_device *dev =
-                   container_of(node, struct acpi_device, g_list);
-               if (dev->driver == drv) {
-                       spin_unlock(&acpi_device_lock);
-                       if (drv->ops.remove)
-                               drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
-                       spin_lock(&acpi_device_lock);
-                       dev->driver = NULL;
-                       dev->driver_data = NULL;
-                       atomic_dec(&drv->references);
-               }
+       /* _PRW */
+       status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
+               goto end;
        }
-       spin_unlock(&acpi_device_lock);
- }
  
- /**
-  * acpi_bus_register_driver - register a driver with the ACPI bus
-  * @driver: driver being registered
-  *
-  * Registers a driver with the ACPI bus.  Searches the namespace for all
-  * devices that match the driver's criteria and binds.  Returns zero for
-  * success or a negative error status for failure.
-  */
- int acpi_bus_register_driver(struct acpi_driver *driver)
- {
+       package = (union acpi_object *)buffer.pointer;
+       status = acpi_bus_extract_wakeup_device_power_package(device, package);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
+               goto end;
+       }
  
-       if (acpi_disabled)
-               return -ENODEV;
+       kfree(buffer.pointer);
  
-       spin_lock(&acpi_device_lock);
-       list_add_tail(&driver->node, &acpi_bus_drivers);
-       spin_unlock(&acpi_device_lock);
-       acpi_driver_attach(driver);
+       device->wakeup.flags.valid = 1;
+       /* Power button, Lid switch always enable wakeup */
+       if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
+               device->wakeup.flags.run_wake = 1;
  
+       end:
+       if (ACPI_FAILURE(status))
+               device->flags.wake_capable = 0;
        return 0;
  }
  
- EXPORT_SYMBOL(acpi_bus_register_driver);
- /**
-  * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
-  * @driver: driver to unregister
-  *
-  * Unregisters a driver with the ACPI bus.  Searches the namespace for all
-  * devices that match the driver's criteria and unbinds.
-  */
- void acpi_bus_unregister_driver(struct acpi_driver *driver)
+ static int acpi_bus_get_power_flags(struct acpi_device *device)
  {
-       acpi_driver_detach(driver);
+       acpi_status status = 0;
+       acpi_handle handle = NULL;
+       u32 i = 0;
  
-       if (!atomic_read(&driver->references)) {
-               spin_lock(&acpi_device_lock);
-               list_del_init(&driver->node);
-               spin_unlock(&acpi_device_lock);
-       }
-       return;
- }
  
- EXPORT_SYMBOL(acpi_bus_unregister_driver);
+       /*
+        * Power Management Flags
+        */
+       status = acpi_get_handle(device->handle, "_PSC", &handle);
+       if (ACPI_SUCCESS(status))
+               device->power.flags.explicit_get = 1;
+       status = acpi_get_handle(device->handle, "_IRC", &handle);
+       if (ACPI_SUCCESS(status))
+               device->power.flags.inrush_current = 1;
  
- /**
-  * acpi_bus_find_driver - check if there is a driver installed for the device
-  * @device: device that we are trying to find a supporting driver for
-  *
-  * Parses the list of registered drivers looking for a driver applicable for
-  * the specified device.
-  */
- static int acpi_bus_find_driver(struct acpi_device *device)
- {
-       int result = 0;
-       struct list_head *node, *next;
+       /*
+        * Enumerate supported power management states
+        */
+       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
+               struct acpi_device_power_state *ps = &device->power.states[i];
+               char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
  
+               /* Evaluate "_PRx" to se if power resources are referenced */
+               acpi_evaluate_reference(device->handle, object_name, NULL,
+                                       &ps->resources);
+               if (ps->resources.count) {
+                       device->power.flags.power_resources = 1;
+                       ps->flags.valid = 1;
+               }
  
-       spin_lock(&acpi_device_lock);
-       list_for_each_safe(node, next, &acpi_bus_drivers) {
-               struct acpi_driver *driver =
-                   container_of(node, struct acpi_driver, node);
-               atomic_inc(&driver->references);
-               spin_unlock(&acpi_device_lock);
-               if (!acpi_bus_match(device, driver)) {
-                       result = acpi_bus_driver_init(device, driver);
-                       if (!result)
-                               goto Done;
+               /* Evaluate "_PSx" to see if we can do explicit sets */
+               object_name[2] = 'S';
+               status = acpi_get_handle(device->handle, object_name, &handle);
+               if (ACPI_SUCCESS(status)) {
+                       ps->flags.explicit_set = 1;
+                       ps->flags.valid = 1;
                }
-               atomic_dec(&driver->references);
-               spin_lock(&acpi_device_lock);
-       }
-       spin_unlock(&acpi_device_lock);
  
-       Done:
-       return result;
- }
+               /* State is valid if we have some power control */
+               if (ps->resources.count || ps->flags.explicit_set)
+                       ps->flags.valid = 1;
  
- /* --------------------------------------------------------------------------
-                                  Device Enumeration
-    -------------------------------------------------------------------------- */
+               ps->power = -1; /* Unknown - driver assigned */
+               ps->latency = -1;       /* Unknown - driver assigned */
+       }
  
- acpi_status
- acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
- {
-       acpi_status status;
-       acpi_handle tmp;
-       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       union acpi_object *obj;
+       /* Set defaults for D0 and D3 states (always valid) */
+       device->power.states[ACPI_STATE_D0].flags.valid = 1;
+       device->power.states[ACPI_STATE_D0].power = 100;
+       device->power.states[ACPI_STATE_D3].flags.valid = 1;
+       device->power.states[ACPI_STATE_D3].power = 0;
  
-       status = acpi_get_handle(handle, "_EJD", &tmp);
-       if (ACPI_FAILURE(status))
-               return status;
+       /* TBD: System wake support and resource requirements. */
  
-       status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
-       if (ACPI_SUCCESS(status)) {
-               obj = buffer.pointer;
-               status = acpi_get_handle(NULL, obj->string.pointer, ejd);
-               kfree(buffer.pointer);
-       }
-       return status;
- }
- EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
+       device->power.state = ACPI_STATE_UNKNOWN;
  
+       return 0;
+ }
  
  static int acpi_bus_get_flags(struct acpi_device *device)
  {
@@@ -782,6 -804,39 +804,39 @@@ static void acpi_device_get_busid(struc
        }
  }
  
+ static int
+ acpi_video_bus_match(struct acpi_device *device)
+ {
+       acpi_handle h_dummy1;
+       acpi_handle h_dummy2;
+       acpi_handle h_dummy3;
+       if (!device)
+               return -EINVAL;
+       /* Since there is no HID, CID for ACPI Video drivers, we have
+        * to check well known required nodes for each feature we support.
+        */
+       /* Does this device able to support video switching ? */
+       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
+           ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
+               return 0;
+       /* Does this device able to retrieve a video ROM ? */
+       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
+               return 0;
+       /* Does this device able to configure which video head to be POSTed ? */
+       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
+           ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
+           ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
+               return 0;
+       return -ENODEV;
+ }
  static void acpi_device_set_id(struct acpi_device *device,
                               struct acpi_device *parent, acpi_handle handle,
                               int type)
                        device->pnp.bus_address = info->address;
                        device->flags.bus_address = 1;
                }
+               if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){
+                       status = acpi_video_bus_match(device);
+                       if(ACPI_SUCCESS(status))
+                               hid = ACPI_VIDEO_HID;
+               }
                break;
        case ACPI_BUS_TYPE_POWER:
                hid = ACPI_POWER_HID;
@@@ -933,41 -994,22 +994,22 @@@ static void acpi_device_get_debug_info(
  
  static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
  {
-       int result = 0;
-       struct acpi_driver *driver;
        if (!dev)
                return -EINVAL;
  
-       driver = dev->driver;
-       if ((driver) && (driver->ops.remove)) {
-               if (driver->ops.stop) {
-                       result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
-                       if (result)
-                               return result;
-               }
-               result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
-               if (result) {
-                       return result;
-               }
-               atomic_dec(&dev->driver->references);
-               dev->driver = NULL;
-               acpi_driver_data(dev) = NULL;
-       }
+       dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
+       device_release_driver(&dev->dev);
  
        if (!rmdevice)
                return 0;
  
+       /*
+        * unbind _ADR-Based Devices when hot removal
+        */
        if (dev->flags.bus_address) {
                if ((dev->parent) && (dev->parent->ops.unbind))
                        dev->parent->ops.unbind(dev);
        }
        acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
  
        return 0;
  
  static int
  acpi_add_single_object(struct acpi_device **child,
-                      struct acpi_device *parent, acpi_handle handle, int type)
+                      struct acpi_device *parent, acpi_handle handle, int type,
+                       struct acpi_bus_ops *ops)
  {
        int result = 0;
        struct acpi_device *device = NULL;
        if (!child)
                return -EINVAL;
  
 -      device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL);
 +      device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
        if (!device) {
                printk(KERN_ERR PREFIX "Memory allocation error\n");
                return -ENOMEM;
        }
 -      memset(device, 0, sizeof(struct acpi_device));
  
        device->handle = handle;
        device->parent = parent;
+       device->bus_ops = *ops; /* workround for not call .start */
  
        acpi_device_get_busid(device, handle, type);
  
  
        acpi_device_get_debug_info(device, handle, type);
  
-       acpi_device_register(device, parent);
+       result = acpi_device_register(device, parent);
  
        /*
-        * Bind _ADR-Based Devices
-        * -----------------------
-        * If there's a a bus address (_ADR) then we utilize the parent's 
-        * 'bind' function (if exists) to bind the ACPI- and natively-
-        * enumerated device representations.
+        * Bind _ADR-Based Devices when hot add
         */
        if (device->flags.bus_address) {
                if (device->parent && device->parent->ops.bind)
                        device->parent->ops.bind(device);
        }
  
-       /*
-        * Locate & Attach Driver
-        * ----------------------
-        * If there's a hardware id (_HID) or compatible ids (_CID) we check
-        * to see if there's a driver installed for this kind of device.  Note
-        * that drivers can install before or after a device is enumerated.
-        *
-        * TBD: Assumes LDM provides driver hot-plug capability.
-        */
-       acpi_bus_find_driver(device);
        end:
        if (!result)
                *child = device;
@@@ -1188,14 -1219,14 +1218,14 @@@ static int acpi_bus_scan(struct acpi_de
  
                if (ops->acpi_op_add)
                        status = acpi_add_single_object(&child, parent,
-                                                       chandle, type);
+                               chandle, type, ops);
                else
                        status = acpi_bus_get_device(chandle, &child);
  
                if (ACPI_FAILURE(status))
                        continue;
  
-               if (ops->acpi_op_start) {
+               if (ops->acpi_op_start && !(ops->acpi_op_add)) {
                        status = acpi_start_single_object(child);
                        if (ACPI_FAILURE(status))
                                continue;
@@@ -1233,13 -1264,13 +1263,13 @@@ acpi_bus_add(struct acpi_device **child
        int result;
        struct acpi_bus_ops ops;
  
+       memset(&ops, 0, sizeof(ops));
+       ops.acpi_op_add = 1;
  
-       result = acpi_add_single_object(child, parent, handle, type);
-       if (!result) {
-               memset(&ops, 0, sizeof(ops));
-               ops.acpi_op_add = 1;
+       result = acpi_add_single_object(child, parent, handle, type, &ops);
+       if (!result)
                result = acpi_bus_scan(*child, &ops);
-       }
        return result;
  }
  
@@@ -1325,127 -1356,35 +1355,35 @@@ static int acpi_bus_scan_fixed(struct a
  {
        int result = 0;
        struct acpi_device *device = NULL;
+       struct acpi_bus_ops ops;
  
        if (!root)
                return -ENODEV;
  
+       memset(&ops, 0, sizeof(ops));
+       ops.acpi_op_add = 1;
+       ops.acpi_op_start = 1;
        /*
         * Enumerate all fixed-feature devices.
         */
 -      if (acpi_fadt.pwr_button == 0) {
 +      if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
                result = acpi_add_single_object(&device, acpi_root,
                                                NULL,
-                                               ACPI_BUS_TYPE_POWER_BUTTON);
-               if (!result)
-                       result = acpi_start_single_object(device);
+                                               ACPI_BUS_TYPE_POWER_BUTTON,
+                                               &ops);
        }
  
 -      if (acpi_fadt.sleep_button == 0) {
 +      if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
                result = acpi_add_single_object(&device, acpi_root,
                                                NULL,
-                                               ACPI_BUS_TYPE_SLEEP_BUTTON);
-               if (!result)
-                       result = acpi_start_single_object(device);
+                                               ACPI_BUS_TYPE_SLEEP_BUTTON,
+                                               &ops);
        }
  
        return result;
  }
  
- static inline struct acpi_device * to_acpi_dev(struct device * dev)
- {
-       return container_of(dev, struct acpi_device, dev);
- }
- static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
- {
-       struct acpi_device * dev, * next;
-       int result;
-       spin_lock(&acpi_device_lock);
-       list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
-               if (dev->driver && dev->driver->ops.suspend) {
-                       spin_unlock(&acpi_device_lock);
-                       result = dev->driver->ops.suspend(dev, 0);
-                       if (result) {
-                               printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
-                                      acpi_device_name(dev),
-                                      acpi_device_bid(dev), result);
-                       }
-                       spin_lock(&acpi_device_lock);
-               }
-       }
-       spin_unlock(&acpi_device_lock);
-       return 0;
- }
- static int acpi_device_suspend(struct device * dev, pm_message_t state)
- {
-       struct acpi_device * acpi_dev = to_acpi_dev(dev);
-       /*
-        * For now, we should only register 1 generic device -
-        * the ACPI root device - and from there, we walk the
-        * tree of ACPI devices to suspend each one using the
-        * ACPI driver methods.
-        */
-       if (acpi_dev->handle == ACPI_ROOT_OBJECT)
-               root_suspend(acpi_dev, state);
-       return 0;
- }
- static int root_resume(struct acpi_device * acpi_dev)
- {
-       struct acpi_device * dev, * next;
-       int result;
-       spin_lock(&acpi_device_lock);
-       list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
-               if (dev->driver && dev->driver->ops.resume) {
-                       spin_unlock(&acpi_device_lock);
-                       result = dev->driver->ops.resume(dev, 0);
-                       if (result) {
-                               printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
-                                      acpi_device_name(dev),
-                                      acpi_device_bid(dev), result);
-                       }
-                       spin_lock(&acpi_device_lock);
-               }
-       }
-       spin_unlock(&acpi_device_lock);
-       return 0;
- }
- static int acpi_device_resume(struct device * dev)
- {
-       struct acpi_device * acpi_dev = to_acpi_dev(dev);
-       /*
-        * For now, we should only register 1 generic device -
-        * the ACPI root device - and from there, we walk the
-        * tree of ACPI devices to resume each one using the
-        * ACPI driver methods.
-        */
-       if (acpi_dev->handle == ACPI_ROOT_OBJECT)
-               root_resume(acpi_dev);
-       return 0;
- }
- static struct bus_type acpi_bus_type = {
-       .name           = "acpi",
-       .suspend        = acpi_device_suspend,
-       .resume         = acpi_device_resume,
- };
  static int __init acpi_scan_init(void)
  {
        int result;
        if (acpi_disabled)
                return 0;
  
-       result = kset_register(&acpi_namespace_kset);
-       if (result < 0)
-               printk(KERN_ERR PREFIX "kset_register error: %d\n", result);
+       memset(&ops, 0, sizeof(ops));
+       ops.acpi_op_add = 1;
+       ops.acpi_op_start = 1;
  
        result = bus_register(&acpi_bus_type);
        if (result) {
         * Create the root device in the bus's device tree
         */
        result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
-                                       ACPI_BUS_TYPE_SYSTEM);
+                                       ACPI_BUS_TYPE_SYSTEM, &ops);
        if (result)
                goto Done;
  
-       result = acpi_start_single_object(acpi_root);
-       if (result)
-               goto Done;
-       acpi_root->dev.bus = &acpi_bus_type;
-       snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
-       result = device_register(&acpi_root->dev);
-       if (result) {
-               /* We don't want to quit even if we failed to add suspend/resume */
-               printk(KERN_ERR PREFIX "Could not register device\n");
-       }
        /*
         * Enumerate devices in the ACPI namespace.
         */
        result = acpi_bus_scan_fixed(acpi_root);
-       if (!result) {
-               memset(&ops, 0, sizeof(ops));
-               ops.acpi_op_add = 1;
-               ops.acpi_op_start = 1;
+       if (!result)
                result = acpi_bus_scan(acpi_root, &ops);
-       }
  
        if (result)
                acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --combined drivers/acpi/system.c
  
  #define _COMPONENT            ACPI_SYSTEM_COMPONENT
  ACPI_MODULE_NAME("acpi_system")
+ #ifdef MODULE_PARAM_PREFIX
+ #undef MODULE_PARAM_PREFIX
+ #endif
+ #define MODULE_PARAM_PREFIX "acpi."
  #define ACPI_SYSTEM_CLASS             "system"
  #define ACPI_SYSTEM_DRIVER_NAME               "ACPI System Driver"
  #define ACPI_SYSTEM_DEVICE_NAME               "System"
  #define ACPI_SYSTEM_FILE_EVENT                "event"
  #define ACPI_SYSTEM_FILE_DSDT         "dsdt"
  #define ACPI_SYSTEM_FILE_FADT         "fadt"
 -extern struct fadt_descriptor acpi_fadt;
  
+ /*
+  * Make ACPICA version work as module param
+  */
+ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
+       int result;
+       result = sprintf(buffer, "%x", ACPI_CA_VERSION);
+       return result;
+ }
+ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
  /* --------------------------------------------------------------------------
                                FS Interface (/proc)
     -------------------------------------------------------------------------- */
+ #ifdef CONFIG_ACPI_PROCFS
  
  static int acpi_system_read_info(struct seq_file *seq, void *offset)
  {
@@@ -62,6 -82,7 +81,7 @@@ static const struct file_operations acp
        .llseek = seq_lseek,
        .release = single_release,
  };
+ #endif
  
  static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
                                     loff_t *);
@@@ -75,16 -96,17 +95,16 @@@ acpi_system_read_dsdt(struct file *file
                      char __user * buffer, size_t count, loff_t * ppos)
  {
        acpi_status status = AE_OK;
 -      struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
 +      struct acpi_table_header *dsdt = NULL;
        ssize_t res;
  
  
 -      status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt);
 +      status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
        res = simple_read_from_buffer(buffer, count, ppos,
 -                                    dsdt.pointer, dsdt.length);
 -      kfree(dsdt.pointer);
 +                                    dsdt, dsdt->length);
  
        return res;
  }
@@@ -101,16 -123,17 +121,16 @@@ acpi_system_read_fadt(struct file *file
                      char __user * buffer, size_t count, loff_t * ppos)
  {
        acpi_status status = AE_OK;
 -      struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL };
 +      struct acpi_table_header *fadt = NULL;
        ssize_t res;
  
  
 -      status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt);
 +      status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
        res = simple_read_from_buffer(buffer, count, ppos,
 -                                    fadt.pointer, fadt.length);
 -      kfree(fadt.pointer);
 +                                    fadt, fadt->length);
  
        return res;
  }
@@@ -125,6 -148,7 +145,7 @@@ static int __init acpi_system_init(void
        if (acpi_disabled)
                return 0;
  
+ #ifdef CONFIG_ACPI_PROCFS
        /* 'info' [R] */
        name = ACPI_SYSTEM_FILE_INFO;
        entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
        else {
                entry->proc_fops = &acpi_system_info_ops;
        }
+ #endif
  
        /* 'dsdt' [R] */
        name = ACPI_SYSTEM_FILE_DSDT;
        Error:
        remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
        remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
+ #ifdef CONFIG_ACPI_PROCFS
        remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
+ #endif
  
        error = -EFAULT;
        goto Done;
diff --combined drivers/acpi/thermal.c
@@@ -82,7 -82,7 +82,7 @@@ MODULE_PARM_DESC(tzp, "Thermal zone pol
  
  static int acpi_thermal_add(struct acpi_device *device);
  static int acpi_thermal_remove(struct acpi_device *device, int type);
- static int acpi_thermal_resume(struct acpi_device *device, int state);
+ static int acpi_thermal_resume(struct acpi_device *device);
  static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
  static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
  static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@@ -663,7 -663,7 +663,7 @@@ static void acpi_thermal_run(unsigned l
  static void acpi_thermal_check(void *data)
  {
        int result = 0;
 -      struct acpi_thermal *tz = (struct acpi_thermal *)data;
 +      struct acpi_thermal *tz = data;
        unsigned long sleep_time = 0;
        int i = 0;
        struct acpi_thermal_state state;
@@@ -778,7 -778,7 +778,7 @@@ static struct proc_dir_entry *acpi_ther
  
  static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
 +      struct acpi_thermal *tz = seq->private;
  
  
        if (!tz)
@@@ -813,7 -813,7 +813,7 @@@ static int acpi_thermal_state_open_fs(s
  static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
  {
        int result = 0;
 -      struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
 +      struct acpi_thermal *tz = seq->private;
  
  
        if (!tz)
@@@ -837,7 -837,7 +837,7 @@@ static int acpi_thermal_temp_open_fs(st
  
  static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
 +      struct acpi_thermal *tz = seq->private;
        int i = 0;
        int j = 0;
  
@@@ -893,8 -893,8 +893,8 @@@ acpi_thermal_write_trip_points(struct f
                               const char __user * buffer,
                               size_t count, loff_t * ppos)
  {
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_thermal *tz = m->private;
  
        char *limit_string;
        int num, critical, hot, passive;
        int i = 0;
  
  
 -      limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
 +      limit_string = kzalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
        if (!limit_string)
                return -ENOMEM;
  
 -      memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
 -
        active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL);
        if (!active) {
                kfree(limit_string);
  
  static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
 +      struct acpi_thermal *tz = seq->private;
  
  
        if (!tz)
@@@ -982,8 -984,8 +982,8 @@@ acpi_thermal_write_cooling_mode(struct 
                                const char __user * buffer,
                                size_t count, loff_t * ppos)
  {
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_thermal *tz = m->private;
        int result = 0;
        char mode_string[12] = { '\0' };
  
  
  static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
 +      struct acpi_thermal *tz = seq->private;
  
  
        if (!tz)
@@@ -1041,8 -1043,8 +1041,8 @@@ acpi_thermal_write_polling(struct file 
                           const char __user * buffer,
                           size_t count, loff_t * ppos)
  {
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_thermal *tz = m->private;
        int result = 0;
        char polling_string[12] = { '\0' };
        int seconds = 0;
@@@ -1168,7 -1170,7 +1168,7 @@@ static int acpi_thermal_remove_fs(struc
  
  static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct acpi_thermal *tz = (struct acpi_thermal *)data;
 +      struct acpi_thermal *tz = data;
        struct acpi_device *device = NULL;
  
  
@@@ -1269,9 -1271,10 +1269,9 @@@ static int acpi_thermal_add(struct acpi
        if (!device)
                return -EINVAL;
  
 -      tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
 +      tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
        if (!tz)
                return -ENOMEM;
 -      memset(tz, 0, sizeof(struct acpi_thermal));
  
        tz->device = device;
        strcpy(tz->name, device->pnp.bus_id);
@@@ -1321,7 -1324,7 +1321,7 @@@ static int acpi_thermal_remove(struct a
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      tz = (struct acpi_thermal *)acpi_driver_data(device);
 +      tz = acpi_driver_data(device);
  
        /* avoid timer adding new defer task */
        tz->zombie = 1;
        return 0;
  }
  
- static int acpi_thermal_resume(struct acpi_device *device, int state)
+ static int acpi_thermal_resume(struct acpi_device *device)
  {
        struct acpi_thermal *tz = NULL;
        int i;
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      tz = (struct acpi_thermal *)acpi_driver_data(device);
 +      tz = acpi_driver_data(device);
  
        acpi_thermal_get_temperature(tz);
  
diff --combined drivers/acpi/video.c
@@@ -3,7 -3,6 +3,7 @@@
   *
   *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
   *  Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
 + *  Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
@@@ -32,7 -31,6 +32,7 @@@
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  
 +#include <linux/backlight.h>
  #include <asm/uaccess.h>
  
  #include <acpi/acpi_bus.h>
  #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
  #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
  
 -#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS    0x82
 -#define       ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x83
 -#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS      0x84
 -#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS     0x85
 -#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF         0x86
 +#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS    0x85
 +#define       ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x86
 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS      0x87
 +#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS     0x88
 +#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF         0x89
  
  #define ACPI_VIDEO_HEAD_INVALID               (~0u - 1)
  #define ACPI_VIDEO_HEAD_END           (~0u)
 +#define MAX_NAME_LEN  20
 +
 +#define ACPI_VIDEO_DISPLAY_CRT        1
 +#define ACPI_VIDEO_DISPLAY_TV 2
 +#define ACPI_VIDEO_DISPLAY_DVI        3
 +#define ACPI_VIDEO_DISPLAY_LCD        4
  
  #define _COMPONENT            ACPI_VIDEO_COMPONENT
  ACPI_MODULE_NAME("acpi_video")
@@@ -73,16 -65,14 +73,14 @@@ MODULE_LICENSE("GPL")
  
  static int acpi_video_bus_add(struct acpi_device *device);
  static int acpi_video_bus_remove(struct acpi_device *device, int type);
- static int acpi_video_bus_match(struct acpi_device *device,
-                               struct acpi_driver *driver);
  
  static struct acpi_driver acpi_video_bus = {
        .name = ACPI_VIDEO_DRIVER_NAME,
        .class = ACPI_VIDEO_CLASS,
+       .ids = ACPI_VIDEO_HID,
        .ops = {
                .add = acpi_video_bus_add,
                .remove = acpi_video_bus_remove,
-               .match = acpi_video_bus_match,
                },
  };
  
@@@ -140,21 -130,20 +138,21 @@@ struct acpi_video_device_flags 
        u8 crt:1;
        u8 lcd:1;
        u8 tvout:1;
 +      u8 dvi:1;
        u8 bios:1;
        u8 unknown:1;
 -      u8 reserved:3;
 +      u8 reserved:2;
  };
  
  struct acpi_video_device_cap {
        u8 _ADR:1;              /*Return the unique ID */
        u8 _BCL:1;              /*Query list of brightness control levels supported */
        u8 _BCM:1;              /*Set the brightness level */
 +      u8 _BQC:1;              /* Get current brightness level */
        u8 _DDC:1;              /*Return the EDID for this device */
        u8 _DCS:1;              /*Return status of output device */
        u8 _DGS:1;              /*Query graphics state */
        u8 _DSS:1;              /*Device state set */
 -      u8 _reserved:1;
  };
  
  struct acpi_video_device_brightness {
@@@ -171,8 -160,6 +169,8 @@@ struct acpi_video_device 
        struct acpi_video_bus *video;
        struct acpi_device *dev;
        struct acpi_video_device_brightness *brightness;
 +      struct backlight_device *backlight;
 +      struct backlight_properties *data;
  };
  
  /* bus */
@@@ -267,35 -254,11 +265,35 @@@ static void acpi_video_device_bind(stru
                                   struct acpi_video_device *device);
  static int acpi_video_device_enumerate(struct acpi_video_bus *video);
  static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
 +static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
 +                      int level);
 +static int acpi_video_device_lcd_get_level_current(
 +                      struct acpi_video_device *device,
 +                      unsigned 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);
  
 +/*backlight device sysfs support*/
 +static int acpi_video_get_brightness(struct backlight_device *bd)
 +{
 +      unsigned long cur_level;
 +      struct acpi_video_device *vd =
 +              (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
 +      acpi_video_device_lcd_get_level_current(vd, &cur_level);
 +      return (int) cur_level;
 +}
 +
 +static int acpi_video_set_brightness(struct backlight_device *bd)
 +{
 +      int request_level = bd->props->brightness;
 +      struct acpi_video_device *vd =
 +              (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
 +      acpi_video_device_lcd_set_level(vd, request_level);
 +      return 0;
 +}
 +
  /* --------------------------------------------------------------------------
                                 Video Management
     -------------------------------------------------------------------------- */
@@@ -421,7 -384,7 +419,7 @@@ acpi_video_device_EDID(struct acpi_vide
        if (ACPI_FAILURE(status))
                return -ENODEV;
  
 -      obj = (union acpi_object *)buffer.pointer;
 +      obj = buffer.pointer;
  
        if (obj && obj->type == ACPI_TYPE_BUFFER)
                *edid = obj;
@@@ -533,7 -496,6 +531,7 @@@ static void acpi_video_device_find_cap(
        acpi_integer status;
        acpi_handle h_dummy1;
        int i;
 +      u32 max_level = 0;
        union acpi_object *obj = NULL;
        struct acpi_video_device_brightness *br = NULL;
  
        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
                device->cap._BCM = 1;
        }
 +      if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
 +              device->cap._BQC = 1;
        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
                device->cap._DDC = 1;
        }
                int count = 0;
                union acpi_object *o;
  
 -              br = kmalloc(sizeof(*br), GFP_KERNEL);
 +              br = kzalloc(sizeof(*br), GFP_KERNEL);
                if (!br) {
                        printk(KERN_ERR "can't allocate memory\n");
                } else {
 -                      memset(br, 0, sizeof(*br));
                        br->levels = kmalloc(obj->package.count *
                                             sizeof *(br->levels), GFP_KERNEL);
                        if (!br->levels)
                                        continue;
                                }
                                br->levels[count] = (u32) o->integer.value;
 +                              if (br->levels[count] > max_level)
 +                                      max_level = br->levels[count];
                                count++;
                        }
                      out:
  
        kfree(obj);
  
 +      if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
 +              unsigned long tmp;
 +              static int count = 0;
 +              char *name;
 +              struct backlight_properties *acpi_video_data;
 +
 +              name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
 +              if (!name)
 +                      return;
 +
 +              acpi_video_data = kzalloc(
 +                      sizeof(struct backlight_properties),
 +                      GFP_KERNEL);
 +              if (!acpi_video_data){
 +                      kfree(name);
 +                      return;
 +              }
 +              acpi_video_data->owner = THIS_MODULE;
 +              acpi_video_data->get_brightness =
 +                      acpi_video_get_brightness;
 +              acpi_video_data->update_status =
 +                      acpi_video_set_brightness;
 +              sprintf(name, "acpi_video%d", count++);
 +              device->data = acpi_video_data;
 +              acpi_video_data->max_brightness = max_level;
 +              acpi_video_device_lcd_get_level_current(device, &tmp);
 +              acpi_video_data->brightness = (int)tmp;
 +              device->backlight = backlight_device_register(name,
 +                      NULL, device, acpi_video_data);
 +              kfree(name);
 +      }
        return;
  }
  
@@@ -724,7 -652,8 +722,7 @@@ static struct proc_dir_entry *acpi_vide
  
  static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_device *dev =
 -          (struct acpi_video_device *)seq->private;
 +      struct acpi_video_device *dev = seq->private;
  
  
        if (!dev)
                seq_printf(seq, "LCD\n");
        else if (dev->flags.tvout)
                seq_printf(seq, "TVOUT\n");
 +      else if (dev->flags.dvi)
 +              seq_printf(seq, "DVI\n");
        else
                seq_printf(seq, "UNKNOWN\n");
  
@@@ -759,7 -686,8 +757,7 @@@ acpi_video_device_info_open_fs(struct i
  static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
  {
        int status;
 -      struct acpi_video_device *dev =
 -          (struct acpi_video_device *)seq->private;
 +      struct acpi_video_device *dev = seq->private;
        unsigned long state;
  
  
@@@ -797,8 -725,8 +795,8 @@@ acpi_video_device_write_state(struct fi
                              size_t count, loff_t * data)
  {
        int status;
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_video_device *dev = m->private;
        char str[12] = { 0 };
        u32 state = 0;
  
  static int
  acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_device *dev =
 -          (struct acpi_video_device *)seq->private;
 +      struct acpi_video_device *dev = seq->private;
        int i;
  
  
@@@ -853,8 -782,8 +851,8 @@@ acpi_video_device_write_brightness(stru
                                   const char __user * buffer,
                                   size_t count, loff_t * data)
  {
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_video_device *dev = m->private;
        char str[4] = { 0 };
        unsigned int level = 0;
        int i;
  
  static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_device *dev =
 -          (struct acpi_video_device *)seq->private;
 +      struct acpi_video_device *dev = seq->private;
        int status;
        int i;
        union acpi_object *edid = NULL;
@@@ -934,7 -864,7 +932,7 @@@ static int acpi_video_device_add_fs(str
        if (!device)
                return -ENODEV;
  
 -      vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
 +      vid_dev = acpi_driver_data(device);
        if (!vid_dev)
                return -ENODEV;
  
@@@ -999,7 -929,7 +997,7 @@@ static int acpi_video_device_remove_fs(
  {
        struct acpi_video_device *vid_dev;
  
 -      vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
 +      vid_dev = acpi_driver_data(device);
        if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
                return -ENODEV;
  
  /* video bus */
  static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
 +      struct acpi_video_bus *video = seq->private;
  
  
        if (!video)
@@@ -1043,7 -973,7 +1041,7 @@@ static int acpi_video_bus_info_open_fs(
  
  static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
 +      struct acpi_video_bus *video = seq->private;
  
  
        if (!video)
@@@ -1063,7 -993,7 +1061,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 = (struct acpi_video_bus *)seq->private;
 +      struct acpi_video_bus *video = seq->private;
        unsigned long options;
        int status;
  
@@@ -1101,7 -1031,7 +1099,7 @@@ acpi_video_bus_POST_info_open_fs(struc
  
  static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
 +      struct acpi_video_bus *video = seq->private;
        int status;
        unsigned long id;
  
  
  static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
  {
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
 +      struct acpi_video_bus *video = seq->private;
  
  
        seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
@@@ -1147,8 -1077,8 +1145,8 @@@ acpi_video_bus_write_POST(struct file *
                          size_t count, loff_t * data)
  {
        int status;
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_video_bus *video = m->private;
        char str[12] = { 0 };
        unsigned long opt, options;
  
@@@ -1187,8 -1117,8 +1185,8 @@@ acpi_video_bus_write_DOS(struct file *f
                         size_t count, loff_t * data)
  {
        int status;
 -      struct seq_file *m = (struct seq_file *)file->private_data;
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
 +      struct seq_file *m = file->private_data;
 +      struct acpi_video_bus *video = m->private;
        char str[12] = { 0 };
        unsigned long opt;
  
@@@ -1218,7 -1148,7 +1216,7 @@@ static int acpi_video_bus_add_fs(struc
        struct acpi_video_bus *video;
  
  
 -      video = (struct acpi_video_bus *)acpi_driver_data(device);
 +      video = acpi_driver_data(device);
  
        if (!acpi_device_dir(device)) {
                acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@@ -1294,7 -1224,7 +1292,7 @@@ static int acpi_video_bus_remove_fs(str
        struct acpi_video_bus *video;
  
  
 -      video = (struct acpi_video_bus *)acpi_driver_data(device);
 +      video = acpi_driver_data(device);
  
        if (acpi_device_dir(device)) {
                remove_proc_entry("info", acpi_device_dir(device));
     -------------------------------------------------------------------------- */
  
  /* device interface */
 +static struct acpi_video_device_attrib*
 +acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
 +{
 +      int count;
 +
 +      for(count = 0; count < video->attached_count; count++)
 +              if((video->attached_array[count].value.int_val & 0xffff) == device_id)
 +                      return &(video->attached_array[count].value.attrib);
 +      return NULL;
 +}
  
  static int
  acpi_video_bus_get_one_device(struct acpi_device *device,
        unsigned long device_id;
        int status;
        struct acpi_video_device *data;
 -
 +      struct acpi_video_device_attrib* attribute;
  
        if (!device || !video)
                return -EINVAL;
            acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
        if (ACPI_SUCCESS(status)) {
  
 -              data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
 +              data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
                if (!data)
                        return -ENOMEM;
  
 -              memset(data, 0, sizeof(struct acpi_video_device));
 -
                strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
                strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
                acpi_driver_data(device) = data;
                data->video = video;
                data->dev = device;
  
 -              switch (device_id & 0xffff) {
 -              case 0x0100:
 -                      data->flags.crt = 1;
 -                      break;
 -              case 0x0400:
 -                      data->flags.lcd = 1;
 -                      break;
 -              case 0x0200:
 -                      data->flags.tvout = 1;
 -                      break;
 -              default:
 +              attribute = acpi_video_get_device_attr(video, device_id);
 +
 +              if((attribute != NULL) && attribute->device_id_scheme) {
 +                      switch (attribute->display_type) {
 +                      case ACPI_VIDEO_DISPLAY_CRT:
 +                              data->flags.crt = 1;
 +                              break;
 +                      case ACPI_VIDEO_DISPLAY_TV:
 +                              data->flags.tvout = 1;
 +                              break;
 +                      case ACPI_VIDEO_DISPLAY_DVI:
 +                              data->flags.dvi = 1;
 +                              break;
 +                      case ACPI_VIDEO_DISPLAY_LCD:
 +                              data->flags.lcd = 1;
 +                              break;
 +                      default:
 +                              data->flags.unknown = 1;
 +                              break;
 +                      }
 +                      if(attribute->bios_can_detect)
 +                              data->flags.bios = 1;
 +              } else
                        data->flags.unknown = 1;
 -                      break;
 -              }
  
                acpi_video_device_bind(video, data);
                acpi_video_device_find_cap(data);
@@@ -1489,7 -1401,7 +1487,7 @@@ static int acpi_video_device_enumerate(
                return status;
        }
  
 -      dod = (union acpi_object *)buffer.pointer;
 +      dod = buffer.pointer;
        if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
                ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
                status = -EFAULT;
  
        count = 0;
        for (i = 0; i < dod->package.count; i++) {
 -              obj = (union acpi_object *)&dod->package.elements[i];
 +              obj = &dod->package.elements[i];
  
                if (obj->type != ACPI_TYPE_INTEGER) {
                        printk(KERN_ERR PREFIX "Invalid _DOD data\n");
@@@ -1595,34 -1507,8 +1593,34 @@@ static in
  acpi_video_get_next_level(struct acpi_video_device *device,
                          u32 level_current, u32 event)
  {
 -      /*Fix me */
 -      return level_current;
 +      int min, max, min_above, max_below, i, l;
 +      max = max_below = 0;
 +      min = min_above = 255;
 +      for (i = 0; i < device->brightness->count; i++) {
 +              l = device->brightness->levels[i];
 +              if (l < min)
 +                      min = l;
 +              if (l > max)
 +                      max = l;
 +              if (l < min_above && l > level_current)
 +                      min_above = l;
 +              if (l > max_below && l < level_current)
 +                      max_below = l;
 +      }
 +
 +      switch (event) {
 +      case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
 +              return (level_current < max) ? min_above : min;
 +      case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
 +              return (level_current < max) ? min_above : max;
 +      case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
 +              return (level_current > min) ? max_below : min;
 +      case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
 +      case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
 +              return 0;
 +      default:
 +              return level_current;
 +      }
  }
  
  static void
@@@ -1680,10 -1566,7 +1678,10 @@@ static int acpi_video_bus_put_one_devic
        status = acpi_remove_notify_handler(device->dev->handle,
                                            ACPI_DEVICE_NOTIFY,
                                            acpi_video_device_notify);
 -
 +      if (device->backlight){
 +              backlight_device_unregister(device->backlight);
 +              kfree(device->data);
 +      }
        return 0;
  }
  
@@@ -1727,7 -1610,7 +1725,7 @@@ static int acpi_video_bus_stop_devices(
  
  static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct acpi_video_bus *video = (struct acpi_video_bus *)data;
 +      struct acpi_video_bus *video = data;
        struct acpi_device *device = NULL;
  
        printk("video bus notify\n");
  
  static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct acpi_video_device *video_device =
 -          (struct acpi_video_device *)data;
 +      struct acpi_video_device *video_device = data;
        struct acpi_device *device = NULL;
  
 -
 -      printk("video device notify\n");
        if (!video_device)
                return;
  
@@@ -1808,9 -1694,10 +1806,9 @@@ static int acpi_video_bus_add(struct ac
        if (!device)
                return -EINVAL;
  
 -      video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
 +      video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
        if (!video)
                return -ENOMEM;
 -      memset(video, 0, sizeof(struct acpi_video_bus));
  
        video->device = device;
        strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
@@@ -1868,7 -1755,7 +1866,7 @@@ static int acpi_video_bus_remove(struc
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
 -      video = (struct acpi_video_bus *)acpi_driver_data(device);
 +      video = acpi_driver_data(device);
  
        acpi_video_bus_stop_devices(video);
  
        return 0;
  }
  
- static int
- acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
- {
-       acpi_handle h_dummy1;
-       acpi_handle h_dummy2;
-       acpi_handle h_dummy3;
-       if (!device || !driver)
-               return -EINVAL;
-       /* Since there is no HID, CID for ACPI Video drivers, we have
-        * to check well known required nodes for each feature we support.
-        */
-       /* Does this device able to support video switching ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
-           ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
-               return 0;
-       /* Does this device able to retrieve a video ROM ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
-               return 0;
-       /* Does this device able to configure which video head to be POSTed ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
-           ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
-           ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
-               return 0;
-       return -ENODEV;
- }
  static int __init acpi_video_init(void)
  {
        int result = 0;
diff --combined include/acpi/acpi_bus.h
@@@ -59,6 -59,7 +59,6 @@@ acpi_evaluate_reference(acpi_handle han
  
  #define ACPI_BUS_FILE_ROOT    "acpi"
  extern struct proc_dir_entry *acpi_root_dir;
 -extern struct fadt_descriptor acpi_fadt;
  
  enum acpi_bus_removal_type {
        ACPI_BUS_REMOVAL_NORMAL = 0,
@@@ -91,13 -92,12 +91,12 @@@ typedef int (*acpi_op_remove) (struct a
  typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
  typedef int (*acpi_op_start) (struct acpi_device * device);
  typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
- typedef int (*acpi_op_suspend) (struct acpi_device * device, int state);
- typedef int (*acpi_op_resume) (struct acpi_device * device, int state);
+ typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state);
+ typedef int (*acpi_op_resume) (struct acpi_device * device);
  typedef int (*acpi_op_scan) (struct acpi_device * device);
  typedef int (*acpi_op_bind) (struct acpi_device * device);
  typedef int (*acpi_op_unbind) (struct acpi_device * device);
- typedef int (*acpi_op_match) (struct acpi_device * device,
-                             struct acpi_driver * driver);
+ typedef int (*acpi_op_shutdown) (struct acpi_device * device);
  
  struct acpi_bus_ops {
        u32 acpi_op_add:1;
        u32 acpi_op_scan:1;
        u32 acpi_op_bind:1;
        u32 acpi_op_unbind:1;
-       u32 acpi_op_match:1;
+       u32 acpi_op_shutdown:1;
        u32 reserved:21;
  };
  
@@@ -125,16 -125,16 +124,16 @@@ struct acpi_device_ops 
        acpi_op_scan scan;
        acpi_op_bind bind;
        acpi_op_unbind unbind;
-       acpi_op_match match;
+       acpi_op_shutdown shutdown;
  };
  
  struct acpi_driver {
-       struct list_head node;
        char name[80];
        char class[80];
-       atomic_t references;
        char *ids;              /* Supported Hardware IDs */
        struct acpi_device_ops ops;
+       struct device_driver drv;
+       struct module *owner;
  };
  
  /*
@@@ -184,7 -184,7 +183,7 @@@ struct acpi_device_dir 
  
  typedef char acpi_bus_id[5];
  typedef unsigned long acpi_bus_address;
- typedef char acpi_hardware_id[9];
+ typedef char acpi_hardware_id[15];
  typedef char acpi_unique_id[9];
  typedef char acpi_device_name[40];
  typedef char acpi_device_class[20];
@@@ -295,11 -295,14 +294,14 @@@ struct acpi_device 
        struct acpi_device_ops ops;
        struct acpi_driver *driver;
        void *driver_data;
-       struct kobject kobj;
        struct device dev;
+       struct acpi_bus_ops bus_ops;    /* workaround for different code path for hotplug */
+       enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
  };
  
  #define acpi_driver_data(d)   ((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)
  
  /*
   * Events
  
  /* _HID definitions */
  
- #define ACPI_POWER_HID                        "ACPI_PWR"
+ #define ACPI_POWER_HID                        "power_resource"
 -#define ACPI_PROCESSOR_HID            "processor"
 +#define ACPI_PROCESSOR_HID            "ACPI0007"
- #define ACPI_SYSTEM_HID                       "ACPI_SYS"
- #define ACPI_THERMAL_HID              "ACPI_THM"
- #define ACPI_BUTTON_HID_POWERF                "ACPI_FPB"
- #define ACPI_BUTTON_HID_SLEEPF                "ACPI_FSB"
+ #define ACPI_SYSTEM_HID                       "acpi_system"
+ #define ACPI_THERMAL_HID              "thermal"
+ #define ACPI_BUTTON_HID_POWERF                "button_power"
+ #define ACPI_BUTTON_HID_SLEEPF                "button_sleep"
+ #define ACPI_VIDEO_HID                        "video"
+ #define ACPI_BAY_HID                  "bay"
  /* --------------------------------------------------------------------------
                                         PCI
     -------------------------------------------------------------------------- */