diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_acpi.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_acpi.c | 55 |
1 files changed, 5 insertions, 50 deletions
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 88a5c57f2e5b..438d795f9fe3 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -24,6 +24,8 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/acpi.h> | 26 | #include <linux/acpi.h> |
27 | #include <linux/pci.h> | ||
28 | #include <linux/pci_hotplug.h> | ||
27 | #include "pciehp.h" | 29 | #include "pciehp.h" |
28 | 30 | ||
29 | #define PCIEHP_DETECT_PCIE (0) | 31 | #define PCIEHP_DETECT_PCIE (0) |
@@ -41,59 +43,11 @@ MODULE_PARM_DESC(pciehp_detect_mode, | |||
41 | " auto(default) - Auto select mode. Use acpi option if duplicate\n" | 43 | " auto(default) - Auto select mode. Use acpi option if duplicate\n" |
42 | " slot ids are found. Otherwise, use pcie option\n"); | 44 | " slot ids are found. Otherwise, use pcie option\n"); |
43 | 45 | ||
44 | static int is_ejectable(acpi_handle handle) | ||
45 | { | ||
46 | acpi_status status; | ||
47 | acpi_handle tmp; | ||
48 | unsigned long long removable; | ||
49 | status = acpi_get_handle(handle, "_ADR", &tmp); | ||
50 | if (ACPI_FAILURE(status)) | ||
51 | return 0; | ||
52 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
53 | if (ACPI_SUCCESS(status)) | ||
54 | return 1; | ||
55 | status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable); | ||
56 | if (ACPI_SUCCESS(status) && removable) | ||
57 | return 1; | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static acpi_status | ||
62 | check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
63 | { | ||
64 | int *found = (int *)context; | ||
65 | if (is_ejectable(handle)) { | ||
66 | *found = 1; | ||
67 | return AE_CTRL_TERMINATE; | ||
68 | } | ||
69 | return AE_OK; | ||
70 | } | ||
71 | |||
72 | static int pciehp_detect_acpi_slot(struct pci_bus *pbus) | ||
73 | { | ||
74 | acpi_handle handle; | ||
75 | struct pci_dev *pdev = pbus->self; | ||
76 | int found = 0; | ||
77 | |||
78 | if (!pdev){ | ||
79 | int seg = pci_domain_nr(pbus), busnr = pbus->number; | ||
80 | handle = acpi_get_pci_rootbridge_handle(seg, busnr); | ||
81 | } else | ||
82 | handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); | ||
83 | |||
84 | if (!handle) | ||
85 | return 0; | ||
86 | |||
87 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
88 | check_hotplug, (void *)&found, NULL); | ||
89 | return found; | ||
90 | } | ||
91 | |||
92 | int pciehp_acpi_slot_detection_check(struct pci_dev *dev) | 46 | int pciehp_acpi_slot_detection_check(struct pci_dev *dev) |
93 | { | 47 | { |
94 | if (slot_detection_mode != PCIEHP_DETECT_ACPI) | 48 | if (slot_detection_mode != PCIEHP_DETECT_ACPI) |
95 | return 0; | 49 | return 0; |
96 | if (pciehp_detect_acpi_slot(dev->subordinate)) | 50 | if (acpi_pci_detect_ejectable(dev->subordinate)) |
97 | return 0; | 51 | return 0; |
98 | return -ENODEV; | 52 | return -ENODEV; |
99 | } | 53 | } |
@@ -135,6 +89,7 @@ static int __init dummy_probe(struct pcie_device *dev, | |||
135 | u32 slot_cap; | 89 | u32 slot_cap; |
136 | struct slot *slot, *tmp; | 90 | struct slot *slot, *tmp; |
137 | struct pci_dev *pdev = dev->port; | 91 | struct pci_dev *pdev = dev->port; |
92 | struct pci_bus *pbus = pdev->subordinate; | ||
138 | if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL))) | 93 | if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL))) |
139 | return -ENOMEM; | 94 | return -ENOMEM; |
140 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 95 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ |
@@ -149,7 +104,7 @@ static int __init dummy_probe(struct pcie_device *dev, | |||
149 | dup_slot_id++; | 104 | dup_slot_id++; |
150 | } | 105 | } |
151 | list_add_tail(&slot->slot_list, &dummy_slots); | 106 | list_add_tail(&slot->slot_list, &dummy_slots); |
152 | if (!acpi_slot_detected && pciehp_detect_acpi_slot(pdev->subordinate)) | 107 | if (!acpi_slot_detected && acpi_pci_detect_ejectable(pbus)) |
153 | acpi_slot_detected = 1; | 108 | acpi_slot_detected = 1; |
154 | return -ENODEV; /* dummy driver always returns error */ | 109 | return -ENODEV; /* dummy driver always returns error */ |
155 | } | 110 | } |