diff options
| -rw-r--r-- | drivers/acpi/bus.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/container.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/dock.c | 452 | ||||
| -rw-r--r-- | drivers/acpi/internal.h | 14 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 14 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 59 | ||||
| -rw-r--r-- | drivers/ata/libata-acpi.c | 72 | ||||
| -rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 134 | ||||
| -rw-r--r-- | include/acpi/acpi_bus.h | 24 | ||||
| -rw-r--r-- | include/acpi/acpi_drivers.h | 26 |
10 files changed, 295 insertions, 505 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e61e7b8a2eaf..afe6f9a919c1 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -400,7 +400,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
| 400 | case ACPI_NOTIFY_BUS_CHECK: | 400 | case ACPI_NOTIFY_BUS_CHECK: |
| 401 | case ACPI_NOTIFY_DEVICE_CHECK: | 401 | case ACPI_NOTIFY_DEVICE_CHECK: |
| 402 | case ACPI_NOTIFY_EJECT_REQUEST: | 402 | case ACPI_NOTIFY_EJECT_REQUEST: |
| 403 | status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); | 403 | status = acpi_hotplug_schedule(adev, type); |
| 404 | if (ACPI_SUCCESS(status)) | 404 | if (ACPI_SUCCESS(status)) |
| 405 | return; | 405 | return; |
| 406 | default: | 406 | default: |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 368f9ddb8480..a55cccbc7356 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
| @@ -68,6 +68,9 @@ static int container_device_attach(struct acpi_device *adev, | |||
| 68 | struct device *dev; | 68 | struct device *dev; |
| 69 | int ret; | 69 | int ret; |
| 70 | 70 | ||
| 71 | if (adev->flags.is_dock_station) | ||
| 72 | return 0; | ||
| 73 | |||
| 71 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); | 74 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); |
| 72 | if (!cdev) | 75 | if (!cdev) |
| 73 | return -ENOMEM; | 76 | return -ENOMEM; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 5bfd769fc91f..a7bd3002dbbc 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * dock.c - ACPI dock station driver | 2 | * dock.c - ACPI dock station driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> | 4 | * Copyright (C) 2006, 2014, Intel Corp. |
| 5 | * Author: Kristen Carlson Accardi <kristen.c.accardi@intel.com> | ||
| 6 | * Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
| 5 | * | 7 | * |
| 6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 7 | * | 9 | * |
| @@ -68,15 +70,10 @@ struct dock_station { | |||
| 68 | }; | 70 | }; |
| 69 | static LIST_HEAD(dock_stations); | 71 | static LIST_HEAD(dock_stations); |
| 70 | static int dock_station_count; | 72 | static int dock_station_count; |
| 71 | static DEFINE_MUTEX(hotplug_lock); | ||
| 72 | 73 | ||
| 73 | struct dock_dependent_device { | 74 | struct dock_dependent_device { |
| 74 | struct list_head list; | 75 | struct list_head list; |
| 75 | acpi_handle handle; | 76 | struct acpi_device *adev; |
| 76 | const struct acpi_dock_ops *hp_ops; | ||
| 77 | void *hp_context; | ||
| 78 | unsigned int hp_refcount; | ||
| 79 | void (*hp_release)(void *); | ||
| 80 | }; | 77 | }; |
| 81 | 78 | ||
| 82 | #define DOCK_DOCKING 0x00000001 | 79 | #define DOCK_DOCKING 0x00000001 |
| @@ -98,13 +95,13 @@ enum dock_callback_type { | |||
| 98 | *****************************************************************************/ | 95 | *****************************************************************************/ |
| 99 | /** | 96 | /** |
| 100 | * add_dock_dependent_device - associate a device with the dock station | 97 | * add_dock_dependent_device - associate a device with the dock station |
| 101 | * @ds: The dock station | 98 | * @ds: Dock station. |
| 102 | * @handle: handle of the dependent device | 99 | * @adev: Dependent ACPI device object. |
| 103 | * | 100 | * |
| 104 | * Add the dependent device to the dock's dependent device list. | 101 | * Add the dependent device to the dock's dependent device list. |
| 105 | */ | 102 | */ |
| 106 | static int __init | 103 | static int add_dock_dependent_device(struct dock_station *ds, |
| 107 | add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | 104 | struct acpi_device *adev) |
| 108 | { | 105 | { |
| 109 | struct dock_dependent_device *dd; | 106 | struct dock_dependent_device *dd; |
| 110 | 107 | ||
| @@ -112,180 +109,120 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | |||
| 112 | if (!dd) | 109 | if (!dd) |
| 113 | return -ENOMEM; | 110 | return -ENOMEM; |
| 114 | 111 | ||
| 115 | dd->handle = handle; | 112 | dd->adev = adev; |
| 116 | INIT_LIST_HEAD(&dd->list); | 113 | INIT_LIST_HEAD(&dd->list); |
| 117 | list_add_tail(&dd->list, &ds->dependent_devices); | 114 | list_add_tail(&dd->list, &ds->dependent_devices); |
| 118 | 115 | ||
| 119 | return 0; | 116 | return 0; |
| 120 | } | 117 | } |
| 121 | 118 | ||
| 122 | static void remove_dock_dependent_devices(struct dock_station *ds) | 119 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, |
| 120 | enum dock_callback_type cb_type) | ||
| 123 | { | 121 | { |
| 124 | struct dock_dependent_device *dd, *aux; | 122 | struct acpi_device *adev = dd->adev; |
| 125 | 123 | ||
| 126 | list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) { | 124 | acpi_lock_hp_context(); |
| 127 | list_del(&dd->list); | ||
| 128 | kfree(dd); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | 125 | ||
| 132 | /** | 126 | if (!adev->hp) |
| 133 | * dock_init_hotplug - Initialize a hotplug device on a docking station. | 127 | goto out; |
| 134 | * @dd: Dock-dependent device. | ||
| 135 | * @ops: Dock operations to attach to the dependent device. | ||
| 136 | * @context: Data to pass to the @ops callbacks and @release. | ||
| 137 | * @init: Optional initialization routine to run after setting up context. | ||
| 138 | * @release: Optional release routine to run on removal. | ||
| 139 | */ | ||
| 140 | static int dock_init_hotplug(struct dock_dependent_device *dd, | ||
| 141 | const struct acpi_dock_ops *ops, void *context, | ||
| 142 | void (*init)(void *), void (*release)(void *)) | ||
| 143 | { | ||
| 144 | int ret = 0; | ||
| 145 | 128 | ||
| 146 | mutex_lock(&hotplug_lock); | 129 | if (cb_type == DOCK_CALL_FIXUP) { |
| 147 | if (WARN_ON(dd->hp_context)) { | 130 | void (*fixup)(struct acpi_device *); |
| 148 | ret = -EEXIST; | ||
| 149 | } else { | ||
| 150 | dd->hp_refcount = 1; | ||
| 151 | dd->hp_ops = ops; | ||
| 152 | dd->hp_context = context; | ||
| 153 | dd->hp_release = release; | ||
| 154 | if (init) | ||
| 155 | init(context); | ||
| 156 | } | ||
| 157 | mutex_unlock(&hotplug_lock); | ||
| 158 | return ret; | ||
| 159 | } | ||
| 160 | 131 | ||
| 161 | /** | 132 | fixup = adev->hp->fixup; |
| 162 | * dock_release_hotplug - Decrement hotplug reference counter of dock device. | 133 | if (fixup) { |
| 163 | * @dd: Dock-dependent device. | 134 | acpi_unlock_hp_context(); |
| 164 | * | 135 | fixup(adev); |
| 165 | * Decrement the reference counter of @dd and if 0, detach its hotplug | 136 | return; |
| 166 | * operations from it, reset its context pointer and run the optional release | 137 | } |
| 167 | * routine if present. | 138 | } else if (cb_type == DOCK_CALL_UEVENT) { |
| 168 | */ | 139 | void (*uevent)(struct acpi_device *, u32); |
| 169 | static void dock_release_hotplug(struct dock_dependent_device *dd) | 140 | |
| 170 | { | 141 | uevent = adev->hp->uevent; |
| 171 | mutex_lock(&hotplug_lock); | 142 | if (uevent) { |
| 172 | if (dd->hp_context && !--dd->hp_refcount) { | 143 | acpi_unlock_hp_context(); |
| 173 | void (*release)(void *) = dd->hp_release; | 144 | uevent(adev, event); |
| 174 | void *context = dd->hp_context; | 145 | return; |
| 175 | 146 | } | |
| 176 | dd->hp_ops = NULL; | 147 | } else { |
| 177 | dd->hp_context = NULL; | 148 | int (*notify)(struct acpi_device *, u32); |
| 178 | dd->hp_release = NULL; | ||
| 179 | if (release) | ||
| 180 | release(context); | ||
| 181 | } | ||
| 182 | mutex_unlock(&hotplug_lock); | ||
| 183 | } | ||
| 184 | 149 | ||
| 185 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | 150 | notify = adev->hp->notify; |
| 186 | enum dock_callback_type cb_type) | 151 | if (notify) { |
| 187 | { | 152 | acpi_unlock_hp_context(); |
| 188 | acpi_notify_handler cb = NULL; | 153 | notify(adev, event); |
| 189 | bool run = false; | ||
