- } 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;
-
- ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags");
-
- /* _PRW */
- status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n"));
- goto end;
- }
-
- package = (union acpi_object *)buffer.pointer;
- status = acpi_bus_extract_wakeup_device_power_package(device, package);
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error extracting _PRW package\n"));
- 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_VALUE(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;
-
- if (type == ACPI_TYPE_PROCESSOR)
- result = acpi_bus_trim(device, 0);
- else
- 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);
-static DECLARE_MUTEX(acpi_bus_drivers_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_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;
-
- ACPI_FUNCTION_TRACE("acpi_bus_driver_init");
-
- if (!device || !driver)
- return_VALUE(-EINVAL);
-
- if (!driver->ops.add)
- return_VALUE(-ENOSYS);
-
- result = driver->ops.add(device);
- if (result) {
- device->driver = NULL;
- acpi_driver_data(device) = NULL;
- return_VALUE(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_VALUE(0);
-}
-
-static int acpi_start_single_object(struct acpi_device *device)
-{
- int result = 0;
- struct acpi_driver *driver;