Bladeren bron

Pull sysfs into test branch

Conflicts:

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

Signed-off-by: Len Brown <len.brown@intel.com>
Len Brown 19 jaren geleden
bovenliggende
commit
975a8e3ed2

+ 9 - 1
Documentation/feature-removal-schedule.txt

@@ -274,6 +274,7 @@ Who:	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
 
 
 ---------------------------
 ---------------------------
 
 
+<<<<<<< test:Documentation/feature-removal-schedule.txt
 What:	ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
 What:	ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
 When:	2.6.21
 When:	2.6.21
 Why:	hotkey.c was an attempt to consolidate multiple drivers that use
 Why:	hotkey.c was an attempt to consolidate multiple drivers that use
@@ -306,11 +307,18 @@ Why:	The ACPI namespace is effectively the symbol list for
 	the BIOS can be extracted and disassembled with acpidump
 	the BIOS can be extracted and disassembled with acpidump
 	and iasl as documented in the pmtools package here:
 	and iasl as documented in the pmtools package here:
 	http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
 	http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
-
 Who:	Len Brown <len.brown@intel.com>
 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
 What:	/proc/acpi/button
 When:	August 2007
 When:	August 2007
 Why:	/proc/acpi/button has been replaced by events to the input layer
 Why:	/proc/acpi/button has been replaced by events to the input layer

+ 14 - 0
drivers/acpi/Kconfig

@@ -77,6 +77,20 @@ config ACPI_SLEEP_PROC_SLEEP
 	  Create /proc/acpi/sleep
 	  Create /proc/acpi/sleep
 	  Deprecated by /sys/power/state
 	  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
 config ACPI_AC
 	tristate "AC Adapter"
 	tristate "AC Adapter"
 	depends on X86
 	depends on X86

+ 1 - 1
drivers/acpi/Makefile

@@ -37,6 +37,7 @@ endif
 
 
 obj-y				+= sleep/
 obj-y				+= sleep/
 obj-y				+= bus.o glue.o
 obj-y				+= bus.o glue.o
+obj-y				+= scan.o motherboard.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
@@ -57,7 +58,6 @@ obj-$(CONFIG_ACPI_NUMA)		+= numa.o
 obj-$(CONFIG_ACPI_ASUS)		+= asus_acpi.o
 obj-$(CONFIG_ACPI_ASUS)		+= asus_acpi.o
 obj-$(CONFIG_ACPI_IBM)		+= ibm_acpi.o
 obj-$(CONFIG_ACPI_IBM)		+= ibm_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
-obj-y				+= scan.o motherboard.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
 obj-y				+= cm_sbs.o
 obj-y				+= cm_sbs.o
 obj-$(CONFIG_ACPI_SBS)		+= i2c_ec.o sbs.o
 obj-$(CONFIG_ACPI_SBS)		+= i2c_ec.o sbs.o

+ 2 - 2
drivers/acpi/battery.c

