+/* --------------------------------------------------------------------------
+ ACPI hotplug 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)
+{
+ if (dev->flags.ejectable == 1)
+ (*(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;
+}
+
+