USB: pxa2xx_udc: use generic gpio layer
authorMilan Svoboda <msvoboda@ra.rockwell.com>
Sat, 30 Jun 2007 13:25:35 +0000 (06:25 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 12 Jul 2007 23:34:42 +0000 (16:34 -0700)
This patch lets the pxa2xx_udc use the generic gpio layer,
on the relevant PXA and IXP systems.

Signed-off-by: Milan Svoboda <msvoboda@ra.rockwell.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/pxa2xx_udc.c
include/asm-arm/arch-ixp4xx/udc.h
include/asm-arm/arch-pxa/udc.h

index 84392e8..c9ec0b3 100644 (file)
@@ -27,6 +27,7 @@
 #undef DEBUG
 // #define     VERBOSE DBG_VERBOSE
 
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 
 #include <asm/byteorder.h>
 #include <asm/dma.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <asm/unaligned.h>
 #include <asm/hardware.h>
-#ifdef CONFIG_ARCH_PXA
-#include <asm/arch/pxa-regs.h>
-#endif
 
 #include <linux/usb/ch9.h>
 #include <linux/usb_gadget.h>
 
-#include <asm/arch/udc.h>
+#include <asm/mach/udc_pxa2xx.h>
 
 
 /*
@@ -155,7 +154,7 @@ static int is_vbus_present(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_vbus)
-               return udc_gpio_get(mach->gpio_vbus);
+               return gpio_get_value(mach->gpio_vbus);
        if (mach->udc_is_connected)
                return mach->udc_is_connected();
        return 1;
@@ -167,7 +166,7 @@ static void pullup_off(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_pullup)
-               udc_gpio_set(mach->gpio_pullup, 0);
+               gpio_set_value(mach->gpio_pullup, 0);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
 }
@@ -177,7 +176,7 @@ static void pullup_on(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_pullup)
-               udc_gpio_set(mach->gpio_pullup, 1);
+               gpio_set_value(mach->gpio_pullup, 1);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
 }
@@ -1742,7 +1741,7 @@ lubbock_vbus_irq(int irq, void *_dev)
 static irqreturn_t udc_vbus_irq(int irq, void *_dev)
 {
        struct pxa2xx_udc       *dev = _dev;
-       int                     vbus = udc_gpio_get(dev->mach->gpio_vbus);
+       int                     vbus = gpio_get_value(dev->mach->gpio_vbus);
 
        pxa2xx_udc_vbus_session(&dev->gadget, vbus);
        return IRQ_HANDLED;
@@ -2535,14 +2534,33 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        /* other non-static parts of init */
        dev->dev = &pdev->dev;
        dev->mach = pdev->dev.platform_data;
+
        if (dev->mach->gpio_vbus) {
-               udc_gpio_init_vbus(dev->mach->gpio_vbus);
-               vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus);
+               if ((retval = gpio_request(dev->mach->gpio_vbus,
+                               "pxa2xx_udc GPIO VBUS"))) {
+                       dev_dbg(&pdev->dev,
+                               "can't get vbus gpio %d, err: %d\n",
+                               dev->mach->gpio_vbus, retval);
+                       return -EBUSY;
+               }
+               gpio_direction_input(dev->mach->gpio_vbus);
+               vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
                set_irq_type(vbus_irq, IRQT_BOTHEDGE);
        } else
                vbus_irq = 0;
-       if (dev->mach->gpio_pullup)
-               udc_gpio_init_pullup(dev->mach->gpio_pullup);
+
+       if (dev->mach->gpio_pullup) {
+               if ((retval = gpio_request(dev->mach->gpio_pullup,
+                               "pca2xx_udc GPIO PULLUP"))) {
+                       dev_dbg(&pdev->dev,
+                               "can't get pullup gpio %d, err: %d\n",
+                               dev->mach->gpio_pullup, retval);
+                       if (dev->mach->gpio_vbus)
+                               gpio_free(dev->mach->gpio_vbus);
+                       return -EBUSY;
+               }
+               gpio_direction_output(dev->mach->gpio_pullup, 0);
+       }
 
        init_timer(&dev->timer);
        dev->timer.function = udc_watchdog;
@@ -2566,6 +2584,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        if (retval != 0) {
                printk(KERN_ERR "%s: can't get irq %d, err %d\n",
                        driver_name, irq, retval);
+               if (dev->mach->gpio_pullup)
+                       gpio_free(dev->mach->gpio_pullup);
+               if (dev->mach->gpio_vbus)
+                       gpio_free(dev->mach->gpio_vbus);
                return -EBUSY;
        }
        dev->got_irq = 1;
@@ -2581,6 +2603,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
                                driver_name, LUBBOCK_USB_DISC_IRQ, retval);
 lubbock_fail0:
                        free_irq(irq, dev);
+                       if (dev->mach->gpio_pullup)
+                               gpio_free(dev->mach->gpio_pullup);
+                       if (dev->mach->gpio_vbus)
+                               gpio_free(dev->mach->gpio_vbus);
                        return -EBUSY;
                }
                retval = request_irq(LUBBOCK_USB_IRQ,
@@ -2608,6 +2634,10 @@ lubbock_fail0:
                        printk(KERN_ERR "%s: can't get irq %i, err %d\n",
                                driver_name, vbus_irq, retval);
                        free_irq(irq, dev);
+                       if (dev->mach->gpio_pullup)
+                               gpio_free(dev->mach->gpio_pullup);
+                       if (dev->mach->gpio_vbus)
+                               gpio_free(dev->mach->gpio_vbus);
                        return -EBUSY;
                }
        }
@@ -2641,8 +2671,13 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
                free_irq(LUBBOCK_USB_IRQ, dev);
        }
 #endif
-       if (dev->mach->gpio_vbus)
-               free_irq(IRQ_GPIO(dev->mach->gpio_vbus), dev);
+       if (dev->mach->gpio_vbus) {
+               free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
+               gpio_free(dev->mach->gpio_vbus);
+       }
+       if (dev->mach->gpio_pullup)
+               gpio_free(dev->mach->gpio_pullup);
+
        platform_set_drvdata(pdev, NULL);
        the_controller = NULL;
        return 0;
index 79b850a..dbdec36 100644 (file)
@@ -6,25 +6,3 @@
 
 extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
-static inline int udc_gpio_to_irq(unsigned gpio)
-{
-       return 0;
-}
-
-static inline void udc_gpio_init_vbus(unsigned gpio)
-{
-}
-
-static inline void udc_gpio_init_pullup(unsigned gpio)
-{
-}
-
-static inline int udc_gpio_get(unsigned gpio)
-{
-       return 0;
-}
-
-static inline void udc_gpio_set(unsigned gpio, int is_on)
-{
-}
-
index 8bc6f9c..27aa3a9 100644 (file)
@@ -1,41 +1,8 @@
 /*
  * linux/include/asm-arm/arch-pxa/udc.h
  *
- * This supports machine-specific differences in how the PXA2xx
- * USB Device Controller (UDC) is wired.
- *
  */
 #include <asm/mach/udc_pxa2xx.h>
 
 extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
-static inline int udc_gpio_to_irq(unsigned gpio)
-{
-       return IRQ_GPIO(gpio & GPIO_MD_MASK_NR);
-}
-
-static inline void udc_gpio_init_vbus(unsigned gpio)
-{
-       pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_IN);
-}
-
-static inline void udc_gpio_init_pullup(unsigned gpio)
-{
-       pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_OUT | GPIO_DFLT_LOW);
-}
-
-static inline int udc_gpio_get(unsigned gpio)
-{
-       return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
-}
-
-static inline void udc_gpio_set(unsigned gpio, int is_on)
-{
-       int mask = GPIO_bit(gpio);
-
-       if (is_on)
-               GPSR(gpio) = mask;
-       else
-               GPCR(gpio) = mask;
-}
-