[RFC/PATCH 3/8] usb: musb: gadget: use new interfaces

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux