summaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpi_pcihp.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2006-05-02 03:54:50 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-19 23:13:22 +0200
commit7430e34c70106a9576fc61d77604d164b187a1b7 (patch)
tree4b9eeaaa3702c9be216f820e8eeaf11f93610d2c /drivers/pci/hotplug/acpi_pcihp.c
parent[PATCH] pciehp: dont call pci_enable_dev (diff)
downloadlinux-7430e34c70106a9576fc61d77604d164b187a1b7.tar.xz
linux-7430e34c70106a9576fc61d77604d164b187a1b7.zip
[PATCH] acpi_pcihp: Fix programming _HPP values
This patch fixes the problem that hotplug parameters are not programed when PCI cards are hot-added by ACPIPHP, SHPCHP and PCIEHP driver. The pci_dev structure being hot-added is not bound to ACPI handle, so we need to trace PCI bus tree to find ACPI handle. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Cc: Kristen Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/acpi_pcihp.c')
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 64cb30d7fc9a..9395fec73423 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -145,14 +145,27 @@ EXPORT_SYMBOL_GPL(acpi_run_oshp);
/* acpi_get_hp_params_from_firmware
*
- * @dev - the pci_dev of the newly added device
+ * @bus - the pci_bus of the bus on which the device is newly added
* @hpp - allocated by the caller
*/
-acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
+acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
struct hotplug_params *hpp)
{
acpi_status status = AE_NOT_FOUND;
- struct pci_dev *pdev = dev;
+ acpi_handle handle, phandle;
+ struct pci_bus *pbus = bus;
+ struct pci_dev *pdev;
+
+ do {
+ pdev = pbus->self;
+ if (!pdev) {
+ handle = acpi_get_pci_rootbridge_handle(
+ pci_domain_nr(pbus), pbus->number);
+ break;
+ }
+ handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
+ pbus = pbus->parent;
+ } while (!handle);
/*
* _HPP settings apply to all child buses, until another _HPP is
@@ -160,15 +173,16 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
* look for it in the parent device scope since that would apply to
* this pci dev. If we don't find any _HPP, use hardcoded defaults
*/
- while (pdev && (ACPI_FAILURE(status))) {
- acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
- if (!handle)
- break;
+ while (handle) {
status = acpi_run_hpp(handle, hpp);
- if (!(pdev->bus->parent))
+ if (ACPI_SUCCESS(status))
+ break;
+ if (acpi_root_bridge(handle))
+ break;
+ status = acpi_get_parent(handle, &phandle);
+ if (ACPI_FAILURE(status))
break;
- /* Check if a parent object supports _HPP */
- pdev = pdev->bus->parent->self;
+ handle = phandle;
}
return status;
}