aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/pci_root.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 2868a9ff6d07..e1bdcc700cbb 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -112,12 +112,17 @@ EXPORT_SYMBOL(acpi_pci_unregister_driver);
112acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) 112acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
113{ 113{
114 struct acpi_pci_root *root; 114 struct acpi_pci_root *root;
115 acpi_handle handle = NULL;
115 116
117 mutex_lock(&acpi_pci_root_lock);
116 list_for_each_entry(root, &acpi_pci_roots, node) 118 list_for_each_entry(root, &acpi_pci_roots, node)
117 if ((root->segment == (u16) seg) && 119 if ((root->segment == (u16) seg) &&
118 (root->secondary.start == (u16) bus)) 120 (root->secondary.start == (u16) bus)) {
119 return root->device->handle; 121 handle = root->device->handle;
120 return NULL; 122 break;
123 }
124 mutex_unlock(&acpi_pci_root_lock);
125 return handle;
121} 126}
122 127
123EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); 128EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
@@ -506,8 +511,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
506 * TBD: Need PCI interface for enumeration/configuration of roots. 511 * TBD: Need PCI interface for enumeration/configuration of roots.
507 */ 512 */
508 513
509 /* TBD: Locking */ 514 mutex_lock(&acpi_pci_root_lock);
510 list_add_tail(&root->node, &acpi_pci_roots); 515 list_add_tail(&root->node, &acpi_pci_roots);
516 mutex_unlock(&acpi_pci_root_lock);
511 517
512 printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", 518 printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
513 acpi_device_name(device), acpi_device_bid(device), 519 acpi_device_name(device), acpi_device_bid(device),
@@ -526,7 +532,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
526 "Bus %04x:%02x not present in PCI namespace\n", 532 "Bus %04x:%02x not present in PCI namespace\n",
527 root->segment, (unsigned int)root->secondary.start); 533 root->segment, (unsigned int)root->secondary.start);
528 result = -ENODEV; 534 result = -ENODEV;
529 goto end; 535 goto out_del_root;
530 } 536 }
531 537
532 /* 538 /*
@@ -536,7 +542,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
536 */ 542 */
537 result = acpi_pci_bind_root(device); 543 result = acpi_pci_bind_root(device);
538 if (result) 544 if (result)
539 goto end; 545 goto out_del_root;
540 546
541 /* 547 /*
542 * PCI Routing Table 548 * PCI Routing Table
@@ -614,9 +620,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
614 620
615 return 0; 621 return 0;
616 622
623out_del_root:
624 mutex_lock(&acpi_pci_root_lock);
625 list_del(&root->node);
626 mutex_unlock(&acpi_pci_root_lock);
617end: 627end:
618 if (!list_empty(&root->node))
619 list_del(&root->node);
620 kfree(root); 628 kfree(root);
621 return result; 629 return result;
622} 630}
@@ -646,11 +654,12 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
646 list_for_each_entry(driver, &acpi_pci_drivers, node) 654 list_for_each_entry(driver, &acpi_pci_drivers, node)
647 if (driver->remove) 655 if (driver->remove)
648 driver->remove(root); 656 driver->remove(root);
649 mutex_unlock(&acpi_pci_root_lock);
650 657
651 device_set_run_wake(root->bus->bridge, false); 658 device_set_run_wake(root->bus->bridge, false);
652 pci_acpi_remove_bus_pm_notifier(device); 659 pci_acpi_remove_bus_pm_notifier(device);
653 660
661 list_del(&root->node);
662 mutex_unlock(&acpi_pci_root_lock);
654 kfree(root); 663 kfree(root);
655 return 0; 664 return 0;
656} 665}