[RFC/PATCH 5/8] usb: gadget: at91: use new interfaces

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

 



use new interfaces from udc-core on at91
controller driver.

Signed-off-by: Felipe Balbi <balbi@xxxxxx>
---
 drivers/usb/gadget/Kconfig    |    1 +
 drivers/usb/gadget/at91_udc.c |  131 +++++++++++++++--------------------------
 drivers/usb/gadget/at91_udc.h |    4 +-
 3 files changed, 51 insertions(+), 85 deletions(-)

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index df3935d..e6d4f2a 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -19,6 +19,7 @@ config USB_UDC_CORE
 menuconfig USB_GADGET
 	tristate "USB Gadget Support"
 	select USB_UDC_CORE if (USB_GADGET_MUSB_HDRC || USB_GADGET_AMD5536UDC)
+	select USB_UDC_CORE if (USB_GADGET_AT91)
 	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/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 93ead19..cbeff67 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -36,6 +36,7 @@
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/clk.h>
+#include <linux/usb/udc.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
@@ -186,7 +187,7 @@ static int proc_udc_show(struct seq_file *s, void *unused)
 			: "disabled",
 		udc->selfpowered ? "self" : "VBUS",
 		udc->suspended ? ", suspended" : "",
-		udc->driver ? udc->driver->driver.name : "(none)");
+		udc->udc.driver ? udc->udc.driver->driver.name : "(none)");
 
 	/* don't access registers when interface isn't clocked */
 	if (!udc->clocked) {
@@ -491,7 +492,7 @@ static int at91_ep_enable(struct usb_ep *_ep,
 		return -EINVAL;
 	}
 
-	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
+	if (!udc->udc.driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
 		DBG("bogus device state\n");
 		return -ESHUTDOWN;
 	}
@@ -631,7 +632,7 @@ static int at91_ep_queue(struct usb_ep *_ep,
 
 	udc = ep->udc;
 
-	if (!udc || !udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
+	if (!udc || !udc->udc.driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
 		DBG("invalid device\n");
 		return -EINVAL;
 	}
@@ -851,7 +852,7 @@ static void udc_reinit(struct at91_udc *udc)
 
 static void stop_activity(struct at91_udc *udc)
 {
-	struct usb_gadget_driver *driver = udc->driver;
+	struct usb_gadget_driver *driver = udc->udc.driver;
 	int i;
 
 	if (udc->gadget.speed == USB_SPEED_UNKNOWN)
@@ -953,7 +954,7 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active)
 	// VDBG("vbus %s\n", is_active ? "on" : "off");
 	spin_lock_irqsave(&udc->lock, flags);
 	udc->vbus = (is_active != 0);
-	if (udc->driver)
+	if (udc->udc.driver)
 		pullup(udc, is_active);
 	else
 		pullup(udc, 0);
@@ -984,12 +985,40 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on)
 	return 0;
 }
 
+static int at91_start(struct usb_gadget *gadget)
+{
+	struct at91_udc	*udc = to_udc(gadget);
+	unsigned long	flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->enabled = 1;
+	udc->selfpowered = 1;
+	pullup(udc, 1);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static void at91_stop(struct usb_gadget *gadget)
+{
+	struct at91_udc *udc = to_udc(gadget);
+	unsigned long	flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->enabled = 0;
+	at91_udp_write(udc, AT91_UDP_IDR, ~0);
+	pullup(udc, 0);
+	spin_unlock_irqrestore(&udc->lock, flags);
+}
+
 static const struct usb_gadget_ops at91_udc_ops = {
 	.get_frame		= at91_get_frame,
 	.wakeup			= at91_wakeup,
 	.set_selfpowered	= at91_set_selfpowered,
 	.vbus_session		= at91_vbus_session,
 	.pullup			= at91_pullup,
+	.start			= at91_start,
+	.stop			= at91_stop,
 
 	/*
 	 * VBUS-powered devices may also also want to support bigger
@@ -1242,9 +1271,9 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
 #undef w_length
 
 	/* pass request up to the gadget driver */
-	if (udc->driver) {
+	if (udc->udc.driver) {
 		spin_unlock(&udc->lock);
-		status = udc->driver->setup(&udc->gadget, &pkt.r);
+		status = udc->udc.driver->setup(&udc->gadget, &pkt.r);
 		spin_lock(&udc->lock);
 	}
 	else
@@ -1455,9 +1484,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
 			 * and then into standby to avoid drawing more than
 			 * 500uA power (2500uA for some high-power configs).
 			 */
-			if (udc->driver && udc->driver->suspend) {
+			if (udc->udc.driver && udc->udc.driver->suspend) {
 				spin_unlock(&udc->lock);
-				udc->driver->suspend(&udc->gadget);
+				udc->udc.driver->suspend(&udc->gadget);
 				spin_lock(&udc->lock);
 			}
 
@@ -1476,9 +1505,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
 			 * would normally want to switch out of slow clock
 			 * mode into normal mode.
 			 */
-			if (udc->driver && udc->driver->resume) {
+			if (udc->udc.driver && udc->udc.driver->resume) {
 				spin_unlock(&udc->lock);
-				udc->driver->resume(&udc->gadget);
+				udc->udc.driver->resume(&udc->gadget);
 				spin_lock(&udc->lock);
 			}
 
@@ -1515,6 +1544,9 @@ static void nop_release(struct device *dev)
 }
 
 static struct at91_udc controller = {
+	.udc	= {
+		.name	= (char *) driver_name,
+	},
 	.gadget = {
 		.ops	= &at91_udc_ops,
 		.ep0	= &controller.ep[0].ep,
@@ -1628,75 +1660,6 @@ static void at91_vbus_timer(unsigned long data)
 		schedule_work(&udc->vbus_timer_work);
 }
 
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
-{
-	struct at91_udc	*udc = &controller;
-	int		retval;
-	unsigned long	flags;
-
-	if (!driver
-			|| driver->speed < USB_SPEED_FULL
-			|| !driver->bind
-			|| !driver->setup) {
-		DBG("bad parameter.\n");
-		return -EINVAL;
-	}
-
-	if (udc->driver) {
-		DBG("UDC already has a gadget driver\n");
-		return -EBUSY;
-	}
-
-	udc->driver = driver;
-	udc->gadget.dev.driver = &driver->driver;
-	dev_set_drvdata(&udc->gadget.dev, &driver->driver);
-	udc->enabled = 1;
-	udc->selfpowered = 1;
-
-	retval = driver->bind(&udc->gadget);
-	if (retval) {
-		DBG("driver->bind() returned %d\n", retval);
-		udc->driver = NULL;
-		udc->gadget.dev.driver = NULL;
-		dev_set_drvdata(&udc->gadget.dev, NULL);
-		udc->enabled = 0;
-		udc->selfpowered = 0;
-		return retval;
-	}
-
-	spin_lock_irqsave(&udc->lock, flags);
-	pullup(udc, 1);
-	spin_unlock_irqrestore(&udc->lock, flags);
-
-	DBG("bound to %s\n", driver->driver.name);
-	return 0;
-}
-EXPORT_SYMBOL (usb_gadget_register_driver);
-
-int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
-{
-	struct at91_udc *udc = &controller;
-	unsigned long	flags;
-
-	if (!driver || driver != udc->driver || !driver->unbind)
-		return -EINVAL;
-
-	spin_lock_irqsave(&udc->lock, flags);
-	udc->enabled = 0;
-	at91_udp_write(udc, AT91_UDP_IDR, ~0);
-	pullup(udc, 0);
-	spin_unlock_irqrestore(&udc->lock, flags);
-
-	driver->unbind(&udc->gadget);
-	udc->gadget.dev.driver = NULL;
-	dev_set_drvdata(&udc->gadget.dev, NULL);
-	udc->driver = NULL;
-
-	DBG("unbound from %s\n", driver->driver.name);
-	return 0;
-}
-EXPORT_SYMBOL (usb_gadget_unregister_driver);
-
 /*-------------------------------------------------------------------------*/
 
 static void at91udc_shutdown(struct platform_device *dev)
@@ -1744,7 +1707,6 @@ static int __init at91udc_probe(struct platform_device *pdev)
 
 	/* init software state */
 	udc = &controller;
-	udc->gadget.dev.parent = dev;
 	udc->board = *(struct at91_udc_data *) dev->platform_data;
 	udc->pdev = pdev;
 	udc->enabled = 0;
@@ -1797,7 +1759,8 @@ static int __init at91udc_probe(struct platform_device *pdev)
 		goto fail0b;
 	}
 
-	retval = device_register(&udc->gadget.dev);
+	udc->udc.gadget = &udc->gadget;
+	retval = usb_add_udc(&pdev->dev, &udc->udc);
 	if (retval < 0)
 		goto fail0b;
 
@@ -1884,7 +1847,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
 
 	DBG("remove\n");
 
-	if (udc->driver)
+	if (udc->udc.driver)
 		return -EBUSY;
 
 	spin_lock_irqsave(&udc->lock, flags);
@@ -1918,7 +1881,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
 static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
 	struct at91_udc *udc = platform_get_drvdata(pdev);
-	int		wake = udc->driver && device_may_wakeup(&pdev->dev);
+	int		wake = udc->udc.driver && device_may_wakeup(&pdev->dev);
 	unsigned long	flags;
 
 	/* Unless we can act normally to the host (letting it wake us up
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index 108ca54..e1aee2b 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -22,6 +22,8 @@
 #ifndef AT91_UDC_H
 #define AT91_UDC_H
 
+#include <linux/usb/udc.h>
+
 /*
  * USB Device Port (UDP) registers.
  * Based on AT91RM9200 datasheet revision E.
@@ -125,9 +127,9 @@ struct at91_ep {
  * access protection for chip registers or driver state
  */
 struct at91_udc {
+	struct usb_udc			udc;
 	struct usb_gadget		gadget;
 	struct at91_ep			ep[NUM_ENDPOINTS];
-	struct usb_gadget_driver	*driver;
 	unsigned			vbus:1;
 	unsigned			enabled:1;
 	unsigned			clocked:1;
-- 
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