diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2011-06-23 14:26:16 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-01 14:31:13 -0700 |
commit | e71eb392c2014e2b377810ad329e36b0229d041c (patch) | |
tree | 9fc9a4528a2af3b15ef85c8eb60fcf77c021ea34 /drivers/usb | |
parent | 352c2dc8b07491bbab77ddf86c20c16a97326ee7 (diff) | |
download | lwn-e71eb392c2014e2b377810ad329e36b0229d041c.tar.gz lwn-e71eb392c2014e2b377810ad329e36b0229d041c.zip |
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 <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 91 |
2 files changed, 17 insertions, 81 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 391237b0dec1..e2ab45219855 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -899,7 +899,6 @@ void musb_start(struct musb *musb) /* put into basic highspeed mode and start session */ musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE - | MUSB_POWER_SOFTCONN | MUSB_POWER_HSENAB /* ENSUSPEND wedges tusb */ /* | MUSB_POWER_ENSUSPEND */ @@ -1526,12 +1525,6 @@ irqreturn_t musb_interrupt(struct musb *musb) (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", musb->int_usb, musb->int_tx, musb->int_rx); - if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) - if (!musb->gadget_driver) { - dev_dbg(musb->controller, "No gadget driver loaded\n"); - return IRQ_HANDLED; - } - /* the core can interrupt us for multiple reasons; docs have * a generic interrupt flowchart to follow */ 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); |