Commit b51306c6 authored by Ajaykumar Hotchandani's avatar Ajaykumar Hotchandani Committed by Jesse Barnes

PCI: Set device power state to PCI_D0 for device without native PM support

During test of one IB card with guest VM, found that, msi is not
initialized properly.

It turns out __write_msi_msg will do nothing if device current_state is
not PCI_D0.  And, that pci device does not have pm_cap in guest VM.

There is an error in setting of power state to PCI_D0 in
pci_enable_device(), but error is not returned for this.  Following is
code flow:

pci_enable_device() -->   __pci_enable_device_flags() -->
do_pci_enable_device() -->   pci_set_power_state() -->
__pci_start_power_transition()

We have following condition inside __pci_start_power_transition():
         if (platform_pci_power_manageable(dev)) {
                 error = platform_pci_set_power_state(dev, state);
                 if (!error)
                         pci_update_current_state(dev, state);
         } else {
                 error = -ENODEV;
                 /* Fall back to PCI_D0 if native PM is not supported */
                 if (!dev->pm_cap)
                         dev->current_state = PCI_D0;
         }

Here, from platform_pci_set_power_state(), acpi_pci_set_power_state() is
getting called and that is failing with ENODEV because of following
condition:

         if (!handle || ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0",&tmp)))
                 return -ENODEV;

Because of that, pci_update_current_state() is not getting called.

With this patch, if device power state can not be set via
platform_pci_set_power_state and that device does not have native pm
support, then PCI device power state will be set to PCI_D0.

-v2: This also reverts 47e9037a, as it's
     not needed after this change.
Acked-by: default avatar"Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Ajaykumar Hotchandani<ajaykumar.hotchandani@oracle.com>
Signed-off-by: Yinghai Lu<yinghai.lu@oracle.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 619a5182
...@@ -225,7 +225,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) ...@@ -225,7 +225,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); pdev = pci_get_slot(pbus, PCI_DEVFN(device, function));
if (pdev) { if (pdev) {
pdev->current_state = PCI_D0;
slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
pci_dev_put(pdev); pci_dev_put(pdev);
} }
......
...@@ -664,6 +664,9 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) ...@@ -664,6 +664,9 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
error = platform_pci_set_power_state(dev, state); error = platform_pci_set_power_state(dev, state);
if (!error) if (!error)
pci_update_current_state(dev, state); pci_update_current_state(dev, state);
/* Fall back to PCI_D0 if native PM is not supported */
if (!dev->pm_cap)
dev->current_state = PCI_D0;
} else { } else {
error = -ENODEV; error = -ENODEV;
/* Fall back to PCI_D0 if native PM is not supported */ /* Fall back to PCI_D0 if native PM is not supported */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment