aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_acpi.c')
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c55
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
44static 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
61static acpi_status
62check_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
72static 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
92int pciehp_acpi_slot_detection_check(struct pci_dev *dev) 46int 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}