usb: gadget: pxa27x_udc: prepare device-tree support
authorRobert Jarzmik <robert.jarzmik@free.fr>
Wed, 1 Oct 2014 20:06:14 +0000 (22:06 +0200)
committerFelipe Balbi <balbi@ti.com>
Mon, 3 Nov 2014 16:00:57 +0000 (10:00 -0600)
For this preparation, a preliminary cleanup is done :
  - convert the probing of pxa27x_udc to gpio_desc.
    The conversion is partial because :
     - the platform data still provides a gpio number, not a gpio desc

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/udc/pxa27x_udc.c
drivers/usb/gadget/udc/pxa27x_udc.h

index 4868369eeec662140637e121664cb1dacc9a4092..d58319765021856df1037c9a2f405b9b44e60a5c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/prefetch.h>
 #include <linux/byteorder/generic.h>
@@ -1507,17 +1508,12 @@ static struct usb_ep_ops pxa_ep_ops = {
  */
 static void dplus_pullup(struct pxa_udc *udc, int on)
 {
-       if (on) {
-               if (gpio_is_valid(udc->mach->gpio_pullup))
-                       gpio_set_value(udc->mach->gpio_pullup,
-                                      !udc->mach->gpio_pullup_inverted);
-               if (udc->mach->udc_command)
+       if (udc->gpiod) {
+               gpiod_set_value(udc->gpiod, on);
+       } else if (udc->mach && udc->mach->udc_command) {
+               if (on)
                        udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
-       } else {
-               if (gpio_is_valid(udc->mach->gpio_pullup))
-                       gpio_set_value(udc->mach->gpio_pullup,
-                                      udc->mach->gpio_pullup_inverted);
-               if (udc->mach->udc_command)
+               else
                        udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
        }
        udc->pullup_on = on;
@@ -1609,7 +1605,7 @@ static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
 {
        struct pxa_udc *udc = to_gadget_udc(_gadget);
 
-       if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
+       if (!udc->gpiod && !udc->mach->udc_command)
                return -EOPNOTSUPP;
 
        dplus_pullup(udc, is_active);
@@ -2416,6 +2412,22 @@ static int pxa_udc_probe(struct platform_device *pdev)
        struct resource *regs;
        struct pxa_udc *udc = &memory;
        int retval = 0, gpio;
+       struct pxa2xx_udc_mach_info *mach = dev_get_platdata(&pdev->dev);
+       unsigned long gpio_flags;
+
+       if (mach) {
+               gpio_flags = mach->gpio_pullup_inverted ? GPIOF_ACTIVE_LOW : 0;
+               gpio = mach->gpio_pullup;
+               if (gpio_is_valid(gpio)) {
+                       retval = devm_gpio_request_one(&pdev->dev, gpio,
+                                                      gpio_flags,
+                                                      "USB D+ pullup");
+                       if (retval)
+                               return retval;
+                       udc->gpiod = gpio_to_desc(mach->gpio_pullup);
+               }
+               udc->mach = mach;
+       }
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!regs)
@@ -2425,21 +2437,15 @@ static int pxa_udc_probe(struct platform_device *pdev)
                return udc->irq;
 
        udc->dev = &pdev->dev;
-       udc->mach = dev_get_platdata(&pdev->dev);
        udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 
-       gpio = udc->mach->gpio_pullup;
-       if (gpio_is_valid(gpio)) {
-               retval = gpio_request(gpio, "USB D+ pullup");
-               if (retval == 0)
-                       gpio_direction_output(gpio,
-                                      udc->mach->gpio_pullup_inverted);
-       }
-       if (retval) {
-               dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n",
-                       gpio, retval);
-               return retval;
+       if (IS_ERR(udc->gpiod)) {
+               dev_err(&pdev->dev, "Couldn't find or request D+ gpio : %ld\n",
+                       PTR_ERR(udc->gpiod));
+               return PTR_ERR(udc->gpiod);
        }
+       if (udc->gpiod)
+               gpiod_direction_output(udc->gpiod, 0);
 
        udc->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(udc->clk)) {
@@ -2501,14 +2507,11 @@ err_clk:
 static int pxa_udc_remove(struct platform_device *_dev)
 {
        struct pxa_udc *udc = platform_get_drvdata(_dev);
-       int gpio = udc->mach->gpio_pullup;
 
        usb_del_gadget_udc(&udc->gadget);
        usb_gadget_unregister_driver(udc->driver);
        free_irq(udc->irq, udc);
        pxa_cleanup_debugfs(udc);
-       if (gpio_is_valid(gpio))
-               gpio_free(gpio);
 
        usb_put_phy(udc->transceiver);
 
index 28f2b53530f57b7e3c54bb01ba29b6a336ad48e0..f02569324ee68c2d68d29523c15a62aeae11b7a4 100644 (file)
@@ -421,6 +421,7 @@ struct udc_stats {
  * @driver: bound gadget (zero, g_ether, g_mass_storage, ...)
  * @dev: device
  * @mach: machine info, used to activate specific GPIO
+ * @gpiod: gpio descriptor of gpio for D+ pullup (or NULL if none)
  * @transceiver: external transceiver to handle vbus sense and D+ pullup
  * @ep0state: control endpoint state machine state
  * @stats: statistics on udc usage
@@ -447,6 +448,7 @@ struct pxa_udc {
        struct usb_gadget_driver                *driver;
        struct device                           *dev;
        struct pxa2xx_udc_mach_info             *mach;
+       struct gpio_desc                        *gpiod;
        struct usb_phy                          *transceiver;
 
        enum ep0_state                          ep0state;