aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/glue.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-02-11 07:20:02 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-02-11 07:20:02 -0500
commit59893298947e0ca28cbaba6d02b9973181f14eea (patch)
tree98d4a2461381458662e5fed813c1d6bc1bfb9f26 /drivers/acpi/glue.c
parent836dc9e3fbbab0c30aa6e664417225f5c1fb1c39 (diff)
parent0613e1f7fd98a0cef2a7add1368a87cdd86a1106 (diff)
Merge branch 'acpi-scan'
* acpi-scan: (30 commits) ACPI / scan: Fix acpi_bus_get_device() check in acpi_match_device() ACPI / scan: Make namespace scanning and trimming mutually exclusive ACPI / scan: Make it clear that acpi_bus_trim() cannot fail ACPI / scan: Drop acpi_bus_add() and use acpi_bus_scan() instead ACPI: update ej_event interface to take acpi_device ACPI / scan: Add second pass to acpi_bus_trim() ACPI / scan: Change the implementation of acpi_bus_trim() ACPI / scan: Drop the second argument of acpi_bus_trim() ACPI / scan: Drop the second argument of acpi_device_unregister() ACPI: Remove the ops field from struct acpi_device ACPI: remove unused acpi_op_bind and acpi_op_unbind ACPI / scan: Fix check of device_attach() return value. ACPI / scan: Treat power resources in a special way ACPI: Remove unused struct acpi_pci_root.id member ACPI: Drop ACPI device .bind() and .unbind() callbacks ACPI / PCI: Move the _PRT setup and cleanup code to pci-acpi.c ACPI / PCI: Rework the setup and cleanup of device wakeup ACPI: Add .setup() and .cleanup() callbacks to struct acpi_bus_type ACPI: Make acpi_bus_scan() and acpi_bus_add() take only one argument ACPI: Replace ACPI device add_type field with a match_driver flag ...
Diffstat (limited to 'drivers/acpi/glue.c')
-rw-r--r--drivers/acpi/glue.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 35da18113216..9aee4fc2b218 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -68,6 +68,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
68{ 68{
69 struct acpi_bus_type *tmp, *ret = NULL; 69 struct acpi_bus_type *tmp, *ret = NULL;
70 70
71 if (!type)
72 return NULL;
73
71 down_read(&bus_type_sem); 74 down_read(&bus_type_sem);
72 list_for_each_entry(tmp, &bus_type_list, list) { 75 list_for_each_entry(tmp, &bus_type_list, list) {
73 if (tmp->bus == type) { 76 if (tmp->bus == type) {
@@ -269,28 +272,39 @@ static int acpi_platform_notify(struct device *dev)
269{ 272{
270 struct acpi_bus_type *type; 273 struct acpi_bus_type *type;
271 acpi_handle handle; 274 acpi_handle handle;
272 int ret = -EINVAL; 275 int ret;
273 276
274 ret = acpi_bind_one(dev, NULL); 277 ret = acpi_bind_one(dev, NULL);
275 if (!ret) 278 if (ret && (!dev->bus || !dev->parent)) {
276 goto out;
277
278 if (!dev->bus || !dev->parent) {
279 /* bridge devices genernally haven't bus or parent */ 279 /* bridge devices genernally haven't bus or parent */
280 ret = acpi_find_bridge_device(dev, &handle); 280 ret = acpi_find_bridge_device(dev, &handle);
281 goto end; 281 if (!ret) {
282 ret = acpi_bind_one(dev, handle);
283 if (ret)
284 goto out;
285 }
282 } 286 }
287
283 type = acpi_get_bus_type(dev->bus); 288 type = acpi_get_bus_type(dev->bus);
284 if (!type) { 289 if (ret) {
285 DBG("No ACPI bus support for %s\n", dev_name(dev)); 290 if (!type || !type->find_device) {
286 ret = -EINVAL; 291 DBG("No ACPI bus support for %s\n", dev_name(dev));
287 goto end; 292 ret = -EINVAL;
293 goto out;
294 }
295
296 ret = type->find_device(dev, &handle);
297 if (ret) {
298 DBG("Unable to get handle for %s\n", dev_name(dev));
299 goto out;
300 }
301 ret = acpi_bind_one(dev, handle);
302 if (ret)
303 goto out;
288 } 304 }
289 if ((ret = type->find_device(dev, &handle)) != 0) 305
290 DBG("Can't get handler for %s\n", dev_name(dev)); 306 if (type && type->setup)
291 end: 307 type->setup(dev);
292 if (!ret)
293 acpi_bind_one(dev, handle);
294 308
295 out: 309 out:
296#if ACPI_GLUE_DEBUG 310#if ACPI_GLUE_DEBUG
@@ -309,6 +323,12 @@ static int acpi_platform_notify(struct device *dev)
309 323
310static int acpi_platform_notify_remove(struct device *dev) 324static int acpi_platform_notify_remove(struct device *dev)
311{ 325{
326 struct acpi_bus_type *type;
327
328 type = acpi_get_bus_type(dev->bus);
329 if (type && type->cleanup)
330 type->cleanup(dev);
331
312 acpi_unbind_one(dev); 332 acpi_unbind_one(dev);
313 return 0; 333 return 0;
314} 334}