[Resend] [PATCH] PCI: Disable PME function of PCI device when scanning PCI device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Subject:PCI: Disable PME function of PCI device when scanning PCI device
>From : Zhao Yakui <yakui.zhao@xxxxxxxxx>

   Maybe #PME is enabled for some PCI devices.And if the PME event can
be generated from D0 state, PME event will be generated when the PCI
device is in D0 state. If the device driver is not loaded for this PCI
device(PME can't be disabled) and the correspond GPE is enabled, the
system will be resumed immediately from the suspend state. This's not
what we wanted.
   Thre is a similar case in ACPI system. If the ACPI device has the
_PRW object, the _PSW/_DSW object will be called in order to disable the
wakeup functionality. Only when it is allowed to wake up the sleeping
state, OSPM will enable it again.

  So it will be reasonable that PME is disabled in the course of
scanning PCI device and enabled again only when PME event is required to
be generated  from the requested PCI state.(For example: D3_hot,
D3_cold). Of course it is also safe to disable PME again when the PME is
disabled for the PCI devices.

Signed-off-by: Zhao Yakui <yakui.zhao@xxxxxxxxx>
Signed-off-by: Li Shaohua <shaohua.li@xxxxxxxxx>
---
 drivers/pci/probe.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

Index: linux-2.6/drivers/pci/probe.c
===================================================================
--- linux-2.6.orig/drivers/pci/probe.c
+++ linux-2.6/drivers/pci/probe.c
@@ -857,6 +857,49 @@ int pci_cfg_space_size_ext(struct pci_de
 	return PCI_CFG_SPACE_SIZE;
 }
 
+/**
+ * pci_disable_pme - Disable the PME function of PCI device
+ * @dev: PCI device affected
+ * -EINVAL is returned if PCI device doesn't support PME.
+ * Zero is returned if the PME is supported and can be disabled.
+ */
+static int pci_disable_pme(struct pci_dev *dev)
+{
+	int pm;
+	u16 value;
+
+	/* find PCI PM capability in list */
+	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+
+	/* If device doesn't support PM Capabilities, it means that PME is
+	 * not supported.
+	 */
+	if (!pm)
+		return -EINVAL;
+	/* Check device's ability to generate PME# */
+	pci_read_config_word(dev, pm + PCI_PM_PMC, &value);
+
+	value &= PCI_PM_CAP_PME_MASK;
+	/* Check if it can generate PME# */
+	if (!value) {
+		/*
+		 * If it is zero, it means that PME is still unsupported
+		 * although there exists the PM capability.
+		 */
+		return -EINVAL;
+	}
+
+	pci_read_config_word(dev, pm + PCI_PM_CTRL, &value);
+
+	/* Clear PME_Status by writing 1 to it */
+	value |= PCI_PM_CTRL_PME_STATUS ;
+	/* Disable PME enable bit */
+	value &= ~PCI_PM_CTRL_PME_ENABLE;
+	pci_write_config_word(dev, pm + PCI_PM_CTRL, value);
+
+	return 0;
+}
+
 int pci_cfg_space_size(struct pci_dev *dev)
 {
 	int pos;
@@ -964,6 +1007,7 @@ static struct pci_dev *pci_scan_device(s
 	}
 
 	pci_vpd_pci22_init(dev);
+	pci_disable_pme(dev);
 
 	return dev;
 }

> On Monday, May 12, 2008 2:22 am Zhao Yakui wrote:
> > Subject:PCI: Disable PME function of PCI device when scanning PCI device
> >
> > >From : Zhao Yakui <yakui.zhao@xxxxxxxxx>
> >
> > If the PME is supported by one PCI device, it will be disabled in the
> > course of scaning PCI device.
> >
> > Signed-off-by: Zhao Yakui <yakui.zhao@xxxxxxxxx>
> > Signed-off-by: Li Shaohua <shaohua.li@xxxxxxxxx>
> 
> I'm missing some context here... was there discussion about PME being a 
> problem with the current defaults?  Can you include some more detail in the 
> changelog?
> 
> Thanks,
> Jesse

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux