Use new interfaces from udc-core on musb gadget driver. Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- drivers/usb/gadget/Kconfig | 1 + drivers/usb/musb/musb_core.c | 4 +- drivers/usb/musb/musb_core.h | 4 +- drivers/usb/musb/musb_gadget.c | 214 ++++++++++------------------------- drivers/usb/musb/musb_gadget_ep0.c | 4 +- drivers/usb/musb/tusb6010.c | 2 +- 6 files changed, 70 insertions(+), 159 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7de6334..ecac288 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -18,6 +18,7 @@ config USB_UDC_CORE menuconfig USB_GADGET tristate "USB Gadget Support" + select USB_UDC_CORE if (USB_GADGET_MUSB_HDRC) help USB is a master/slave protocol, organized with one master host (such as a PC) controlling up to 127 peripheral devices. diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 540c766..9f26fc0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -115,7 +115,7 @@ #define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) -unsigned musb_debug; +unsigned musb_debug = 5; module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); @@ -1584,7 +1584,7 @@ irqreturn_t musb_interrupt(struct musb *musb) #ifdef CONFIG_USB_GADGET_MUSB_HDRC if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) - if (!musb->gadget_driver) { + if (!musb->udc.driver) { DBG(5, "No gadget driver loaded\n"); return IRQ_HANDLED; } diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 91d6779..f35e457 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -42,6 +42,7 @@ #include <linux/timer.h> #include <linux/clk.h> #include <linux/device.h> +#include <linux/usb/udc.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/usb.h> @@ -446,8 +447,9 @@ struct musb { u8 test_mode_nr; u16 ackpend; /* ep0 */ enum musb_g_ep0_state ep0_state; + + struct usb_udc udc; struct usb_gadget g; /* the gadget */ - struct usb_gadget_driver *gadget_driver; /* its driver */ #endif struct musb_hdrc_config *config; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d065e23..e113c7b 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -47,6 +47,8 @@ #include "musb_core.h" +static int musb_gadget_start(struct usb_gadget *gadget); +static void musb_gadget_stop(struct usb_gadget *gadget); /* MUSB PERIPHERAL status 3-mar-2006: * @@ -1502,7 +1504,7 @@ static void musb_pullup(struct musb *musb, int is_on) /* FIXME if on, HdrcStart; if off, HdrcStop */ DBG(3, "gadget %s D+ pullup %s\n", - musb->gadget_driver->function, is_on ? "on" : "off"); + musb->udc.driver->function, is_on ? "on" : "off"); musb_writeb(musb->mregs, MUSB_POWER, power); } @@ -1555,6 +1557,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, }; /* ----------------------------------------------------------------------- */ @@ -1567,13 +1571,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { */ static struct musb *the_gadget; -static void musb_gadget_release(struct device *dev) -{ - /* kref_put(WHAT) */ - dev_dbg(dev, "%s\n", __func__); -} - - static void __init init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) { @@ -1659,13 +1656,9 @@ int __init musb_gadget_setup(struct musb *musb) musb->g.ops = &musb_gadget_operations; musb->g.is_dualspeed = 1; musb->g.speed = USB_SPEED_UNKNOWN; - - /* this "gadget" abstracts/virtualizes the controller */ - dev_set_name(&musb->g.dev, "gadget"); - musb->g.dev.parent = musb->controller; - musb->g.dev.dma_mask = musb->controller->dma_mask; - musb->g.dev.release = musb_gadget_release; musb->g.name = musb_driver_name; + musb->udc.name = musb_driver_name; + musb->udc.gadget = &musb->g; if (is_otg_enabled(musb)) musb->g.is_otg = 1; @@ -1675,9 +1668,10 @@ int __init musb_gadget_setup(struct musb *musb) musb->is_active = 0; musb_platform_try_idle(musb, 0); - status = device_register(&musb->g.dev); + status = usb_add_udc(musb->controller, &musb->udc); if (status != 0) the_gadget = NULL; + return status; } @@ -1686,7 +1680,7 @@ void musb_gadget_cleanup(struct musb *musb) if (musb != the_gadget) return; - device_unregister(&musb->g.dev); + usb_del_udc(&musb->udc); the_gadget = NULL; } @@ -1701,132 +1695,68 @@ void musb_gadget_cleanup(struct musb *musb) * @param driver the gadget driver * @return <0 if error, 0 if everything is fine */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +static int musb_gadget_start(struct usb_gadget *gadget) { - int retval; + struct musb *musb = gadget_to_musb(gadget); unsigned long flags; - struct musb *musb = the_gadget; - - if (!driver - || driver->speed != USB_SPEED_HIGH - || !driver->bind - || !driver->setup) - return -EINVAL; - - /* driver must be initialized to support peripheral mode */ - if (!musb) { - DBG(1, "%s, no dev??\n", __func__); - return -ENODEV; - } + int retval = 0; - DBG(3, "registering driver %s\n", driver->function); spin_lock_irqsave(&musb->lock, flags); - if (musb->gadget_driver) { - DBG(1, "%s is already bound to %s\n", - musb_driver_name, - musb->gadget_driver->driver.name); - retval = -EBUSY; - } else { - musb->gadget_driver = driver; - musb->g.dev.driver = &driver->driver; - driver->driver.bus = NULL; - musb->softconnect = 1; - retval = 0; - } - - spin_unlock_irqrestore(&musb->lock, flags); + otg_set_peripheral(musb->xceiv, gadget); + musb->xceiv->state = OTG_STATE_B_IDLE; + musb->is_active = 1; - if (retval == 0) { - retval = driver->bind(&musb->g); - if (retval != 0) { - DBG(3, "bind to driver %s failed --> %d\n", - driver->driver.name, retval); - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - } + /* FIXME this ignores the softconnect flag. Drivers are + * allowed hold the peripheral inactive until for example + * userspace hooks up printer hardware or DSP codecs, so + * hosts only see fully functional devices. + */ - spin_lock_irqsave(&musb->lock, flags); + if (!is_otg_enabled(musb)) + musb_start(musb); - otg_set_peripheral(musb->xceiv, &musb->g); - musb->xceiv->state = OTG_STATE_B_IDLE; - musb->is_active = 1; + if (is_otg_enabled(musb)) { + DBG(3, "OTG startup...\n"); - /* FIXME this ignores the softconnect flag. Drivers are - * allowed hold the peripheral inactive until for example - * userspace hooks up printer hardware or DSP codecs, so - * hosts only see fully functional devices. + /* REVISIT: funcall to other code, which also + * handles power budgeting ... this way also + * ensures HdrcStart is indirectly called. */ - - 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)) { - DBG(3, "OTG startup...\n"); - - /* REVISIT: funcall to other code, which also - * handles power budgeting ... this way also - * ensures HdrcStart is indirectly called. - */ - retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); - if (retval < 0) { - DBG(1, "add_hcd failed, %d\n", retval); - spin_lock_irqsave(&musb->lock, flags); - otg_set_peripheral(musb->xceiv, NULL); - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - spin_unlock_irqrestore(&musb->lock, flags); - } + retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); + if (retval < 0) { + DBG(1, "add_hcd failed, %d\n", retval); + otg_set_peripheral(musb->xceiv, NULL); } } + spin_unlock_irqrestore(&musb->lock, flags); + return retval; } -EXPORT_SYMBOL(usb_gadget_register_driver); -static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) +static void stop_activity(struct musb *musb) { int i; struct musb_hw_ep *hw_ep; - /* don't disconnect if it's not connected */ - if (musb->g.speed == USB_SPEED_UNKNOWN) - driver = NULL; - else - musb->g.speed = USB_SPEED_UNKNOWN; - - /* deactivate the hardware */ - if (musb->softconnect) { - musb->softconnect = 0; - musb_pullup(musb, 0); - } musb_stop(musb); /* killing any outstanding requests will quiesce the driver; * then report disconnect */ - if (driver) { - for (i = 0, hw_ep = musb->endpoints; - i < musb->nr_endpoints; - i++, hw_ep++) { - musb_ep_select(musb->mregs, i); - if (hw_ep->is_shared_fifo /* || !epnum */) { + for (i = 0, hw_ep = musb->endpoints; + i < musb->nr_endpoints; + i++, hw_ep++) { + musb_ep_select(musb->mregs, i); + if (hw_ep->is_shared_fifo /* || !epnum */) { + nuke(&hw_ep->ep_in, -ESHUTDOWN); + } else { + if (hw_ep->max_packet_sz_tx) nuke(&hw_ep->ep_in, -ESHUTDOWN); - } else { - if (hw_ep->max_packet_sz_tx) - nuke(&hw_ep->ep_in, -ESHUTDOWN); - if (hw_ep->max_packet_sz_rx) - nuke(&hw_ep->ep_out, -ESHUTDOWN); - } + if (hw_ep->max_packet_sz_rx) + nuke(&hw_ep->ep_out, -ESHUTDOWN); } - - spin_unlock(&musb->lock); - driver->disconnect(&musb->g); - spin_lock(&musb->lock); } } @@ -1836,14 +1766,10 @@ 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 void musb_gadget_stop(struct usb_gadget *gadget) { + struct musb *musb = gadget_to_musb(gadget); unsigned long flags; - int retval = 0; - struct musb *musb = the_gadget; - - if (!driver || !driver->unbind || !musb) - return -EINVAL; /* REVISIT always use otg_set_peripheral() here too; * this needs to shut down the OTG engine. @@ -1855,40 +1781,22 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) musb_hnp_stop(musb); #endif - if (musb->gadget_driver == driver) { - - (void) musb_gadget_vbus_draw(&musb->g, 0); - - musb->xceiv->state = OTG_STATE_UNDEFINED; - stop_activity(musb, driver); - otg_set_peripheral(musb->xceiv, NULL); - - DBG(3, "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->xceiv->state = OTG_STATE_UNDEFINED; + stop_activity(musb); + otg_set_peripheral(musb->xceiv, NULL); - musb->is_active = 0; - musb_platform_try_idle(musb, 0); - } else - retval = -EINVAL; + musb->is_active = 0; + musb_platform_try_idle(musb, 0); spin_unlock_irqrestore(&musb->lock, flags); - if (is_otg_enabled(musb) && retval == 0) { + if (is_otg_enabled(musb)) { usb_remove_hcd(musb_to_hcd(musb)); /* FIXME we need to be able to register another * gadget driver here and have everything work; * that currently misbehaves. */ } - - return retval; } -EXPORT_SYMBOL(usb_gadget_unregister_driver); - /* ----------------------------------------------------------------------- */ @@ -1903,9 +1811,9 @@ void musb_g_resume(struct musb *musb) case OTG_STATE_B_WAIT_ACON: case OTG_STATE_B_PERIPHERAL: musb->is_active = 1; - if (musb->gadget_driver && musb->gadget_driver->resume) { + if (musb->udc.driver && musb->udc.driver->resume) { spin_unlock(&musb->lock); - musb->gadget_driver->resume(&musb->g); + musb->udc.driver->resume(&musb->g); spin_lock(&musb->lock); } break; @@ -1930,9 +1838,9 @@ void musb_g_suspend(struct musb *musb) break; case OTG_STATE_B_PERIPHERAL: musb->is_suspended = 1; - if (musb->gadget_driver && musb->gadget_driver->suspend) { + if (musb->udc.driver && musb->udc.driver->suspend) { spin_unlock(&musb->lock); - musb->gadget_driver->suspend(&musb->g); + musb->udc.driver->suspend(&musb->g); spin_lock(&musb->lock); } break; @@ -1966,9 +1874,9 @@ void musb_g_disconnect(struct musb *musb) (void) musb_gadget_vbus_draw(&musb->g, 0); musb->g.speed = USB_SPEED_UNKNOWN; - if (musb->gadget_driver && musb->gadget_driver->disconnect) { + if (musb->udc.driver && musb->udc.driver->disconnect) { spin_unlock(&musb->lock); - musb->gadget_driver->disconnect(&musb->g); + musb->udc.driver->disconnect(&musb->g); spin_lock(&musb->lock); } @@ -2010,8 +1918,8 @@ __acquires(musb->lock) (devctl & MUSB_DEVCTL_BDEVICE) ? "B-Device" : "A-Device", musb_readb(mbase, MUSB_FADDR), - musb->gadget_driver - ? musb->gadget_driver->driver.name + musb->udc.driver + ? musb->udc.driver->driver.name : NULL ); diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 6dd03f4..7b92d07 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -649,10 +649,10 @@ __releases(musb->lock) __acquires(musb->lock) { int retval; - if (!musb->gadget_driver) + if (!musb->udc.driver) return -EOPNOTSUPP; spin_unlock(&musb->lock); - retval = musb->gadget_driver->setup(&musb->g, ctrlrequest); + retval = musb->udc.driver->setup(&musb->g, ctrlrequest); spin_lock(&musb->lock); return retval; } diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 3c48e77..010fab5 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -444,7 +444,7 @@ static void musb_do_idle(unsigned long _musb) goto done; #ifdef CONFIG_USB_GADGET_MUSB_HDRC - if (is_peripheral_enabled(musb) && !musb->gadget_driver) + if (is_peripheral_enabled(musb) && !musb->udc.driver) wakeups = 0; else { wakeups = TUSB_PRCM_WHOSTDISCON -- 1.7.3.rc0.35.g8ac8c -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html