1/2: fix power manager recall problem.
PATCH 1/1 1/2: fix power manager recall problem.
Hello Patrick Mochel, Pavel Machek:
I'm tested the 2.5.3X suspend function and found the problem.
I'm enable debug option here is the log.
----------------------
skip...
Freeing memory: |
Syncing disks before copy
call device_resume SUSPEND_NOTIFY
Suspending devices
suspending device PCI device 8086:7111
suspending device PCI device 1022:2000
call device_resume SUSPEND_SAVE_STATE
Suspending devices
suspending device PCI device 8086:7111
suspending device PCI device 1022:2000
call device_resume SUSPEND_DISABLE
Suspending devices
suspending device PCI device 8086:7111
suspending device PCI device 1022:2000
call pm_send_all PM_SUSPEND
call pci_pm_suspend
call pcnet32_suspend
/critical section: Counting pages to copy[nosave c02af000] (pages needed: 4795+512=5307 free: 27972)
Alloc pagedir
[nosave c02af000]<4>Freeing prev allocated pagedir
call device_resume RESUME_RESTORE_STATE
resuming device PCI device 1022:2000
call pcnet32_resume
resuming device PCI device 8086:7111
resuming device i8259A PIC
skip......
------------------------
first the we call device suspend it suspend pci device and other device, but when we call pm_send_all to pm_suspend, it retry to suspend pci device, here is the real problem.
This patch can fix it. Please apply.
------------------------------
drivers/base/power.c +16 -0
@@ -37,6 +37,14 @@down (&device_sem);list_for_each (node,&global_device_list) {struct device * dev =to_dev (node); +if (dev->bus) { +char *name = dev->bus->name; +pr_debug ("bus is %s\n" , name); +if (strncmp (name,"pci" ,3 ) ==0 ) { +pr_debug ("skip pci bus\n" ); +continue ; + } + }if (device_present (dev) && dev->driver && dev->driver->suspend) {pr_debug ("suspending device %s\n" ,dev->name); error = dev->driver->suspend (dev,state,level);
@@ -63,6 +71,14 @@down (&device_sem);list_for_each_prev (node,&global_device_list) {struct device * dev =to_dev (node); +if (dev->bus) { +char *name = dev->bus->name; +pr_debug ("bus is %s\n" , name); +if (strncmp (name,"pci" ,3 ) ==0 ) { +pr_debug ("skip pci bus\n" ); +continue ; + } + }if (device_present (dev) && dev->driver && dev->driver->resume) {pr_debug ("resuming device %s\n" ,dev->name); dev->driver->resume (dev,level);
Signature · 1 line
- Hu Gang
Quoted 4 lines
first the we call device suspend it suspend pci device and other device, but when we call
pm_send_alltopm_suspend, it retry to suspend pci device, here is the real problem.This patch can fix it. Please apply.
...
drivers/base/power.c line 46
Quoted 6 lines
drivers/base/power.c +6
-0+char *name = dev->bus->name; +pr_debug ("bus is %s\n" , name); +if (strncmp (name,"pci" ,3 ) ==0 ) { +pr_debug ("skip pci bus\n" ); +continue ; + }
This is a hack. the pm_* interface should not be used, as it cannot guarantee proper ordering when shutting down or resuming devices. If you experience problems, please remove the pm_send callbacks and make the drivers adhere to the new power management interface.
Thanks,
-pat