diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-24 18:36:48 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-24 18:36:48 -0400 |
commit | d3ce52f50cc1697504130897f1d7c489b62dae1c (patch) | |
tree | b91971ad26f7b59c71e775d7e71b9dc89da8e568 /drivers/pci | |
parent | 18d63c35a265465b7137c4ea9c6b135aada13c3c (diff) | |
parent | 5ba113f7c4fb06cfdd6cba92353ac55ad5b81b75 (diff) |
Merge branch 'pci/jiang-acpiphp' into next
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 466233b481b1..3d6d4fd1e3c5 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -115,6 +115,35 @@ static const struct acpi_dock_ops acpiphp_dock_ops = { | |||
115 | .handler = handle_hotplug_event_func, | 115 | .handler = handle_hotplug_event_func, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | ||
119 | static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) | ||
120 | { | ||
121 | u32 reg32; | ||
122 | acpi_handle tmp; | ||
123 | struct acpi_pci_root *root; | ||
124 | |||
125 | /* Check whether the PCIe port supports native PCIe hotplug */ | ||
126 | if (pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32)) | ||
127 | return false; | ||
128 | if (!(reg32 & PCI_EXP_SLTCAP_HPC)) | ||
129 | return false; | ||
130 | |||
131 | /* | ||
132 | * Check whether native PCIe hotplug has been enabled for | ||
133 | * this PCIe hierarchy. | ||
134 | */ | ||
135 | tmp = acpi_find_root_bridge_handle(pdev); | ||
136 | if (!tmp) | ||
137 | return false; | ||
138 | root = acpi_pci_find_root(tmp); | ||
139 | if (!root) | ||
140 | return false; | ||
141 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | ||
142 | return false; | ||
143 | |||
144 | return true; | ||
145 | } | ||
146 | |||
118 | /* callback routine to register each ACPI PCI slot object */ | 147 | /* callback routine to register each ACPI PCI slot object */ |
119 | static acpi_status | 148 | static acpi_status |
120 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | 149 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) |
@@ -142,16 +171,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
142 | function = adr & 0xffff; | 171 | function = adr & 0xffff; |
143 | 172 | ||
144 | pdev = pbus->self; | 173 | pdev = pbus->self; |
145 | if (pdev && pci_is_pcie(pdev)) { | 174 | if (pdev && device_is_managed_by_native_pciehp(pdev)) |
146 | tmp = acpi_find_root_bridge_handle(pdev); | 175 | return AE_OK; |
147 | if (tmp) { | ||
148 | struct acpi_pci_root *root = acpi_pci_find_root(tmp); | ||
149 | |||
150 | if (root && (root->osc_control_set & | ||
151 | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | ||
152 | return AE_OK; | ||
153 | } | ||
154 | } | ||
155 | 176 | ||
156 | newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); | 177 | newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); |
157 | if (!newfunc) | 178 | if (!newfunc) |