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>
This commit is contained in:
parent
5128993b6f
commit
5aa4af2ce6
@ -38,6 +38,7 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb/ulpi.h>
|
||||
#include <plat/usb.h>
|
||||
|
||||
/*
|
||||
@ -236,6 +237,35 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void omap_ehci_soft_phy_reset(struct ehci_hcd_omap *omap, u8 port)
|
||||
{
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
|
||||
unsigned reg = 0;
|
||||
|
||||
reg = ULPI_FUNC_CTRL_RESET
|
||||
/* FUNCTION_CTRL_SET register */
|
||||
| (ULPI_SET(ULPI_FUNC_CTRL) << EHCI_INSNREG05_ULPI_REGADD_SHIFT)
|
||||
/* Write */
|
||||
| (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT)
|
||||
/* PORTn */
|
||||
| ((port + 1) << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT)
|
||||
/* start ULPI access*/
|
||||
| (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT);
|
||||
|
||||
ehci_omap_writel(omap->ehci_base, EHCI_INSNREG05_ULPI, reg);
|
||||
|
||||
/* Wait for ULPI access completion */
|
||||
while ((ehci_omap_readl(omap->ehci_base, EHCI_INSNREG05_ULPI)
|
||||
& (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) {
|
||||
cpu_relax();
|
||||
|
||||
if (time_after(jiffies, timeout)) {
|
||||
dev_dbg(omap->dev, "phy reset operation timed out\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* omap_start_ehc
|
||||
* - Start the TI USBHOST controller
|
||||
*/
|
||||
@ -425,6 +455,12 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
|
||||
gpio_set_value(omap->reset_gpio_port[1], 1);
|
||||
}
|
||||
|
||||
/* Soft reset the PHY using PHY reset command over ULPI */
|
||||
if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
|
||||
omap_ehci_soft_phy_reset(omap, 0);
|
||||
if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
|
||||
omap_ehci_soft_phy_reset(omap, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
err_sys_status:
|
||||
|
Loading…
Reference in New Issue
Block a user