Patch abstracts and moves common USB OHCI platform setup code of da8xx
based boards to mach-davinci/usb.c file, thereby it avoids repetition of
code.
Patch is based on consolidation concern raised by Sekhar Nori.
https://lkml.org/lkml/2011/12/21/48

Signed-off-by: Manjunathappa, Prakash <[email protected]>
---
 arch/arm/mach-davinci/board-da830-evm.c     |   86 +++-----------------
 arch/arm/mach-davinci/board-omapl138-hawk.c |   93 +++-------------------
 arch/arm/mach-davinci/include/mach/da8xx.h  |    2 +
 arch/arm/mach-davinci/include/mach/usb.h    |   32 +++++++-
 arch/arm/mach-davinci/usb.c                 |  116 +++++++++++++++++++++++++++
 drivers/usb/host/ohci-da8xx.c               |   15 ++--
 6 files changed, 178 insertions(+), 166 deletions(-)

diff --git a/arch/arm/mach-davinci/board-da830-evm.c 
b/arch/arm/mach-davinci/board-da830-evm.c
index dc1afe5..edc8277 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -46,59 +46,23 @@ static const short da830_evm_usb11_pins[] = {
        -1
 };
 
-static da8xx_ocic_handler_t da830_evm_usb_ocic_handler;
-
-static int da830_evm_usb_set_power(unsigned port, int on)
-{
-       gpio_set_value(ON_BD_USB_DRV, on);
-       return 0;
-}
-
-static int da830_evm_usb_get_power(unsigned port)
-{
-       return gpio_get_value(ON_BD_USB_DRV);
-}
-
-static int da830_evm_usb_get_oci(unsigned port)
-{
-       return !gpio_get_value(ON_BD_USB_OVC);
-}
-
 static irqreturn_t da830_evm_usb_ocic_irq(int, void *);
 
-static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
-{
-       int irq         = gpio_to_irq(ON_BD_USB_OVC);
-       int error       = 0;
-
-       if (handler != NULL) {
-               da830_evm_usb_ocic_handler = handler;
-
-               error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
-                                   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                                   "OHCI over-current indicator", NULL);
-               if (error)
-                       printk(KERN_ERR "%s: could not request IRQ to watch "
-                              "over-current indicator changes\n", __func__);
-       } else
-               free_irq(irq, NULL);
-
-       return error;
-}
-
 static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
-       .set_power      = da830_evm_usb_set_power,
-       .get_power      = da830_evm_usb_get_power,
-       .get_oci        = da830_evm_usb_get_oci,
-       .ocic_notify    = da830_evm_usb_ocic_notify,
-
-       /* TPS2065 switch @ 5V */
-       .potpgt         = (3 + 1) / 2,  /* 3 ms max */
+       .type                   = GPIO_BASED,
+       .method = {
+               .gpio_method = {
+                       .power_control_pin      = ON_BD_USB_DRV,
+                       .over_current_indicator = ON_BD_USB_OVC,
+               },
+       },
+       .board_ocic_handler     = da830_evm_usb_ocic_irq,
 };
 
-static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
+static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *handler)
 {
-       da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1);
+       if (handler != NULL)
+               ((da8xx_ocic_handler_t)handler)(&da830_evm_usb11_pdata, 1);
        return IRQ_HANDLED;
 }
 
@@ -156,33 +120,7 @@ static __init void da830_evm_usb_init(void)
                                   __func__, ret);
        }
 
-       ret = davinci_cfg_reg_list(da830_evm_usb11_pins);
-       if (ret) {
-               pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
-                          __func__, ret);
-               return;
-       }
-
-       ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
-       if (ret) {
-               printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
-                      "power control: %d\n", __func__, ret);
-               return;
-       }
-       gpio_direction_output(ON_BD_USB_DRV, 0);
-
-       ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
-       if (ret) {
-               printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
-                      "over-current indicator: %d\n", __func__, ret);
-               return;
-       }
-       gpio_direction_input(ON_BD_USB_OVC);
-
-       ret = da8xx_register_usb11(&da830_evm_usb11_pdata);
-       if (ret)
-               pr_warning("%s: USB 1.1 registration failed: %d\n",
-                          __func__, ret);
+       da8xx_board_usb_init(da830_evm_usb11_pins, &da830_evm_usb11_pdata);
 }
 
 static struct davinci_uart_config da830_evm_uart_config __initdata = {
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c 
b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 45e8157..9214923 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -184,77 +184,34 @@ mmc_setup_wp_fail:
 }
 
 static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
-static da8xx_ocic_handler_t hawk_usb_ocic_handler;
 
 static const short da850_hawk_usb11_pins[] = {
        DA850_GPIO2_4, DA850_GPIO6_13,
        -1
 };
 
-static int hawk_usb_set_power(unsigned port, int on)
-{
-       gpio_set_value(DA850_USB1_VBUS_PIN, on);
-       return 0;
-}
-
-static int hawk_usb_get_power(unsigned port)
-{
-       return gpio_get_value(DA850_USB1_VBUS_PIN);
-}
-
-static int hawk_usb_get_oci(unsigned port)
-{
-       return !gpio_get_value(DA850_USB1_OC_PIN);
-}
-
-static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
-{
-       int irq         = gpio_to_irq(DA850_USB1_OC_PIN);
-       int error       = 0;
-
-       if (handler != NULL) {
-               hawk_usb_ocic_handler = handler;
-
-               error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
-                                       IRQF_DISABLED | IRQF_TRIGGER_RISING |
-                                       IRQF_TRIGGER_FALLING,
-                                       "OHCI over-current indicator", NULL);
-               if (error)
-                       pr_err("%s: could not request IRQ to watch "
-                               "over-current indicator changes\n", __func__);
-       } else {
-               free_irq(irq, NULL);
-       }
-       return error;
-}
-
 static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
-       .set_power      = hawk_usb_set_power,
-       .get_power      = hawk_usb_get_power,
-       .get_oci        = hawk_usb_get_oci,
-       .ocic_notify    = hawk_usb_ocic_notify,
-       /* TPS2087 switch @ 5V */
-       .potpgt         = (3 + 1) / 2,  /* 3 ms max */
+       .type   = GPIO_BASED,
+       .method = {
+               .gpio_method = {
+                       .power_control_pin      = DA850_USB1_VBUS_PIN,
+                       .over_current_indicator = DA850_USB1_OC_PIN,
+               },
+       },
+       .board_ocic_handler     = omapl138_hawk_usb_ocic_irq,
 };
 
-static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
+static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *handler)
 {
-       hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1);
+       if (handler != NULL)
+               ((da8xx_ocic_handler_t)handler)(&omapl138_hawk_usb11_pdata, 1);
        return IRQ_HANDLED;
 }
 
 static __init void omapl138_hawk_usb_init(void)
 {
-       int ret;
        u32 cfgchip2;
 
-       ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
-       if (ret) {
-               pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
-                       __func__, ret);
-               return;
-       }
-
        /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */
 
        cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
@@ -262,35 +219,9 @@ static __init void omapl138_hawk_usb_init(void)
        cfgchip2 |=  CFGCHIP2_REFFREQ_24MHZ;
        __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
 
-       ret = gpio_request_one(DA850_USB1_VBUS_PIN,
-                       GPIOF_DIR_OUT, "USB1 VBUS");
-       if (ret < 0) {
-               pr_err("%s: failed to request GPIO for USB 1.1 port "
-                       "power control: %d\n", __func__, ret);
-               return;
-       }
-
-       ret = gpio_request_one(DA850_USB1_OC_PIN,
-                       GPIOF_DIR_IN, "USB1 OC");
-       if (ret < 0) {
-               pr_err("%s: failed to request GPIO for USB 1.1 port "
-                       "over-current indicator: %d\n", __func__, ret);
-               goto usb11_setup_oc_fail;
-       }
-
-       ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
-       if (ret) {
-               pr_warning("%s: USB 1.1 registration failed: %d\n",
-                       __func__, ret);
-               goto usb11_setup_fail;
-       }
+       da8xx_board_usb_init(da850_hawk_usb11_pins, &omapl138_hawk_usb11_pdata);
 
        return;
-
-usb11_setup_fail:
-       gpio_free(DA850_USB1_OC_PIN);
-usb11_setup_oc_fail:
-       gpio_free(DA850_USB1_VBUS_PIN);
 }
 
 static struct davinci_uart_config omapl138_hawk_uart_config __initdata = {
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h 
b/arch/arm/mach-davinci/include/mach/da8xx.h
index ee3461d..691e1cc 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -78,6 +78,8 @@ int da850_register_edma(struct edma_rsv_info *rsv[2]);
 int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
 int da8xx_register_spi(int instance, struct spi_board_info *info, unsigned 
len);
 int da8xx_register_watchdog(void);
+void __init da8xx_board_usb_init(const short pins[],
+               struct da8xx_ohci_root_hub *usb11_pdata);
 int da8xx_register_usb20(unsigned mA, unsigned potpgt);
 int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
 int da8xx_register_emac(void);
diff --git a/arch/arm/mach-davinci/include/mach/usb.h 
b/arch/arm/mach-davinci/include/mach/usb.h
index e0bc4ab..1a6f211 100644
--- a/arch/arm/mach-davinci/include/mach/usb.h
+++ b/arch/arm/mach-davinci/include/mach/usb.h
@@ -11,6 +11,8 @@
 #ifndef __ASM_ARCH_USB_H
 #define __ASM_ARCH_USB_H
 
+#include <linux/interrupt.h>
+
 /* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */
 #define CFGCHIP2_PHYCLKGD      (1 << 17)
 #define CFGCHIP2_VBUSSENSE     (1 << 16)
@@ -33,25 +35,47 @@
 #define CFGCHIP2_REFFREQ_12MHZ (1 << 0)
 #define CFGCHIP2_REFFREQ_24MHZ (2 << 0)
 #define CFGCHIP2_REFFREQ_48MHZ (3 << 0)
+enum usb_power_n_ovc_method {
+       GPIO_BASED = 1,
+};
 
 struct da8xx_ohci_root_hub;
 
 typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
                                     unsigned port);
 
+struct gpio_based {
+       u32 power_control_pin;
+       u32 over_current_indicator;
+};
+
 /* Passed as the platform data to the OHCI driver */
 struct da8xx_ohci_root_hub {
        /* Switch the port power on/off */
-       int     (*set_power)(unsigned port, int on);
+       int     (*set_power)(unsigned port, struct da8xx_ohci_root_hub *hub,
+                       int on);
        /* Read the port power status */
-       int     (*get_power)(unsigned port);
+       int     (*get_power)(unsigned port, struct da8xx_ohci_root_hub *hub);
        /* Read the port over-current indicator */
-       int     (*get_oci)(unsigned port);
+       int     (*get_oci)(unsigned port, struct da8xx_ohci_root_hub *hub);
        /* Over-current indicator change notification (pass NULL to disable) */
-       int     (*ocic_notify)(da8xx_ocic_handler_t handler);
+       int     (*ocic_notify)(da8xx_ocic_handler_t handler,
+                       struct da8xx_ohci_root_hub *hub);
 
        /* Time from power on to power good (in 2 ms units) */
        u8      potpgt;
+
+       /* Power control and over current control method */
+       unsigned int type;
+       union power_n_overcurrent_pins {
+               struct gpio_based gpio_method;
+               /* Add data pertaining other methods here. For example if its
+                * I2C based.
+                */
+       } method;
+
+       /* board specific handler */
+       irq_handler_t board_ocic_handler;
 };
 
 void davinci_setup_usb(unsigned mA, unsigned potpgt_ms);
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
index 23d2b6d..25c3520 100644
--- a/arch/arm/mach-davinci/usb.c
+++ b/arch/arm/mach-davinci/usb.c
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 
 #include <linux/usb/musb.h>
 
