Skip to content

Commit

Permalink
[PATCH] pm: print name of failed suspend function
Browse files Browse the repository at this point in the history
Print more diagnostic info to help identify the source of power management
suspend failures.

Example:

usb_hcd_pci_suspend(): pci_set_power_state+0x0/0x1af() returns -22
pci_device_suspend(): usb_hcd_pci_suspend+0x0/0x11b() returns -22
suspend_device(): pci_device_suspend+0x0/0x34() returns -22

Work-in-progress.  It needs lots more suspend_report_result() calls sprinkled
everywhere.

Cc: Patrick Mochel <mochel@digitalimplant.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Nigel Cunningham <nigel@suspend2.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Andrew Morton authored and Greg Kroah-Hartman committed Apr 14, 2006
1 parent 3722540 commit 0266949
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 8 deletions.
12 changes: 12 additions & 0 deletions drivers/base/power/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <linux/vt_kern.h>
#include <linux/device.h>
#include <linux/kallsyms.h>
#include <linux/pm.h>
#include "../base.h"
#include "power.h"

Expand Down Expand Up @@ -58,6 +60,7 @@ int suspend_device(struct device * dev, pm_message_t state)
if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
dev_dbg(dev, "suspending\n");
error = dev->bus->suspend(dev, state);
suspend_report_result(dev->bus->suspend, error);
}
up(&dev->sem);
return error;
Expand Down Expand Up @@ -169,3 +172,12 @@ int device_power_down(pm_message_t state)

EXPORT_SYMBOL_GPL(device_power_down);

void __suspend_report_result(const char *function, void *fn, int ret)
{
if (ret) {
printk(KERN_ERR "%s(): ", function);
print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
printk("%d\n", ret);
}
}
EXPORT_SYMBOL_GPL(__suspend_report_result);
6 changes: 4 additions & 2 deletions drivers/pci/pci-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
struct pci_driver * drv = pci_dev->driver;
int i = 0;

if (drv && drv->suspend)
if (drv && drv->suspend) {
i = drv->suspend(pci_dev, state);
else
suspend_report_result(drv->suspend, i);
} else {
pci_save_state(pci_dev);
}
return i;
}

Expand Down
6 changes: 4 additions & 2 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,11 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
* Can enter D0 from any state, but if we can only go deeper
* to sleep if we're already in a low power state
*/
if (state != PCI_D0 && dev->current_state > state)
if (state != PCI_D0 && dev->current_state > state) {
printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n",
__FUNCTION__, pci_name(dev), state, dev->current_state);
return -EINVAL;
else if (dev->current_state == state)
} else if (dev->current_state == state)
return 0; /* we're already there */

/* find PCI PM capability in list */
Expand Down
7 changes: 3 additions & 4 deletions drivers/usb/core/hcd-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,9 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)

if (hcd->driver->suspend) {
retval = hcd->driver->suspend(hcd, message);
if (retval) {
dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n",
retval);
suspend_report_result(hcd->driver->suspend, retval);
if (retval)
goto done;
}
}
synchronize_irq(dev->irq);

Expand Down Expand Up @@ -263,6 +261,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
* some device state (e.g. as part of clock reinit).
*/
retval = pci_set_power_state (dev, PCI_D3hot);
suspend_report_result(pci_set_power_state, retval);
if (retval == 0) {
int wake = device_can_wakeup(&hcd->self.root_hub->dev);

Expand Down
8 changes: 8 additions & 0 deletions include/linux/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ extern int device_suspend(pm_message_t state);

extern int dpm_runtime_suspend(struct device *, pm_message_t);
extern void dpm_runtime_resume(struct device *);
extern void __suspend_report_result(const char *function, void *fn, int ret);

#define suspend_report_result(fn, ret) \
do { \
__suspend_report_result(__FUNCTION__, fn, ret); \
} while (0)

#else /* !CONFIG_PM */

Expand All @@ -219,6 +225,8 @@ static inline void dpm_runtime_resume(struct device * dev)
{
}

#define suspend_report_result(fn, ret) do { } while (0)

#endif

/* changes to device_may_wakeup take effect on the next pm state change.
Expand Down

0 comments on commit 0266949

Please sign in to comment.