mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 18:24:14 +08:00
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>
This commit is contained in:
parent
352c2dc8b0
commit
e71eb392c2
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user