Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c92f56cb authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'acpi-cleanup'

* acpi-cleanup: (21 commits)
  ACPI / dock: fix error return code in dock_add()
  ACPI / dock: Drop unnecessary local variable from dock_add()
  ACPI / dock / PCI: Drop ACPI dock notifier chain
  ACPI / dock: Do not check CONFIG_ACPI_DOCK_MODULE
  ACPI / dock: Do not leak memory on falilures to add a dock station
  ACPI: Drop ACPI bus notifier call chain
  ACPI / dock: Rework the handling of notifications
  ACPI / dock: Simplify dock_init_hotplug() and dock_release_hotplug()
  ACPI / dock: Walk list in reverse order during removal of devices
  ACPI / dock: Rework and simplify find_dock_devices()
  ACPI / dock: Drop the hp_lock mutex from struct dock_station
  ACPI: simplify acpiphp driver with new helper functions
  ACPI: simplify dock driver with new helper functions
  ACPI: Export acpi_(bay)|(dock)_match() from scan.c
  ACPI: introduce two helper functions for _EJ0 and _LCK
  ACPI: introduce helper function acpi_execute_simple_method()
  ACPI: introduce helper function acpi_has_method()
  ACPI / dock: simplify dock_create_acpi_device()
  ACPI / dock: mark initialization functions with __init
  ACPI / dock: drop redundant spin lock in dock station object
  ...
parents d8dfad38 0177f29f
Loading
Loading
Loading
Loading
+5 −14
Original line number Diff line number Diff line
@@ -527,18 +527,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
static int acpi_battery_set_alarm(struct acpi_battery *battery)
{
	acpi_status status = 0;
	union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
	struct acpi_object_list arg_list = { 1, &arg0 };

	if (!acpi_battery_present(battery) ||
	    !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
		return -ENODEV;

	arg0.integer.value = battery->alarm;

	mutex_lock(&battery->lock);
	status = acpi_evaluate_object(battery->device->handle, "_BTP",
				 &arg_list, NULL);
	status = acpi_execute_simple_method(battery->device->handle, "_BTP",
					    battery->alarm);
	mutex_unlock(&battery->lock);

	if (ACPI_FAILURE(status))
@@ -550,12 +546,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)

static int acpi_battery_init_alarm(struct acpi_battery *battery)
{
	acpi_status status = AE_OK;
	acpi_handle handle = NULL;

	/* See if alarms are supported, and if so, set default */
	status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
	if (ACPI_FAILURE(status)) {
	if (!acpi_has_method(battery->device->handle, "_BTP")) {
		clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
		return 0;
	}
@@ -1068,7 +1060,7 @@ static int acpi_battery_add(struct acpi_device *device)
{
	int result = 0;
	struct acpi_battery *battery = NULL;
	acpi_handle handle;

	if (!device)
		return -EINVAL;
	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
@@ -1080,8 +1072,7 @@ static int acpi_battery_add(struct acpi_device *device)
	device->driver_data = battery;
	mutex_init(&battery->lock);
	mutex_init(&battery->sysfs_lock);
	if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle,
			"_BIX", &handle)))
	if (acpi_has_method(battery->device->handle, "_BIX"))
		set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
	result = acpi_battery_update(battery);
	if (result)
+1 −21
Original line number Diff line number Diff line
@@ -499,19 +499,6 @@ static void acpi_bus_check_scope(acpi_handle handle)
	 */
}

static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
int register_acpi_bus_notifier(struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&acpi_bus_notify_list, nb);
}
EXPORT_SYMBOL_GPL(register_acpi_bus_notifier);

void unregister_acpi_bus_notifier(struct notifier_block *nb)
{
	blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb);
}
EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);

/**
 * acpi_bus_notify
 * ---------------
@@ -525,9 +512,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n",
			  type, handle));

	blocking_notifier_call_chain(&acpi_bus_notify_list,
		type, (void *)handle);

	switch (type) {

	case ACPI_NOTIFY_BUS_CHECK:
@@ -593,8 +577,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
static int __init acpi_bus_init_irq(void)
{
	acpi_status status;
	union acpi_object arg = { ACPI_TYPE_INTEGER };
	struct acpi_object_list arg_list = { 1, &arg };
	char *message = NULL;


@@ -623,9 +605,7 @@ static int __init acpi_bus_init_irq(void)

	printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);

	arg.integer.value = acpi_irq_model;

	status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
	status = acpi_execute_simple_method(NULL, "\\_PIC", acpi_irq_model);
	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
		return -ENODEV;
+125 −273
Original line number Diff line number Diff line
@@ -51,8 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
	" the driver to wait for userspace to write the undock sysfs file "
	" before undocking");

static struct atomic_notifier_head dock_notifier_list;

static const struct acpi_device_id dock_device_ids[] = {
	{"LNXDOCK", 0},
	{"", 0},
@@ -63,8 +61,6 @@ struct dock_station {
	acpi_handle handle;
	unsigned long last_dock_time;
	u32 flags;
	spinlock_t dd_lock;
	struct mutex hp_lock;
	struct list_head dependent_devices;

	struct list_head sibling;
@@ -91,6 +87,12 @@ struct dock_dependent_device {
#define DOCK_EVENT	3
#define UNDOCK_EVENT	2

enum dock_callback_type {
	DOCK_CALL_HANDLER,
	DOCK_CALL_FIXUP,
	DOCK_CALL_UEVENT,
};

/*****************************************************************************
 *                         Dock Dependent device functions                   *
 *****************************************************************************/
@@ -101,7 +103,7 @@ struct dock_dependent_device {
 *
 * Add the dependent device to the dock's dependent device list.
 */
static int
static int __init
add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
{
	struct dock_dependent_device *dd;
@@ -112,14 +114,21 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)

	dd->handle = handle;
	INIT_LIST_HEAD(&dd->list);

	spin_lock(&ds->dd_lock);
	list_add_tail(&dd->list, &ds->dependent_devices);
	spin_unlock(&ds->dd_lock);

	return 0;
}

static void remove_dock_dependent_devices(struct dock_station *ds)
{
	struct dock_dependent_device *dd, *aux;

	list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) {
		list_del(&dd->list);
		kfree(dd);
	}
}

/**
 * dock_init_hotplug - Initialize a hotplug device on a docking station.
 * @dd: Dock-dependent device.
@@ -135,19 +144,16 @@ static int dock_init_hotplug(struct dock_dependent_device *dd,
	int ret = 0;

	mutex_lock(&hotplug_lock);

	if (dd->hp_context) {
	if (WARN_ON(dd->hp_context)) {
		ret = -EEXIST;
	} else {
		dd->hp_refcount = 1;
		dd->hp_ops = ops;
		dd->hp_context = context;
		dd->hp_release = release;
	}

	if (!WARN_ON(ret) && init)
		if (init)
			init(context);

	}
	mutex_unlock(&hotplug_lock);
	return ret;
}
@@ -162,27 +168,22 @@ static int dock_init_hotplug(struct dock_dependent_device *dd,
 */
static void dock_release_hotplug(struct dock_dependent_device *dd)
{
	void (*release)(void *) = NULL;
	void *context = NULL;

	mutex_lock(&hotplug_lock);

	if (dd->hp_context && !--dd->hp_refcount) {
		void (*release)(void *) = dd->hp_release;
		void *context = dd->hp_context;

		dd->hp_ops = NULL;
		context = dd->hp_context;
		dd->hp_context = NULL;
		release = dd->hp_release;
		dd->hp_release = NULL;
	}

	if (release && context)
		if (release)
			release(context);

	}
	mutex_unlock(&hotplug_lock);
}

static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
			       bool uevent)
			       enum dock_callback_type cb_type)
{
	acpi_notify_handler cb = NULL;
	bool run = false;
@@ -192,8 +193,18 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
	if (dd->hp_context) {
		run = true;
		dd->hp_refcount++;
		if (dd->hp_ops)
			cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler;
		if (dd->hp_ops) {
			switch (cb_type) {
			case DOCK_CALL_FIXUP:
				cb = dd->hp_ops->fixup;
				break;
			case DOCK_CALL_UEVENT:
				cb = dd->hp_ops->uevent;
				break;
			default:
				cb = dd->hp_ops->handler;
			}
		}
	}

