aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-10-07 17:16:55 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-10-07 17:16:55 -0400
commitd727b60659a1173eb4142a5fc521ce67c28b34e1 (patch)
tree793d0fc86ecf98331024db5c86bc271cc72aa2d2
parent3ee72ca99288f1de95ec9c570e43f531c8799f06 (diff)
parent2a5306cc5f383b0e7414c75e458111afd4a563a4 (diff)
Merge branch 'pm-runtime' into pm-for-linus
* pm-runtime: PM / Tracing: build rpm-traces.c only if CONFIG_PM_RUNTIME is set PM / Runtime: Replace dev_dbg() with trace_rpm_*() PM / Runtime: Introduce trace points for tracing rpm_* functions PM / Runtime: Don't run callbacks under lock for power.irq_safe set USB: Add wakeup info to debugging messages PM / Runtime: pm_runtime_idle() can be called in atomic context PM / Runtime: Add macro to test for runtime PM events PM / Runtime: Add might_sleep() to runtime PM functions
-rw-r--r--Documentation/power/runtime_pm.txt2
-rw-r--r--Documentation/usb/power-management.txt8
-rw-r--r--drivers/base/power/runtime.c94
-rw-r--r--drivers/bluetooth/btusb.c2
-rw-r--r--drivers/hid/hid-picolcd.c2
-rw-r--r--drivers/hid/usbhid/hid-core.c7
-rw-r--r--drivers/net/usb/usbnet.c2
-rw-r--r--drivers/net/wimax/i2400m/usb.c4
-rw-r--r--drivers/usb/class/cdc-acm.c2
-rw-r--r--drivers/usb/class/cdc-wdm.c6
-rw-r--r--drivers/usb/core/driver.c9
-rw-r--r--drivers/usb/core/hcd.c9
-rw-r--r--drivers/usb/core/hub.c15
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/serial/usb_wwan.c2
-rw-r--r--include/linux/pm.h2
-rw-r--r--include/trace/events/rpm.h99
-rw-r--r--kernel/trace/Makefile3
-rw-r--r--kernel/trace/rpm-traces.c20
-rw-r--r--sound/usb/card.c2
20 files changed, 226 insertions, 66 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 6066e3a6b9a..1f054046bc7 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -477,12 +477,14 @@ pm_runtime_autosuspend_expiration()
477If pm_runtime_irq_safe() has been called for a device then the following helper 477If pm_runtime_irq_safe() has been called for a device then the following helper
478functions may also be used in interrupt context: 478functions may also be used in interrupt context:
479 479
480pm_runtime_idle()
480pm_runtime_suspend() 481pm_runtime_suspend()
481pm_runtime_autosuspend() 482pm_runtime_autosuspend()
482pm_runtime_resume() 483pm_runtime_resume()
483pm_runtime_get_sync() 484pm_runtime_get_sync()
484pm_runtime_put_sync() 485pm_runtime_put_sync()
485pm_runtime_put_sync_suspend() 486pm_runtime_put_sync_suspend()
487pm_runtime_put_sync_autosuspend()
486 488
4875. Runtime PM Initialization, Device Probing and Removal 4895. Runtime PM Initialization, Device Probing and Removal
488 490
diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt
index c9ffa9ced7e..e8662a5fbc5 100644
--- a/Documentation/usb/power-management.txt
+++ b/Documentation/usb/power-management.txt
@@ -439,10 +439,10 @@ cause autosuspends to fail with -EBUSY if the driver needs to use the
439device. 439device.
440 440
441External suspend calls should never be allowed to fail in this way, 441External suspend calls should never be allowed to fail in this way,
442only autosuspend calls. The driver can tell them apart by checking 442only autosuspend calls. The driver can tell them apart by applying
443the PM_EVENT_AUTO bit in the message.event argument to the suspend 443the PMSG_IS_AUTO() macro to the message argument to the suspend
444method; this bit will be set for internal PM events (autosuspend) and 444method; it will return True for internal PM events (autosuspend) and
445clear for external PM events. 445False for external PM events.
446 446
447 447
448 Mutual exclusion 448 Mutual exclusion
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index acb3f83b807..7a6fb5e34a0 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/sched.h> 10#include <linux/sched.h>
11#include <linux/pm_runtime.h> 11#include <linux/pm_runtime.h>
12#include <trace/events/rpm.h>
12#include "power.h" 13#include "power.h"
13 14
14static int rpm_resume(struct device *dev, int rpmflags); 15static int rpm_resume(struct device *dev, int rpmflags);
@@ -155,6 +156,31 @@ static int rpm_check_suspend_allowed(struct device *dev)
155} 156}
156 157
157/** 158/**
159 * __rpm_callback - Run a given runtime PM callback for a given device.
160 * @cb: Runtime PM callback to run.
161 * @dev: Device to run the callback for.
162 */
163static int __rpm_callback(int (*cb)(struct device *), struct device *dev)
164 __releases(&dev->power.lock) __acquires(&dev->power.lock)
165{
166 int retval;
167
168 if (dev->power.irq_safe)
169 spin_unlock(&dev->power.lock);
170 else
171 spin_unlock_irq(&dev->power.lock);
172
173 retval = cb(dev);
174
175 if (dev->power.irq_safe)
176 spin_lock(&dev->power.lock);
177 else
178 spin_lock_irq(&dev->power.lock);
179
180 return retval;
181}
182
183/**
158 * rpm_idle - Notify device bus type if the device can be suspended. 184 * rpm_idle - Notify device bus type if the device can be suspended.
159 * @dev: Device to notify the bus type about. 185 * @dev: Device to notify the bus type about.
160 * @rpmflags: Flag bits. 186 * @rpmflags: Flag bits.
@@ -171,6 +197,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
171 int (*callback)(struct device *); 197 int (*callback)(struct device *);
172 int retval; 198 int retval;
173 199
200 trace_rpm_idle(dev, rpmflags);
174 retval = rpm_check_suspend_allowed(dev); 201 retval = rpm_check_suspend_allowed(dev);
175 if (retval < 0) 202 if (retval < 0)
176 ; /* Conditions are wrong. */ 203 ; /* Conditions are wrong. */
@@ -225,24 +252,14 @@ static int rpm_idle(struct device *dev, int rpmflags)
225 else 252 else
226 callback = NULL; 253 callback = NULL;
227 254
228 if (callback) { 255 if (callback)
229 if (dev->power.irq_safe) 256 __rpm_callback(callback, dev);
230 spin_unlock(&dev->power.lock);
231 else
232 spin_unlock_irq(&dev->power.lock);
233
234 callback(dev);
235
236 if (dev->power.irq_safe)
237 spin_lock(&dev->power.lock);
238 else
239 spin_lock_irq(&dev->power.lock);
240 }
241 257
242 dev->power.idle_notification = false; 258 dev->power.idle_notification = false;
243 wake_up_all(&dev->power.wait_queue); 259 wake_up_all(&dev->power.wait_queue);
244 260
245 out: 261 out:
262 trace_rpm_return_int(dev, _THIS_IP_, retval);
246 return retval; 263 return retval;
247} 264}
248 265
@@ -252,22 +269,14 @@ static int rpm_idle(struct device *dev, int rpmflags)
252 * @dev: Device to run the callback for. 269 * @dev: Device to run the callback for.
253 */ 270 */
254static int rpm_callback(int (*cb)(struct device *), struct device *dev) 271static int rpm_callback(int (*cb)(struct device *), struct device *dev)
255 __releases(&dev->power.lock) __acquires(&dev->power.lock)
256{ 272{
257 int retval; 273 int retval;
258 274
259 if (!cb) 275 if (!cb)
260 return -ENOSYS; 276 return -ENOSYS;
261 277
262 if (dev->power.irq_safe) { 278 retval = __rpm_callback(cb, dev);
263 retval = cb(dev);
264 } else {
265 spin_unlock_irq(&dev->power.lock);
266
267 retval = cb(dev);
268 279
269 spin_lock_irq(&dev->power.lock);
270 }
271 dev->power.runtime_error = retval; 280 dev->power.runtime_error = retval;
272 return retval != -EACCES ? retval : -EIO; 281 return retval != -EACCES ? retval : -EIO;
273} 282}
@@ -295,7 +304,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
295 struct device *parent = NULL; 304 struct device *parent = NULL;
296 int retval; 305 int retval;
297 306
298 dev_dbg(dev, "%s flags 0x%x\n", __func__, rpmflags); 307 trace_rpm_suspend(dev, rpmflags);
299 308
300 repeat: 309 repeat:
301 retval = rpm_check_suspend_allowed(dev); 310 retval = rpm_check_suspend_allowed(dev);
@@ -347,6 +356,15 @@ static int rpm_suspend(struct device *dev, int rpmflags)
347 goto out; 356 goto out;
348 } 357 }
349 358
359 if (dev->power.irq_safe) {
360 spin_unlock(&dev->power.lock);
361
362 cpu_relax();
363
364 spin_lock(&dev->power.lock);
365 goto repeat;
366 }
367
350 /* Wait for the other suspend running in parallel with us. */ 368 /* Wait for the other suspend running in parallel with us. */
351 for (;;) { 369 for (;;) {
352 prepare_to_wait(&dev->power.wait_queue, &wait, 370 prepare_to_wait(&dev->power.wait_queue, &wait,
@@ -430,7 +448,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
430 } 448 }
431 449
432 out: 450 out:
433 dev_dbg(dev, "%s returns %d\n", __func__, retval); 451 trace_rpm_return_int(dev, _THIS_IP_, retval);
434 452
435 return retval; 453 return retval;
436} 454}
@@ -459,7 +477,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
459 struct device *parent = NULL; 477 struct device *parent = NULL;
460 int retval = 0; 478 int retval = 0;
461 479
462 dev_dbg(dev, "%s flags 0x%x\n", __func__, rpmflags); 480 trace_rpm_resume(dev, rpmflags);
463 481
464 repeat: 482 repeat:
465 if (dev->power.runtime_error) 483 if (dev->power.runtime_error)
@@ -496,6 +514,15 @@ static int rpm_resume(struct device *dev, int rpmflags)
496 goto out; 514 goto out;
497 } 515 }
498 516
517 if (dev->power.irq_safe) {
518 spin_unlock(&dev->power.lock);
519
520 cpu_relax();
521
522 spin_lock(&dev->power.lock);
523 goto repeat;
524 }
525
499 /* Wait for the operation carried out in parallel with us. */ 526 /* Wait for the operation carried out in parallel with us. */
500 for (;;) { 527 for (;;) {
501 prepare_to_wait(&dev->power.wait_queue, &wait, 528 prepare_to_wait(&dev->power.wait_queue, &wait,
@@ -615,7 +642,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
615 spin_lock_irq(&dev->power.lock); 642 spin_lock_irq(&dev->power.lock);
616 } 643 }
617 644
618 dev_dbg(dev, "%s returns %d\n", __func__, retval); 645 trace_rpm_return_int(dev, _THIS_IP_, retval);
619 646
620 return retval; 647 return retval;
621} 648}
@@ -732,13 +759,16 @@ EXPORT_SYMBOL_GPL(pm_schedule_suspend);
732 * return immediately if it is larger than zero. Then carry out an idle 759 * return immediately if it is larger than zero. Then carry out an idle
733 * notification, either synchronous or asynchronous. 760 * notification, either synchronous or asynchronous.
734 * 761 *
735 * This routine may be called in atomic context if the RPM_ASYNC flag is set. 762 * This routine may be called in atomic context if the RPM_ASYNC flag is set,
763 * or if pm_runtime_irq_safe() has been called.
736 */ 764 */
737int __pm_runtime_idle(struct device *dev, int rpmflags) 765int __pm_runtime_idle(struct device *dev, int rpmflags)
738{ 766{
739 unsigned long flags; 767 unsigned long flags;
740 int retval; 768 int retval;
741 769
770 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
771
742 if (rpmflags & RPM_GET_PUT) { 772 if (rpmflags & RPM_GET_PUT) {
743 if (!atomic_dec_and_test(&dev->power.usage_count)) 773 if (!atomic_dec_and_test(&dev->power.usage_count))
744 return 0; 774 return 0;
@@ -761,13 +791,16 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle);
761 * return immediately if it is larger than zero. Then carry out a suspend, 791 * return immediately if it is larger than zero. Then carry out a suspend,
762 * either synchronous or asynchronous. 792 * either synchronous or asynchronous.
763 * 793 *
764 * This routine may be called in atomic context if the RPM_ASYNC flag is set. 794 * This routine may be called in atomic context if the RPM_ASYNC flag is set,
795 * or if pm_runtime_irq_safe() has been called.
765 */ 796 */
766int __pm_runtime_suspend(struct device *dev, int rpmflags) 797int __pm_runtime_suspend(struct device *dev, int rpmflags)
767{ 798{
768 unsigned long flags; 799 unsigned long flags;
769 int retval; 800 int retval;
770 801
802 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
803
771 if (rpmflags & RPM_GET_PUT) { 804 if (rpmflags & RPM_GET_PUT) {
772 if (!atomic_dec_and_test(&dev->power.usage_count)) 805 if (!atomic_dec_and_test(&dev->power.usage_count))
773 return 0; 806 return 0;
@@ -789,13 +822,16 @@ EXPORT_SYMBOL_GPL(__pm_runtime_suspend);
789 * If the RPM_GET_PUT flag is set, increment the device's usage count. Then 822 * If the RPM_GET_PUT flag is set, increment the device's usage count. Then
790 * carry out a resume, either synchronous or asynchronous. 823 * carry out a resume, either synchronous or asynchronous.
791 * 824 *
792 * This routine may be called in atomic context if the RPM_ASYNC flag is set. 825 * This routine may be called in atomic context if the RPM_ASYNC flag is set,
826 * or if pm_runtime_irq_safe() has been called.
793 */ 827 */
794int __pm_runtime_resume(struct device *dev, int rpmflags) 828int __pm_runtime_resume(struct device *dev, int rpmflags)
795{ 829{
796 unsigned long flags; 830 unsigned long flags;
797 int retval; 831 int retval;
798 832
833 might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
834
799 if (rpmflags & RPM_GET_PUT) 835 if (rpmflags & RPM_GET_PUT)
800 atomic_inc(&dev->power.usage_count); 836 atomic_inc(&dev->power.usage_count);
801 837
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 9cbac6b445e..6767b4a3d48 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1116,7 +1116,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
1116 return 0; 1116 return 0;
1117 1117
1118 spin_lock_irq(&data->txlock); 1118 spin_lock_irq(&data->txlock);
1119 if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) { 1119 if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
1120 set_bit(BTUSB_SUSPENDING, &data->flags); 1120 set_bit(BTUSB_SUSPENDING, &data->flags);
1121 spin_unlock_irq(&data->txlock); 1121 spin_unlock_irq(&data->txlock);
1122 } else { 1122 } else {
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index 9d8710f8bc7..1782693819f 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -2409,7 +2409,7 @@ static int picolcd_raw_event(struct hid_device *hdev,
2409#ifdef CONFIG_PM 2409#ifdef CONFIG_PM
2410static int picolcd_suspend(struct hid_device *hdev, pm_message_t message) 2410static int picolcd_suspend(struct hid_device *hdev, pm_message_t message)
2411{ 2411{
2412 if (message.event & PM_EVENT_AUTO) 2412 if (PMSG_IS_AUTO(message))
2413 return 0; 2413 return 0;
2414 2414
2415 picolcd_suspend_backlight(hid_get_drvdata(hdev)); 2415 picolcd_suspend_backlight(hid_get_drvdata(hdev));
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ad978f5748d..a9fa294ee7d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1332,7 +1332,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1332 struct usbhid_device *usbhid = hid->driver_data; 1332 struct usbhid_device *usbhid = hid->driver_data;
1333 int status; 1333 int status;
1334 1334
1335 if (message.event & PM_EVENT_AUTO) { 1335 if (PMSG_IS_AUTO(message)) {
1336 spin_lock_irq(&usbhid->lock); /* Sync with error handler */ 1336 spin_lock_irq(&usbhid->lock); /* Sync with error handler */
1337 if (!test_bit(HID_RESET_PENDING, &usbhid->iofl) 1337 if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
1338 && !test_bit(HID_CLEAR_HALT, &usbhid->iofl) 1338 && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
@@ -1367,7 +1367,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1367 return -EIO; 1367 return -EIO;
1368 } 1368 }
1369 1369
1370 if (!ignoreled && (message.event & PM_EVENT_AUTO)) { 1370 if (!ignoreled && PMSG_IS_AUTO(message)) {
1371 spin_lock_irq(&usbhid->lock); 1371 spin_lock_irq(&usbhid->lock);
1372 if (test_bit(HID_LED_ON, &usbhid->iofl)) { 1372 if (test_bit(HID_LED_ON, &usbhid->iofl)) {
1373 spin_unlock_irq(&usbhid->lock); 1373 spin_unlock_irq(&usbhid->lock);
@@ -1380,8 +1380,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1380 hid_cancel_delayed_stuff(usbhid); 1380 hid_cancel_delayed_stuff(usbhid);
1381 hid_cease_io(usbhid); 1381 hid_cease_io(usbhid);
1382 1382
1383 if ((message.event & PM_EVENT_AUTO) && 1383 if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
1384 test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
1385 /* lost race against keypresses */ 1384 /* lost race against keypresses */
1386 status = hid_start_in(hid); 1385 status = hid_start_in(hid);
1387 if (status < 0) 1386 if (status < 0)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index ce395fe5de2..f1c435ba528 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1470,7 +1470,7 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
1470 if (!dev->suspend_count++) { 1470 if (!dev->suspend_count++) {
1471 spin_lock_irq(&dev->txq.lock); 1471 spin_lock_irq(&dev->txq.lock);
1472 /* don't autosuspend while transmitting */ 1472 /* don't autosuspend while transmitting */
1473 if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) { 1473 if (dev->txq.qlen && PMSG_IS_AUTO(message)) {
1474 spin_unlock_irq(&dev->txq.lock); 1474 spin_unlock_irq(&dev->txq.lock);
1475 return -EBUSY; 1475 return -EBUSY;
1476 } else { 1476 } else {
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 298f2b0b631..9a644d052f1 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -599,7 +599,7 @@ void i2400mu_disconnect(struct usb_interface *iface)
599 * 599 *
600 * As well, the device might refuse going to sleep for whichever 600 * As well, the device might refuse going to sleep for whichever
601 * reason. In this case we just fail. For system suspend/hibernate, 601 * reason. In this case we just fail. For system suspend/hibernate,
602 * we *can't* fail. We check PM_EVENT_AUTO to see if the 602 * we *can't* fail. We check PMSG_IS_AUTO to see if the
603 * suspend call comes from the USB stack or from the system and act 603 * suspend call comes from the USB stack or from the system and act
604 * in consequence. 604 * in consequence.
605 * 605 *
@@ -615,7 +615,7 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
615 struct i2400m *i2400m = &i2400mu->i2400m; 615 struct i2400m *i2400m = &i2400mu->i2400m;
616 616
617#ifdef CONFIG_PM 617#ifdef CONFIG_PM
618 if (pm_msg.event & PM_EVENT_AUTO) 618 if (PMSG_IS_AUTO(pm_msg))
619 is_autosuspend = 1; 619 is_autosuspend = 1;
620#endif 620#endif
621 621
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index dac7676ce21..94e6c5c09dd 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1305,7 +1305,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
1305 struct acm *acm = usb_get_intfdata(intf); 1305 struct acm *acm = usb_get_intfdata(intf);
1306 int cnt; 1306 int cnt;
1307 1307
1308 if (message.event & PM_EVENT_AUTO) { 1308 if (PMSG_IS_AUTO(message)) {
1309 int b; 1309 int b;
1310 1310
1311 spin_lock_irq(&acm->write_lock); 1311 spin_lock_irq(&acm->write_lock);
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 2b9ff518b50..42f180aca3f 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -798,11 +798,11 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
798 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); 798 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
799 799
800 /* if this is an autosuspend the caller does the locking */ 800 /* if this is an autosuspend the caller does the locking */
801 if (!(message.event & PM_EVENT_AUTO)) 801 if (!PMSG_IS_AUTO(message))
802 mutex_lock(&desc->lock); 802 mutex_lock(&desc->lock);
803 spin_lock_irq(&desc->iuspin); 803 spin_lock_irq(&desc->iuspin);
804 804
805 if ((message.event & PM_EVENT_AUTO) && 805 if (PMSG_IS_AUTO(message) &&
806 (test_bit(WDM_IN_USE, &desc->flags) 806 (test_bit(WDM_IN_USE, &desc->flags)
807 || test_bit(WDM_RESPONDING, &desc->flags))) { 807 || test_bit(WDM_RESPONDING, &desc->flags))) {
808 spin_unlock_irq(&desc->iuspin); 808 spin_unlock_irq(&desc->iuspin);
@@ -815,7 +815,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
815 kill_urbs(desc); 815 kill_urbs(desc);
816 cancel_work_sync(&desc->rxwork); 816 cancel_work_sync(&desc->rxwork);
817 } 817 }
818 if (!(message.event & PM_EVENT_AUTO)) 818 if (!PMSG_IS_AUTO(message))
819 mutex_unlock(&desc->lock); 819 mutex_unlock(&desc->lock);
820 820
821 return rv; 821 return rv;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 34e3da5aa72..e03042883c6 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1046,8 +1046,7 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg)
1046 /* Non-root devices on a full/low-speed bus must wait for their 1046 /* Non-root devices on a full/low-speed bus must wait for their
1047 * companion high-speed root hub, in case a handoff is needed. 1047 * companion high-speed root hub, in case a handoff is needed.
1048 */ 1048 */
1049 if (!(msg.event & PM_EVENT_AUTO) && udev->parent && 1049 if (!PMSG_IS_AUTO(msg) && udev->parent && udev->bus->hs_companion)
1050 udev->bus->hs_companion)
1051 device_pm_wait_for_dev(&udev->dev, 1050 device_pm_wait_for_dev(&udev->dev,
1052 &udev->bus->hs_companion->root_hub->dev); 1051 &udev->bus->hs_companion->root_hub->dev);
1053 1052
@@ -1075,7 +1074,7 @@ static int usb_suspend_interface(struct usb_device *udev,
1075 1074
1076 if (driver->suspend) { 1075 if (driver->suspend) {
1077 status = driver->suspend(intf, msg); 1076 status = driver->suspend(intf, msg);
1078 if (status && !(msg.event & PM_EVENT_AUTO)) 1077 if (status && !PMSG_IS_AUTO(msg))
1079 dev_err(&intf->dev, "%s error %d\n", 1078 dev_err(&intf->dev, "%s error %d\n",
1080 "suspend", status); 1079 "suspend", status);
1081 } else { 1080 } else {
@@ -1189,7 +1188,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1189 status = usb_suspend_interface(udev, intf, msg); 1188 status = usb_suspend_interface(udev, intf, msg);
1190 1189
1191 /* Ignore errors during system sleep transitions */ 1190 /* Ignore errors during system sleep transitions */
1192 if (!(msg.event & PM_EVENT_AUTO)) 1191 if (!PMSG_IS_AUTO(msg))
1193 status = 0; 1192 status = 0;
1194 if (status != 0) 1193 if (status != 0)
1195 break; 1194 break;
@@ -1199,7 +1198,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1199 status = usb_suspend_device(udev, msg); 1198 status = usb_suspend_device(udev, msg);
1200 1199
1201 /* Again, ignore errors during system sleep transitions */ 1200 /* Again, ignore errors during system sleep transitions */
1202 if (!(msg.event & PM_EVENT_AUTO)) 1201 if (!PMSG_IS_AUTO(msg))
1203 status = 0; 1202 status = 0;
1204 } 1203 }
1205 1204
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 73cbbd85219..3b9d906339e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1961,8 +1961,9 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
1961 int status; 1961 int status;
1962 int old_state = hcd->state; 1962 int old_state = hcd->state;
1963 1963
1964 dev_dbg(&rhdev->dev, "bus %s%s\n", 1964 dev_dbg(&rhdev->dev, "bus %ssuspend, wakeup %d\n",
1965 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); 1965 (PMSG_IS_AUTO(msg) ? "auto-" : ""),
1966 rhdev->do_remote_wakeup);
1966 if (HCD_DEAD(hcd)) { 1967 if (HCD_DEAD(hcd)) {
1967 dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend"); 1968 dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend");
1968 return 0; 1969 return 0;
@@ -1997,8 +1998,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
1997 int status; 1998 int status;
1998 int old_state = hcd->state; 1999 int old_state = hcd->state;
1999 2000
2000 dev_dbg(&rhdev->dev, "usb %s%s\n", 2001 dev_dbg(&rhdev->dev, "usb %sresume\n",
2001 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); 2002 (PMSG_IS_AUTO(msg) ? "auto-" : ""));
2002 if (HCD_DEAD(hcd)) { 2003 if (HCD_DEAD(hcd)) {
2003 dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume"); 2004 dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume");
2004 return 0; 2005 return 0;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a428aa080a3..13bc83240ad 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2324,8 +2324,6 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2324 int port1 = udev->portnum; 2324 int port1 = udev->portnum;
2325 int status; 2325 int status;
2326 2326
2327 // dev_dbg(hub->intfdev, "suspend port %d\n", port1);
2328
2329 /* enable remote wakeup when appropriate; this lets the device 2327 /* enable remote wakeup when appropriate; this lets the device
2330 * wake up the upstream hub (including maybe the root hub). 2328 * wake up the upstream hub (including maybe the root hub).
2331 * 2329 *
@@ -2342,7 +2340,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2342 dev_dbg(&udev->dev, "won't remote wakeup, status %d\n", 2340 dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
2343 status); 2341 status);
2344 /* bail if autosuspend is requested */ 2342 /* bail if autosuspend is requested */
2345 if (msg.event & PM_EVENT_AUTO) 2343 if (PMSG_IS_AUTO(msg))
2346 return status; 2344 return status;
2347 } 2345 }
2348 } 2346 }
@@ -2367,12 +2365,13 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2367 USB_CTRL_SET_TIMEOUT); 2365 USB_CTRL_SET_TIMEOUT);
2368 2366
2369 /* System sleep transitions should never fail */ 2367 /* System sleep transitions should never fail */
2370 if (!(msg.event & PM_EVENT_AUTO)) 2368 if (!PMSG_IS_AUTO(msg))
2371 status = 0; 2369 status = 0;
2372 } else { 2370 } else {
2373 /* device has up to 10 msec to fully suspend */ 2371 /* device has up to 10 msec to fully suspend */
2374 dev_dbg(&udev->dev, "usb %ssuspend\n", 2372 dev_dbg(&udev->dev, "usb %ssuspend, wakeup %d\n",
2375 (msg.event & PM_EVENT_AUTO ? "auto-" : "")); 2373 (PMSG_IS_AUTO(msg) ? "auto-" : ""),
2374 udev->do_remote_wakeup);
2376 usb_set_device_state(udev, USB_STATE_SUSPENDED); 2375 usb_set_device_state(udev, USB_STATE_SUSPENDED);
2377 msleep(10); 2376 msleep(10);
2378 } 2377 }
@@ -2523,7 +2522,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
2523 } else { 2522 } else {
2524 /* drive resume for at least 20 msec */ 2523 /* drive resume for at least 20 msec */
2525 dev_dbg(&udev->dev, "usb %sresume\n", 2524 dev_dbg(&udev->dev, "usb %sresume\n",
2526 (msg.event & PM_EVENT_AUTO ? "auto-" : "")); 2525 (PMSG_IS_AUTO(msg) ? "auto-" : ""));
2527 msleep(25); 2526 msleep(25);
2528 2527
2529 /* Virtual root hubs can trigger on GET_PORT_STATUS to 2528 /* Virtual root hubs can trigger on GET_PORT_STATUS to
@@ -2625,7 +2624,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
2625 udev = hdev->children [port1-1]; 2624 udev = hdev->children [port1-1];
2626 if (udev && udev->can_submit) { 2625 if (udev && udev->can_submit) {
2627 dev_warn(&intf->dev, "port %d nyet suspended\n", port1); 2626 dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
2628 if (msg.event & PM_EVENT_AUTO) 2627 if (PMSG_IS_AUTO(msg))
2629 return -EBUSY; 2628 return -EBUSY;
2630 } 2629 }
2631 } 2630 }
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index d5d136a53b6..b18179bda0d 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -1009,7 +1009,7 @@ static int sierra_suspend(struct usb_serial *serial, pm_message_t message)
1009 struct sierra_intf_private *intfdata; 1009 struct sierra_intf_private *intfdata;
1010 int b; 1010 int b;
1011 1011
1012 if (message.event & PM_EVENT_AUTO) { 1012 if (PMSG_IS_AUTO(message)) {
1013 intfdata = serial->private; 1013 intfdata = serial->private;
1014 spin_lock_irq(&intfdata->susp_lock); 1014 spin_lock_irq(&intfdata->susp_lock);
1015 b = intfdata->in_flight; 1015 b = intfdata->in_flight;
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index e4fad5e643d..d555ca9567b 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -651,7 +651,7 @@ int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
651 651
652 dbg("%s entered", __func__); 652 dbg("%s entered", __func__);
653 653
654 if (message.event & PM_EVENT_AUTO) { 654 if (PMSG_IS_AUTO(message)) {
655 spin_lock_irq(&intfdata->susp_lock); 655 spin_lock_irq(&intfdata->susp_lock);
656 b = intfdata->in_flight; 656 b = intfdata->in_flight;
657 spin_unlock_irq(&intfdata->susp_lock); 657 spin_unlock_irq(&intfdata->susp_lock);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index f7c84c9abd3..18de9f89349 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -366,6 +366,8 @@ extern struct dev_pm_ops generic_subsys_pm_ops;
366#define PMSG_AUTO_RESUME ((struct pm_message) \ 366#define PMSG_AUTO_RESUME ((struct pm_message) \
367 { .event = PM_EVENT_AUTO_RESUME, }) 367 { .event = PM_EVENT_AUTO_RESUME, })
368 368
369#define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0)
370
369/** 371/**
370 * Device run-time power management status. 372 * Device run-time power management status.
371 * 373 *
diff --git a/include/trace/events/rpm.h b/include/trace/events/rpm.h
new file mode 100644
index 00000000000..d62c558bf64
--- /dev/null
+++ b/include/trace/events/rpm.h
@@ -0,0 +1,99 @@
1
2#undef TRACE_SYSTEM
3#define TRACE_SYSTEM rpm
4
5#if !defined(_TRACE_RUNTIME_POWER_H) || defined(TRACE_HEADER_MULTI_READ)
6#define _TRACE_RUNTIME_POWER_H
7
8#include <linux/ktime.h>
9#include <linux/tracepoint.h>
10#include <linux/device.h>
11
12/*
13 * The rpm_internal events are used for tracing some important
14 * runtime pm internal functions.
15 */
16DECLARE_EVENT_CLASS(rpm_internal,
17
18 TP_PROTO(struct device *dev, int flags),
19
20 TP_ARGS(dev, flags),
21
22 TP_STRUCT__entry(
23 __string( name, dev_name(dev) )
24 __field( int, flags )
25 __field( int , usage_count )
26 __field( int , disable_depth )
27 __field( int , runtime_auto )
28 __field( int , request_pending )
29 __field( int , irq_safe )
30 __field( int , child_count )
31 ),
32
33 TP_fast_assign(
34 __assign_str(name, dev_name(dev));
35 __entry->flags = flags;
36 __entry->usage_count = atomic_read(
37 &dev->power.usage_count);
38 __entry->disable_depth = dev->power.disable_depth;
39 __entry->runtime_auto = dev->power.runtime_auto;
40 __entry->request_pending = dev->power.request_pending;
41 __entry->irq_safe = dev->power.irq_safe;
42 __entry->child_count = atomic_read(
43 &dev->power.child_count);
44 ),
45
46 TP_printk("%s flags-%x cnt-%-2d dep-%-2d auto-%-1d p-%-1d"
47 " irq-%-1d child-%d",
48 __get_str(name), __entry->flags,
49 __entry->usage_count,
50 __entry->disable_depth,
51 __entry->runtime_auto,
52 __entry->request_pending,
53 __entry->irq_safe,
54 __entry->child_count
55 )
56);
57DEFINE_EVENT(rpm_internal, rpm_suspend,
58
59 TP_PROTO(struct device *dev, int flags),
60
61 TP_ARGS(dev, flags)
62);
63DEFINE_EVENT(rpm_internal, rpm_resume,
64
65 TP_PROTO(struct device *dev, int flags),
66
67 TP_ARGS(dev, flags)
68);
69DEFINE_EVENT(rpm_internal, rpm_idle,
70
71 TP_PROTO(struct device *dev, int flags),
72
73 TP_ARGS(dev, flags)
74);
75
76TRACE_EVENT(rpm_return_int,
77 TP_PROTO(struct device *dev, unsigned long ip, int ret),
78 TP_ARGS(dev, ip, ret),
79
80 TP_STRUCT__entry(
81 __string( name, dev_name(dev))
82 __field( unsigned long, ip )
83 __field( int, ret )
84 ),
85
86 TP_fast_assign(
87 __assign_str(name, dev_name(dev));
88 __entry->ip = ip;
89 __entry->ret = ret;
90 ),
91
92 TP_printk("%pS:%s ret=%d", (void *)__entry->ip, __get_str(name),
93 __entry->ret)
94);
95
96#endif /* _TRACE_RUNTIME_POWER_H */
97
98/* This part must be outside protection */
99#include <trace/define_trace.h>
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 761c510a06c..f49405f842f 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -53,6 +53,9 @@ endif
53obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o 53obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
54obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o 54obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
55obj-$(CONFIG_TRACEPOINTS) += power-traces.o 55obj-$(CONFIG_TRACEPOINTS) += power-traces.o
56ifeq ($(CONFIG_PM_RUNTIME),y)
57obj-$(CONFIG_TRACEPOINTS) += rpm-traces.o
58endif
56ifeq ($(CONFIG_TRACING),y) 59ifeq ($(CONFIG_TRACING),y)
57obj-$(CONFIG_KGDB_KDB) += trace_kdb.o 60obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
58endif 61endif
diff --git a/kernel/trace/rpm-traces.c b/kernel/trace/rpm-traces.c
new file mode 100644
index 00000000000..4b3b5eaf94d
--- /dev/null
+++ b/kernel/trace/rpm-traces.c
@@ -0,0 +1,20 @@
1/*
2 * Power trace points
3 *
4 * Copyright (C) 2009 Ming Lei <ming.lei@canonical.com>
5 */
6
7#include <linux/string.h>
8#include <linux/types.h>
9#include <linux/workqueue.h>
10#include <linux/sched.h>
11#include <linux/module.h>
12#include <linux/usb.h>
13
14#define CREATE_TRACE_POINTS
15#include <trace/events/rpm.h>
16
17EXPORT_TRACEPOINT_SYMBOL_GPL(rpm_return_int);
18EXPORT_TRACEPOINT_SYMBOL_GPL(rpm_idle);
19EXPORT_TRACEPOINT_SYMBOL_GPL(rpm_suspend);
20EXPORT_TRACEPOINT_SYMBOL_GPL(rpm_resume);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index d8f2bf40145..3068f043099 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -631,7 +631,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
631 if (chip == (void *)-1L) 631 if (chip == (void *)-1L)
632 return 0; 632 return 0;
633 633
634 if (!(message.event & PM_EVENT_AUTO)) { 634 if (!PMSG_IS_AUTO(message)) {
635 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 635 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
636 if (!chip->num_suspended_intf++) { 636 if (!chip->num_suspended_intf++) {
637 list_for_each(p, &chip->pcm_list) { 637 list_for_each(p, &chip->pcm_list) {