aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c125
1 files changed, 11 insertions, 114 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ca05064f3ff7..2dd11e0bac24 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -51,6 +51,12 @@ static int acpi_pci_root_add(struct acpi_device *device,
51 const struct acpi_device_id *not_used); 51 const struct acpi_device_id *not_used);
52static void acpi_pci_root_remove(struct acpi_device *device); 52static void acpi_pci_root_remove(struct acpi_device *device);
53 53
54static int acpi_pci_root_scan_dependent(struct acpi_device *adev)
55{
56 acpiphp_check_host_bridge(adev->handle);
57 return 0;
58}
59
54#define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \ 60#define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \
55 | OSC_PCI_ASPM_SUPPORT \ 61 | OSC_PCI_ASPM_SUPPORT \
56 | OSC_PCI_CLOCK_PM_SUPPORT \ 62 | OSC_PCI_CLOCK_PM_SUPPORT \
@@ -66,7 +72,8 @@ static struct acpi_scan_handler pci_root_handler = {
66 .attach = acpi_pci_root_add, 72 .attach = acpi_pci_root_add,
67 .detach = acpi_pci_root_remove, 73 .detach = acpi_pci_root_remove,
68 .hotplug = { 74 .hotplug = {
69 .ignore = true, 75 .enabled = true,
76 .scan_dependent = acpi_pci_root_scan_dependent,
70 }, 77 },
71}; 78};
72 79
@@ -624,119 +631,9 @@ static void acpi_pci_root_remove(struct acpi_device *device)
624void __init acpi_pci_root_init(void) 631void __init acpi_pci_root_init(void)
625{ 632{
626 acpi_hest_init(); 633 acpi_hest_init();
627 634 if (acpi_pci_disabled)
628 if (!acpi_pci_disabled) {
629 pci_acpi_crs_quirks();
630 acpi_scan_add_handler(&pci_root_handler);
631 }
632}
633/* Support root bridge hotplug */
634
635static void handle_root_bridge_insertion(acpi_handle handle)
636{
637 struct acpi_device *device = NULL;
638
639 acpi_bus_get_device(handle, &device);
640 if (acpi_device_enumerated(device)) {
641 dev_printk(KERN_DEBUG, &device->dev,
642 "acpi device already exists; ignoring notify\n");
643 return;
644 }
645
646 if (acpi_bus_scan(handle))
647 acpi_handle_err(handle, "cannot add bridge to acpi list\n");
648}
649
650static void hotplug_event_root(void *data, u32 type)
651{
652 acpi_handle handle = data;
653 struct acpi_pci_root *root;
654
655 acpi_scan_lock_acquire();
656
657 root = acpi_pci_find_root(handle);
658
659 switch (type) {
660 case ACPI_NOTIFY_BUS_CHECK:
661 /* bus enumerate */
662 acpi_handle_printk(KERN_DEBUG, handle,
663 "Bus check notify on %s\n", __func__);
664 if (root)
665 acpiphp_check_host_bridge(handle);
666 else
667 handle_root_bridge_insertion(handle);
668
669 break;
670
671 case ACPI_NOTIFY_DEVICE_CHECK:
672 /* device check */
673 acpi_handle_printk(KERN_DEBUG, handle,
674 "Device check notify on %s\n", __func__);
675 if (!root)
676 handle_root_bridge_insertion(handle);
677 break;
678
679 case ACPI_NOTIFY_EJECT_REQUEST:
680 /* request device eject */
681 acpi_handle_printk(KERN_DEBUG, handle,
682 "Device eject notify on %s\n", __func__);
683 if (!root)
684 break;
685
686 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
687 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
688 get_device(&root->device->dev);
689
690 acpi_scan_lock_release();
691
692 acpi_device_hotplug(root->device, ACPI_NOTIFY_EJECT_REQUEST);
693 return; 635 return;
694 default:
695 acpi_handle_warn(handle,
696 "notify_handler: unknown event type 0x%x\n",
697 type);
698 break;
699 }
700
701 acpi_scan_lock_release();
702}
703
704static void handle_hotplug_event_root(acpi_handle handle, u32 type,
705 void *context)
706{
707 acpi_hotplug_execute(hotplug_event_root, handle, type);
708}
709
710static acpi_status __init
711find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
712{
713 acpi_status status;
714 int *count = (int *)context;
715
716 if (!acpi_is_root_bridge(handle))
717 return AE_OK;
718
719 (*count)++;
720
721 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
722 handle_hotplug_event_root, NULL);
723 if (ACPI_FAILURE(status))
724 acpi_handle_printk(KERN_DEBUG, handle,
725 "notify handler is not installed, exit status: %u\n",
726 (unsigned int)status);
727 else
728 acpi_handle_printk(KERN_DEBUG, handle,
729 "notify handler is installed\n");
730
731 return AE_OK;
732}
733
734void __init acpi_pci_root_hp_init(void)
735{
736 int num = 0;
737
738 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
739 ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
740 636
741 printk(KERN_DEBUG "Found %d acpi root devices\n", num); 637 pci_acpi_crs_quirks();
638 acpi_scan_add_handler_with_hotplug(&pci_root_handler, "pci_root");
742} 639}