	mutex_unlock(&hotplug_lock);
@@ -220,63 +231,17 @@ find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
{
	struct dock_dependent_device *dd;

	spin_lock(&ds->dd_lock);
	list_for_each_entry(dd, &ds->dependent_devices, list) {
		if (handle == dd->handle) {
			spin_unlock(&ds->dd_lock);
	list_for_each_entry(dd, &ds->dependent_devices, list)
		if (handle == dd->handle)
			return dd;
		}
	}
	spin_unlock(&ds->dd_lock);

	return NULL;
}

/*****************************************************************************
 *                         Dock functions                                    *
 *****************************************************************************/
/**
 * is_dock - see if a device is a dock station
 * @handle: acpi handle of the device
 *
 * If an acpi object has a _DCK method, then it is by definition a dock
 * station, so return true.
 */
static int is_dock(acpi_handle handle)
{
	acpi_status status;
	acpi_handle tmp;

	status = acpi_get_handle(handle, "_DCK", &tmp);
	if (ACPI_FAILURE(status))
		return 0;
	return 1;
}

static int is_ejectable(acpi_handle handle)
{
	acpi_status status;
	acpi_handle tmp;

	status = acpi_get_handle(handle, "_EJ0", &tmp);
	if (ACPI_FAILURE(status))
		return 0;
	return 1;
}

static int is_ata(acpi_handle handle)
{
	acpi_handle tmp;

	if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
	   (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
	   (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
	   (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
		return 1;

	return 0;
}

static int is_battery(acpi_handle handle)
static int __init is_battery(acpi_handle handle)
{
	struct acpi_device_info *info;
	int ret = 1;
@@ -292,17 +257,13 @@ static int is_battery(acpi_handle handle)
	return ret;
}

static int is_ejectable_bay(acpi_handle handle)
/* Check whether ACPI object is an ejectable battery or disk bay */
static bool __init is_ejectable_bay(acpi_handle handle)
{
	acpi_handle phandle;
	if (acpi_has_method(handle, "_EJ0") && is_battery(handle))
		return true;

	if (!is_ejectable(handle))
		return 0;
	if (is_battery(handle) || is_ata(handle))
		return 1;
	if (!acpi_get_parent(handle, &phandle) && is_ata(phandle))
		return 1;
	return 0;
	return acpi_bay_match(handle);
}

/**
@@ -320,7 +281,7 @@ int is_dock_device(acpi_handle handle)
	if (!dock_station_count)
		return 0;

	if (is_dock(handle))
	if (acpi_dock_match(handle))
		return 1;

	list_for_each_entry(dock_station, &dock_stations, sibling)
@@ -359,10 +320,8 @@ static int dock_present(struct dock_station *ds)
 *  handle if one does not exist already.  This should cause
 *  acpi to scan for drivers for the given devices, and call
 *  matching driver's add routine.
 *
 *  Returns a pointer to the acpi_device corresponding to the handle.
 */
static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
static void dock_create_acpi_device(acpi_handle handle)
{
	struct acpi_device *device;
	int ret;
@@ -375,10 +334,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
		ret = acpi_bus_scan(handle);
		if (ret)
			pr_debug("error adding bus, %x\n", -ret);

		acpi_bus_get_device(handle, &device);
	}
	return device;
}

/**
@@ -397,9 +353,29 @@ static void dock_remove_acpi_device(acpi_handle handle)
}

/**
 * hotplug_dock_devices - insert or remove devices on the dock station
 * hot_remove_dock_devices - Remove dock station devices.
 * @ds: Dock station.
 */
static void hot_remove_dock_devices(struct dock_station *ds)
{
	struct dock_dependent_device *dd;

	/*
	 * Walk the list in reverse order so that devices that have been added
	 * last are removed first (in case there are some indirect dependencies
	 * between them).
	 */
	list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
		dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false);

	list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
		dock_remove_acpi_device(dd->handle);
}

/**
 * hotplug_dock_devices - Insert devices on a dock station.
 * @ds: the dock station
 * @event: either bus check or eject request
 * @event: either bus check or device check request
 *
 * Some devices on the dock station need to have drivers called
 * to perform hotplug operations after a dock event has occurred.
@@ -410,28 +386,22 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
{
	struct dock_dependent_device *dd;

	mutex_lock(&ds->hp_lock);
	/* Call driver specific post-dock fixups. */
	list_for_each_entry(dd, &ds->dependent_devices, list)
		dock_hotplug_event(dd, event, DOCK_CALL_FIXUP);

	/*
	 * First call driver specific hotplug functions
	 */
	/* Call driver specific hotplug functions. */
	list_for_each_entry(dd, &ds->dependent_devices, list)
		dock_hotplug_event(dd, event, false);
		dock_hotplug_event(dd, event, DOCK_CALL_HANDLER);

	/*
	 * Now make sure that an acpi_device is created for each
	 * dependent device, or removed if this is an eject request.
	 * This will cause acpi_drivers to be stopped/started if they
	 * exist
	 * Now make sure that an acpi_device is created for each dependent
	 * device.  That will cause scan handlers to be attached to device
	 * objects or acpi_drivers to be stopped/started if they are present.
	 */
	list_for_each_entry(dd, &ds->dependent_devices, list) {
		if (event == ACPI_NOTIFY_EJECT_REQUEST)
			dock_remove_acpi_device(dd->handle);
		else
	list_for_each_entry(dd, &ds->dependent_devices, list)
		dock_create_acpi_device(dd->handle);
}
	mutex_unlock(&ds->hp_lock);
}

static void dock_event(struct dock_station *ds, u32 event, int num)
{
@@ -453,43 +423,12 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);

