diff options
Diffstat (limited to 'drivers/pci/hotplug/acpi_pcihp.c')
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 93e37f0666ab..e17ef54f0efc 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware); | |||
382 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) | 382 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) |
383 | { | 383 | { |
384 | acpi_status status; | 384 | acpi_status status; |
385 | acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); | 385 | acpi_handle chandle, handle; |
386 | struct pci_dev *pdev = dev; | 386 | struct pci_dev *pdev = dev; |
387 | struct pci_bus *parent; | 387 | struct pci_bus *parent; |
388 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; | 388 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -399,10 +399,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) | |||
399 | * Per PCI firmware specification, we should run the ACPI _OSC | 399 | * Per PCI firmware specification, we should run the ACPI _OSC |
400 | * method to get control of hotplug hardware before using it. If | 400 | * method to get control of hotplug hardware before using it. If |
401 | * an _OSC is missing, we look for an OSHP to do the same thing. | 401 | * an _OSC is missing, we look for an OSHP to do the same thing. |
402 | * To handle different BIOS behavior, we look for _OSC and OSHP | 402 | * To handle different BIOS behavior, we look for _OSC on a root |
403 | * within the scope of the hotplug controller and its parents, | 403 | * bridge preferentially (according to PCI fw spec). Later for |
404 | * OSHP within the scope of the hotplug controller and its parents, | ||
404 | * upto the host bridge under which this controller exists. | 405 | * upto the host bridge under which this controller exists. |
405 | */ | 406 | */ |
407 | handle = acpi_find_root_bridge_handle(pdev); | ||
408 | if (handle) { | ||
409 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); | ||
410 | dbg("Trying to get hotplug control for %s\n", | ||
411 | (char *)string.pointer); | ||
412 | status = pci_osc_control_set(handle, flags); | ||
413 | if (ACPI_SUCCESS(status)) | ||
414 | goto got_one; | ||
415 | kfree(string.pointer); | ||
416 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; | ||
417 | } | ||
418 | |||
419 | pdev = dev; | ||
420 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
406 | while (!handle) { | 421 | while (!handle) { |
407 | /* | 422 | /* |
408 | * This hotplug controller was not listed in the ACPI name | 423 | * This hotplug controller was not listed in the ACPI name |
@@ -427,15 +442,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) | |||
427 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); | 442 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); |
428 | dbg("Trying to get hotplug control for %s \n", | 443 | dbg("Trying to get hotplug control for %s \n", |
429 | (char *)string.pointer); | 444 | (char *)string.pointer); |
430 | status = pci_osc_control_set(handle, flags); | 445 | status = acpi_run_oshp(handle); |
431 | if (status == AE_NOT_FOUND) | 446 | if (ACPI_SUCCESS(status)) |
432 | status = acpi_run_oshp(handle); | 447 | goto got_one; |
433 | if (ACPI_SUCCESS(status)) { | ||
434 | dbg("Gained control for hotplug HW for pci %s (%s)\n", | ||
435 | pci_name(dev), (char *)string.pointer); | ||
436 | kfree(string.pointer); | ||
437 | return 0; | ||
438 | } | ||
439 | if (acpi_root_bridge(handle)) | 448 | if (acpi_root_bridge(handle)) |
440 | break; | 449 | break; |
441 | chandle = handle; | 450 | chandle = handle; |
@@ -449,6 +458,11 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) | |||
449 | 458 | ||
450 | kfree(string.pointer); | 459 | kfree(string.pointer); |
451 | return -ENODEV; | 460 | return -ENODEV; |
461 | got_one: | ||
462 | dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev), | ||
463 | (char *)string.pointer); | ||
464 | kfree(string.pointer); | ||
465 | return 0; | ||
452 | } | 466 | } |
453 | EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); | 467 | EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); |
454 | 468 | ||