From 0f91349b89f37dfad7b77f7829a105b6a0f526ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 28 Jun 2011 16:33:47 +0300 Subject: usb: gadget: convert all users to the new udc infrastructure peripheral drivers are using usb_add_gadget()/usb_del_gadget() to register/unregister to the udc-core. The udc-core will take the first available gadget driver and attach function driver which is calling usb_gadget_register_driver(). This is the same behaviour we have right now. Only dummy_hcd was tested, the others were compiled tested. Cc: Alan Stern Cc: Anton Tikhomirov Cc: Ben Dooks Cc: Dan Carpenter Cc: Darius Augulis Cc: Eric Miao Cc: Jingoo Han Cc: Kukjin Kim Cc: Kuninori Morimoto Cc: Li Yang Cc: Michael Hennerich Acked-by: Mike Frysinger Cc: Nicolas Ferre Cc: Pavankumar Kondeti Cc: Roy Huang Cc: Russell King Cc: Toshiharu Okada Cc: Xiaochen Shen Cc: Yoshihiro Shimoda Cc: Yuan-Hsin Chen Cc: cxie4 Cc: linux-geode@lists.infradead.org Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers/usb/musb/musb_gadget.c') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 0a50a35e1853..728572cf709c 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1704,6 +1704,10 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) return 0; } +static int musb_gadget_start(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)); +static int musb_gadget_stop(struct usb_gadget_driver *driver); + static const struct usb_gadget_ops musb_gadget_operations = { .get_frame = musb_gadget_get_frame, .wakeup = musb_gadget_wakeup, @@ -1711,6 +1715,8 @@ static const struct usb_gadget_ops musb_gadget_operations = { /* .vbus_session = musb_gadget_vbus_session, */ .vbus_draw = musb_gadget_vbus_draw, .pullup = musb_gadget_pullup, + .start = musb_gadget_start, + .stop = musb_gadget_stop, }; /* ----------------------------------------------------------------------- */ @@ -1835,7 +1841,16 @@ int __init musb_gadget_setup(struct musb *musb) if (status != 0) { put_device(&musb->g.dev); the_gadget = NULL; + return status; } + status = usb_add_gadget_udc(musb->controller, &musb->g); + if (status) + goto err; + + return 0; +err: + device_unregister(&musb->g.dev); + the_gadget = NULL; return status; } @@ -1844,6 +1859,7 @@ void musb_gadget_cleanup(struct musb *musb) if (musb != the_gadget) return; + usb_del_gadget_udc(&musb->g); device_unregister(&musb->g.dev); the_gadget = NULL; } @@ -1860,7 +1876,7 @@ void musb_gadget_cleanup(struct musb *musb) * @param bind the driver's bind function * @return <0 if error, 0 if everything is fine */ -int usb_gadget_probe_driver(struct usb_gadget_driver *driver, +static int musb_gadget_start(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *)) { struct musb *musb = the_gadget; @@ -1962,7 +1978,6 @@ err1: err0: return retval; } -EXPORT_SYMBOL(usb_gadget_probe_driver); static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) { @@ -2012,7 +2027,7 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) * * @param driver the gadget driver to unregister */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +static int musb_gadget_stop(struct usb_gadget_driver *driver) { struct musb *musb = the_gadget; unsigned long flags; @@ -2071,8 +2086,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) return 0; } -EXPORT_SYMBOL(usb_gadget_unregister_driver); - /* ----------------------------------------------------------------------- */ -- cgit v1.2.3 From 622859634a663c5e55d0e2a2cdbb55ac058d97b3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 22 Jun 2011 17:28:09 +0300 Subject: usb: musb: drop a gigantic amount of ifdeferry the MUSB IP is always OTG, so there's no point in adding so many ifdefs on the code. Drop those and always compile the driver for OTG support. This also allows us to drop the useless "driver mode" choice. For doing that, we need to make musb depend on both Host and Peripheral side. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/usb/musb/musb_gadget.c') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 728572cf709c..37e70d390de8 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -2048,9 +2048,7 @@ static int musb_gadget_stop(struct usb_gadget_driver *driver) spin_lock_irqsave(&musb->lock, flags); -#ifdef CONFIG_USB_MUSB_OTG musb_hnp_stop(musb); -#endif (void) musb_gadget_vbus_draw(&musb->g, 0); @@ -2171,7 +2169,6 @@ void musb_g_disconnect(struct musb *musb) switch (musb->xceiv->state) { default: -#ifdef CONFIG_USB_MUSB_OTG dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", otg_state_string(musb->xceiv->state)); musb->xceiv->state = OTG_STATE_A_IDLE; @@ -2183,7 +2180,6 @@ void musb_g_disconnect(struct musb *musb) break; case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_HOST: -#endif case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_IDLE: musb->xceiv->state = OTG_STATE_B_IDLE; -- cgit v1.2.3 From e71eb392c2014e2b377810ad329e36b0229d041c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 23 Jun 2011 14:26:16 +0200 Subject: usb: musb: convert musb to new style bind udc-core checks for valid callbacks so there is no need for the driver to do so. Also "can-be-bound-once" is verified by udc-core. The pull-up callback is called by udc-core afterwords. [ balbi@ti.com : keep holding gadget_driver pointer for now remove the stupid check for gadget_driver otherwise we don't handle IRQs ] Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 91 ++++++++---------------------------------- 1 file changed, 17 insertions(+), 74 deletions(-) (limited to 'drivers/usb/musb/musb_gadget.c') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 37e70d390de8..8b626548989f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1657,8 +1657,8 @@ static void musb_pullup(struct musb *musb, int is_on) /* FIXME if on, HdrcStart; if off, HdrcStop */ - dev_dbg(musb->controller, "gadget %s D+ pullup %s\n", - musb->gadget_driver->function, is_on ? "on" : "off"); + dev_dbg(musb->controller, "gadget D+ pullup %s\n", + is_on ? "on" : "off"); musb_writeb(musb->mregs, MUSB_POWER, power); } @@ -1704,9 +1704,10 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int musb_gadget_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); -static int musb_gadget_stop(struct usb_gadget_driver *driver); +static int musb_gadget_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int musb_gadget_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops musb_gadget_operations = { .get_frame = musb_gadget_get_frame, @@ -1715,8 +1716,8 @@ static const struct usb_gadget_ops musb_gadget_operations = { /* .vbus_session = musb_gadget_vbus_session, */ .vbus_draw = musb_gadget_vbus_draw, .pullup = musb_gadget_pullup, - .start = musb_gadget_start, - .stop = musb_gadget_stop, + .udc_start = musb_gadget_start, + .udc_stop = musb_gadget_stop, }; /* ----------------------------------------------------------------------- */ @@ -1727,7 +1728,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { * about there being only one external upstream port. It assumes * all peripheral ports are external... */ -static struct musb *the_gadget; static void musb_gadget_release(struct device *dev) { @@ -1814,9 +1814,6 @@ int __init musb_gadget_setup(struct musb *musb) * musb peripherals at the same time, only the bus lock * is probably held. */ - if (the_gadget) - return -EBUSY; - the_gadget = musb; musb->g.ops = &musb_gadget_operations; musb->g.is_dualspeed = 1; @@ -1840,7 +1837,6 @@ int __init musb_gadget_setup(struct musb *musb) status = device_register(&musb->g.dev); if (status != 0) { put_device(&musb->g.dev); - the_gadget = NULL; return status; } status = usb_add_gadget_udc(musb->controller, &musb->g); @@ -1850,18 +1846,13 @@ int __init musb_gadget_setup(struct musb *musb) return 0; err: device_unregister(&musb->g.dev); - the_gadget = NULL; return status; } void musb_gadget_cleanup(struct musb *musb) { - if (musb != the_gadget) - return; - usb_del_gadget_udc(&musb->g); device_unregister(&musb->g.dev); - the_gadget = NULL; } /* @@ -1873,59 +1864,30 @@ void musb_gadget_cleanup(struct musb *musb) * -ENOMEM no memory to perform the operation * * @param driver the gadget driver - * @param bind the driver's bind function * @return <0 if error, 0 if everything is fine */ -static int musb_gadget_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) +static int musb_gadget_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct musb *musb = the_gadget; + struct musb *musb = gadget_to_musb(g); unsigned long flags; int retval = -EINVAL; - if (!driver - || driver->speed != USB_SPEED_HIGH - || !bind || !driver->setup) + if (driver->speed != USB_SPEED_HIGH) goto err0; - /* driver must be initialized to support peripheral mode */ - if (!musb) { - dev_dbg(musb->controller, "no dev??\n"); - retval = -ENODEV; - goto err0; - } - pm_runtime_get_sync(musb->controller); dev_dbg(musb->controller, "registering driver %s\n", driver->function); - if (musb->gadget_driver) { - dev_dbg(musb->controller, "%s is already bound to %s\n", - musb_driver_name, - musb->gadget_driver->driver.name); - retval = -EBUSY; - goto err0; - } - - spin_lock_irqsave(&musb->lock, flags); + musb->softconnect = 0; musb->gadget_driver = driver; - musb->g.dev.driver = &driver->driver; - driver->driver.bus = NULL; - musb->softconnect = 1; - spin_unlock_irqrestore(&musb->lock, flags); - - retval = bind(&musb->g); - if (retval) { - dev_dbg(musb->controller, "bind to driver %s failed --> %d\n", - driver->driver.name, retval); - goto err1; - } spin_lock_irqsave(&musb->lock, flags); + musb->is_active = 1; otg_set_peripheral(musb->xceiv, &musb->g); musb->xceiv->state = OTG_STATE_B_IDLE; - musb->is_active = 1; /* * FIXME this ignores the softconnect flag. Drivers are @@ -1937,8 +1899,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver, if (!is_otg_enabled(musb)) musb_start(musb); - otg_set_peripheral(musb->xceiv, &musb->g); - spin_unlock_irqrestore(&musb->lock, flags); if (is_otg_enabled(musb)) { @@ -1970,11 +1930,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver, err2: if (!is_otg_enabled(musb)) musb_stop(musb); - -err1: - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - err0: return retval; } @@ -2027,17 +1982,12 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) * * @param driver the gadget driver to unregister */ -static int musb_gadget_stop(struct usb_gadget_driver *driver) +static int musb_gadget_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct musb *musb = the_gadget; + struct musb *musb = gadget_to_musb(g); unsigned long flags; - if (!driver || !driver->unbind || !musb) - return -EINVAL; - - if (!musb->gadget_driver) - return -EINVAL; - if (musb->xceiv->last_event == USB_EVENT_NONE) pm_runtime_get_sync(musb->controller); @@ -2058,13 +2008,6 @@ static int musb_gadget_stop(struct usb_gadget_driver *driver) dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); - spin_unlock_irqrestore(&musb->lock, flags); - driver->unbind(&musb->g); - spin_lock_irqsave(&musb->lock, flags); - - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - musb->is_active = 0; musb_platform_try_idle(musb, 0); spin_unlock_irqrestore(&musb->lock, flags); -- cgit v1.2.3