[linux-pm] [linux-usb-devel] [PATCH]switching off autosuspend through sysfs

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

 



On Wednesday 24 January 2007 6:15 pm, David Brownell wrote:

> > So, what kind of devices do support these files?  I can think of:
> > 	PCI
> 
> Actually, PCI still doesn't because of strangeness in the init
> sequencing on at least PPC ... I can forward the patch that makes
> X86 init the wakeup flag from the PM attributes.

And here it is.  Last refreshed against 2.6.20-rc5; it still works
like a charm on x86.  (As it did since before that PPC patch...)
I have no idea whether this still makes trouble on PPC.

- Dave


=================	CUT HERE
This patch teaches "pci_dev" about the driver model wakeup support:

 - It marks devices as supporting wakeup when the PME# capability is
   listed in its PCI PM capability.

 - pci_enable_wake() refuses to enable wake if that's been disabled
   (e.g. through sysfs).

NOTE that PowerPC does PCI probing a bit differently ... which evidently
causes this to fail on that platform (and maybe others).

One issue is that the driver model "init + add == register" pattern isn't
used inside PCI ...  and the PCI probe change that made PowerPC happier
worsened the problem by making "add" do some "init" too.  Maybe PCI should
match the driver model a lot more closely and grow a "pci_dev_init()".


Index: g26/drivers/pci/probe.c
===================================================================
--- g26.orig/drivers/pci/probe.c	2007-01-20 05:09:21.000000000 -0800
+++ g26/drivers/pci/probe.c	2007-01-20 05:18:42.000000000 -0800
@@ -654,6 +654,7 @@ static void pci_read_irq(struct pci_dev 
 static int pci_setup_device(struct pci_dev * dev)
 {
 	u32 class;
+	u16 pm;
 
 	sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
@@ -682,6 +683,19 @@ static int pci_setup_device(struct pci_d
 		pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
 		pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
 
+		/* PCI PM capable devices may be able to issue PME# (wakeup) */
+		pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+		if (pm) {
+			pci_read_config_word(dev, pm + PCI_PM_PMC, &pm);
+			if (pm & PCI_PM_CAP_PME_MASK)
+				device_init_wakeup(&dev->dev, 1);
+
+			/* REVISIT: if (pm & PCI_PM_CAP_PME_D3cold) then
+			 * pci pm spec 1.2, section 3.2.4 says we should
+			 * init PCI_PM_CTRL_PME_{STATUS,ENABLE} ...
+			 */
+		}
+
 		/*
 		 *	Do the ugly legacy mode stuff here rather than broken chip
 		 *	quirk code. Legacy mode ATA controllers have fixed
@@ -848,6 +862,7 @@ pci_scan_device(struct pci_bus *bus, int
 
 	dev->bus = bus;
 	dev->sysdata = bus->sysdata;
+	device_initialize(&dev->dev);
 	dev->dev.parent = bus->bridge;
 	dev->dev.bus = &pci_bus_type;
 	dev->devfn = devfn;
@@ -871,7 +886,6 @@ pci_scan_device(struct pci_bus *bus, int
 
 void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
-	device_initialize(&dev->dev);
 	dev->dev.release = pci_release_dev;
 	pci_dev_get(dev);
 
Index: g26/drivers/pci/pci.c
===================================================================
--- g26.orig/drivers/pci/pci.c	2007-01-20 05:18:31.000000000 -0800
+++ g26/drivers/pci/pci.c	2007-01-20 05:18:42.000000000 -0800
@@ -817,6 +817,10 @@ int pci_enable_wake(struct pci_dev *dev,
 	if (!pm) 
 		return enable ? -EIO : 0; 
 
+	/* don't enable unless policy set through driver core allows it */
+	if (!device_may_wakeup(&dev->dev) && enable)
+		return -EROFS;
+
 	/* Check device's ability to generate PME# */
 	pci_read_config_word(dev,pm+PCI_PM_PMC,&value);
 




[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux