Commit ab943a2e125b098489ccaa0166c2c52f8266d9ed

Authored by David Brownell
Committed by Greg Kroah-Hartman
1 parent 8942939a6c

USB: gadget: gadget zero uses new suspend/resume hooks

Use the new device-level suspend/resume hooks for Gadget Zero;
always enable them with the OTG test mode; and support remote
wakeup on both configurations even in non-OTG mode.

This ensures that both configurations can pass the USBCV remote
wakeup tests when the OTG test mode is enabled.  This changes
behavior by adding autoresume support to the loopback config
even in non-OTG mode; the test failure was that it didn't work
in OTG mode.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 4 changed files with 74 additions and 58 deletions Side-by-side Diff

drivers/usb/gadget/f_loopback.c
... ... @@ -359,7 +359,7 @@
359 359 * loopback_add - add a loopback testing configuration to a device
360 360 * @cdev: the device to support the loopback configuration
361 361 */
362   -int __init loopback_add(struct usb_composite_dev *cdev)
  362 +int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
363 363 {
364 364 int id;
365 365  
... ... @@ -371,6 +371,10 @@
371 371  
372 372 loopback_intf.iInterface = id;
373 373 loopback_driver.iConfiguration = id;
  374 +
  375 + /* support autoresume for remote wakeup testing */
  376 + if (autoresume)
  377 + sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
374 378  
375 379 /* support OTG systems */
376 380 if (gadget_is_otg(cdev->gadget)) {
drivers/usb/gadget/f_sourcesink.c
... ... @@ -59,7 +59,6 @@
59 59  
60 60 struct usb_ep *in_ep;
61 61 struct usb_ep *out_ep;
62   - struct timer_list resume;
63 62 };
64 63  
65 64 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
... ... @@ -67,10 +66,6 @@
67 66 return container_of(f, struct f_sourcesink, function);
68 67 }
69 68  
70   -static unsigned autoresume;
71   -module_param(autoresume, uint, 0);
72   -MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
73   -
74 69 static unsigned pattern;
75 70 module_param(pattern, uint, 0);
76 71 MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
... ... @@ -155,21 +150,6 @@
155 150  
156 151 /*-------------------------------------------------------------------------*/
157 152  
158   -static void sourcesink_autoresume(unsigned long _c)
159   -{
160   - struct usb_composite_dev *cdev = (void *)_c;
161   - struct usb_gadget *g = cdev->gadget;
162   -
163   - /* Normally the host would be woken up for something
164   - * more significant than just a timer firing; likely
165   - * because of some direct user request.
166   - */
167   - if (g->speed != USB_SPEED_UNKNOWN) {
168   - int status = usb_gadget_wakeup(g);
169   - DBG(cdev, "%s --> %d\n", __func__, status);
170   - }
171   -}
172   -
173 153 static int __init
174 154 sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
175 155 {
... ... @@ -198,9 +178,6 @@
198 178 goto autoconf_fail;
199 179 ss->out_ep->driver_data = cdev; /* claim */
200 180  
201   - setup_timer(&ss->resume, sourcesink_autoresume,
202   - (unsigned long) c->cdev);
203   -
204 181 /* support high speed hardware */
205 182 if (gadget_is_dualspeed(c->cdev->gadget)) {
206 183 hs_source_desc.bEndpointAddress =
... ... @@ -359,7 +336,6 @@
359 336  
360 337 cdev = ss->function.config->cdev;
361 338 disable_endpoints(cdev, ss->in_ep, ss->out_ep);
362   - del_timer(&ss->resume);
363 339 VDBG(cdev, "%s disabled\n", ss->function.name);
364 340 }
365 341  
... ... @@ -426,30 +402,6 @@
426 402 disable_source_sink(ss);
427 403 }
428 404  
429   -static void sourcesink_suspend(struct usb_function *f)
430   -{
431   - struct f_sourcesink *ss = func_to_ss(f);
432   - struct usb_composite_dev *cdev = f->config->cdev;
433   -
434   - if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
435   - return;
436   -
437   - if (autoresume) {
438   - mod_timer(&ss->resume, jiffies + (HZ * autoresume));
439   - DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
440   - } else
441   - DBG(cdev, "%s\n", __func__);
442   -}
443   -
444   -static void sourcesink_resume(struct usb_function *f)
445   -{
446   - struct f_sourcesink *ss = func_to_ss(f);
447   - struct usb_composite_dev *cdev = f->config->cdev;
448   -
449   - DBG(cdev, "%s\n", __func__);
450   - del_timer(&ss->resume);
451   -}
452   -
453 405 /*-------------------------------------------------------------------------*/
454 406  
455 407 static int __init sourcesink_bind_config(struct usb_configuration *c)
... ... @@ -467,8 +419,6 @@
467 419 ss->function.unbind = sourcesink_unbind;
468 420 ss->function.set_alt = sourcesink_set_alt;
469 421 ss->function.disable = sourcesink_disable;
470   - ss->function.suspend = sourcesink_suspend;
471   - ss->function.resume = sourcesink_resume;
472 422  
473 423 status = usb_add_function(c, &ss->function);
474 424 if (status)
... ... @@ -559,7 +509,7 @@
559 509 * sourcesink_add - add a source/sink testing configuration to a device
560 510 * @cdev: the device to support the configuration
561 511 */
562   -int __init sourcesink_add(struct usb_composite_dev *cdev)
  512 +int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
563 513 {
564 514 int id;
565 515  
drivers/usb/gadget/g_zero.h
... ... @@ -19,8 +19,8 @@
19 19 struct usb_ep *in, struct usb_ep *out);
20 20  
21 21 /* configuration-specific linkup */
22   -int sourcesink_add(struct usb_composite_dev *cdev);
23   -int loopback_add(struct usb_composite_dev *cdev);
  22 +int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
  23 +int loopback_add(struct usb_composite_dev *cdev, bool autoresume);
24 24  
25 25 #endif /* __G_ZERO_H */
drivers/usb/gadget/zero.c
... ... @@ -102,11 +102,21 @@
102 102 #ifndef CONFIG_USB_ZERO_HNPTEST
103 103 #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */
104 104 #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */
  105 +#define DEFAULT_AUTORESUME 0
105 106 #else
106 107 #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */
107 108 #define DRIVER_PRODUCT_NUM 0xbadd
  109 +#define DEFAULT_AUTORESUME 5
108 110 #endif
109 111  
  112 +/* If the optional "autoresume" mode is enabled, it provides good
  113 + * functional coverage for the "USBCV" test harness from USB-IF.
  114 + * It's always set if OTG mode is enabled.
  115 + */
  116 +unsigned autoresume = DEFAULT_AUTORESUME;
  117 +module_param(autoresume, uint, S_IRUGO);
  118 +MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
  119 +
110 120 /*-------------------------------------------------------------------------*/
111 121  
112 122 static struct usb_device_descriptor device_desc = {
... ... @@ -212,6 +222,47 @@
212 222  
213 223 /*-------------------------------------------------------------------------*/
214 224  
  225 +static struct timer_list autoresume_timer;
  226 +
  227 +static void zero_autoresume(unsigned long _c)
  228 +{
  229 + struct usb_composite_dev *cdev = (void *)_c;
  230 + struct usb_gadget *g = cdev->gadget;
  231 +
  232 + /* unconfigured devices can't issue wakeups */
  233 + if (!cdev->config)
  234 + return;
  235 +
  236 + /* Normally the host would be woken up for something
  237 + * more significant than just a timer firing; likely
  238 + * because of some direct user request.
  239 + */
  240 + if (g->speed != USB_SPEED_UNKNOWN) {
  241 + int status = usb_gadget_wakeup(g);
  242 + INFO(cdev, "%s --> %d\n", __func__, status);
  243 + }
  244 +}
  245 +
  246 +static void zero_suspend(struct usb_composite_dev *cdev)
  247 +{
  248 + if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
  249 + return;
  250 +
  251 + if (autoresume) {
  252 + mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
  253 + DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
  254 + } else
  255 + DBG(cdev, "%s\n", __func__);
  256 +}
  257 +
  258 +static void zero_resume(struct usb_composite_dev *cdev)
  259 +{
  260 + DBG(cdev, "%s\n", __func__);
  261 + del_timer(&autoresume_timer);
  262 +}
  263 +
  264 +/*-------------------------------------------------------------------------*/
  265 +
215 266 static int __init zero_bind(struct usb_composite_dev *cdev)
216 267 {
217 268 int gcnum;
218 269  
219 270  
220 271  
221 272  
... ... @@ -239,17 +290,19 @@
239 290 strings_dev[STRING_SERIAL_IDX].id = id;
240 291 device_desc.iSerialNumber = id;
241 292  
  293 + setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
  294 +
242 295 /* Register primary, then secondary configuration. Note that
243 296 * SH3 only allows one config...
244 297 */
245 298 if (loopdefault) {
246   - loopback_add(cdev);
  299 + loopback_add(cdev, autoresume != 0);
247 300 if (!gadget_is_sh(gadget))
248   - sourcesink_add(cdev);
  301 + sourcesink_add(cdev, autoresume != 0);
249 302 } else {
250   - sourcesink_add(cdev);
  303 + sourcesink_add(cdev, autoresume != 0);
251 304 if (!gadget_is_sh(gadget))
252   - loopback_add(cdev);
  305 + loopback_add(cdev, autoresume != 0);
253 306 }
254 307  
255 308 gcnum = usb_gadget_controller_number(gadget);
256 309  
... ... @@ -278,11 +331,20 @@
278 331 return 0;
279 332 }
280 333  
  334 +static int zero_unbind(struct usb_composite_dev *cdev)
  335 +{
  336 + del_timer_sync(&autoresume_timer);
  337 + return 0;
  338 +}
  339 +
281 340 static struct usb_composite_driver zero_driver = {
282 341 .name = "zero",
283 342 .dev = &device_desc,
284 343 .strings = dev_strings,
285 344 .bind = zero_bind,
  345 + .unbind = zero_unbind,
  346 + .suspend = zero_suspend,
  347 + .resume = zero_resume,
286 348 };
287 349  
288 350 MODULE_AUTHOR("David Brownell");