summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2011-06-23 14:26:16 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-01 14:31:13 -0700
commite71eb392c2014e2b377810ad329e36b0229d041c (patch)
tree9fc9a4528a2af3b15ef85c8eb60fcf77c021ea34 /drivers/usb
parent352c2dc8b07491bbab77ddf86c20c16a97326ee7 (diff)
downloadlwn-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.c7
-rw-r--r--drivers/usb/musb/musb_gadget.c91
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);