From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Rafael J. Wysocki" Subject: [PATCH 2/2] PCI PM: Fix pci_update_current_state Date: Sat, 27 Dec 2008 16:18:28 +0100 Message-ID: <200812271618.28713.rjw@sisk.pl> References: <200812271614.44197.rjw@sisk.pl> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6419446770150390706==" Return-path: In-Reply-To: <200812271614.44197.rjw@sisk.pl> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Mime-version: 1.0 Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org To: Jesse Barnes Cc: pm list , LKML List-Id: linux-pm@vger.kernel.org --===============6419446770150390706== Content-Type: multipart/alternative; boundary="Boundary-00=_EdkVJfbtwBFrTq0" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-00=_EdkVJfbtwBFrTq0 Content-Type: text/plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit From: Rafael J. Wysocki 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 --- drivers/pci/pci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) Index: linux-2.6/drivers/pci/pci.c =================================================================== --- linux-2.6.orig/drivers/pci/pci.c +++ linux-2.6/drivers/pci/pci.c @@ -524,14 +524,17 @@ pci_raw_set_power_state(struct pci_dev * * pci_update_current_state - Read PCI power state of given device from its * PCI PM registers and cache it * @dev: PCI device to handle. + * @state: State to cache in case the device doesn't have the PM capability */ -static void pci_update_current_state(struct pci_dev *dev) +static void pci_update_current_state(struct pci_dev *dev, pci_power_t state) { 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); + } else { + dev->current_state = state; } } @@ -574,7 +577,7 @@ int pci_set_power_state(struct pci_dev * */ int ret = platform_pci_set_power_state(dev, PCI_D0); if (!ret) - pci_update_current_state(dev); + pci_update_current_state(dev, PCI_D0); } /* This device is quirked not to be put into D3, so don't put it in D3 */ @@ -587,7 +590,7 @@ int pci_set_power_state(struct pci_dev * /* Allow the platform to finalize the transition */ int ret = platform_pci_set_power_state(dev, state); if (!ret) { - pci_update_current_state(dev); + pci_update_current_state(dev, state); error = 0; } } --Boundary-00=_EdkVJfbtwBFrTq0 Content-Type: text/html; charset="iso-8859-15" Content-Transfer-Encoding: 7bit

From: Rafael J. Wysocki <rjw@sisk.pl>

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>

---

drivers/pci/pci.c | 9 ++++++---

1 file changed, 6 insertions(+), 3 deletions(-)

Index: linux-2.6/drivers/pci/pci.c

===================================================================

--- linux-2.6.orig/drivers/pci/pci.c

+++ linux-2.6/drivers/pci/pci.c

@@ -524,14 +524,17 @@ pci_raw_set_power_state(struct pci_dev *

* pci_update_current_state - Read PCI power state of given device from its

* PCI PM registers and cache it

* @dev: PCI device to handle.

+ * @state: State to cache in case the device doesn't have the PM capability

*/

-static void pci_update_current_state(struct pci_dev *dev)

+static void pci_update_current_state(struct pci_dev *dev, pci_power_t state)

{

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);

+ } else {

+ dev->current_state = state;

}

}

@@ -574,7 +577,7 @@ int pci_set_power_state(struct pci_dev *

*/

int ret = platform_pci_set_power_state(dev, PCI_D0);

if (!ret)

- pci_update_current_state(dev);

+ pci_update_current_state(dev, PCI_D0);

}

/* This device is quirked not to be put into D3, so

don't put it in D3 */

@@ -587,7 +590,7 @@ int pci_set_power_state(struct pci_dev *

/* Allow the platform to finalize the transition */

int ret = platform_pci_set_power_state(dev, state);

if (!ret) {

- pci_update_current_state(dev);

+ pci_update_current_state(dev, state);

error = 0;

}

}

--Boundary-00=_EdkVJfbtwBFrTq0-- --===============6419446770150390706== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline --===============6419446770150390706==--