+ 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;
+}
+
+/**
+ * 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)
+{
+ int ret;
+
+ if (acpi_disabled)
+ return -ENODEV;
+ driver->drv.name = driver->name;
+ driver->drv.bus = &acpi_bus_type;
+ driver->drv.owner = driver->owner;
+
+ ret = driver_register(&driver->drv);
+ return ret;
+}
+
+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;
+}
+
+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;
+ }