[RFC/RFT][PATCH 4-1/5] ACPI / scan: Add bind/unbind callbacks to struct acpi_scan_handler

From: Rafael J. Wysocki
Date: Tue Jan 21 2014 - 18:11:46 EST

From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>

In some cases it may be necessary to perform certain setup/cleanup
operations on a device object representing a physical device after
it has been associated with an ACPI companion by acpi_bind_one() or
before disassociating it from that companion by acpi_unbind_one(),
respectively. If there is a struct acpi_bus_type object for the
given device's bus type, the .setup()/.cleanup() callbacks from there
are executed for these purposes. However, an analogous mechanism will
be necessary for devices whose bus types don't have corresponding
struct acpi_bus_type objects and that have specific ACPI scan handlers.

For those devices, add new .bind() and .unbind() callbacks to struct
acpi_scan_handler that will be executed by acpi_platform_notify()
right after the given device has been associated with an ACPI
comapnion and by acpi_platform_notify_remove() right before calling
acpi_unbind_one() for that device, respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
drivers/acpi/glue.c | 12 ++++++++++++
include/acpi/acpi_bus.h | 2 ++
2 files changed, 14 insertions(+)

Index: linux-pm/drivers/acpi/glue.c
--- linux-pm.orig/drivers/acpi/glue.c
+++ linux-pm/drivers/acpi/glue.c
@@ -287,6 +287,7 @@ EXPORT_SYMBOL_GPL(acpi_unbind_one);
static int acpi_platform_notify(struct device *dev)
struct acpi_bus_type *type = acpi_get_bus_type(dev);
+ struct acpi_device *adev;
int ret;

ret = acpi_bind_one(dev, NULL);
@@ -303,9 +304,14 @@ static int acpi_platform_notify(struct d
if (ret)
goto out;
+ adev = ACPI_COMPANION(dev);
+ if (!adev)
+ goto out;

if (type && type->setup)
+ else if (adev->handler && adev->handler->bind)
+ adev->handler->bind(dev);

@@ -324,11 +330,17 @@ static int acpi_platform_notify(struct d

static int acpi_platform_notify_remove(struct device *dev)
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_bus_type *type;

+ if (!adev)
+ return 0;
type = acpi_get_bus_type(dev);
if (type && type->cleanup)
+ else if (adev->handler && adev->handler->unbind)
+ adev->handler->unbind(dev);

return 0;
Index: linux-pm/include/acpi/acpi_bus.h
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -133,6 +133,8 @@ struct acpi_scan_handler {
struct list_head list_node;
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
+ void (*bind)(struct device *phys_dev);
+ void (*unbind)(struct device *phys_dev);
struct acpi_hotplug_profile hotplug;

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/