Commit e71eb392 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Greg Kroah-Hartman

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: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 352c2dc8
...@@ -899,7 +899,6 @@ void musb_start(struct musb *musb) ...@@ -899,7 +899,6 @@ void musb_start(struct musb *musb)
/* put into basic highspeed mode and start session */ /* put into basic highspeed mode and start session */
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
| MUSB_POWER_SOFTCONN
| MUSB_POWER_HSENAB | MUSB_POWER_HSENAB
/* ENSUSPEND wedges tusb */ /* ENSUSPEND wedges tusb */
/* | MUSB_POWER_ENSUSPEND */ /* | MUSB_POWER_ENSUSPEND */
...@@ -1526,12 +1525,6 @@ irqreturn_t musb_interrupt(struct musb *musb) ...@@ -1526,12 +1525,6 @@ irqreturn_t musb_interrupt(struct musb *musb)
(devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral",
musb->int_usb, musb->int_tx, musb->int_rx); 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 /* the core can interrupt us for multiple reasons; docs have
* a generic interrupt flowchart to follow * a generic interrupt flowchart to follow
*/ */
......
...@@ -1657,8 +1657,8 @@ static void musb_pullup(struct musb *musb, int is_on) ...@@ -1657,8 +1657,8 @@ static void musb_pullup(struct musb *musb, int is_on)
/* FIXME if on, HdrcStart; if off, HdrcStop */ /* FIXME if on, HdrcStart; if off, HdrcStop */
dev_dbg(musb->controller, "gadget %s D+ pullup %s\n", dev_dbg(musb->controller, "gadget D+ pullup %s\n",
musb->gadget_driver->function, is_on ? "on" : "off"); is_on ? "on" : "off");
musb_writeb(musb->mregs, MUSB_POWER, power); musb_writeb(musb->mregs, MUSB_POWER, power);
} }
...@@ -1704,9 +1704,10 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) ...@@ -1704,9 +1704,10 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)
return 0; return 0;
} }
static int musb_gadget_start(struct usb_gadget_driver *driver, static int musb_gadget_start(struct usb_gadget *g,
int (*bind)(struct usb_gadget *)); struct usb_gadget_driver *driver);
static int musb_gadget_stop(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 = { static const struct usb_gadget_ops musb_gadget_operations = {
.get_frame = musb_gadget_get_frame, .get_frame = musb_gadget_get_frame,
...@@ -1715,8 +1716,8 @@ static const struct usb_gadget_ops musb_gadget_operations = { ...@@ -1715,8 +1716,8 @@ static const struct usb_gadget_ops musb_gadget_operations = {
/* .vbus_session = musb_gadget_vbus_session, */ /* .vbus_session = musb_gadget_vbus_session, */
.vbus_draw = musb_gadget_vbus_draw, .vbus_draw = musb_gadget_vbus_draw,
.pullup = musb_gadget_pullup, .pullup = musb_gadget_pullup,
.start = musb_gadget_start, .udc_start = musb_gadget_start,
.stop = musb_gadget_stop, .udc_stop = musb_gadget_stop,
}; };
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
...@@ -1727,7 +1728,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { ...@@ -1727,7 +1728,6 @@ static const struct usb_gadget_ops musb_gadget_operations = {
* about there being only one external upstream port. It assumes * about there being only one external upstream port. It assumes
* all peripheral ports are external... * all peripheral ports are external...
*/ */
static struct musb *the_gadget;
static void musb_gadget_release(struct device *dev) static void musb_gadget_release(struct device *dev)
{ {
...@@ -1814,9 +1814,6 @@ int __init musb_gadget_setup(struct musb *musb) ...@@ -1814,9 +1814,6 @@ int __init musb_gadget_setup(struct musb *musb)
* musb peripherals at the same time, only the bus lock * musb peripherals at the same time, only the bus lock
* is probably held. * is probably held.
*/ */
if (the_gadget)
return -EBUSY;
the_gadget = musb;
musb->g.ops = &musb_gadget_operations; musb->g.ops = &musb_gadget_operations;
musb->g.is_dualspeed = 1; musb->g.is_dualspeed = 1;
...@@ -1840,7 +1837,6 @@ int __init musb_gadget_setup(struct musb *musb) ...@@ -1840,7 +1837,6 @@ int __init musb_gadget_setup(struct musb *musb)
status = device_register(&musb->g.dev); status = device_register(&musb->g.dev);
if (status != 0) { if (status != 0) {
put_device(&musb->g.dev); put_device(&musb->g.dev);
the_gadget = NULL;
return status; return status;
} }
status = usb_add_gadget_udc(musb->controller, &musb->g); status = usb_add_gadget_udc(musb->controller, &musb->g);
...@@ -1850,18 +1846,13 @@ int __init musb_gadget_setup(struct musb *musb) ...@@ -1850,18 +1846,13 @@ int __init musb_gadget_setup(struct musb *musb)
return 0; return 0;
err: err:
device_unregister(&musb->g.dev); device_unregister(&musb->g.dev);
the_gadget = NULL;
return status; return status;
} }
void musb_gadget_cleanup(struct musb *musb) void musb_gadget_cleanup(struct musb *musb)
{ {
if (musb != the_gadget)
return;
usb_del_gadget_udc(&musb->g); usb_del_gadget_udc(&musb->g);
device_unregister(&musb->g.dev); device_unregister(&musb->g.dev);
the_gadget = NULL;
} }
/* /*
...@@ -1873,59 +1864,30 @@ void musb_gadget_cleanup(struct musb *musb) ...@@ -1873,59 +1864,30 @@ void musb_gadget_cleanup(struct musb *musb)
* -ENOMEM no memory to perform the operation * -ENOMEM no memory to perform the operation
* *
* @param driver the gadget driver * @param driver the gadget driver
* @param bind the driver's bind function
* @return <0 if error, 0 if everything is fine * @return <0 if error, 0 if everything is fine
*/ */
static int musb_gadget_start(struct usb_gadget_driver *driver, static int musb_gadget_start(struct usb_gadget *g,
int (*bind)(struct usb_gadget *)) struct usb_gadget_driver *driver)
{ {
struct musb *musb = the_gadget; struct musb *musb = gadget_to_musb(g);
unsigned long flags; unsigned long flags;
int retval = -EINVAL; int retval = -EINVAL;
if (!driver if (driver->speed != USB_SPEED_HIGH)
|| driver->speed != USB_SPEED_HIGH
|| !bind || !driver->setup)
goto err0; 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); pm_runtime_get_sync(musb->controller);
dev_dbg(musb->controller, "registering driver %s\n", driver->function); dev_dbg(musb->controller, "registering driver %s\n", driver->function);
if (musb->gadget_driver) { musb->softconnect = 0;
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->gadget_driver = driver; 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); spin_lock_irqsave(&musb->lock, flags);
musb->is_active = 1;
otg_set_peripheral(musb->xceiv, &musb->g); otg_set_peripheral(musb->xceiv, &musb->g);
musb->xceiv->state = OTG_STATE_B_IDLE; musb->xceiv->state = OTG_STATE_B_IDLE;
musb->is_active = 1;
/* /*
* FIXME this ignores the softconnect flag. Drivers are * FIXME this ignores the softconnect flag. Drivers are
...@@ -1937,8 +1899,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver, ...@@ -1937,8 +1899,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver,
if (!is_otg_enabled(musb)) if (!is_otg_enabled(musb))
musb_start(musb); musb_start(musb);
otg_set_peripheral(musb->xceiv, &musb->g);
spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags);
if (is_otg_enabled(musb)) { if (is_otg_enabled(musb)) {
...@@ -1970,11 +1930,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver, ...@@ -1970,11 +1930,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver,
err2: err2:
if (!is_otg_enabled(musb)) if (!is_otg_enabled(musb))
musb_stop(musb); musb_stop(musb);
err1:
musb->gadget_driver = NULL;
musb->g.dev.driver = NULL;
err0: err0:
return retval; return retval;
} }
...@@ -2027,17 +1982,12 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) ...@@ -2027,17 +1982,12 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
* *
* @param driver the gadget driver to unregister * @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; unsigned long flags;
if (!driver || !driver->unbind || !musb)
return -EINVAL;
if (!musb->gadget_driver)
return -EINVAL;
if (musb->xceiv->last_event == USB_EVENT_NONE) if (musb->xceiv->last_event == USB_EVENT_NONE)
pm_runtime_get_sync(musb->controller); pm_runtime_get_sync(musb->controller);
...@@ -2058,13 +2008,6 @@ static int musb_gadget_stop(struct usb_gadget_driver *driver) ...@@ -2058,13 +2008,6 @@ static int musb_gadget_stop(struct usb_gadget_driver *driver)
dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); 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->is_active = 0;
musb_platform_try_idle(musb, 0); musb_platform_try_idle(musb, 0);
spin_unlock_irqrestore(&musb->lock, flags); spin_unlock_irqrestore(&musb->lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment