[PATCH 1/2] arm:da8xx:usb: move common OHCI platform setup code to mach-davinci/usb.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


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 <prakash.pm@xxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


B and H Foto and Electronics Corp.

[Linux Media]     [Video for Linux]     [Linux Input]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Free Online Dating]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]     [More Archives]

Add to Google Powered by Linux