aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-02-17 17:36:58 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-02-22 19:20:24 -0500
commit58ff463396ad00828e922d50998787e97fd32512 (patch)
tree4964b07518a02736a23839d89bb7ac4a065dede8
parent6d3be84aab461815978d970aa45f5bc9e52dd772 (diff)
PCI PM: Add function for checking PME status of devices
Add function pci_check_pme_status() that will check the PME status bit of given device and clear it along with the PME enable bit. It will be necessary for PCI run-time power management. Based on a patch from Shaohua Li <shaohua.li@intel.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/pci.c35
-rw-r--r--drivers/pci/pci.h1
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 1f9be53c39ba..5723446544fd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1195,6 +1195,41 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
1195} 1195}
1196 1196
1197/** 1197/**
1198 * pci_check_pme_status - Check if given device has generated PME.
1199 * @dev: Device to check.
1200 *
1201 * Check the PME status of the device and if set, clear it and clear PME enable
1202 * (if set). Return 'true' if PME status and PME enable were both set or
1203 * 'false' otherwise.
1204 */
1205bool pci_check_pme_status(struct pci_dev *dev)
1206{
1207 int pmcsr_pos;
1208 u16 pmcsr;
1209 bool ret = false;
1210
1211 if (!dev->pm_cap)
1212 return false;
1213
1214 pmcsr_pos = dev->pm_cap + PCI_PM_CTRL;
1215 pci_read_config_word(dev, pmcsr_pos, &pmcsr);
1216 if (!(pmcsr & PCI_PM_CTRL_PME_STATUS))
1217 return false;
1218
1219 /* Clear PME status. */
1220 pmcsr |= PCI_PM_CTRL_PME_STATUS;
1221 if (pmcsr & PCI_PM_CTRL_PME_ENABLE) {
1222 /* Disable PME to avoid interrupt flood. */
1223 pmcsr &= ~PCI_PM_CTRL_PME_ENABLE;
1224 ret = true;
1225 }
1226
1227 pci_write_config_word(dev, pmcsr_pos, pmcsr);
1228
1229 return ret;
1230}
1231
1232/**
1198 * pci_pme_capable - check the capability of PCI device to generate PME# 1233 * pci_pme_capable - check the capability of PCI device to generate PME#
1199 * @dev: PCI device to handle. 1234 * @dev: PCI device to handle.
1200 * @state: PCI state from which device will issue PME#. 1235 * @state: PCI state from which device will issue PME#.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 5d169bc3ccd1..b95b0a077d31 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -49,6 +49,7 @@ struct pci_platform_pm_ops {
49extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); 49extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops);
50extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); 50extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
51extern void pci_disable_enabled_device(struct pci_dev *dev); 51extern void pci_disable_enabled_device(struct pci_dev *dev);
52extern bool pci_check_pme_status(struct pci_dev *dev);
52extern void pci_pm_init(struct pci_dev *dev); 53extern void pci_pm_init(struct pci_dev *dev);
53extern void platform_pci_wakeup_init(struct pci_dev *dev); 54extern void platform_pci_wakeup_init(struct pci_dev *dev);
54extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); 55extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);