@@ -11,12 +12,70 @@
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/usb.h>
+#include <mach/mux.h>
 
 #define DAVINCI_USB_OTG_BASE   0x01c64000
 
 #define DA8XX_USB0_BASE        0x01e00000
 #define DA8XX_USB1_BASE        0x01e25000
 
+static int da8xx_usb_set_power(unsigned port, struct da8xx_ohci_root_hub *hub,
+               int on)
+{
+       struct gpio_based *gpio = (hub->type == GPIO_BASED) ?
+               &hub->method.gpio_method : NULL;
+
+       if (hub->type == GPIO_BASED)
+               gpio_set_value(gpio->power_control_pin, on);
+       return 0;
+}
+
+static int da8xx_usb_get_power(unsigned port, struct da8xx_ohci_root_hub *hub)
+{
+       struct gpio_based *gpio = (hub->type == GPIO_BASED) ?
+               &hub->method.gpio_method : NULL;
+
+       if (hub->type == GPIO_BASED)
+               return gpio_get_value(gpio->power_control_pin);
+       return 0;
+}
+
+static int da8xx_usb_get_oci(unsigned port, struct da8xx_ohci_root_hub *hub)
+{
+       struct gpio_based *gpio = (hub->type == GPIO_BASED) ?
+               &hub->method.gpio_method : NULL;
+
+       if (hub->type == GPIO_BASED)
+               return !gpio_get_value(gpio->over_current_indicator);
+       return 0;
+}
+
+static int da8xx_usb_ocic_notify(da8xx_ocic_handler_t handler,
+               struct da8xx_ohci_root_hub *hub)
+{
+       int irq         = -1;
+       int error       = 0;
+       struct gpio_based *gpio = (hub->type == GPIO_BASED) ?
+               &hub->method.gpio_method : NULL;
+
+       if (hub->type == GPIO_BASED)
+               irq = gpio_to_irq(gpio->over_current_indicator);
+
+       if (handler != NULL) {
+
+               error = request_irq(irq, hub->board_ocic_handler,
+                                       IRQF_TRIGGER_RISING |
+                                       IRQF_TRIGGER_FALLING,
+                                       "OHCI over-current indicator", handler);
+               if (error)
+                       pr_err("%s: could not request IRQ to watch "
+                               "over-current indicator changes\n", __func__);
+       } else {
+               free_irq(irq, NULL);
+       }
+       return error;
+}
+
 #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
 static struct musb_hdrc_eps_bits musb_eps[] = {
        { "ep1_tx", 8, },
@@ -177,4 +236,61 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub 
*pdata)
        da8xx_usb11_device.dev.platform_data = pdata;
        return platform_device_register(&da8xx_usb11_device);
 }
