/* 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
* 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;
}
{
acpi_status status;
- status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp);
+ status = acpi_get_hp_params_from_firmware(bridge->pci_bus, &bridge->hpp);
if (ACPI_FAILURE(status)) {
/* use default numbers */
bridge->hpp.cache_line_size = 0x10;
memset(&bridge, 0, sizeof(bridge));
bridge.handle = handle;
+ bridge.pci_bus = bus;
bridge.pci_dev = bus->self;
decode_hpp(&bridge);
list_for_each_entry(dev, &bus->devices, bus_list)
#include <acpi/acpi_bus.h>
#include <acpi/actypes.h>
extern acpi_status acpi_run_oshp(acpi_handle handle);
-extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
+extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
struct hotplug_params *hpp);
int acpi_root_bridge(acpi_handle handle);
#endif
static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
- if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
+ if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
return -ENODEV;
return 0;
}
static inline int get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp)
{
- if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
+ if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
return -ENODEV;
return 0;
}