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

Commit 1253f7aa authored by Shaohua Li's avatar Shaohua Li Committed by Len Brown
Browse files

dock: introduce .uevent for devices in dock, eg libata



dock's uevent reported itself, not ata. It might be difficult to find an
ata device just according to a dock. This patch introduces docking ops
for each device in a dock. when docking, dock driver can send device
specific uevent. This should help dock station too (not just bay)

Signed-off-by: default avatarShaohua Li <shaohua.li@intel.com>
Acked-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent f730ae18
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ struct dock_dependent_device {
	struct list_head list;
	struct list_head hotplug_list;
	acpi_handle handle;
	acpi_notify_handler handler;
	struct acpi_dock_ops *ops;
	void *context;
};

@@ -385,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
	 * First call driver specific hotplug functions
	 */
	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
		if (dd->handler)
			dd->handler(dd->handle, event, dd->context);
		if (dd->ops && dd->ops->handler)
			dd->ops->handler(dd->handle, event, dd->context);
	}

	/*
@@ -409,6 +409,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
	struct device *dev = &ds->dock_device->dev;
	char event_string[13];
	char *envp[] = { event_string, NULL };
	struct dock_dependent_device *dd;

	if (num == UNDOCK_EVENT)
		sprintf(event_string, "EVENT=undock");
@@ -419,6 +420,13 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
	 * Indicate that the status of the dock station has
	 * changed.
	 */
	if (num == DOCK_EVENT)
		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);

	list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
		if (dd->ops && dd->ops->uevent)
			dd->ops->uevent(dd->handle, event, dd->context);
	if (num != DOCK_EVENT)
		kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
}

@@ -588,7 +596,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
/**
 * register_hotplug_dock_device - register a hotplug function
 * @handle: the handle of the device
 * @handler: the acpi_notifier_handler to call after docking
 * @ops: handlers to call after docking
 * @context: device specific data
 *
 * If a driver would like to perform a hotplug operation after a dock
@@ -596,7 +604,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
 * the dock driver after _DCK is executed.
 */
int
register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
			     void *context)
{
	struct dock_dependent_device *dd;
@@ -612,7 +620,7 @@ register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
	list_for_each_entry(dock_station, &dock_stations, sibiling) {
		dd = find_dock_dependent_device(dock_station, handle);
		if (dd) {
			dd->handler = handler;
			dd->ops = ops;
			dd->context = context;
			dock_add_hotplug_device(dock_station, dd);
			return 0;
+42 −2
Original line number Diff line number Diff line
@@ -209,6 +209,46 @@ static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
	ata_acpi_handle_hotplug(ap, NULL, event);
}

static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
	u32 event)
{
	struct kobject *kobj = NULL;
	char event_string[20];
	char *envp[] = { event_string, NULL };

	if (dev) {
		if (dev->sdev)
			kobj = &dev->sdev->sdev_gendev.kobj;
	} else
		kobj = &ap->dev->kobj;

	if (kobj) {
		snprintf(event_string, 20, "BAY_EVENT=%d", event);
		kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
	}
}

static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
{
	ata_acpi_uevent(data, NULL, event);
}

static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
{
	struct ata_device *dev = data;
	ata_acpi_uevent(dev->link->ap, dev, event);
}

static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
	.handler = ata_acpi_dev_notify_dock,
	.uevent = ata_acpi_dev_uevent,
};

static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
	.handler = ata_acpi_ap_notify_dock,
	.uevent = ata_acpi_ap_uevent,
};

/**
 * ata_acpi_associate - associate ATA host with ACPI objects
 * @host: target ATA host
@@ -244,7 +284,7 @@ void ata_acpi_associate(struct ata_host *host)
		if (ap->acpi_handle) {
			/* we might be on a docking station */
			register_hotplug_dock_device(ap->acpi_handle,
					     ata_acpi_ap_notify_dock, ap);
					     &ata_acpi_ap_dock_ops, ap);
		}

		for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
@@ -253,7 +293,7 @@ void ata_acpi_associate(struct ata_host *host)
			if (dev->acpi_handle) {
				/* we might be on a docking station */
				register_hotplug_dock_device(dev->acpi_handle,
					     ata_acpi_dev_notify_dock, dev);
					     &ata_acpi_dev_dock_ops, dev);
			}
		}
	}
+4 −2
Original line number Diff line number Diff line
@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
}



static struct acpi_dock_ops acpiphp_dock_ops = {
	.handler = handle_hotplug_event_func,
};

/* callback routine to register each ACPI PCI slot object */
static acpi_status
@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
		 */
		newfunc->flags &= ~FUNC_HAS_EJ0;
		if (register_hotplug_dock_device(handle,
			handle_hotplug_event_func, newfunc))
			&acpiphp_dock_ops, newfunc))
			dbg("failed to register dock device\n");

		/* we need to be notified when dock events happen
+7 −2
Original line number Diff line number Diff line
@@ -115,12 +115,17 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
/*--------------------------------------------------------------------------
                                  Dock Station
  -------------------------------------------------------------------------- */
struct acpi_dock_ops {
	acpi_notify_handler handler;
	acpi_notify_handler uevent;
};

#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
extern int is_dock_device(acpi_handle handle);
extern int register_dock_notifier(struct notifier_block *nb);
extern void unregister_dock_notifier(struct notifier_block *nb);
extern int register_hotplug_dock_device(acpi_handle handle,
					acpi_notify_handler handler,
					struct acpi_dock_ops *ops,
					void *context);
extern void unregister_hotplug_dock_device(acpi_handle handle);
#else
@@ -136,7 +141,7 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
{
}
static inline int register_hotplug_dock_device(acpi_handle handle,
					       acpi_notify_handler handler,
					       struct acpi_dock_ops *ops,
					       void *context)
{
	return -ENODEV;