@@ -64,7 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
 
 static int acpi_battery_add(struct acpi_device *device);
 static int acpi_battery_add(struct acpi_device *device);
 static int acpi_battery_remove(struct acpi_device *device, int type);
 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 = {
 static struct acpi_driver acpi_battery_driver = {
 	.name = ACPI_BATTERY_DRIVER_NAME,
 	.name = ACPI_BATTERY_DRIVER_NAME,
@@ -753,7 +753,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 }
 }
 
 
 /* this is needed to learn about changes made in suspended state */
 /* 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;
 	struct acpi_battery *battery;
 
 

+ 1 - 1
drivers/acpi/bus.c

@@ -192,7 +192,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
 
 
 	if (!device->flags.power_manageable) {
 	if (!device->flags.power_manageable) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
-				device->kobj.name));
+				device->dev.kobj.name));
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 	/*
 	/*

+ 1 - 1
drivers/acpi/button.c

@@ -75,7 +75,7 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 static struct acpi_driver acpi_button_driver = {
 static struct acpi_driver acpi_button_driver = {
 	.name = ACPI_BUTTON_DRIVER_NAME,
 	.name = ACPI_BUTTON_DRIVER_NAME,
 	.class = ACPI_BUTTON_CLASS,
 	.class = ACPI_BUTTON_CLASS,
-	.ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E",
+	.ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
 	.ops = {
 	.ops = {
 		.add = acpi_button_add,
 		.add = acpi_button_add,
 		.remove = acpi_button_remove,
 		.remove = acpi_button_remove,

+ 3 - 3
drivers/acpi/container.c

@@ -167,7 +167,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 			if (ACPI_FAILURE(status) || !device) {
 			if (ACPI_FAILURE(status) || !device) {
 				result = container_device_add(&device, handle);
 				result = container_device_add(&device, handle);
 				if (!result)
 				if (!result)
-					kobject_uevent(&device->kobj,
+					kobject_uevent(&device->dev.kobj,
 						       KOBJ_ONLINE);
 						       KOBJ_ONLINE);
 				else
 				else
 					printk("Failed to add container\n");
 					printk("Failed to add container\n");
@@ -175,13 +175,13 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 		} else {
 		} else {
 			if (ACPI_SUCCESS(status)) {
 			if (ACPI_SUCCESS(status)) {
 				/* device exist and this is a remove request */
 				/* device exist and this is a remove request */
-				kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+				kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
 			}
 			}
 		}
 		}
 		break;
 		break;
 	case ACPI_NOTIFY_EJECT_REQUEST:
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		if (!acpi_bus_get_device(handle, &device) && device) {
 		if (!acpi_bus_get_device(handle, &device) && device) {
-			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
 		}
 		}
 		break;
 		break;
 	default:
 	default:

+ 57 - 5
drivers/acpi/debug.c

@@ -13,14 +13,11 @@
 
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("debug")
 ACPI_MODULE_NAME("debug")
-#define ACPI_SYSTEM_FILE_DEBUG_LAYER	"debug_layer"
-#define ACPI_SYSTEM_FILE_DEBUG_LEVEL	"debug_level"
+
 #ifdef MODULE_PARAM_PREFIX
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
 #endif
 #endif
-#define MODULE_PARAM_PREFIX
-    module_param(acpi_dbg_layer, uint, 0400);
-module_param(acpi_dbg_level, uint, 0400);
+#define MODULE_PARAM_PREFIX "acpi."
 
 
 struct acpi_dlayer {
 struct acpi_dlayer {
 	const char *name;
 	const char *name;
@@ -86,6 +83,60 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
 	ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
 	ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
 };
 };
 
 
+/* --------------------------------------------------------------------------
+                              FS Interface (/sys)
+   -------------------------------------------------------------------------- */
+static int param_get_debug_layer(char *buffer, struct kernel_param *kp) {
+	int result = 0;
+	int i;
+
+	result = sprintf(buffer, "%-25s\tHex        SET\n", "Description");
+
+	for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) {
+		result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
+					acpi_debug_layers[i].name,
+					acpi_debug_layers[i].value,
+					(acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' ');
+	}
+	result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
+					ACPI_ALL_DRIVERS,
+					(acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
+					ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
+					ACPI_ALL_DRIVERS) == 0 ? ' ' : '-');
+	result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer);
+
+	return result;
+}
+
+static int param_get_debug_level(char *buffer, struct kernel_param *kp) {
+	int result = 0;
+	int i;
+
+	result = sprintf(buffer, "%-25s\tHex        SET\n", "Description");
+
+	for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
+		result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
+				     acpi_debug_levels[i].name,
+				     acpi_debug_levels[i].value,
+				     (acpi_dbg_level & acpi_debug_levels[i].
+				      value) ? '*' : ' ');
+	}
+	result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n",
+			     acpi_dbg_level);
+
+	return result;
+}
+
+module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644);
+module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644);
+
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_PROCFS
+#define ACPI_SYSTEM_FILE_DEBUG_LAYER	"debug_layer"
+#define ACPI_SYSTEM_FILE_DEBUG_LEVEL		"debug_level"
+
 static int
 static int
 acpi_system_read_debug(char *page,
 acpi_system_read_debug(char *page,
 		       char **start, off_t off, int count, int *eof, void *data)
 		       char **start, off_t off, int count, int *eof, void *data)
@@ -221,3 +272,4 @@ static int __init acpi_debug_init(void)
 }
 }
 
 
 subsys_initcall(acpi_debug_init);
 subsys_initcall(acpi_debug_init);
+#endif

+ 4 - 4
drivers/acpi/fan.c

@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
 
 
 static int acpi_fan_add(struct acpi_device *device);
 static int acpi_fan_add(struct acpi_device *device);
 static int acpi_fan_remove(struct acpi_device *device, int type);
 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 = {
 static struct acpi_driver acpi_fan_driver = {
 	.name = ACPI_FAN_DRIVER_NAME,
 	.name = ACPI_FAN_DRIVER_NAME,
@@ -237,7 +237,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
 	return 0;
 	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)
 	if (!device)
 		return -EINVAL;
 		return -EINVAL;
@@ -247,7 +247,7 @@ static int acpi_fan_suspend(struct acpi_device *device, int state)
 	return AE_OK;
 	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 result = 0;
 	int power_state = 0;
 	int power_state = 0;

+ 4 - 15
drivers/acpi/motherboard.c

@@ -33,8 +33,7 @@
 ACPI_MODULE_NAME("acpi_motherboard")
 ACPI_MODULE_NAME("acpi_motherboard")
 
 
 /* Dell use PNP0C01 instead of PNP0C02 */
 /* 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 legacy IO ports, only IO ports beyond 0x1000 are reserved
  * Doesn't care about the failure of 'request_region', since other may reserve
  * Doesn't care about the failure of 'request_region', since other may reserve
@@ -110,19 +109,10 @@ static int acpi_motherboard_add(struct acpi_device *device)
 	return 0;
 	return 0;
 }
 }
 
 
-static struct acpi_driver acpi_motherboard_driver1 = {
+static struct acpi_driver acpi_motherboard_driver = {
 	.name = "motherboard",
 	.name = "motherboard",
 	.class = "",
 	.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 = {
 	.ops = {
 		.add = acpi_motherboard_add,
 		.add = acpi_motherboard_add,
 		},
 		},
@@ -173,8 +163,7 @@ static void __init acpi_reserve_resources(void)
 
 
 static int __init acpi_motherboard_init(void)
 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
 	 * Guarantee motherboard IO reservation first
 	 * This module must run after scan.c
 	 * This module must run after scan.c

+ 22 - 3
drivers/acpi/pci_root.c

@@ -165,6 +165,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
 	return AE_OK;
 	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)
 static int acpi_pci_root_add(struct acpi_device *device)
 {
 {
 	int result = 0;
 	int result = 0;
@@ -173,6 +188,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
 	acpi_status status = AE_OK;
 	acpi_status status = AE_OK;
 	unsigned long value = 0;
 	unsigned long value = 0;
 	acpi_handle handle = NULL;
 	acpi_handle handle = NULL;
+	struct acpi_device *child;
 
 
 
 
 	if (!device)
 	if (!device)
@@ -188,9 +204,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
 	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
 	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
 	acpi_driver_data(device) = root;
 	acpi_driver_data(device) = root;
 
 
-	/*
-	 * TBD: Doesn't the bus driver automatically set this?
-	 */
 	device->ops.bind = acpi_pci_bind;
 	device->ops.bind = acpi_pci_bind;
 
 
 	/* 
 	/* 
@@ -312,6 +325,12 @@ static int acpi_pci_root_add(struct acpi_device *device)
 		result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
 		result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
 					      root->id.bus);
 					      root->id.bus);
 
 
+	/*
+	 * Scan and bind all _ADR-Based Devices
+	 */
+	list_for_each_entry(child, &device->children, node)
+		acpi_pci_bridge_scan(child);
+
       end:
       end:
 	if (result) {
 	if (result) {
 		if (!list_empty(&root->node))
 		if (!list_empty(&root->node))

+ 4 - 4
drivers/acpi/processor_core.c

@@ -814,7 +814,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
 	if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
-		kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
+		kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -852,13 +852,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
 		}
 		}
 
 
 		if (pr->id >= 0 && (pr->id < NR_CPUS)) {
 		if (pr->id >= 0 && (pr->id < NR_CPUS)) {
-			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
 			break;
 			break;
 		}
 		}
 
 
 		result = acpi_processor_start(device);
 		result = acpi_processor_start(device);
 		if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
 		if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
-			kobject_uevent(&device->kobj, KOBJ_ONLINE);
+			kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
 		} else {
 		} else {
 			printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
 			printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
 				    acpi_device_bid(device));
 				    acpi_device_bid(device));
