aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-sysfs.c
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2012-06-22 22:23:51 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-06-23 12:50:59 -0400
commit448bd857d48e69b33ef323739dc6d8ca20d4cda7 (patch)
tree4c1178f9c7dd2d78af2ac1ed26b214b04be1554a /drivers/pci/pci-sysfs.c
parent8497f696686ae1ab3f01e5956046d59844b9f500 (diff)
PCI/PM: add PCIe runtime D3cold support
This patch adds runtime D3cold support and corresponding ACPI platform support. This patch only enables runtime D3cold support; it does not enable D3cold support during system suspend/hibernate. D3cold is the deepest power saving state for a PCIe device, where its main power is removed. While it is in D3cold, you can't access the device at all, not even its configuration space (which is still accessible in D3hot). Therefore the PCI PM registers can not be used to transition into/out of the D3cold state; that must be done by platform logic such as ACPI _PR3. To support wakeup from D3cold, a system may provide auxiliary power, which allows a device to request wakeup using a Beacon or the sideband WAKE# signal. WAKE# is usually connected to platform logic such as ACPI GPE. This is quite different from other power saving states, where devices request wakeup via a PME message on the PCIe link. Some devices, such as those in plug-in slots, have no direct platform logic. For example, there is usually no ACPI _PR3 for them. D3cold support for these devices can be done via the PCIe Downstream Port leading to the device. When the PCIe port is powered on/off, the device is powered on/off too. Wakeup events from the device will be notified to the corresponding PCIe port. For more information about PCIe D3cold and corresponding ACPI support, please refer to: - PCI Express Base Specification Revision 2.0 - Advanced Configuration and Power Interface Specification Revision 5.0 [bhelgaas: changelog] Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl> Originally-by: Zheng Yan <zheng.z.yan@intel.com> Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r--drivers/pci/pci-sysfs.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 86c63fe45d11..1426db0c0607 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -28,6 +28,7 @@
28#include <linux/pci-aspm.h> 28#include <linux/pci-aspm.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/vgaarb.h> 30#include <linux/vgaarb.h>
31#include <linux/pm_runtime.h>
31#include "pci.h" 32#include "pci.h"
32 33
33static int sysfs_initialized; /* = 0 */ 34static int sysfs_initialized; /* = 0 */
@@ -378,6 +379,31 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
378 379
379#endif 380#endif
380 381
382#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
383static ssize_t d3cold_allowed_store(struct device *dev,
384 struct device_attribute *attr,
385 const char *buf, size_t count)
386{
387 struct pci_dev *pdev = to_pci_dev(dev);
388 unsigned long val;
389
390 if (strict_strtoul(buf, 0, &val) < 0)
391 return -EINVAL;
392
393 pdev->d3cold_allowed = !!val;
394 pm_runtime_resume(dev);
395
396 return count;
397}
398
399static ssize_t d3cold_allowed_show(struct device *dev,
400 struct device_attribute *attr, char *buf)
401{
402 struct pci_dev *pdev = to_pci_dev(dev);
403 return sprintf (buf, "%u\n", pdev->d3cold_allowed);
404}
405#endif
406
381struct device_attribute pci_dev_attrs[] = { 407struct device_attribute pci_dev_attrs[] = {
382 __ATTR_RO(resource), 408 __ATTR_RO(resource),
383 __ATTR_RO(vendor), 409 __ATTR_RO(vendor),
@@ -402,6 +428,9 @@ struct device_attribute pci_dev_attrs[] = {
402 __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store), 428 __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
403 __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store), 429 __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
404#endif 430#endif
431#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
432 __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store),
433#endif
405 __ATTR_NULL, 434 __ATTR_NULL,
406}; 435};
407 436