diff options
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r-- | drivers/acpi/pci_root.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index cd4de7e038ea..c6bcb8c719d8 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci-acpi.h> | 34 | #include <linux/pci-acpi.h> |
35 | #include <linux/pci-aspm.h> | 35 | #include <linux/pci-aspm.h> |
36 | #include <linux/dmar.h> | ||
36 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
37 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
38 | #include <linux/dmi.h> | 39 | #include <linux/dmi.h> |
@@ -525,6 +526,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
525 | struct acpi_pci_root *root; | 526 | struct acpi_pci_root *root; |
526 | acpi_handle handle = device->handle; | 527 | acpi_handle handle = device->handle; |
527 | int no_aspm = 0, clear_aspm = 0; | 528 | int no_aspm = 0, clear_aspm = 0; |
529 | bool hotadd = system_state != SYSTEM_BOOTING; | ||
528 | 530 | ||
529 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 531 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
530 | if (!root) | 532 | if (!root) |
@@ -571,6 +573,11 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
571 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 573 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
572 | device->driver_data = root; | 574 | device->driver_data = root; |
573 | 575 | ||
576 | if (hotadd && dmar_device_add(handle)) { | ||
577 | result = -ENXIO; | ||
578 | goto end; | ||
579 | } | ||
580 | |||
574 | pr_info(PREFIX "%s [%s] (domain %04x %pR)\n", | 581 | pr_info(PREFIX "%s [%s] (domain %04x %pR)\n", |
575 | acpi_device_name(device), acpi_device_bid(device), | 582 | acpi_device_name(device), acpi_device_bid(device), |
576 | root->segment, &root->secondary); | 583 | root->segment, &root->secondary); |
@@ -597,7 +604,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
597 | root->segment, (unsigned int)root->secondary.start); | 604 | root->segment, (unsigned int)root->secondary.start); |
598 | device->driver_data = NULL; | 605 | device->driver_data = NULL; |
599 | result = -ENODEV; | 606 | result = -ENODEV; |
600 | goto end; | 607 | goto remove_dmar; |
601 | } | 608 | } |
602 | 609 | ||
603 | if (clear_aspm) { | 610 | if (clear_aspm) { |
@@ -611,7 +618,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
611 | if (device->wakeup.flags.run_wake) | 618 | if (device->wakeup.flags.run_wake) |
612 | device_set_run_wake(root->bus->bridge, true); | 619 | device_set_run_wake(root->bus->bridge, true); |
613 | 620 | ||
614 | if (system_state != SYSTEM_BOOTING) { | 621 | if (hotadd) { |
615 | pcibios_resource_survey_bus(root->bus); | 622 | pcibios_resource_survey_bus(root->bus); |
616 | pci_assign_unassigned_root_bus_resources(root->bus); | 623 | pci_assign_unassigned_root_bus_resources(root->bus); |
617 | } | 624 | } |
@@ -621,6 +628,9 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
621 | pci_unlock_rescan_remove(); | 628 | pci_unlock_rescan_remove(); |
622 | return 1; | 629 | return 1; |
623 | 630 | ||
631 | remove_dmar: | ||
632 | if (hotadd) | ||
633 | dmar_device_remove(handle); | ||
624 | end: | 634 | end: |
625 | kfree(root); | 635 | kfree(root); |
626 | return result; | 636 | return result; |
@@ -639,6 +649,8 @@ static void acpi_pci_root_remove(struct acpi_device *device) | |||
639 | 649 | ||
640 | pci_remove_root_bus(root->bus); | 650 | pci_remove_root_bus(root->bus); |
641 | 651 | ||
652 | dmar_device_remove(device->handle); | ||
653 | |||
642 | pci_unlock_rescan_remove(); | 654 | pci_unlock_rescan_remove(); |
643 | 655 | ||
644 | kfree(root); | 656 | kfree(root); |