@@ -881,7 +881,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
 		}
 		}
 
 
 		if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
 		if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
-			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
 		break;
 		break;
 	default:
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,

+ 591 - 669
drivers/acpi/scan.c

@@ -21,470 +21,408 @@ extern struct acpi_device *acpi_root;
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 
 
 static LIST_HEAD(acpi_device_list);
 static LIST_HEAD(acpi_device_list);
+static LIST_HEAD(acpi_bus_id_list);
 DEFINE_SPINLOCK(acpi_device_lock);
 DEFINE_SPINLOCK(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 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;
 	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 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;
 	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
  * acpi_bus_driver_init - add a device to a driver
  * @device: the device to add and initialize
  * @device: the device to add and initialize
  * @driver: driver for the device
  * @driver: driver for the device
  *
  *
  * Used to initialize a device via its device driver.  Called whenever a 
  * 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
 static int
 acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
 acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
@@ -535,162 +473,246 @@ static int acpi_start_single_object(struct acpi_device *device)
 	return result;
 	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;
 	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)
 static int acpi_bus_get_flags(struct acpi_device *device)
 {
 {
@@ -782,6 +804,39 @@ static void acpi_device_get_busid(struct acpi_device *device,
 	}
 	}
 }
 }
 
 
+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,
 static void acpi_device_set_id(struct acpi_device *device,
 			       struct acpi_device *parent, acpi_handle handle,
 			       struct acpi_device *parent, acpi_handle handle,
 			       int type)
 			       int type)