	list_for_each_entry(dd, &ds->dependent_devices, list)
		dock_hotplug_event(dd, event, true);
		dock_hotplug_event(dd, event, DOCK_CALL_UEVENT);

	if (num != DOCK_EVENT)
		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
}

/**
 * eject_dock - respond to a dock eject request
 * @ds: the dock station
 *
 * This is called after _DCK is called, to execute the dock station's
 * _EJ0 method.
 */
static void eject_dock(struct dock_station *ds)
{
	struct acpi_object_list arg_list;
	union acpi_object arg;
	acpi_status status;
	acpi_handle tmp;

	/* all dock devices should have _EJ0, but check anyway */
	status = acpi_get_handle(ds->handle, "_EJ0", &tmp);
	if (ACPI_FAILURE(status)) {
		pr_debug("No _EJ0 support for dock device\n");
		return;
	}

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

	status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL);
	if (ACPI_FAILURE(status))
		pr_debug("Failed to evaluate _EJ0!\n");
}

/**
 * handle_dock - handle a dock event
 * @ds: the dock station
@@ -550,27 +489,6 @@ static inline void complete_undock(struct dock_station *ds)
	ds->flags &= ~(DOCK_UNDOCKING);
}

static void dock_lock(struct dock_station *ds, int lock)
{
	struct acpi_object_list arg_list;
	union acpi_object arg;
	acpi_status status;

	arg_list.count = 1;
	arg_list.pointer = &arg;
	arg.type = ACPI_TYPE_INTEGER;
	arg.integer.value = !!lock;
	status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL);
	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
		if (lock)
			acpi_handle_warn(ds->handle,
				"Locking device failed (0x%x)\n", status);
		else
			acpi_handle_warn(ds->handle,
				"Unlocking device failed (0x%x)\n", status);
	}
}

/**
 * dock_in_progress - see if we are in the middle of handling a dock event
 * @ds: the dock station
@@ -587,37 +505,6 @@ static int dock_in_progress(struct dock_station *ds)
	return 0;
}

/**
 * register_dock_notifier - add yourself to the dock notifier list
 * @nb: the callers notifier block
 *
 * If a driver wishes to be notified about dock events, they can
 * use this function to put a notifier block on the dock notifier list.
 * this notifier call chain will be called after a dock event, but
 * before hotplugging any new devices.
 */
