diff options
Diffstat (limited to 'drivers/usb/gadget/pxa25x_udc.c')
| -rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 136 |
1 files changed, 39 insertions, 97 deletions
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index f7ff9e8e746..9984437d295 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -21,18 +21,18 @@ #include <linux/ioport.h> #include <linux/types.h> #include <linux/errno.h> +#include <linux/err.h> #include <linux/delay.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/timer.h> #include <linux/list.h> #include <linux/interrupt.h> #include <linux/mm.h> +#include <linux/platform_data/pxa2xx_udc.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/irq.h> #include <linux/clk.h> -#include <linux/err.h> #include <linux/seq_file.h> #include <linux/debugfs.h> #include <linux/io.h> @@ -53,15 +53,13 @@ */ #ifdef CONFIG_ARCH_PXA #include <mach/pxa25x-udc.h> +#include <mach/hardware.h> #endif #ifdef CONFIG_ARCH_LUBBOCK #include <mach/lubbock.h> #endif -#include <asm/mach/udc_pxa2xx.h> - - /* * This driver handles the USB Device Controller (UDC) in Intel's PXA 25x * series processors. The UDC for the IXP 4xx series is very similar. @@ -993,14 +991,15 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) udc = container_of(_gadget, struct pxa25x_udc, gadget); - if (udc->transceiver) + if (!IS_ERR_OR_NULL(udc->transceiver)) return usb_phy_set_power(udc->transceiver, mA); return -EOPNOTSUPP; } -static int pxa25x_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)); -static int pxa25x_stop(struct usb_gadget_driver *driver); +static int pxa25x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver); +static int pxa25x_udc_stop(struct usb_gadget *g, + struct usb_gadget_driver *driver); static const struct usb_gadget_ops pxa25x_udc_ops = { .get_frame = pxa25x_udc_get_frame, @@ -1008,8 +1007,8 @@ static const struct usb_gadget_ops pxa25x_udc_ops = { .vbus_session = pxa25x_udc_vbus_session, .pullup = pxa25x_udc_pullup, .vbus_draw = pxa25x_udc_vbus_draw, - .start = pxa25x_start, - .stop = pxa25x_stop, + .udc_start = pxa25x_udc_start, + .udc_stop = pxa25x_udc_stop, }; /*-------------------------------------------------------------------------*/ @@ -1194,6 +1193,7 @@ static void udc_reinit(struct pxa25x_udc *dev) ep->stopped = 0; INIT_LIST_HEAD (&ep->queue); ep->pio_irqs = 0; + usb_ep_set_maxpacket_limit(&ep->ep, ep->ep.maxpacket); } /* the rest was statically initialized, and is read-only */ @@ -1256,58 +1256,25 @@ static void udc_enable (struct pxa25x_udc *dev) * disconnect is reported. then a host may connect again, or * the driver might get unbound. */ -static int pxa25x_start(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) +static int pxa25x_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) { - struct pxa25x_udc *dev = the_controller; + struct pxa25x_udc *dev = to_pxa25x(g); int retval; - if (!driver - || driver->max_speed < USB_SPEED_FULL - || !bind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - /* first hook up the driver ... */ dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; dev->pullup = 1; - retval = device_add (&dev->gadget.dev); - if (retval) { -fail: - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - retval = bind(&dev->gadget); - if (retval) { - DMSG("bind to driver %s --> error %d\n", - driver->driver.name, retval); - device_del (&dev->gadget.dev); - goto fail; - } - /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ - DMSG("registered gadget driver '%s'\n", driver->driver.name); - /* connect to bus through transceiver */ - if (dev->transceiver) { + if (!IS_ERR_OR_NULL(dev->transceiver)) { retval = otg_set_peripheral(dev->transceiver->otg, &dev->gadget); - if (retval) { - DMSG("can't bind to transceiver\n"); - if (driver->unbind) - driver->unbind(&dev->gadget); + if (retval) goto bind_fail; - } } pullup(dev); @@ -1344,14 +1311,10 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) udc_reinit(dev); } -static int pxa25x_stop(struct usb_gadget_driver *driver) +static int pxa25x_udc_stop(struct usb_gadget*g, + struct usb_gadget_driver *driver) { - struct pxa25x_udc *dev = the_controller; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; + struct pxa25x_udc *dev = to_pxa25x(g); local_irq_disable(); dev->pullup = 0; @@ -1359,17 +1322,13 @@ static int pxa25x_stop(struct usb_gadget_driver *driver) stop_activity(dev, driver); local_irq_enable(); - if (dev->transceiver) + if (!IS_ERR_OR_NULL(dev->transceiver)) (void) otg_set_peripheral(dev->transceiver->otg, NULL); - driver->unbind(&dev->gadget); - dev->gadget.dev.driver = NULL; dev->driver = NULL; - device_del (&dev->gadget.dev); - - DMSG("unregistered gadget driver '%s'\n", driver->driver.name); dump_state(dev); + return 0; } @@ -2096,12 +2055,14 @@ static struct pxa25x_udc memory = { /* * probe - binds to the platform device */ -static int __init pxa25x_udc_probe(struct platform_device *pdev) +static int pxa25x_udc_probe(struct platform_device *pdev) { struct pxa25x_udc *dev = &memory; int retval, irq; u32 chiprev; + pr_info("%s: version %s\n", driver_name, DRIVER_VERSION); + /* insist on Intel/ARM/XScale */ asm("mrc%? p15, 0, %0, c0, c0" : "=r" (chiprev)); if ((chiprev & CP15R0_VENDOR_MASK) != CP15R0_XSCALE_VALUE) { @@ -2157,9 +2118,9 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) /* other non-static parts of init */ dev->dev = &pdev->dev; - dev->mach = pdev->dev.platform_data; + dev->mach = dev_get_platdata(&pdev->dev); - dev->transceiver = usb_get_transceiver(); + dev->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); if (gpio_is_valid(dev->mach->gpio_pullup)) { if ((retval = gpio_request(dev->mach->gpio_pullup, @@ -2176,10 +2137,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->timer.function = udc_watchdog; dev->timer.data = (unsigned long) dev; - device_initialize(&dev->gadget.dev); - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - the_controller = dev; platform_set_drvdata(pdev, dev); @@ -2200,19 +2157,15 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_LUBBOCK if (machine_is_lubbock()) { - retval = request_irq(LUBBOCK_USB_DISC_IRQ, - lubbock_vbus_irq, - IRQF_SAMPLE_RANDOM, - driver_name, dev); + retval = request_irq(LUBBOCK_USB_DISC_IRQ, lubbock_vbus_irq, + 0, driver_name, dev); if (retval != 0) { pr_err("%s: can't get irq %i, err %d\n", driver_name, LUBBOCK_USB_DISC_IRQ, retval); goto err_irq_lub; } - retval = request_irq(LUBBOCK_USB_IRQ, - lubbock_vbus_irq, - IRQF_SAMPLE_RANDOM, - driver_name, dev); + retval = request_irq(LUBBOCK_USB_IRQ, lubbock_vbus_irq, + 0, driver_name, dev); if (retval != 0) { pr_err("%s: can't get irq %i, err %d\n", driver_name, LUBBOCK_USB_IRQ, retval); @@ -2237,8 +2190,8 @@ lubbock_fail0: if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: - if (dev->transceiver) { - usb_put_transceiver(dev->transceiver); + if (!IS_ERR_OR_NULL(dev->transceiver)) { + usb_put_phy(dev->transceiver); dev->transceiver = NULL; } clk_put(dev->clk); @@ -2251,14 +2204,14 @@ static void pxa25x_udc_shutdown(struct platform_device *_dev) pullup_off(); } -static int __exit pxa25x_udc_remove(struct platform_device *pdev) +static int pxa25x_udc_remove(struct platform_device *pdev) { struct pxa25x_udc *dev = platform_get_drvdata(pdev); - usb_del_gadget_udc(&dev->gadget); if (dev->driver) return -EBUSY; + usb_del_gadget_udc(&dev->gadget); dev->pullup = 0; pullup(dev); @@ -2279,12 +2232,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) clk_put(dev->clk); - if (dev->transceiver) { - usb_put_transceiver(dev->transceiver); + if (!IS_ERR_OR_NULL(dev->transceiver)) { + usb_put_phy(dev->transceiver); dev->transceiver = NULL; } - platform_set_drvdata(pdev, NULL); the_controller = NULL; return 0; } @@ -2343,7 +2295,8 @@ static int pxa25x_udc_resume(struct platform_device *dev) static struct platform_driver udc_driver = { .shutdown = pxa25x_udc_shutdown, - .remove = __exit_p(pxa25x_udc_remove), + .probe = pxa25x_udc_probe, + .remove = pxa25x_udc_remove, .suspend = pxa25x_udc_suspend, .resume = pxa25x_udc_resume, .driver = { @@ -2352,18 +2305,7 @@ static struct platform_driver udc_driver = { }, }; -static int __init udc_init(void) -{ - pr_info("%s: version %s\n", driver_name, DRIVER_VERSION); - return platform_driver_probe(&udc_driver, pxa25x_udc_probe); -} -module_init(udc_init); - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); +module_platform_driver(udc_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell"); |