@@ -812,6 +867,12 @@ static void acpi_device_set_id(struct acpi_device *device,
 			device->pnp.bus_address = info->address;
 			device->pnp.bus_address = info->address;
 			device->flags.bus_address = 1;
 			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;
 		break;
 	case ACPI_BUS_TYPE_POWER:
 	case ACPI_BUS_TYPE_POWER:
 		hid = ACPI_POWER_HID;
 		hid = ACPI_POWER_HID;
@@ -933,41 +994,22 @@ static void acpi_device_get_debug_info(struct acpi_device *device,
 
 
 static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 {
 {
-	int result = 0;
-	struct acpi_driver *driver;
-
-
 	if (!dev)
 	if (!dev)
 		return -EINVAL;
 		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)
 	if (!rmdevice)
 		return 0;
 		return 0;
 
 
+	/*
+	 * unbind _ADR-Based Devices when hot removal
+	 */
 	if (dev->flags.bus_address) {
 	if (dev->flags.bus_address) {
 		if ((dev->parent) && (dev->parent->ops.unbind))
 		if ((dev->parent) && (dev->parent->ops.unbind))
 			dev->parent->ops.unbind(dev);
 			dev->parent->ops.unbind(dev);
 	}
 	}
-
 	acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
 	acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
 
 
 	return 0;
 	return 0;
@@ -975,7 +1017,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 
 
 static int
 static int
 acpi_add_single_object(struct acpi_device **child,
 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;
 	int result = 0;
 	struct acpi_device *device = NULL;
 	struct acpi_device *device = NULL;
@@ -992,6 +1035,8 @@ acpi_add_single_object(struct acpi_device **child,
 
 
 	device->handle = handle;
 	device->handle = handle;
 	device->parent = parent;
 	device->parent = parent;
+	device->bus_ops = *ops; /* workround for not call .start */
+
 
 
 	acpi_device_get_busid(device, handle, type);
 	acpi_device_get_busid(device, handle, type);
 
 
@@ -1078,31 +1123,16 @@ acpi_add_single_object(struct acpi_device **child,
 
 
 	acpi_device_get_debug_info(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->flags.bus_address) {
 		if (device->parent && device->parent->ops.bind)
 		if (device->parent && device->parent->ops.bind)
 			device->parent->ops.bind(device);
 			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:
       end:
 	if (!result)
 	if (!result)
 		*child = device;
 		*child = device;
@@ -1188,14 +1218,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
 
 
 		if (ops->acpi_op_add)
 		if (ops->acpi_op_add)
 			status = acpi_add_single_object(&child, parent,
 			status = acpi_add_single_object(&child, parent,
-							chandle, type);
+				chandle, type, ops);
 		else
 		else
 			status = acpi_bus_get_device(chandle, &child);
 			status = acpi_bus_get_device(chandle, &child);
 
 
 		if (ACPI_FAILURE(status))
 		if (ACPI_FAILURE(status))
 			continue;
 			continue;
 
 
-		if (ops->acpi_op_start) {
+		if (ops->acpi_op_start && !(ops->acpi_op_add)) {
 			status = acpi_start_single_object(child);
 			status = acpi_start_single_object(child);
 			if (ACPI_FAILURE(status))
 			if (ACPI_FAILURE(status))
 				continue;
 				continue;
@@ -1233,13 +1263,13 @@ acpi_bus_add(struct acpi_device **child,
 	int result;
 	int result;
 	struct acpi_bus_ops ops;
 	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);
 		result = acpi_bus_scan(*child, &ops);
-	}
+
 	return result;
 	return result;
 }
 }
 
 
@@ -1325,127 +1355,35 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
 {
 {
 	int result = 0;
 	int result = 0;
 	struct acpi_device *device = NULL;
 	struct acpi_device *device = NULL;
-
+	struct acpi_bus_ops ops;
 
 
 	if (!root)
 	if (!root)
 		return -ENODEV;
 		return -ENODEV;
 
 
+	memset(&ops, 0, sizeof(ops));
+	ops.acpi_op_add = 1;
+	ops.acpi_op_start = 1;
+
 	/*
 	/*
 	 * Enumerate all fixed-feature devices.
 	 * Enumerate all fixed-feature devices.
 	 */
 	 */
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, acpi_root,
 		result = acpi_add_single_object(&device, acpi_root,
 						NULL,
 						NULL,
-						ACPI_BUS_TYPE_POWER_BUTTON);
-		if (!result)
-			result = acpi_start_single_object(device);
+						ACPI_BUS_TYPE_POWER_BUTTON,
+						&ops);
 	}
 	}
 
 
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, acpi_root,
 		result = acpi_add_single_object(&device, acpi_root,
 						NULL,
 						NULL,
-						ACPI_BUS_TYPE_SLEEP_BUTTON);
-		if (!result)
-			result = acpi_start_single_object(device);
+						ACPI_BUS_TYPE_SLEEP_BUTTON,
+						&ops);
 	}
 	}
 
 
 	return result;
 	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)
 static int __init acpi_scan_init(void)
 {
 {
 	int result;
 	int result;
@@ -1455,9 +1393,9 @@ static int __init acpi_scan_init(void)
 	if (acpi_disabled)
 	if (acpi_disabled)
 		return 0;
 		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);
 	result = bus_register(&acpi_bus_type);
 	if (result) {
 	if (result) {
@@ -1469,32 +1407,16 @@ static int __init acpi_scan_init(void)
 	 * Create the root device in the bus's device tree
 	 * Create the root device in the bus's device tree
 	 */
 	 */
 	result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
 	result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
-					ACPI_BUS_TYPE_SYSTEM);
+					ACPI_BUS_TYPE_SYSTEM, &ops);
 	if (result)
 	if (result)
 		goto Done;
 		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.
 	 * Enumerate devices in the ACPI namespace.
 	 */
 	 */
 	result = acpi_bus_scan_fixed(acpi_root);
 	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);
 		result = acpi_bus_scan(acpi_root, &ops);
-	}
 
 
 	if (result)
 	if (result)
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);

