aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/usb.h
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-08-30 15:47:02 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 14:58:57 -0400
commit645daaab0b6adc35c1838df2a82f9d729fdb1767 (patch)
tree908d58f6c0ad01e9c1622a4c12c9c8080c629baa /include/linux/usb.h
parentb6956ffa595db97656d5901ca8fec77ef272d41a (diff)
usbcore: add autosuspend/autoresume infrastructure
This patch (as739) adds the basic infrastructure for USB autosuspend and autoresume. The main features are: PM usage counters added to struct usb_device and struct usb_interface, indicating whether it's okay to autosuspend them or they are currently in use. Flag added to usb_device indicating whether the current suspend/resume operation originated from outside or as an autosuspend/autoresume. Flag added to usb_driver indicating whether the driver supports autosuspend. If not, no device bound to the driver will be autosuspended. Mutex added to usb_device for protecting PM operations. Unlike the device semaphore, the locking rule for the pm_mutex is that you must acquire the locks going _up_ the device tree. New routines handling autosuspend/autoresume requests for interfaces and devices. Suspend and resume requests are propagated up the device tree (but not outside the USB subsystem). work_struct added to usb_device, for carrying out delayed autosuspend requests. Autoresume added (and autosuspend prevented) during probe and disconnect. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'include/linux/usb.h')
-rw-r--r--include/linux/usb.h33
1 files changed, 33 insertions, 0 deletions
diff --git a/include/linux/usb.h b/include/linux/usb.h
index df5c93eb3ce9..0da15b0b02be 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -19,6 +19,7 @@
19#include <linux/fs.h> /* for struct file_operations */ 19#include <linux/fs.h> /* for struct file_operations */
20#include <linux/completion.h> /* for struct completion */ 20#include <linux/completion.h> /* for struct completion */
21#include <linux/sched.h> /* for current && schedule_timeout */ 21#include <linux/sched.h> /* for current && schedule_timeout */
22#include <linux/mutex.h> /* for struct mutex */
22 23
23struct usb_device; 24struct usb_device;
24struct usb_driver; 25struct usb_driver;
@@ -103,8 +104,12 @@ enum usb_interface_condition {
103 * @condition: binding state of the interface: not bound, binding 104 * @condition: binding state of the interface: not bound, binding
104 * (in probe()), bound to a driver, or unbinding (in disconnect()) 105 * (in probe()), bound to a driver, or unbinding (in disconnect())
105 * @is_active: flag set when the interface is bound and not suspended. 106 * @is_active: flag set when the interface is bound and not suspended.
107 * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
108 * capability during autosuspend.
106 * @dev: driver model's view of this device 109 * @dev: driver model's view of this device
107 * @class_dev: driver model's class view of this device. 110 * @class_dev: driver model's class view of this device.
111 * @pm_usage_cnt: PM usage counter for this interface; autosuspend is not
112 * allowed unless the counter is 0.
108 * 113 *
109 * USB device drivers attach to interfaces on a physical device. Each 114 * USB device drivers attach to interfaces on a physical device. Each
110 * interface encapsulates a single high level function, such as feeding 115 * interface encapsulates a single high level function, such as feeding
@@ -144,9 +149,11 @@ struct usb_interface {
144 * bound to */ 149 * bound to */
145 enum usb_interface_condition condition; /* state of binding */ 150 enum usb_interface_condition condition; /* state of binding */
146 unsigned is_active:1; /* the interface is not suspended */ 151 unsigned is_active:1; /* the interface is not suspended */
152 unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
147 153
148 struct device dev; /* interface specific device info */ 154 struct device dev; /* interface specific device info */
149 struct class_device *class_dev; 155 struct class_device *class_dev;
156 int pm_usage_cnt; /* usage counter for autosuspend */
150}; 157};
151#define to_usb_interface(d) container_of(d, struct usb_interface, dev) 158#define to_usb_interface(d) container_of(d, struct usb_interface, dev)
152#define interface_to_usbdev(intf) \ 159#define interface_to_usbdev(intf) \
@@ -372,6 +379,15 @@ struct usb_device {
372 379
373 int maxchild; /* Number of ports if hub */ 380 int maxchild; /* Number of ports if hub */
374 struct usb_device *children[USB_MAXCHILDREN]; 381 struct usb_device *children[USB_MAXCHILDREN];
382
383#ifdef CONFIG_PM
384 struct work_struct autosuspend; /* for delayed autosuspends */
385 struct mutex pm_mutex; /* protects PM operations */
386 int pm_usage_cnt; /* usage counter for autosuspend */
387
388 unsigned auto_pm:1; /* autosuspend/resume in progress */
389 unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */
390#endif
375}; 391};
376#define to_usb_device(d) container_of(d, struct usb_device, dev) 392#define to_usb_device(d) container_of(d, struct usb_device, dev)
377 393
@@ -392,6 +408,17 @@ extern int usb_reset_composite_device(struct usb_device *dev,
392 408
393extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); 409extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
394 410
411/* USB autosuspend and autoresume */
412#ifdef CONFIG_USB_SUSPEND
413extern int usb_autopm_get_interface(struct usb_interface *intf);
414extern void usb_autopm_put_interface(struct usb_interface *intf);
415
416#else
417#define usb_autopm_get_interface(intf) 0
418#define usb_autopm_put_interface(intf) do {} while (0)
419#endif
420
421
395/*-------------------------------------------------------------------------*/ 422/*-------------------------------------------------------------------------*/
396 423
397/* for drivers using iso endpoints */ 424/* for drivers using iso endpoints */
@@ -593,6 +620,8 @@ struct usbdrv_wrap {
593 * @drvwrap: Driver-model core structure wrapper. 620 * @drvwrap: Driver-model core structure wrapper.
594 * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be 621 * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
595 * added to this driver by preventing the sysfs file from being created. 622 * added to this driver by preventing the sysfs file from being created.
623 * @supports_autosuspend: if set to 0, the USB core will not allow autosuspend
624 * for interfaces bound to this driver.
596 * 625 *
597 * USB interface drivers must provide a name, probe() and disconnect() 626 * USB interface drivers must provide a name, probe() and disconnect()
598 * methods, and an id_table. Other driver fields are optional. 627 * methods, and an id_table. Other driver fields are optional.
@@ -631,6 +660,7 @@ struct usb_driver {
631 struct usb_dynids dynids; 660 struct usb_dynids dynids;
632 struct usbdrv_wrap drvwrap; 661 struct usbdrv_wrap drvwrap;
633 unsigned int no_dynamic_id:1; 662 unsigned int no_dynamic_id:1;
663 unsigned int supports_autosuspend:1;
634}; 664};
635#define to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver) 665#define to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver)
636 666
@@ -648,6 +678,8 @@ struct usb_driver {
648 * @suspend: Called when the device is going to be suspended by the system. 678 * @suspend: Called when the device is going to be suspended by the system.
649 * @resume: Called when the device is being resumed by the system. 679 * @resume: Called when the device is being resumed by the system.
650 * @drvwrap: Driver-model core structure wrapper. 680 * @drvwrap: Driver-model core structure wrapper.
681 * @supports_autosuspend: if set to 0, the USB core will not allow autosuspend
682 * for devices bound to this driver.
651 * 683 *
652 * USB drivers must provide all the fields listed above except drvwrap. 684 * USB drivers must provide all the fields listed above except drvwrap.
653 */ 685 */
@@ -660,6 +692,7 @@ struct usb_device_driver {
660 int (*suspend) (struct usb_device *udev, pm_message_t message); 692 int (*suspend) (struct usb_device *udev, pm_message_t message);
661 int (*resume) (struct usb_device *udev); 693 int (*resume) (struct usb_device *udev);
662 struct usbdrv_wrap drvwrap; 694 struct usbdrv_wrap drvwrap;
695 unsigned int supports_autosuspend:1;
663}; 696};
664#define to_usb_device_driver(d) container_of(d, struct usb_device_driver, \ 697#define to_usb_device_driver(d) container_of(d, struct usb_device_driver, \
665 drvwrap.driver) 698 drvwrap.driver)