Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02669492 authored by Andrew Morton's avatar Andrew Morton Committed by Greg Kroah-Hartman
Browse files

[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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 37225401
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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);
+4 −2
Original line number Diff line number Diff line
@@ -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;
}

+4 −2
Original line number Diff line number Diff line
@@ -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 */
+3 −4
Original line number Diff line number Diff line
@@ -213,12 +213,10 @@ 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);

	/* FIXME until the generic PM interfaces change a lot more, this
@@ -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);

+8 −0
Original line number Diff line number Diff line
@@ -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.