+ 24 - 0
drivers/acpi/system.c

@@ -32,6 +32,11 @@
 
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("acpi_system")
 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_CLASS		"system"
 #define ACPI_SYSTEM_DRIVER_NAME		"ACPI System Driver"
 #define ACPI_SYSTEM_DRIVER_NAME		"ACPI System Driver"
 #define ACPI_SYSTEM_DEVICE_NAME		"System"
 #define ACPI_SYSTEM_DEVICE_NAME		"System"
@@ -40,9 +45,23 @@ ACPI_MODULE_NAME("acpi_system")
 #define ACPI_SYSTEM_FILE_DSDT		"dsdt"
 #define ACPI_SYSTEM_FILE_DSDT		"dsdt"
 #define ACPI_SYSTEM_FILE_FADT		"fadt"
 #define ACPI_SYSTEM_FILE_FADT		"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)
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
    -------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_PROCFS
 
 
 static int acpi_system_read_info(struct seq_file *seq, void *offset)
 static int acpi_system_read_info(struct seq_file *seq, void *offset)
 {
 {
@@ -62,6 +81,7 @@ static const struct file_operations acpi_system_info_ops = {
 	.llseek = seq_lseek,
 	.llseek = seq_lseek,
 	.release = single_release,
 	.release = single_release,
 };
 };
+#endif
 
 
 static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
 static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
 				     loff_t *);
 				     loff_t *);
@@ -125,6 +145,7 @@ static int __init acpi_system_init(void)
 	if (acpi_disabled)
 	if (acpi_disabled)
 		return 0;
 		return 0;
 
 
+#ifdef CONFIG_ACPI_PROCFS
 	/* 'info' [R] */
 	/* 'info' [R] */
 	name = ACPI_SYSTEM_FILE_INFO;
 	name = ACPI_SYSTEM_FILE_INFO;
 	entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
 	entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -133,6 +154,7 @@ static int __init acpi_system_init(void)
 	else {
 	else {
 		entry->proc_fops = &acpi_system_info_ops;
 		entry->proc_fops = &acpi_system_info_ops;
 	}
 	}
+#endif
 
 
 	/* 'dsdt' [R] */
 	/* 'dsdt' [R] */
 	name = ACPI_SYSTEM_FILE_DSDT;
 	name = ACPI_SYSTEM_FILE_DSDT;
@@ -156,7 +178,9 @@ static int __init acpi_system_init(void)
       Error:
       Error:
 	remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
 	remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
 	remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, 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);
 	remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
+#endif
 
 
 	error = -EFAULT;
 	error = -EFAULT;
 	goto Done;
 	goto Done;

+ 2 - 2
drivers/acpi/thermal.c

@@ -82,7 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
 
 
 static int acpi_thermal_add(struct acpi_device *device);
 static int acpi_thermal_add(struct acpi_device *device);
 static int acpi_thermal_remove(struct acpi_device *device, int type);
 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_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_temp_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -1353,7 +1353,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
 	return 0;
 	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;
 	struct acpi_thermal *tz = NULL;
 	int i;
 	int i;

+ 1 - 36
drivers/acpi/video.c

@@ -73,16 +73,14 @@ MODULE_LICENSE("GPL");
 
 
 static int acpi_video_bus_add(struct acpi_device *device);
 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_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 = {
 static struct acpi_driver acpi_video_bus = {
 	.name = ACPI_VIDEO_DRIVER_NAME,
 	.name = ACPI_VIDEO_DRIVER_NAME,
 	.class = ACPI_VIDEO_CLASS,
 	.class = ACPI_VIDEO_CLASS,
+	.ids = ACPI_VIDEO_HID,
 	.ops = {
 	.ops = {
 		.add = acpi_video_bus_add,
 		.add = acpi_video_bus_add,
 		.remove = acpi_video_bus_remove,
 		.remove = acpi_video_bus_remove,
-		.match = acpi_video_bus_match,
 		},
 		},
 };
 };
 
 
@@ -1885,39 +1883,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
 	return 0;
 	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)
 static int __init acpi_video_init(void)
 {
 {
 	int result = 0;
 	int result = 0;

+ 12 - 10
include/acpi/acpi_bus.h

@@ -91,13 +91,12 @@ typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
 typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
 typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
 typedef int (*acpi_op_start) (struct acpi_device * device);
 typedef int (*acpi_op_start) (struct acpi_device * device);
 typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
 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_scan) (struct acpi_device * device);
 typedef int (*acpi_op_bind) (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_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 {
 struct acpi_bus_ops {
 	u32 acpi_op_add:1;
 	u32 acpi_op_add:1;
@@ -110,7 +109,7 @@ struct acpi_bus_ops {
 	u32 acpi_op_scan:1;
 	u32 acpi_op_scan:1;
 	u32 acpi_op_bind:1;
 	u32 acpi_op_bind:1;
 	u32 acpi_op_unbind:1;
 	u32 acpi_op_unbind:1;
-	u32 acpi_op_match:1;
+	u32 acpi_op_shutdown:1;
 	u32 reserved:21;
 	u32 reserved:21;
 };
 };
 
 
@@ -125,16 +124,16 @@ struct acpi_device_ops {
 	acpi_op_scan scan;
 	acpi_op_scan scan;
 	acpi_op_bind bind;
 	acpi_op_bind bind;
 	acpi_op_unbind unbind;
 	acpi_op_unbind unbind;
-	acpi_op_match match;
+	acpi_op_shutdown shutdown;
 };
 };
 
 
 struct acpi_driver {
 struct acpi_driver {
-	struct list_head node;
 	char name[80];
 	char name[80];
 	char class[80];
 	char class[80];
-	atomic_t references;
 	char *ids;		/* Supported Hardware IDs */
 	char *ids;		/* Supported Hardware IDs */
 	struct acpi_device_ops ops;
 	struct acpi_device_ops ops;
+	struct device_driver drv;
+	struct module *owner;
 };
 };
 
 
 /*
 /*
@@ -184,7 +183,7 @@ struct acpi_device_dir {
 
 
 typedef char acpi_bus_id[5];
 typedef char acpi_bus_id[5];
 typedef unsigned long acpi_bus_address;
 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_unique_id[9];
 typedef char acpi_device_name[40];
 typedef char acpi_device_name[40];
 typedef char acpi_device_class[20];
 typedef char acpi_device_class[20];
@@ -295,11 +294,14 @@ struct acpi_device {
 	struct acpi_device_ops ops;
 	struct acpi_device_ops ops;
 	struct acpi_driver *driver;
 	struct acpi_driver *driver;
 	void *driver_data;
 	void *driver_data;
-	struct kobject kobj;
 	struct device dev;
 	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 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
  * Events

+ 7 - 6
include/acpi/acpi_drivers.h

@@ -36,13 +36,14 @@
 
 
 /* _HID definitions */
 /* _HID definitions */
 
 
-#define ACPI_POWER_HID			"ACPI_PWR"
+#define ACPI_POWER_HID			"power_resource"
 #define ACPI_PROCESSOR_HID		"ACPI0007"
 #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
                                        PCI
    -------------------------------------------------------------------------- */
    -------------------------------------------------------------------------- */