diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2008-12-27 10:30:52 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-01-07 14:13:08 -0500 |
commit | f06fc0b6f8a6846e0ad48aee7b0f282b4fb5dcdc (patch) | |
tree | a723b05eedd9457ad50a0fb4220c73beac11f46a /drivers/pci/pci.c | |
parent | eb9c39d031bbcfd4005bd7e0337c3fd3909c1bf7 (diff) |
PCI PM: Fix pci_update_current_state
Currently, PCI devices without the PM capability that are power
manageable by the platform (eg. ACPI) are not handled correctly
by pci_set_power_state(), because their current_state field is not
updated to reflect the new power state of the device. Fix this by
making pci_update_current_state() accept additional argument
representing the power state of the device as set by the platform.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b807330e500..9d2aa6366fd0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -525,14 +525,17 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
525 | * pci_update_current_state - Read PCI power state of given device from its | 525 | * pci_update_current_state - Read PCI power state of given device from its |
526 | * PCI PM registers and cache it | 526 | * PCI PM registers and cache it |
527 | * @dev: PCI device to handle. | 527 | * @dev: PCI device to handle. |
528 | * @state: State to cache in case the device doesn't have the PM capability | ||
528 | */ | 529 | */ |
529 | static void pci_update_current_state(struct pci_dev *dev) | 530 | static void pci_update_current_state(struct pci_dev *dev, pci_power_t state) |
530 | { | 531 | { |
531 | if (dev->pm_cap) { | 532 | if (dev->pm_cap) { |
532 | u16 pmcsr; | 533 | u16 pmcsr; |
533 | 534 | ||
534 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | 535 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); |
535 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); | 536 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); |
537 | } else { | ||
538 | dev->current_state = state; | ||
536 | } | 539 | } |
537 | } | 540 | } |
538 | 541 | ||
@@ -575,7 +578,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
575 | */ | 578 | */ |
576 | int ret = platform_pci_set_power_state(dev, PCI_D0); | 579 | int ret = platform_pci_set_power_state(dev, PCI_D0); |
577 | if (!ret) | 580 | if (!ret) |
578 | pci_update_current_state(dev); | 581 | pci_update_current_state(dev, PCI_D0); |
579 | } | 582 | } |
580 | /* This device is quirked not to be put into D3, so | 583 | /* This device is quirked not to be put into D3, so |
581 | don't put it in D3 */ | 584 | don't put it in D3 */ |
@@ -588,7 +591,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
588 | /* Allow the platform to finalize the transition */ | 591 | /* Allow the platform to finalize the transition */ |
589 | int ret = platform_pci_set_power_state(dev, state); | 592 | int ret = platform_pci_set_power_state(dev, state); |
590 | if (!ret) { | 593 | if (!ret) { |
591 | pci_update_current_state(dev); | 594 | pci_update_current_state(dev, state); |
592 | error = 0; | 595 | error = 0; |
593 | } | 596 | } |
594 | } | 597 | } |