/*
 * scan.c - support for transforming the ACPI namespace into individual objects
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/acpi.h>

#include <acpi/acpi_drivers.h>
#include <acpi/acinterp.h>	/* for acpi_ex_eisa_id_to_string() */

#define _COMPONENT		ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("scan")
#define STRUCT_TO_INT(s)	(*((int*)&s))
extern struct acpi_device *acpi_root;

#define ACPI_BUS_CLASS			"system_bus"
#define ACPI_BUS_HID			"ACPI_BUS"
#define ACPI_BUS_DRIVER_NAME		"ACPI Bus Driver"
#define ACPI_BUS_DEVICE_NAME		"System Bus"

static LIST_HEAD(acpi_device_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);
};

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)
{
	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,
};

static struct kobj_type ktype_acpi_ns = {
	.sysfs_ops = &acpi_device_sysfs_ops,
	.release = acpi_device_release,
};

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 (!dev->driver)
		return 0;

	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
			   "PHYSDEVDRIVER=%s", dev->driver->name))
		return -ENOMEM;

	envp[i] = NULL;

	return 0;
}

static struct kset_uevent_ops namespace_uevent_ops = {
	.uevent = &namespace_uevent,
};

static struct kset acpi_namespace_kset = {
	.kobj = {
		 .name = "namespace",
		 },
	.subsys = &acpi_subsys,
	.ktype = &ktype_acpi_ns,
	.uevent_ops = &namespace_uevent_ops,
};

static void acpi_device_register(struct acpi_device *device,
				 struct acpi_device *parent)
{
	/*
	 * 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);

	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);

	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;
	kobject_register(&device->kobj);
	create_sysfs_device_files(device);
}

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);

	spin_unlock(&acpi_device_lock);

	acpi_detach_data(device->handle, acpi_bus_data_handler);
	remove_sysfs_device_files(device);
	kobject_unregister(&device->kobj);
}

void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
{

	/* TBD */

	return;
}

static int acpi_bus_get_power_flags(struct acpi_device *device)
{
	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;

	/*
	 * 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;
		}

		/* 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 */
	}

	/* 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;

	return 0;
}

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 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;
		}

		device->wakeup.resources.handles[i] = element->reference.handle;
	}

	return AE_OK;
}

static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
{
	acpi_status status = 0;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *package = NULL;


	/* _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;
	}

	acpi_os_free(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;

      end:
	if (ACPI_FAILURE(status))
		device->flags.wake_capable = 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)

ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);

/**
 * 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)
{
	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);
}

static int acpi_eject_operation(acpi_handle handle, int lockable)
{
	struct acpi_object_list arg_list;
	union acpi_object arg;
	acpi_status status = AE_OK;

	/*
	 * TBD: evaluate _PS3?
	 */

	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);
	}

	arg_list.count = 1;
	arg_list.pointer = &arg;
	arg.type = ACPI_TYPE_INTEGER;
	arg.integer.value = 1;

	/*
	 * TBD: _EJD support.
	 */

	status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
	if (ACPI_FAILURE(status)) {
		return (-ENODEV);
	}

	return (0);
}

static ssize_t
acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
{
	int result;
	int ret = count;
	int islockable;
	acpi_status status;
	acpi_handle handle;
	acpi_object_type type = 0;

	if ((!count) || (buf[0] != '1')) {
		return -EINVAL;
	}
#ifndef FORCE_EJECT
	if (device->driver == NULL) {
		ret = -ENODEV;
		goto err;
	}
#endif
	status = acpi_get_type(device->handle, &type);
	if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
		ret = -ENODEV;
		goto err;
	}

	islockable = device->flags.lockable;
	handle = device->handle;

	result = acpi_bus_trim(device, 1);

	if (!result)
		result = acpi_eject_operation(handle, islockable);

	if (result) {
		ret = -EBUSY;
	}
      err:
	return ret;
}

/* --------------------------------------------------------------------------
                              Performance Management
   -------------------------------------------------------------------------- */

static int acpi_bus_get_perf_flags(struct acpi_device *device)
{
	device->performance.state = ACPI_STATE_UNKNOWN;
	return 0;
}

/* --------------------------------------------------------------------------
                                 Driver Management
   -------------------------------------------------------------------------- */

static LIST_HEAD(acpi_bus_drivers);

/**
 * 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_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.
 */
static int
acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
{
	int result = 0;


	if (!device || !driver)
		return -EINVAL;

	if (!driver->ops.add)
		return -ENOSYS;

	result = driver->ops.add(device);
	if (result) {
		device->driver = NULL;
		acpi_driver_data(device) = NULL;
		return result;
	}

	device->driver = driver;

	/*
	 * TBD - Configuration Management: Assign resources to device based
	 * upon possible configuration and currently allocated resources.
	 */

	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "Driver successfully bound to device\n"));
	return 0;
}

static int acpi_start_single_object(struct acpi_device *device)
{
	int result = 0;
	struct acpi_driver *driver;


	if (!(driver = device->driver))
		return 0;

	if (driver->ops.start) {
		result = driver->ops.start(device);
		if (result && driver->ops.remove)
			driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
	}

	return result;
}

static void acpi_driver_attach(struct acpi_driver *drv)
{
	struct list_head *node, *next;


	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 || !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));
			}
		}
		spin_lock(&acpi_device_lock);
	}
	spin_unlock(&acpi_device_lock);
}

static void acpi_driver_detach(struct acpi_driver *drv)
{
	struct list_head *node, *next;


	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);
		}
	}
	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)
{

	if (acpi_disabled)
		return -ENODEV;

	spin_lock(&acpi_device_lock);
	list_add_tail(&driver->node, &acpi_bus_drivers);
	spin_unlock(&acpi_device_lock);
	acpi_driver_attach(driver);

	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)
{
	acpi_driver_detach(driver);

	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);