+
+void __init da8xx_board_usb_init(const short pins[],
+               struct da8xx_ohci_root_hub *usb11_pdata)
+{
+       int ret;
+       struct gpio_based *gpio = (usb11_pdata->type == GPIO_BASED) ?
+               &usb11_pdata->method.gpio_method : NULL;
+
+       ret = davinci_cfg_reg_list(pins);
+       if (ret) {
+               pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+                          __func__, ret);
+               return;
+       }
+
+       if (usb11_pdata->type == GPIO_BASED) {
+
+               ret = gpio_request_one(gpio->power_control_pin,
+                               GPIOF_OUT_INIT_LOW, "ON_BD_USB_DRV");
+               if (ret) {
+                       pr_err("%s: failed to request GPIO for USB 1.1 port "
+                              "power control: %d\n", __func__, ret);
+                       return;
+               }
+
+               ret = gpio_request_one(gpio->over_current_indicator, GPIOF_IN,
+                               "ON_BD_USB_OVC");
+               if (ret) {
+                       pr_err("%s: failed to request GPIO for USB 1.1 port "
+                              "over-current indicator: %d\n", __func__, ret);
+                       goto usb11_setup_oc_fail;
+               }
+       }
+
+       usb11_pdata->set_power = da8xx_usb_set_power;
+       usb11_pdata->get_power = da8xx_usb_get_power;
+       usb11_pdata->get_oci = da8xx_usb_get_oci;
+       usb11_pdata->ocic_notify = da8xx_usb_ocic_notify;
+       /* TPS2087 switch @ 5V */
+       usb11_pdata->potpgt = (3 + 1) / 2;
+
+       ret = da8xx_register_usb11(usb11_pdata);
+       if (ret) {
+               pr_warning("%s: USB 1.1 registration failed: %d\n",
+                          __func__, ret);
+               goto usb11_setup_fail;
+       }
+
+       return;
+
+usb11_setup_fail:
+       if (usb11_pdata->type == GPIO_BASED)
+               gpio_free(gpio->over_current_indicator);
+usb11_setup_oc_fail:
+       if (usb11_pdata->type == GPIO_BASED)
+               gpio_free(gpio->power_control_pin);
+}
 #endif /* CONFIG_DAVINCI_DA8XX */
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 8435097..b3e2413 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -78,8 +78,8 @@ static void ohci_da8xx_ocic_handler(struct 
da8xx_ohci_root_hub *hub,
        ocic_mask |= 1 << port;
 
        /* Once over-current is detected, the port needs to be powered down */
-       if (hub->get_oci(port) > 0)
-               hub->set_power(port, 0);
+       if (hub->get_oci(port, hub) > 0)
+               hub->set_power(port, hub, 0);
 }
 
 static int ohci_da8xx_init(struct usb_hcd *hcd)
@@ -185,11 +185,11 @@ static int ohci_da8xx_hub_control(struct usb_hcd *hcd, 
u16 typeReq, u16 wValue,
                temp = roothub_portstatus(hcd_to_ohci(hcd), wIndex - 1);
 
                /* The port power status (PPS) bit defaults to 1 */
-               if (hub->get_power && hub->get_power(wIndex) == 0)
+               if (hub->get_power && hub->get_power(wIndex, hub) == 0)
                        temp &= ~RH_PS_PPS;
 
                /* The port over-current indicator (POCI) bit is always 0 */
-               if (hub->get_oci && hub->get_oci(wIndex) > 0)
+               if (hub->get_oci && hub->get_oci(wIndex, hub) > 0)
                        temp |=  RH_PS_POCI;
 
                /* The over-current indicator change (OCIC) bit is 0 too */
@@ -217,7 +217,8 @@ check_port:
                        if (!hub->set_power)
                                return -EPIPE;
 
-                       return hub->set_power(wIndex, temp) ? -EPIPE : 0;
+                       return hub->set_power(wIndex, hub,
+                                       temp) ? -EPIPE : 0;
                case USB_PORT_FEAT_C_OVER_CURRENT:
                        dev_dbg(dev, "%sPortFeature(%u): %s\n",
                                temp ? "Set" : "Clear", wIndex,
@@ -349,7 +350,7 @@ static int usb_hcd_da8xx_probe(const struct hc_driver 
*driver,
                goto err4;
 
        if (hub->ocic_notify) {
-               error = hub->ocic_notify(ohci_da8xx_ocic_handler);
+               error = hub->ocic_notify(ohci_da8xx_ocic_handler, hub);
                if (!error)
                        return 0;
        }
@@ -382,7 +383,7 @@ usb_hcd_da8xx_remove(struct usb_hcd *hcd, struct 
platform_device *pdev)
 {
        struct da8xx_ohci_root_hub *hub = pdev->dev.platform_data;
 
-       hub->ocic_notify(NULL);
+       hub->ocic_notify(NULL, NULL);
        usb_remove_hcd(hcd);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-- 
1.7.1

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to