aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-omap.c
diff options
context:
space:
mode:
authorAjay Kumar Gupta <ajay.gupta@ti.com>2010-07-08 04:33:02 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:39 -0400
commit5aa4af2ce6a0643f32d47f21614817792b85298d (patch)
tree800657f58baa200390d58a8b0d348a3a7c590b88 /drivers/usb/host/ehci-omap.c
parent5128993b6f5f38bc567f3c246248ca29fd599132 (diff)
USB: ehci_omap: fix device detect issue with modules
Currently devices don't get detected automatically if the ehci module is inserted 2nd time onward. We need to disconnect and reconnect the device for it to get detected and enumerated. Resetting the USB PHY using PHY reset comamnd over ULPI fixes this issue. Tested on OMAP3EVM. Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> Acked-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-omap.c')
-rw-r--r--drivers/usb/host/ehci-omap.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 5450e628157f..116ae280053a 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -38,6 +38,7 @@
38#include <linux/gpio.h> 38#include <linux/gpio.h>
39#include <linux/regulator/consumer.h> 39#include <linux/regulator/consumer.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/usb/ulpi.h>
41#include <plat/usb.h> 42#include <plat/usb.h>
42 43
43/* 44/*
@@ -236,6 +237,35 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask)
236 237
237/*-------------------------------------------------------------------------*/ 238/*-------------------------------------------------------------------------*/
238 239
240static void omap_ehci_soft_phy_reset(struct ehci_hcd_omap *omap, u8 port)
241{
242 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
243 unsigned reg = 0;
244
245 reg = ULPI_FUNC_CTRL_RESET
246 /* FUNCTION_CTRL_SET register */
247 | (ULPI_SET(ULPI_FUNC_CTRL) << EHCI_INSNREG05_ULPI_REGADD_SHIFT)
248 /* Write */
249 | (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT)
250 /* PORTn */
251 | ((port + 1) << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT)
252 /* start ULPI access*/
253 | (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT);
254
255 ehci_omap_writel(omap->ehci_base, EHCI_INSNREG05_ULPI, reg);
256
257 /* Wait for ULPI access completion */
258 while ((ehci_omap_readl(omap->ehci_base, EHCI_INSNREG05_ULPI)
259 & (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) {
260 cpu_relax();
261
262 if (time_after(jiffies, timeout)) {
263 dev_dbg(omap->dev, "phy reset operation timed out\n");
264 break;
265 }
266 }
267}
268
239/* omap_start_ehc 269/* omap_start_ehc
240 * - Start the TI USBHOST controller 270 * - Start the TI USBHOST controller
241 */ 271 */
@@ -425,6 +455,12 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
425 gpio_set_value(omap->reset_gpio_port[1], 1); 455 gpio_set_value(omap->reset_gpio_port[1], 1);
426 } 456 }
427 457
458 /* Soft reset the PHY using PHY reset command over ULPI */
459 if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
460 omap_ehci_soft_phy_reset(omap, 0);
461 if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
462 omap_ehci_soft_phy_reset(omap, 1);
463
428 return 0; 464 return 0;
429 465
430err_sys_status: 466err_sys_status: