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