[PATCH] pm: print name of failed suspend function
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>
This commit is contained in:
parent
372254018e
commit
0266949205
5 changed files with 31 additions and 8 deletions
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue