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