gadget: struct device - replace bus_id with dev_name(), dev_set_name()
[safe/jmp/linux-2.6] / drivers / usb / gadget / at91_udc.c
index 36b36e0..0b2bb8f 100644 (file)
@@ -21,8 +21,7 @@
  * Boston, MA  02111-1307, USA.
  */
 
-#undef DEBUG
-#undef VERBOSE
+#undef VERBOSE_DEBUG
 #undef PACKET_TRACE
 
 #include <linux/kernel.h>
@@ -31,7 +30,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
 #include <linux/clk.h>
 #include <linux/usb/ch9.h>
-#include <linux/usb_gadget.h>
+#include <linux/usb/gadget.h>
 
 #include <asm/byteorder.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/mach-types.h>
+#include <asm/gpio.h>
 
-#include <asm/arch/gpio.h>
-#include <asm/arch/board.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/at91sam9261_matrix.h>
+#include <mach/board.h>
+#include <mach/cpu.h>
+#include <mach/at91sam9261_matrix.h>
 
 #include "at91_udc.h"
 
@@ -233,6 +230,7 @@ static int proc_udc_open(struct inode *inode, struct file *file)
 }
 
 static const struct file_operations proc_ops = {
+       .owner          = THIS_MODULE,
        .open           = proc_udc_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@ -241,15 +239,7 @@ static const struct file_operations proc_ops = {
 
 static void create_debug_file(struct at91_udc *udc)
 {
-       struct proc_dir_entry *pde;
-
-       pde = create_proc_entry (debug_filename, 0, NULL);
-       udc->pde = pde;
-       if (pde == NULL)
-               return;
-
-       pde->proc_fops = &proc_ops;
-       pde->data = udc;
+       udc->pde = proc_create_data(debug_filename, 0, NULL, &proc_ops, udc);
 }
 
 static void remove_debug_file(struct at91_udc *udc)
@@ -391,6 +381,7 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req)
        u32             csr = __raw_readl(creg);
        u8 __iomem      *dreg = ep->creg + (AT91_UDP_FDR(0) - AT91_UDP_CSR(0));
        unsigned        total, count, is_last;
+       u8              *buf;
 
        /*
         * TODO: allow for writing two packets to the fifo ... that'll
@@ -415,6 +406,8 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req)
                        return 0;
        }
 
+       buf = req->req.buf + req->req.actual;
+       prefetch(buf);
        total = req->req.length - req->req.actual;
        if (ep->ep.maxpacket < total) {
                count = ep->ep.maxpacket;
@@ -437,7 +430,7 @@ static int write_fifo(struct at91_ep *ep, struct at91_request *req)
         * recover when the actual bytecount matters (e.g. for USB Test
         * and Measurement Class devices).
         */
-       __raw_writesb(dreg, req->req.buf + req->req.actual, count);
+       __raw_writesb(dreg, buf, count);
        csr &= ~SET_FX;
        csr |= CLR_FX | AT91_UDP_TXPKTRDY;
        __raw_writel(csr, creg);
@@ -459,7 +452,7 @@ static void nuke(struct at91_ep *ep, int status)
        if (list_empty(&ep->queue))
                return;
 
-       VDBG("%s %s\n", __FUNCTION__, ep->ep.name);
+       VDBG("%s %s\n", __func__, ep->ep.name);
        while (!list_empty(&ep->queue)) {
                req = list_entry(ep->queue.next, struct at91_request, queue);
                done(ep, req, status);
@@ -581,7 +574,7 @@ static int at91_ep_disable (struct usb_ep * _ep)
  */
 
 static struct usb_request *
-at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
+at91_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
 {
        struct at91_request *req;
 
@@ -602,25 +595,6 @@ static void at91_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
        kfree(req);
 }
 
-static void *at91_ep_alloc_buffer(
-       struct usb_ep *_ep,
-       unsigned bytes,
-       dma_addr_t *dma,
-       gfp_t gfp_flags)
-{
-       *dma = ~0;
-       return kmalloc(bytes, gfp_flags);
-}
-
-static void at91_ep_free_buffer(
-       struct usb_ep *ep,
-       void *buf,
-       dma_addr_t dma,
-       unsigned bytes)
-{
-       kfree(buf);
-}
-
 static int at91_ep_queue(struct usb_ep *_ep,
                        struct usb_request *_req, gfp_t gfp_flags)
 {
@@ -784,13 +758,11 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
        return status;
 }
 
-static struct usb_ep_ops at91_ep_ops = {
+static const struct usb_ep_ops at91_ep_ops = {
        .enable         = at91_ep_enable,
        .disable        = at91_ep_disable,
        .alloc_request  = at91_ep_alloc_request,
        .free_request   = at91_ep_free_request,
-       .alloc_buffer   = at91_ep_alloc_buffer,
-       .free_buffer    = at91_ep_free_buffer,
        .queue          = at91_ep_queue,
        .dequeue        = at91_ep_dequeue,
        .set_halt       = at91_ep_set_halt,
@@ -815,7 +787,7 @@ static int at91_wakeup(struct usb_gadget *gadget)
        int             status = -EINVAL;
        unsigned long   flags;
 
-       DBG("%s\n", __FUNCTION__ );
+       DBG("%s\n", __func__ );
        local_irq_save(flags);
 
        if (!udc->clocked || !udc->suspended)
@@ -903,16 +875,19 @@ static void clk_off(struct at91_udc *udc)
  */
 static void pullup(struct at91_udc *udc, int is_on)
 {
+       int     active = !udc->board.pullup_active_low;
+
        if (!udc->enabled || !udc->vbus)
                is_on = 0;
        DBG("%sactive\n", is_on ? "" : "in");
 
        if (is_on) {
                clk_on(udc);
+               at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
                at91_udp_write(udc, AT91_UDP_TXVC, 0);
                if (cpu_is_at91rm9200())
-                       at91_set_gpio_value(udc->board.pullup_pin, 1);
-               else if (cpu_is_at91sam9260()) {
+                       gpio_set_value(udc->board.pullup_pin, active);
+               else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
                        u32     txvc = at91_udp_read(udc, AT91_UDP_TXVC);
 
                        txvc |= AT91_UDP_TXVC_PUON;
@@ -926,10 +901,11 @@ static void pullup(struct at91_udc *udc, int is_on)
                }
        } else {
                stop_activity(udc);
+               at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
                at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
                if (cpu_is_at91rm9200())
-                       at91_set_gpio_value(udc->board.pullup_pin, 0);
-               else if (cpu_is_at91sam9260()) {
+                       gpio_set_value(udc->board.pullup_pin, !active);
+               else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
                        u32     txvc = at91_udp_read(udc, AT91_UDP_TXVC);
 
                        txvc &= ~AT91_UDP_TXVC_PUON;
@@ -1173,7 +1149,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
                        | USB_REQ_GET_STATUS:
                tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
                ep = &udc->ep[tmp];
-               if (tmp > NUM_ENDPOINTS || (tmp && !ep->desc))
+               if (tmp >= NUM_ENDPOINTS || (tmp && !ep->desc))
                        goto stall;
 
                if (tmp) {
@@ -1196,7 +1172,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
                        | USB_REQ_SET_FEATURE:
                tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
                ep = &udc->ep[tmp];
-               if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS)
+               if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS)
                        goto stall;
                if (!ep->desc || ep->is_iso)
                        goto stall;
@@ -1215,7 +1191,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
                        | USB_REQ_CLEAR_FEATURE:
                tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
                ep = &udc->ep[tmp];
-               if (w_value != USB_ENDPOINT_HALT || tmp > NUM_ENDPOINTS)
+               if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS)
                        goto stall;
                if (tmp == 0)
                        goto succeed;
@@ -1498,7 +1474,7 @@ static struct at91_udc controller = {
                .ep0    = &controller.ep[0].ep,
                .name   = driver_name,
                .dev    = {
-                       .bus_id = "gadget",
+                       .init_name = "gadget",
                        .release = nop_release,
                }
        },
@@ -1571,7 +1547,7 @@ static irqreturn_t at91_vbus_irq(int irq, void *_udc)
 
        /* vbus needs at least brief debouncing */
        udelay(10);
-       value = at91_get_gpio_value(udc->board.vbus_pin);
+       value = gpio_get_value(udc->board.vbus_pin);
        if (value != udc->vbus)
                at91_vbus_session(&udc->gadget, value);
 
@@ -1636,6 +1612,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
        local_irq_enable();
 
        driver->unbind(&udc->gadget);
+       udc->gadget.dev.driver = NULL;
+       udc->gadget.dev.driver_data = NULL;
        udc->driver = NULL;
 
        DBG("unbound from %s\n", driver->driver.name);
@@ -1651,7 +1629,7 @@ static void at91udc_shutdown(struct platform_device *dev)
        pullup(platform_get_drvdata(dev), 0);
 }
 
-static int __devinit at91udc_probe(struct platform_device *pdev)
+static int __init at91udc_probe(struct platform_device *pdev)
 {
        struct device   *dev = &pdev->dev;
        struct at91_udc *udc;
@@ -1665,12 +1643,12 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
        }
 
        if (pdev->num_resources != 2) {
-               DBG("invalid num_resources");
+               DBG("invalid num_resources\n");
                return -ENODEV;
        }
        if ((pdev->resource[0].flags != IORESOURCE_MEM)
                        || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
-               DBG("invalid resource type");
+               DBG("invalid resource type\n");
                return -ENODEV;
        }
 
@@ -1692,10 +1670,39 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
        udc->pdev = pdev;
        udc->enabled = 0;
 
+       /* rm9200 needs manual D+ pullup; off by default */
+       if (cpu_is_at91rm9200()) {
+               if (udc->board.pullup_pin <= 0) {
+                       DBG("no D+ pullup?\n");
+                       retval = -ENODEV;
+                       goto fail0;
+               }
+               retval = gpio_request(udc->board.pullup_pin, "udc_pullup");
+               if (retval) {
+                       DBG("D+ pullup is busy\n");
+                       goto fail0;
+               }
+               gpio_direction_output(udc->board.pullup_pin,
+                               udc->board.pullup_active_low);
+       }
+
+       /* newer chips have more FIFO memory than rm9200 */
+       if (cpu_is_at91sam9260()) {
+               udc->ep[0].maxpacket = 64;
+               udc->ep[3].maxpacket = 64;
+               udc->ep[4].maxpacket = 512;
+               udc->ep[5].maxpacket = 512;
+       } else if (cpu_is_at91sam9261()) {
+               udc->ep[3].maxpacket = 64;
+       } else if (cpu_is_at91sam9263()) {
+               udc->ep[0].maxpacket = 64;
+               udc->ep[3].maxpacket = 64;
+       }
+
        udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1);
        if (!udc->udp_baseaddr) {
-               release_mem_region(res->start, res->end - res->start + 1);
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto fail0a;
        }
 
        udc_reinit(udc);
@@ -1706,12 +1713,13 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
        if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) {
                DBG("clocks missing\n");
                retval = -ENODEV;
-               goto fail0;
+               /* NOTE: we "know" here that refcounts on these are NOPs */
+               goto fail0b;
        }
 
        retval = device_register(&udc->gadget.dev);
        if (retval < 0)
-               goto fail0;
+               goto fail0b;
 
        /* don't do anything until we have both gadget driver and VBUS */
        clk_enable(udc->iclk);
@@ -1723,25 +1731,32 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
 
        /* request UDC and maybe VBUS irqs */
        udc->udp_irq = platform_get_irq(pdev, 0);
-       if (request_irq(udc->udp_irq, at91_udc_irq,
-                       IRQF_DISABLED, driver_name, udc)) {
+       retval = request_irq(udc->udp_irq, at91_udc_irq,
+                       IRQF_DISABLED, driver_name, udc);
+       if (retval < 0) {
                DBG("request irq %d failed\n", udc->udp_irq);
-               retval = -EBUSY;
                goto fail1;
        }
        if (udc->board.vbus_pin > 0) {
+               retval = gpio_request(udc->board.vbus_pin, "udc_vbus");
+               if (retval < 0) {
+                       DBG("request vbus pin failed\n");
+                       goto fail2;
+               }
+               gpio_direction_input(udc->board.vbus_pin);
+
                /*
                 * Get the initial state of VBUS - we cannot expect
                 * a pending interrupt.
                 */
-               udc->vbus = at91_get_gpio_value(udc->board.vbus_pin);
+               udc->vbus = gpio_get_value(udc->board.vbus_pin);
                if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
                                IRQF_DISABLED, driver_name, udc)) {
                        DBG("request vbus irq %d failed\n",
                                        udc->board.vbus_pin);
                        free_irq(udc->udp_irq, udc);
                        retval = -EBUSY;
-                       goto fail1;
+                       goto fail3;
                }
        } else {
                DBG("no VBUS detection, assuming always-on\n");
@@ -1754,15 +1769,25 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
        INFO("%s version %s\n", driver_name, DRIVER_VERSION);
        return 0;
 
+fail3:
+       if (udc->board.vbus_pin > 0)
+               gpio_free(udc->board.vbus_pin);
+fail2:
+       free_irq(udc->udp_irq, udc);
 fail1:
        device_unregister(&udc->gadget.dev);
+fail0b:
+       iounmap(udc->udp_baseaddr);
+fail0a:
+       if (cpu_is_at91rm9200())
+               gpio_free(udc->board.pullup_pin);
 fail0:
        release_mem_region(res->start, res->end - res->start + 1);
        DBG("%s probe failed, %d\n", driver_name, retval);
        return retval;
 }
 
-static int __devexit at91udc_remove(struct platform_device *pdev)
+static int __exit at91udc_remove(struct platform_device *pdev)
 {
        struct at91_udc *udc = platform_get_drvdata(pdev);
        struct resource *res;
@@ -1776,12 +1801,18 @@ static int __devexit at91udc_remove(struct platform_device *pdev)
 
        device_init_wakeup(&pdev->dev, 0);
        remove_debug_file(udc);
-       if (udc->board.vbus_pin > 0)
+       if (udc->board.vbus_pin > 0) {
                free_irq(udc->board.vbus_pin, udc);
+               gpio_free(udc->board.vbus_pin);
+       }
        free_irq(udc->udp_irq, udc);
        device_unregister(&udc->gadget.dev);
 
        iounmap(udc->udp_baseaddr);
+
+       if (cpu_is_at91rm9200())
+               gpio_free(udc->board.pullup_pin);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(res->start, res->end - res->start + 1);
 
@@ -1835,9 +1866,8 @@ static int at91udc_resume(struct platform_device *pdev)
 #define        at91udc_resume  NULL
 #endif
 
-static struct platform_driver at91_udc = {
-       .probe          = at91udc_probe,
-       .remove         = __devexit_p(at91udc_remove),
+static struct platform_driver at91_udc_driver = {
+       .remove         = __exit_p(at91udc_remove),
        .shutdown       = at91udc_shutdown,
        .suspend        = at91udc_suspend,
        .resume         = at91udc_resume,
@@ -1847,18 +1877,19 @@ static struct platform_driver at91_udc = {
        },
 };
 
-static int __devinit udc_init_module(void)
+static int __init udc_init_module(void)
 {
-       return platform_driver_register(&at91_udc);
+       return platform_driver_probe(&at91_udc_driver, at91udc_probe);
 }
 module_init(udc_init_module);
 
-static void __devexit udc_exit_module(void)
+static void __exit udc_exit_module(void)
 {
-       platform_driver_unregister(&at91_udc);
+       platform_driver_unregister(&at91_udc_driver);
 }
 module_exit(udc_exit_module);
 
 MODULE_DESCRIPTION("AT91 udc driver");
 MODULE_AUTHOR("Thomas Rathbone, David Brownell");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_udc");