aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/internal.h2
-rw-r--r--drivers/acpi/pci_root.c125
-rw-r--r--drivers/acpi/scan.c42
-rw-r--r--include/acpi/acpi_bus.h2
4 files changed, 37 insertions, 134 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index a0d42cf5b0c5..f4aa467c407e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -28,7 +28,6 @@ int init_acpi_device_notify(void);
28int acpi_scan_init(void); 28int acpi_scan_init(void);
29void acpi_pci_root_init(void); 29void acpi_pci_root_init(void);
30void acpi_pci_link_init(void); 30void acpi_pci_link_init(void);
31void acpi_pci_root_hp_init(void);
32void acpi_processor_init(void); 31void acpi_processor_init(void);
33void acpi_platform_init(void); 32void acpi_platform_init(void);
34int acpi_sysfs_init(void); 33int acpi_sysfs_init(void);
@@ -89,7 +88,6 @@ void acpi_device_add_finalize(struct acpi_device *device);
89void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); 88void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
90int acpi_bind_one(struct device *dev, acpi_handle handle); 89int acpi_bind_one(struct device *dev, acpi_handle handle);
91int acpi_unbind_one(struct device *dev); 90int acpi_unbind_one(struct device *dev);
92void acpi_device_hotplug(void *data, u32 ost_src);
93bool acpi_device_is_present(struct acpi_device *adev); 91bool acpi_device_is_present(struct acpi_device *adev);
94 92
95/* -------------------------------------------------------------------------- 93/* --------------------------------------------------------------------------
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}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index dd0ff9de9277..18865c86c463 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -283,17 +283,6 @@ static int acpi_scan_device_check(struct acpi_device *adev)
283{ 283{
284 int error; 284 int error;
285 285
286 /*
287 * This function is only called for device objects for which matching
288 * scan handlers exist. The only situation in which the scan handler is
289 * not attached to this device object yet is when the device has just
290 * appeared (either it wasn't present at all before or it was removed
291 * and then added again).
292 */
293 if (adev->handler) {
294 dev_warn(&adev->dev, "Already enumerated\n");
295 return -EBUSY;
296 }
297 error = acpi_bus_scan(adev->handle); 286 error = acpi_bus_scan(adev->handle);
298 if (error) { 287 if (error) {
299 dev_warn(&adev->dev, "Namespace scan failure\n"); 288 dev_warn(&adev->dev, "Namespace scan failure\n");
@@ -309,10 +298,11 @@ static int acpi_scan_device_check(struct acpi_device *adev)
309 return 0; 298 return 0;
310} 299}
311 300
312void acpi_device_hotplug(void *data, u32 src) 301static void acpi_device_hotplug(void *data, u32 src)
313{ 302{
314 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 303 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
315 struct acpi_device *adev = data; 304 struct acpi_device *adev = data;
305 struct acpi_scan_handler *handler;
316 int error; 306 int error;
317 307
318 lock_device_hotplug(); 308 lock_device_hotplug();
@@ -326,12 +316,32 @@ void acpi_device_hotplug(void *data, u32 src)
326 if (adev->handle == INVALID_ACPI_HANDLE) 316 if (adev->handle == INVALID_ACPI_HANDLE)
327 goto out; 317 goto out;
328 318
319 handler = adev->handler;
320
329 switch (src) { 321 switch (src) {
330 case ACPI_NOTIFY_BUS_CHECK: 322 case ACPI_NOTIFY_BUS_CHECK:
331 error = acpi_bus_scan(adev->handle); 323 if (handler) {
324 error = handler->hotplug.scan_dependent ?
325 handler->hotplug.scan_dependent(adev) :
326 acpi_bus_scan(adev->handle);
327 } else {
328 error = acpi_scan_device_check(adev);
329 }
332 break; 330 break;
333 case ACPI_NOTIFY_DEVICE_CHECK: 331 case ACPI_NOTIFY_DEVICE_CHECK:
334 error = acpi_scan_device_check(adev); 332 /*
333 * This code is only run for device objects for which matching
334 * scan handlers exist. The only situation in which the scan
335 * handler is not attached to this device object yet is when the
336 * device has just appeared (either it wasn't present at all
337 * before or it was removed and then added again).
338 */
339 if (adev->handler) {
340 dev_warn(&adev->dev, "Already enumerated\n");
341 error = -EBUSY;
342 } else {
343 error = acpi_scan_device_check(adev);
344 }
335 break; 345 break;
336 case ACPI_NOTIFY_EJECT_REQUEST: 346 case ACPI_NOTIFY_EJECT_REQUEST:
337 case ACPI_OST_EC_OSPM_EJECT: 347 case ACPI_OST_EC_OSPM_EJECT:
@@ -1805,7 +1815,7 @@ static void acpi_scan_init_hotplug(acpi_handle handle, int type)
1805 */ 1815 */
1806 list_for_each_entry(hwid, &pnp.ids, list) { 1816 list_for_each_entry(hwid, &pnp.ids, list) {
1807 handler = acpi_scan_match_handler(hwid->id, NULL); 1817 handler = acpi_scan_match_handler(hwid->id, NULL);
1808 if (handler && !handler->hotplug.ignore) { 1818 if (handler) {
1809 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1819 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
1810 acpi_hotplug_notify_cb, handler); 1820 acpi_hotplug_notify_cb, handler);
1811 break; 1821 break;
@@ -2083,8 +2093,6 @@ int __init acpi_scan_init(void)
2083 2093
2084 acpi_update_all_gpes(); 2094 acpi_update_all_gpes();
2085 2095
2086 acpi_pci_root_hp_init();
2087
2088 out: 2096 out:
2089 mutex_unlock(&acpi_scan_lock); 2097 mutex_unlock(&acpi_scan_lock);
2090 return result; 2098 return result;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index e748dbfca9d5..2359c69f1680 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -100,8 +100,8 @@ enum acpi_hotplug_mode {
100struct acpi_hotplug_profile { 100struct acpi_hotplug_profile {
101 struct kobject kobj; 101 struct kobject kobj;
102 bool enabled:1; 102 bool enabled:1;
103 bool ignore:1;
104 enum acpi_hotplug_mode mode; 103 enum acpi_hotplug_mode mode;
104 int (*scan_dependent)(struct acpi_device *adev);
105}; 105};
106 106
107static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile( 107static inline struct acpi_hotplug_profile *to_acpi_hotplug_profile(