aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-11-06 17:11:28 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2011-12-05 13:21:48 -0500
commitd90116ea38f7768dac0349f01ffbc2663d63b7e9 (patch)
tree0301aca686bf5fbace16390dd8f863871a99020e
parent486b10b9f43500741cd63a878d0ef23cd87fc66d (diff)
PCI/ACPI: Make acpiphp ignore root bridges using SHPC native hotplug
If the kernel has requested control of the SHPC native hotplug feature for a given root bridge, the acpiphp driver should not try to handle that root bridge and it should leave it to shpchp. Failing to do so causes problems to happen if shpchp is loaded and unloaded before loading acpiphp (ACPI-based hotplug won't work in that case anyway). To address this issue make find_root_bridges() ignore PCI root bridges with SHPC native hotplug enabled and make add_bridge() return error code if SHPC native hotplug is enabled for the given root bridge. This causes acpiphp to refuse to load if SHPC native hotplug is enabled for all root bridges and to refuse binding to the root bridges with SHPC native hotplug enabled. Reviewed-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c4
-rw-r--r--include/linux/acpi.h4
2 files changed, 6 insertions, 2 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index fce1c54a0c8d..ba43c037de80 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -467,7 +467,7 @@ static int add_bridge(acpi_handle handle)
467 * granted by the BIOS for it. 467 * granted by the BIOS for it.
468 */ 468 */
469 root = acpi_pci_find_root(handle); 469 root = acpi_pci_find_root(handle);
470 if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) 470 if (root && (root->osc_control_set & OSC_PCI_NATIVE_HOTPLUG))
471 return -ENODEV; 471 return -ENODEV;
472 472
473 /* if the bridge doesn't have _STA, we assume it is always there */ 473 /* if the bridge doesn't have _STA, we assume it is always there */
@@ -1395,7 +1395,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
1395 if (!root) 1395 if (!root)
1396 return AE_OK; 1396 return AE_OK;
1397 1397
1398 if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) 1398 if (root->osc_control_set & OSC_PCI_NATIVE_HOTPLUG)
1399 return AE_OK; 1399 return AE_OK;
1400 1400
1401 (*count)++; 1401 (*count)++;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 6001b4da39dd..627a3a42e4d8 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -302,6 +302,10 @@ extern bool osc_sb_apei_support_acked;
302 OSC_PCI_EXPRESS_PME_CONTROL | \ 302 OSC_PCI_EXPRESS_PME_CONTROL | \
303 OSC_PCI_EXPRESS_AER_CONTROL | \ 303 OSC_PCI_EXPRESS_AER_CONTROL | \
304 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) 304 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
305
306#define OSC_PCI_NATIVE_HOTPLUG (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
307 OSC_SHPC_NATIVE_HP_CONTROL)
308
305extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, 309extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
306 u32 *mask, u32 req); 310 u32 *mask, u32 req);
307extern void acpi_early_init(void); 311extern void acpi_early_init(void);