diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2008-12-16 22:07:38 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-01-07 14:13:10 -0500 |
commit | c9ffa5a586a97da4d552f89b8f39eea79a63a612 (patch) | |
tree | 47e4a6de7df1c5d41bff61f8bfc81eb464b8d2c6 /drivers/pci/hotplug/pciehp.h | |
parent | 873392ca514f87eae39f53b6944caf85b1a047cb (diff) |
PCI: pciehp: add ACPI based slot detection
There is a problem that some non hot-pluggable PCIe slots are detected
as hot-pluggable by pciehp on some platforms. The immediate cause of
this problem is that hot-plug capable bit in the Slot Capabilities
register is set even for non hot-pluggable slots on those platforms.
It seems a BIOS/hardware problem, but we need workaround about that.
Some of those platforms define hot-pluggable PCIe slots on ACPI
namespace properly, while hot-plug capable bit in the Slot
Capabilities register is set improperly. So using ACPI namespace
information in pciehp to detect PCIe hot-pluggable slots would be a
workaround.
This patch adds 'pciehp_detect_mode' module option. When 'acpi' is
specified, pciehp uses ACPI namespace information to detect PCIe
hot-pluggable slots.
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.h')
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index b2801a7ee37f..27fd18f019f8 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -220,11 +220,23 @@ struct hpc_ops { | |||
220 | #include <acpi/actypes.h> | 220 | #include <acpi/actypes.h> |
221 | #include <linux/pci-acpi.h> | 221 | #include <linux/pci-acpi.h> |
222 | 222 | ||
223 | extern void __init pciehp_acpi_slot_detection_init(void); | ||
224 | extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); | ||
225 | |||
226 | static inline void pciehp_firmware_init(void) | ||
227 | { | ||
228 | pciehp_acpi_slot_detection_init(); | ||
229 | } | ||
230 | |||
223 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) | 231 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) |
224 | { | 232 | { |
233 | int retval; | ||
225 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | 234 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | |
226 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | 235 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); |
227 | return acpi_get_hp_hw_control_from_firmware(dev, flags); | 236 | retval = acpi_get_hp_hw_control_from_firmware(dev, flags); |
237 | if (retval) | ||
238 | return retval; | ||
239 | return pciehp_acpi_slot_detection_check(dev); | ||
228 | } | 240 | } |
229 | 241 | ||
230 | static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, | 242 | static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, |
@@ -235,6 +247,7 @@ static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, | |||
235 | return 0; | 247 | return 0; |
236 | } | 248 | } |
237 | #else | 249 | #else |
250 | #define pciehp_firmware_init() do {} while (0) | ||
238 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 | 251 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 |
239 | #define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) | 252 | #define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) |
240 | #endif /* CONFIG_ACPI */ | 253 | #endif /* CONFIG_ACPI */ |