aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2011-06-23 08:26:15 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-01 17:31:13 -0400
commit352c2dc8b07491bbab77ddf86c20c16a97326ee7 (patch)
treea1aaa9ab0b95701e4f8aba194bfbbb42df81b572
parentb5738413c96126e8191bc506b403cd55950b8f9a (diff)
usb: gadget: udc-core: add "new-style" registration interface
udc_start() should only trigger the internal state machine and make minimal house keeping. Before that call udc-core calls the bind() callback and after the callback the pullup(). udc_stop() is simillar, udc-core calls pullup(), unbind() and finally udc_stop(). Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/gadget/udc-core.c75
-rw-r--r--include/linux/usb/gadget.h6
2 files changed, 77 insertions, 4 deletions
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 83e9e5f99b4a..2ddb7c8b5b3d 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -73,6 +73,26 @@ static inline int usb_gadget_start(struct usb_gadget *gadget,
73} 73}
74 74
75/** 75/**
76 * usb_gadget_udc_start - tells usb device controller to start up
77 * @gadget: The gadget we want to get started
78 * @driver: The driver we want to bind to @gadget
79 *
80 * This call is issued by the UDC Class driver when it's about
81 * to register a gadget driver to the device controller, before
82 * calling gadget driver's bind() method.
83 *
84 * It allows the controller to be powered off until strictly
85 * necessary to have it powered on.
86 *
87 * Returns zero on success, else negative errno.
88 */
89static inline int usb_gadget_udc_start(struct usb_gadget *gadget,
90 struct usb_gadget_driver *driver)
91{
92 return gadget->ops->udc_start(gadget, driver);
93}
94
95/**
76 * usb_gadget_stop - tells usb device controller we don't need it anymore 96 * usb_gadget_stop - tells usb device controller we don't need it anymore
77 * @gadget: The device we want to stop activity 97 * @gadget: The device we want to stop activity
78 * @driver: The driver to unbind from @gadget 98 * @driver: The driver to unbind from @gadget
@@ -91,6 +111,24 @@ static inline void usb_gadget_stop(struct usb_gadget *gadget,
91} 111}
92 112
93/** 113/**
114 * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
115 * @gadget: The device we want to stop activity
116 * @driver: The driver to unbind from @gadget
117 *
118 * This call is issued by the UDC Class driver after calling
119 * gadget driver's unbind() method.
120 *
121 * The details are implementation specific, but it can go as
122 * far as powering off UDC completely and disable its data
123 * line pullups.
124 */
125static inline void usb_gadget_udc_stop(struct usb_gadget *gadget,
126 struct usb_gadget_driver *driver)
127{
128 gadget->ops->udc_stop(gadget, driver);
129}
130
131/**
94 * usb_udc_release - release the usb_udc struct 132 * usb_udc_release - release the usb_udc struct
95 * @dev: the dev member within usb_udc 133 * @dev: the dev member within usb_udc
96 * 134 *
@@ -155,6 +193,14 @@ err1:
155} 193}
156EXPORT_SYMBOL_GPL(usb_add_gadget_udc); 194EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
157 195
196static int udc_is_newstyle(struct usb_udc *udc)
197{
198 if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop)
199 return 1;
200 return 0;
201}
202
203
158static void usb_gadget_remove_driver(struct usb_udc *udc) 204static void usb_gadget_remove_driver(struct usb_udc *udc)
159{ 205{
160 dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", 206 dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
@@ -162,7 +208,14 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
162 208
163 kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); 209 kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
164 210
165 usb_gadget_stop(udc->gadget, udc->driver); 211 if (udc_is_newstyle(udc)) {
212 usb_gadget_disconnect(udc->gadget);
213 udc->driver->unbind(udc->gadget);
214 usb_gadget_udc_stop(udc->gadget, udc->driver);
215
216 } else {
217 usb_gadget_stop(udc->gadget, udc->driver);
218 }
166 219
167 udc->driver = NULL; 220 udc->driver = NULL;
168 udc->dev.driver = NULL; 221 udc->dev.driver = NULL;
@@ -232,9 +285,23 @@ found:
232 udc->driver = driver; 285 udc->driver = driver;
233 udc->dev.driver = &driver->driver; 286 udc->dev.driver = &driver->driver;
234 287
235 ret = usb_gadget_start(udc->gadget, driver, bind); 288 if (udc_is_newstyle(udc)) {
236 if (ret) 289 ret = bind(udc->gadget);
237 goto err1; 290 if (ret)
291 goto err1;
292 ret = usb_gadget_udc_start(udc->gadget, driver);
293 if (ret) {
294 driver->unbind(udc->gadget);
295 goto err1;
296 }
297 usb_gadget_connect(udc->gadget);
298 } else {
299
300 ret = usb_gadget_start(udc->gadget, driver, bind);
301 if (ret)
302 goto err1;
303
304 }
238 305
239 kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); 306 kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
240 mutex_unlock(&udc_lock); 307 mutex_unlock(&udc_lock);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index afb67d997f0c..087f4b931833 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -459,6 +459,12 @@ struct usb_gadget_ops {
459 int (*ioctl)(struct usb_gadget *, 459 int (*ioctl)(struct usb_gadget *,
460 unsigned code, unsigned long param); 460 unsigned code, unsigned long param);
461 void (*get_config_params)(struct usb_dcd_config_params *); 461 void (*get_config_params)(struct usb_dcd_config_params *);
462 int (*udc_start)(struct usb_gadget *,
463 struct usb_gadget_driver *);
464 int (*udc_stop)(struct usb_gadget *,
465 struct usb_gadget_driver *);
466
467 /* Those two are deprecated */
462 int (*start)(struct usb_gadget_driver *, 468 int (*start)(struct usb_gadget_driver *,
463 int (*bind)(struct usb_gadget *)); 469 int (*bind)(struct usb_gadget *));
464 int (*stop)(struct usb_gadget_driver *); 470 int (*stop)(struct usb_gadget_driver *);