aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2006-03-23 04:38:34 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-04-14 14:41:25 -0400
commit026694920579590c73b5c56705d543568ed5ad41 (patch)
tree1c3ad318fe65c5812dd33008af8e77389ee31c46
parent372254018eb1b65ee69210d11686bfc65c8d84db (diff)
[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>
-rw-r--r--drivers/base/power/suspend.c12
-rw-r--r--drivers/pci/pci-driver.c6
-rw-r--r--drivers/pci/pci.c6
-rw-r--r--drivers/usb/core/hcd-pci.c7
-rw-r--r--include/linux/pm.h8
5 files changed, 31 insertions, 8 deletions
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index bdb60663f2ef..662209d3f42d 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -10,6 +10,8 @@
10 10
11#include <linux/vt_kern.h> 11#include <linux/vt_kern.h>
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/kallsyms.h>
14#include <linux/pm.h>
13#include "../base.h" 15#include "../base.h"
14#include "power.h" 16#include "power.h"
15 17
@@ -58,6 +60,7 @@ int suspend_device(struct device * dev, pm_message_t state)
58 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { 60 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
59 dev_dbg(dev, "suspending\n"); 61 dev_dbg(dev, "suspending\n");
60 error = dev->bus->suspend(dev, state); 62 error = dev->bus->suspend(dev, state);
63 suspend_report_result(dev->bus->suspend, error);
61 } 64 }
62 up(&dev->sem); 65 up(&dev->sem);
63 return error; 66 return error;
@@ -169,3 +172,12 @@ int device_power_down(pm_message_t state)
169 172
170EXPORT_SYMBOL_GPL(device_power_down); 173EXPORT_SYMBOL_GPL(device_power_down);
171 174
175void __suspend_report_result(const char *function, void *fn, int ret)
176{
177 if (ret) {
178 printk(KERN_ERR "%s(): ", function);
179 print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
180 printk("%d\n", ret);
181 }
182}
183EXPORT_SYMBOL_GPL(__suspend_report_result);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f22f69ac6445..1456759936c5 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -271,10 +271,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
271 struct pci_driver * drv = pci_dev->driver; 271 struct pci_driver * drv = pci_dev->driver;
272 int i = 0; 272 int i = 0;
273 273
274 if (drv && drv->suspend) 274 if (drv && drv->suspend) {
275 i = drv->suspend(pci_dev, state); 275 i = drv->suspend(pci_dev, state);
276 else 276 suspend_report_result(drv->suspend, i);
277 } else {
277 pci_save_state(pci_dev); 278 pci_save_state(pci_dev);
279 }
278 return i; 280 return i;
279} 281}
280 282
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index bea1ad1ad5ba..042fa5265cf6 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -307,9 +307,11 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
307 * Can enter D0 from any state, but if we can only go deeper 307 * Can enter D0 from any state, but if we can only go deeper
308 * to sleep if we're already in a low power state 308 * to sleep if we're already in a low power state
309 */ 309 */
310 if (state != PCI_D0 && dev->current_state > state) 310 if (state != PCI_D0 && dev->current_state > state) {
311 printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n",
312 __FUNCTION__, pci_name(dev), state, dev->current_state);
311 return -EINVAL; 313 return -EINVAL;
312 else if (dev->current_state == state) 314 } else if (dev->current_state == state)
313 return 0; /* we're already there */ 315 return 0; /* we're already there */
314 316
315 /* find PCI PM capability in list */ 317 /* find PCI PM capability in list */
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 0d2193b69235..66b78404ab34 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -213,11 +213,9 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
213 213
214 if (hcd->driver->suspend) { 214 if (hcd->driver->suspend) {
215 retval = hcd->driver->suspend(hcd, message); 215 retval = hcd->driver->suspend(hcd, message);
216 if (retval) { 216 suspend_report_result(hcd->driver->suspend, retval);
217 dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", 217 if (retval)
218 retval);
219 goto done; 218 goto done;
220 }
221 } 219 }
222 synchronize_irq(dev->irq); 220 synchronize_irq(dev->irq);
223 221
@@ -263,6 +261,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
263 * some device state (e.g. as part of clock reinit). 261 * some device state (e.g. as part of clock reinit).
264 */ 262 */
265 retval = pci_set_power_state (dev, PCI_D3hot); 263 retval = pci_set_power_state (dev, PCI_D3hot);
264 suspend_report_result(pci_set_power_state, retval);
266 if (retval == 0) { 265 if (retval == 0) {
267 int wake = device_can_wakeup(&hcd->self.root_hub->dev); 266 int wake = device_can_wakeup(&hcd->self.root_hub->dev);
268 267
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 6df2585c0169..66be58902b17 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -199,6 +199,12 @@ extern int device_suspend(pm_message_t state);
199 199
200extern int dpm_runtime_suspend(struct device *, pm_message_t); 200extern int dpm_runtime_suspend(struct device *, pm_message_t);
201extern void dpm_runtime_resume(struct device *); 201extern void dpm_runtime_resume(struct device *);
202extern void __suspend_report_result(const char *function, void *fn, int ret);
203
204#define suspend_report_result(fn, ret) \
205 do { \
206 __suspend_report_result(__FUNCTION__, fn, ret); \
207 } while (0)
202 208
203#else /* !CONFIG_PM */ 209#else /* !CONFIG_PM */
204 210
@@ -219,6 +225,8 @@ static inline void dpm_runtime_resume(struct device * dev)
219{ 225{
220} 226}
221 227
228#define suspend_report_result(fn, ret) do { } while (0)
229
222#endif 230#endif
223 231
224/* changes to device_may_wakeup take effect on the next pm state change. 232/* changes to device_may_wakeup take effect on the next pm state change.