int register_dock_notifier(struct notifier_block *nb)
{
	if (!dock_station_count)
		return -ENODEV;

	return atomic_notifier_chain_register(&dock_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(register_dock_notifier);

/**
 * unregister_dock_notifier - remove yourself from the dock notifier list
 * @nb: the callers notifier block
 */
void unregister_dock_notifier(struct notifier_block *nb)
{
	if (!dock_station_count)
		return;

	atomic_notifier_chain_unregister(&dock_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(unregister_dock_notifier);

/**
 * register_hotplug_dock_device - register a hotplug function
 * @handle: the handle of the device
@@ -703,10 +590,10 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
	 */
	dock_event(ds, event, UNDOCK_EVENT);

	hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
	hot_remove_dock_devices(ds);
	undock(ds);
	dock_lock(ds, 0);
	eject_dock(ds);
	acpi_evaluate_lck(ds->handle, 0);
	acpi_evaluate_ej0(ds->handle);
	if (dock_present(ds)) {
		acpi_handle_err(ds->handle, "Unable to undock!\n");
		return -EBUSY;
@@ -717,18 +604,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)

/**
 * dock_notify - act upon an acpi dock notification
 * @handle: the dock station handle
 * @ds: dock station
 * @event: the acpi event
 * @data: our driver data struct
 *
 * If we are notified to dock, then check to see if the dock is
 * present and then dock.  Notify all drivers of the dock event,
 * and then hotplug and devices that may need hotplugging.
 */
static void dock_notify(acpi_handle handle, u32 event, void *data)
static void dock_notify(struct dock_station *ds, u32 event)
{
	struct dock_station *ds = data;
	struct acpi_device *tmp;
	acpi_handle handle = ds->handle;
	struct acpi_device *ad;
	int surprise_removal = 0;

	/*
@@ -751,8 +637,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
	switch (event) {
	case ACPI_NOTIFY_BUS_CHECK:
	case ACPI_NOTIFY_DEVICE_CHECK:
		if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
		   &tmp)) {
		if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) {
			begin_dock(ds);
			dock(ds);
			if (!dock_present(ds)) {
@@ -760,12 +645,10 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
				complete_dock(ds);
				break;
			}
			atomic_notifier_call_chain(&dock_notifier_list,
						   event, NULL);
			hotplug_dock_devices(ds, event);
			complete_dock(ds);
			dock_event(ds, event, DOCK_EVENT);
			dock_lock(ds, 1);
			acpi_evaluate_lck(ds->handle, 1);
			acpi_update_all_gpes();
			break;
		}
@@ -789,9 +672,8 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
}

struct dock_data {
	acpi_handle handle;
	unsigned long event;
	struct dock_station *ds;
	u32 event;
};

static void acpi_dock_deferred_cb(void *context)
@@ -799,52 +681,31 @@ static void acpi_dock_deferred_cb(void *context)
	struct dock_data *data = context;

	acpi_scan_lock_acquire();
	dock_notify(data->handle, data->event, data->ds);
	dock_notify(data->ds, data->event);
	acpi_scan_lock_release();
	kfree(data);
}

static int acpi_dock_notifier_call(struct notifier_block *this,
	unsigned long event, void *data)
static void dock_notify_handler(acpi_handle handle, u32 event, void *data)
{
	struct dock_station *dock_station;
	acpi_handle handle = data;
	struct dock_data *dd;

	if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
	   && event != ACPI_NOTIFY_EJECT_REQUEST)
		return 0;

	acpi_scan_lock_acquire();

	list_for_each_entry(dock_station, &dock_stations, sibling) {
		if (dock_station->handle == handle) {
			struct dock_data *dd;
			acpi_status status;
		return;

	dd = kmalloc(sizeof(*dd), GFP_KERNEL);
			if (!dd)
				break;
	if (dd) {
		acpi_status status;

			dd->handle = handle;
		dd->ds = data;
		dd->event = event;
			dd->ds = dock_station;
			status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
							 dd);
		status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
		if (ACPI_FAILURE(status))
			kfree(dd);

			break;
	}
}

	acpi_scan_lock_release();
	return 0;
}

static struct notifier_block dock_acpi_notifier = {
	.notifier_call = acpi_dock_notifier_call,
};

/**
 * find_dock_devices - find devices on the dock station
 * @handle: the handle of the device we are examining
@@ -856,29 +717,16 @@ static struct notifier_block dock_acpi_notifier = {
 * check to see if an object has an _EJD method.  If it does, then it
 * will see if it is dependent on the dock station.
 */
static acpi_status
find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl,
					    void *context, void **rv)
{
	acpi_status status;
	acpi_handle tmp, parent;
	struct dock_station *ds = context;
	acpi_handle ejd = NULL;

	status = acpi_bus_get_ejd(handle, &tmp);
	if (ACPI_FAILURE(status)) {
		/* try the parent device as well */
		status = acpi_get_parent(handle, &parent);
		if (ACPI_FAILURE(status))
			goto fdd_out;
		/* see if parent is dependent on dock */
		status = acpi_bus_get_ejd(parent, &tmp);
		if (ACPI_FAILURE(status))
			goto fdd_out;
	}

	if (tmp == ds->handle)
	acpi_bus_get_ejd(handle, &ejd);
	if (ejd == ds->handle)
		add_dock_dependent_device(ds, handle);

fdd_out:
	return AE_OK;
}

@@ -988,13 +836,13 @@ static struct attribute_group dock_attribute_group = {
 */
static int __init dock_add(acpi_handle handle)
{
	int ret, id;
	struct dock_station ds, *dock_station;
	struct dock_station *dock_station, ds = { NULL, };
	struct platform_device *dd;
	acpi_status status;
	int ret;

	id = dock_station_count;
	memset(&ds, 0, sizeof(ds));
	dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds));
	dd = platform_device_register_data(NULL, "dock", dock_station_count,
					   &ds, sizeof(ds));
	if (IS_ERR(dd))
		return PTR_ERR(dd);

@@ -1004,18 +852,15 @@ static int __init dock_add(acpi_handle handle)
	dock_station->dock_device = dd;
	dock_station->last_dock_time = jiffies - HZ;

	mutex_init(&dock_station->hp_lock);
	spin_lock_init(&dock_station->dd_lock);
	INIT_LIST_HEAD(&dock_station->sibling);
	ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
	INIT_LIST_HEAD(&dock_station->dependent_devices);

	/* we want the dock device to send uevents */
	dev_set_uevent_suppress(&dd->dev, 0);

	if (is_dock(handle))
	if (acpi_dock_match(handle))
		dock_station->flags |= DOCK_IS_DOCK;
	if (is_ata(handle))
	if (acpi_ata_match(handle))
		dock_station->flags |= DOCK_IS_ATA;
	if (is_battery(handle))
		dock_station->flags |= DOCK_IS_BAT;
@@ -1034,11 +879,19 @@ static int __init dock_add(acpi_handle handle)
	if (ret)
		goto err_rmgroup;

	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
					     dock_notify_handler, dock_station);
	if (ACPI_FAILURE(status)) {
		ret = -ENODEV;
		goto err_rmgroup;
	}

	dock_station_count++;
	list_add(&dock_station->sibling, &dock_stations);
	return 0;

err_rmgroup:
	remove_dock_dependent_devices(dock_station);
	sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
err_unregister:
	platform_device_unregister(dd);
@@ -1058,7 +911,7 @@ static int __init dock_add(acpi_handle handle)
static __init acpi_status
find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
{
	if (is_dock(handle) || is_ejectable_bay(handle))
	if (acpi_dock_match(handle) || is_ejectable_bay(handle))
		dock_add(handle);

	return AE_OK;
@@ -1078,7 +931,6 @@ void __init acpi_dock_init(void)
		return;
	}

	register_acpi_bus_notifier(&dock_acpi_notifier);
	pr_info(PREFIX "%s: %d docks/bays found\n",
		ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
}
+1 −3
Original line number Diff line number Diff line
@@ -1049,10 +1049,8 @@ int __init acpi_ec_ecdt_probe(void)
		* which needs it, has fake EC._INI method, so use it as flag.
		* Keep boot_ec struct as it will be needed soon.
		*/
		acpi_handle dummy;
		if (!dmi_name_in_vendors("ASUS") ||
		    ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI",
							&dummy)))
		    !acpi_has_method(boot_ec->handle, "_INI"))
			return -ENODEV;
	}
install:
+1 −3
Original line number Diff line number Diff line
@@ -637,9 +637,7 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
	}

	/* Execute _PSW */
	arg_list.count = 1;
	in_arg[0].integer.value = enable;
	status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
	status = acpi_execute_simple_method(dev->handle, "_PSW", enable);
	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
		printk(KERN_ERR PREFIX "_PSW execution failed\n");
		dev->wakeup.flags.valid = 0;
Loading