1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
From 7eef82d231578140c6000d04846a48bdaf341a65 Mon Sep 17 00:00:00 2001
From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Date: Tue, 24 Mar 2009 17:23:19 -0700
Subject: [PATCH] USB: gadget: composite device-level suspend/resume hooks
Address one open question in the composite gadget framework:
Yes, we should have device-level suspend/resume callbacks
in addition to the function-level ones. We have at least one
scenario (with gadget zero in OTG test mode) that's awkward
to handle without it.
Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
---
drivers/usb/gadget/composite.c | 8 ++++++--
include/linux/usb/composite.h | 8 ++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 40f1da7..59e8523 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1014,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
- /* REVISIT: should we have config and device level
+ /* REVISIT: should we have config level
* suspend/resume callbacks?
*/
DBG(cdev, "suspend\n");
@@ -1024,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget)
f->suspend(f);
}
}
+ if (composite->suspend)
+ composite->suspend(cdev);
}
static void
@@ -1032,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
- /* REVISIT: should we have config and device level
+ /* REVISIT: should we have config level
* suspend/resume callbacks?
*/
DBG(cdev, "resume\n");
+ if (composite->resume)
+ composite->resume(cdev);
if (cdev->config) {
list_for_each_entry(f, &cdev->config->functions, list) {
if (f->resume)
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 935c380..acd7b0f 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -244,6 +244,10 @@ int usb_add_config(struct usb_composite_dev *,
* value; it should return zero on successful initialization.
* @unbind: Reverses @bind(); called as a side effect of unregistering
* this driver.
+ * @suspend: Notifies when the host stops sending USB traffic,
+ * after function notifications
+ * @resume: Notifies configuration when the host restarts USB traffic,
+ * before function notifications
*
* Devices default to reporting self powered operation. Devices which rely
* on bus powered operation should report this in their @bind() method.
@@ -268,6 +272,10 @@ struct usb_composite_driver {
int (*bind)(struct usb_composite_dev *);
int (*unbind)(struct usb_composite_dev *);
+
+ /* global suspend hooks */
+ void (*suspend)(struct usb_composite_dev *);
+ void (*resume)(struct usb_composite_dev *);
};
extern int usb_composite_register(struct usb_composite_driver *);
--
1.6.0.4
|