/**
 * 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;


	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;
		}
		atomic_dec(&driver->references);
		spin_lock(&acpi_device_lock);
	}
	spin_unlock(&acpi_device_lock);

      Done:
	return result;
}

/* --------------------------------------------------------------------------
                                 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);


static int acpi_bus_get_flags(struct acpi_device *device)
{
	acpi_status status = AE_OK;
	acpi_handle temp = NULL;


	/* Presence of _STA indicates 'dynamic_status' */
	status = acpi_get_handle(device->handle, "_STA", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.dynamic_status = 1;

	/* Presence of _CID indicates 'compatible_ids' */
	status = acpi_get_handle(device->handle, "_CID", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.compatible_ids = 1;

	/* Presence of _RMV indicates 'removable' */
	status = acpi_get_handle(device->handle, "_RMV", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.removable = 1;

	/* Presence of _EJD|_EJ0 indicates 'ejectable' */
	status = acpi_get_handle(device->handle, "_EJD", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.ejectable = 1;
	else {
		status = acpi_get_handle(device->handle, "_EJ0", &temp);
		if (ACPI_SUCCESS(status))
			device->flags.ejectable = 1;
	}

	/* Presence of _LCK indicates 'lockable' */
	status = acpi_get_handle(device->handle, "_LCK", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.lockable = 1;

	/* Presence of _PS0|_PR0 indicates 'power manageable' */
	status = acpi_get_handle(device->handle, "_PS0", &temp);
	if (ACPI_FAILURE(status))
		status = acpi_get_handle(device->handle, "_PR0", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.power_manageable = 1;

	/* Presence of _PRW indicates wake capable */
	status = acpi_get_handle(device->handle, "_PRW", &temp);
	if (ACPI_SUCCESS(status))
		device->flags.wake_capable = 1;

	/* TBD: Peformance management */

	return 0;
}

static void acpi_device_get_busid(struct acpi_device *device,
				  acpi_handle handle, int type)
{
	char bus_id[5] = { '?', 0 };
	struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
	int i = 0;

	/*
	 * Bus ID
	 * ------
	 * The device's Bus ID is simply the object name.
	 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
	 */
	switch (type) {
	case ACPI_BUS_TYPE_SYSTEM:
		strcpy(device->pnp.bus_id, "ACPI");
		break;
	case ACPI_BUS_TYPE_POWER_BUTTON:
		strcpy(device->pnp.bus_id, "PWRF");
		break;
	case ACPI_BUS_TYPE_SLEEP_BUTTON:
		strcpy(device->pnp.bus_id, "SLPF");
		break;
	default:
		acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
		/* Clean up trailing underscores (if any) */
		for (i = 3; i > 1; i--) {
			if (bus_id[i] == '_')
				bus_id[i] = '\0';
			else
				break;
		}
		strcpy(device->pnp.bus_id, bus_id);
		break;
	}
}

static void acpi_device_set_id(struct acpi_device *device,
			       struct acpi_device *parent, acpi_handle handle,
			       int type)
{
	struct acpi_device_info *info;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	char *hid = NULL;
	char *uid = NULL;
	struct acpi_compatible_id_list *cid_list = NULL;
	acpi_status status;

	switch (type) {
	case ACPI_BUS_TYPE_DEVICE:
		status = acpi_get_object_info(handle, &buffer);
		if (ACPI_FAILURE(status)) {
			printk("%s: Error reading device info\n", __FUNCTION__);
			return;
		}

		info = buffer.pointer;
		if (info->valid & ACPI_VALID_HID)
			hid = info->hardware_id.value;
		if (info->valid & ACPI_VALID_UID)
			uid = info->unique_id.value;
		if (info->valid & ACPI_VALID_CID)
			cid_list = &info->compatibility_id;
		if (info->valid & ACPI_VALID_ADR) {
			device->pnp.bus_address = info->address;
			device->flags.bus_address = 1;
		}
		break;
	case ACPI_BUS_TYPE_POWER:
		hid = ACPI_POWER_HID;
		break;
	case ACPI_BUS_TYPE_PROCESSOR:
		hid = ACPI_PROCESSOR_HID;
		break;
	case ACPI_BUS_TYPE_SYSTEM:
		hid = ACPI_SYSTEM_HID;
		break;
	case ACPI_BUS_TYPE_THERMAL:
		hid = ACPI_THERMAL_HID;
		break;
	case ACPI_BUS_TYPE_POWER_BUTTON:
		hid = ACPI_BUTTON_HID_POWERF;
		break;
	case ACPI_BUS_TYPE_SLEEP_BUTTON:
		hid = ACPI_BUTTON_HID_SLEEPF;
		break;
	}

	/* 
	 * \_SB
	 * ----
	 * Fix for the system root bus device -- the only root-level device.
	 */
	if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
		hid = ACPI_BUS_HID;
		strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
		strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
	}

	if (hid) {
		strcpy(device->pnp.hardware_id, hid);
		device->flags.hardware_id = 1;
	}
	if (uid) {
		strcpy(device->pnp.unique_id, uid);
		device->flags.unique_id = 1;
	}
	if (cid_list) {
		device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL);
		if (device->pnp.cid_list)
			memcpy(device->pnp.cid_list, cid_list, cid_list->size);
		else
			printk(KERN_ERR "Memory allocation error\n");
	}

	acpi_os_free(buffer.pointer);
}

static int acpi_device_set_context(struct acpi_device *device, int type)
{
	acpi_status status = AE_OK;
	int result = 0;
	/*
	 * Context
	 * -------
	 * Attach this 'struct acpi_device' to the ACPI object.  This makes
	 * resolutions from handle->device very efficient.  Note that we need
	 * to be careful with fixed-feature devices as they all attach to the
	 * root object.
	 */
	if (type != ACPI_BUS_TYPE_POWER_BUTTON &&
	    type != ACPI_BUS_TYPE_SLEEP_BUTTON) {
		status = acpi_attach_data(device->handle,
					  acpi_bus_data_handler, device);

		if (ACPI_FAILURE(status)) {
			printk("Error attaching device data\n");
			result = -ENODEV;
		}
	}
	return result;
}

static void acpi_device_get_debug_info(struct acpi_device *device,
				       acpi_handle handle, int type)
{
#ifdef CONFIG_ACPI_DEBUG_OUTPUT
	char *type_string = NULL;
	char name[80] = { '?', '\0' };
	struct acpi_buffer buffer = { sizeof(name), name };

	switch (type) {
	case ACPI_BUS_TYPE_DEVICE:
		type_string = "Device";
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
		break;
	case ACPI_BUS_TYPE_POWER:
		type_string = "Power Resource";
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
		break;
	case ACPI_BUS_TYPE_PROCESSOR:
		type_string = "Processor";
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
		break;
	case ACPI_BUS_TYPE_SYSTEM:
		type_string = "System";
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
		break;
	case ACPI_BUS_TYPE_THERMAL:
		type_string = "Thermal Zone";
		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
		break;
	case ACPI_BUS_TYPE_POWER_BUTTON:
		type_string = "Power Button";
		sprintf(name, "PWRB");
		break;
	case ACPI_BUS_TYPE_SLEEP_BUTTON:
		type_string = "Sleep Button";
		sprintf(name, "SLPB");
		break;
	}

	printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle);
#endif				/*CONFIG_ACPI_DEBUG_OUTPUT */
}

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;
	}

	if (!rmdevice)
		return 0;

	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)
{
	int result = 0;
	struct acpi_device *device = NULL;


	if (!child)
		return -EINVAL;

	device = kmalloc(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;

	acpi_device_get_busid(device, handle, type);

	/*
	 * Flags
	 * -----
	 * Get prior to calling acpi_bus_get_status() so we know whether
	 * or not _STA is present.  Note that we only look for object
	 * handles -- cannot evaluate objects until we know the device is
	 * present and properly initialized.
	 */
	result = acpi_bus_get_flags(device);
	if (result)
		goto end;

	/*
	 * Status
	 * ------
	 * See if the device is present.  We always assume that non-Device
	 * and non-Processor objects (e.g. thermal zones, power resources,
	 * etc.) are present, functioning, etc. (at least when parent object
	 * is present).  Note that _STA has a different meaning for some
	 * objects (e.g. power resources) so we need to be careful how we use
	 * it.
	 */
	switch (type) {
	case ACPI_BUS_TYPE_PROCESSOR:
	case ACPI_BUS_TYPE_DEVICE:
		result = acpi_bus_get_status(device);
		if (ACPI_FAILURE(result) || !device->status.present) {
			result = -ENOENT;
			goto end;
		}
		break;
	default:
		STRUCT_TO_INT(device->status) = 0x0F;
		break;
	}

	/*
	 * Initialize Device
	 * -----------------
	 * TBD: Synch with Core's enumeration/initialization process.
	 */

	/*
	 * Hardware ID, Unique ID, & Bus Address
	 * -------------------------------------
	 */
	acpi_device_set_id(device, parent, handle, type);

	/*
	 * Power Management
	 * ----------------
	 */
	if (device->flags.power_manageable) {
		result = acpi_bus_get_power_flags(device);
		if (result)
			goto end;
	}

	/*
	 * Wakeup device management
	 *-----------------------
	 */
	if (device->flags.wake_capable) {
		result = acpi_bus_get_wakeup_device_flags(device);
		if (result)
			goto end;
	}

	/*
	 * Performance Management
	 * ----------------------
	 */
	if (device->flags.performance_manageable) {
		result = acpi_bus_get_perf_flags(device);
		if (result)
			goto end;
	}

	if ((result = acpi_device_set_context(device, type)))
		goto end;

	acpi_device_get_debug_info(device, handle, type);

	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.
	 */
	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;
	else {
		kfree(device->pnp.cid_list);
		kfree(device);
	}

	return result;
}

static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
{
	acpi_status status = AE_OK;
	struct acpi_device *parent = NULL;
	struct acpi_device *child = NULL;
	acpi_handle phandle = NULL;
	acpi_handle chandle = NULL;
	acpi_object_type type = 0;
	u32 level = 1;


	if (!start)
		return -EINVAL;

	parent = start;
	phandle = start->handle;

	/*
	 * Parse through the ACPI namespace, identify all 'devices', and
	 * create a new 'struct acpi_device' for each.
	 */
	while ((level > 0) && parent) {

		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
					      chandle, &chandle);

		/*
		 * If this scope is exhausted then move our way back up.
		 */
		if (ACPI_FAILURE(status)) {
			level--;
			chandle = phandle;
			acpi_get_parent(phandle, &phandle);
			if (parent->parent)
				parent = parent->parent;
			continue;
		}

		status = acpi_get_type(chandle, &type);
		if (ACPI_FAILURE(status))
			continue;

		/*
		 * If this is a scope object then parse it (depth-first).
		 */
		if (type == ACPI_TYPE_LOCAL_SCOPE) {
			level++;
			phandle = chandle;
			chandle = NULL;
			continue;
		}

		/*
		 * We're only interested in objects that we consider 'devices'.
		 */
		switch (type) {
		case ACPI_TYPE_DEVICE:
			type = ACPI_BUS_TYPE_DEVICE;
			break;
		case ACPI_TYPE_PROCESSOR:
			type = ACPI_BUS_TYPE_PROCESSOR;
			break;
		case ACPI_TYPE_THERMAL:
			type = ACPI_BUS_TYPE_THERMAL;
			break;
		case ACPI_TYPE_POWER:
			type = ACPI_BUS_TYPE_POWER;
			break;
		default:
			continue;
		}

		if (ops->acpi_op_add)
			status = acpi_add_single_object(&child, parent,
							chandle, type);
		else
			status = acpi_bus_get_device(chandle, &child);

		if (ACPI_FAILURE(status))
			continue;

		if (ops->acpi_op_start) {
			status = acpi_start_single_object(child);
			if (ACPI_FAILURE(status))
				continue;
		}

		/*
		 * If the device is present, enabled, and functioning then
		 * parse its scope (depth-first).  Note that we need to
		 * represent absent devices to facilitate PnP notifications
		 * -- but only the subtree head (not all of its children,
		 * which will be enumerated when the parent is inserted).
		 *
		 * TBD: Need notifications and other detection mechanisms
		 *      in place before we can fully implement this.
		 */
		if (child->status.present) {
			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
						      NULL, NULL);
			if (ACPI_SUCCESS(status)) {
				level++;
				phandle = chandle;
				chandle = NULL;
				parent = child;
			}
		}
	}

	return 0;
}

int
acpi_bus_add(struct acpi_device **child,
	     struct acpi_device *parent, acpi_handle handle, int type)
{
	int result;
	struct acpi_bus_ops ops;


	result = acpi_add_single_object(child, parent, handle, type);
	if (!result) {
		memset(&ops, 0, sizeof(ops));
		ops.acpi_op_add = 1;
		result = acpi_bus_scan(*child, &ops);
	}
	return result;
}

EXPORT_SYMBOL(acpi_bus_add);

int acpi_bus_start(struct acpi_device *device)
{
	int result;
	struct acpi_bus_ops ops;


	if (!device)
		return -EINVAL;

	result = acpi_start_single_object(device);
	if (!result) {
		memset(&ops, 0, sizeof(ops));
		ops.acpi_op_start = 1;
		result = acpi_bus_scan(device, &ops);
	}
	return result;
}

EXPORT_SYMBOL(acpi_bus_start);

int acpi_bus_trim(struct acpi_device *start, int rmdevice)
{
	acpi_status status;
	struct acpi_device *parent, *child;
	acpi_handle phandle, chandle;
	acpi_object_type type;
	u32 level = 1;
	int err = 0;

	parent = start;
	phandle = start->handle;
	child = chandle = NULL;

	while ((level > 0) && parent && (!err)) {
		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
					      chandle, &chandle);

		/*
		 * If this scope is exhausted then move our way back up.
		 */
		if (ACPI_FAILURE(status)) {
			level--;
			chandle = phandle;
			acpi_get_parent(phandle, &phandle);
			child = parent;
			parent = parent->parent;

			if (level == 0)
				err = acpi_bus_remove(child, rmdevice);
			else
				err = acpi_bus_remove(child, 1);

			continue;
		}

		status = acpi_get_type(chandle, &type);
		if (ACPI_FAILURE(status)) {
			continue;
		}
		/*
		 * If there is a device corresponding to chandle then
		 * parse it (depth-first).
		 */
		if (acpi_bus_get_device(chandle, &child) == 0) {
			level++;
			phandle = chandle;
			chandle = NULL;
			parent = child;
		}
		continue;
	}
	return err;
}
EXPORT_SYMBOL_GPL(acpi_bus_trim);


static int acpi_bus_scan_fixed(struct acpi_device *root)
{
	int result = 0;
	struct acpi_device *device = NULL;


	if (!root)
		return -ENODEV;

	/*
	 * Enumerate all fixed-feature devices.
	 */
	if (acpi_fadt.pwr_button == 0) {
		result = acpi_add_single_object(&device, acpi_root,
						NULL,
						ACPI_BUS_TYPE_POWER_BUTTON);
		if (!result)
			result = acpi_start_single_object(device);
	}

	if (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);
	}

	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;
	struct acpi_bus_ops ops;


	if (acpi_disabled)
		return 0;

	kset_register(&acpi_namespace_kset);

	result = bus_register(&acpi_bus_type);
	if (result) {
		/* We don't want to quit even if we failed to add suspend/resume */
		printk(KERN_ERR PREFIX "Could not register bus type\n");
	}

	/*
	 * 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);
	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;
		result = acpi_bus_scan(acpi_root, &ops);
	}

	if (result)
		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);

      Done:
	return result;
}

subsys_initcall(acpi_scan_init);
