aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_acpi.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2008-12-16 22:09:12 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-07 14:13:11 -0500
commite8c331e963c58b83db24b7d0e39e8c07f687dbc6 (patch)
treeda9e7df2441da952dc11bd732b0171d3170fa8bf /drivers/pci/hotplug/pciehp_acpi.c
parente046cbd6c05ee859244245d7beeac395cd0057b3 (diff)
PCI hotplug: introduce functions for ACPI slot detection
Some ACPI related PCI hotplug code can be shared among PCI hotplug drivers. This patch introduces the following functions in drivers/pci/hotplug/acpi_pcihp.c to share the code, and changes acpiphp and pciehp to use them. - int acpi_pci_detect_ejectable(struct pci_bus *pbus) This checks if the specified PCI bus has ejectable slots. - int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle) This checks if the specified handle is ejectable ACPI PCI slot. The 'pbus' parameter is needed to check if 'handle' is PCI related ACPI object. This patch also introduces the following inline function in include/linux/pci-acpi.h, which is useful to get ACPI handle of the PCI bridge from struct pci_bus of the bridge's secondary bus. - static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus) This returns ACPI handle of the PCI bridge which generates PCI bus specified by 'pbus'. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
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}