PCI: read current power state at enable time
When we enable a PCI device, we avoid doing a lot of the initial setup work if the device's enable count is non-zero. If we don't fetch the power state though, we may later fail to set up MSI due to the unknown status. So pick it up before we short circuit the rest due to a pre-existing enable or mismatched enable/disable pair (as happens with VGA devices, which are special in a special way). Tested-by: Jesse Brandeburg <jesse.brandeburg@gmail.com> Reported-by: Dave Airlie <airlied@linux.ie> Tested-by: Dave Airlie <airlied@linux.ie> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
3b519e4ea6
commit
97c145f7c8
1 changed files with 12 additions and 0 deletions
|
@ -1007,6 +1007,18 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
|
|||
int err;
|
||||
int i, bars = 0;
|
||||
|
||||
/*
|
||||
* Power state could be unknown at this point, either due to a fresh
|
||||
* boot or a device removal call. So get the current power state
|
||||
* so that things like MSI message writing will behave as expected
|
||||
* (e.g. if the device really is in D0 at enable time).
|
||||
*/
|
||||
if (dev->pm_cap) {
|
||||
u16 pmcsr;
|
||||
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
|
||||
dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
|
||||
}
|
||||
|
||||
if (atomic_add_return(1, &dev->enable_cnt) > 1)
|
||||
return 0; /* already enabled */
|
||||
|
||||
|
|
Loading…
Reference in a new issue