mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
ARM: OMAP3: USB: Fix the EHCI ULPI PHY reset issue
It is observed that the echi ports of 3430 sdp board are not working due to the random timing of programming the associated GPIOs of the ULPI PHYs of the EHCI for reset. If the PHYs are reset at during usbhs core driver, host ports will not work because EHCI driver is loaded after the resetting PHYs. The PHYs should be in reset state while initializing the EHCI controller. The code which does the GPIO pins associated with the PHYs are programmed to reset is moved from the USB host core driver to EHCI driver. Signed-off-by: Keshava Munegowda <[email protected]> Reviewed-by: Partha Basak <[email protected]> Acked-by: Felipe Balbi <[email protected]> Tested-by: Igor Grinberg <[email protected]> Signed-off-by: Samuel Ortiz <[email protected]>
This commit is contained in:
parent
8eaeb93933
commit
1fcb57d0f6
2 changed files with 37 additions and 46 deletions
|
|
@ -42,6 +42,7 @@
|
|||
#include <plat/usb.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
/* EHCI Register Set */
|
||||
#define EHCI_INSNREG04 (0xA0)
|
||||
|
|
@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (pdata->phy_reset) {
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[0]))
|
||||
gpio_request_one(pdata->reset_gpio_port[0],
|
||||
GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
|
||||
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[1]))
|
||||
gpio_request_one(pdata->reset_gpio_port[1],
|
||||
GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
|
||||
|
||||
/* Hold the PHY in RESET for enough time till DIR is high */
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
|
|
@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
|
|||
/* root ports should always stay powered */
|
||||
ehci_port_power(omap_ehci, 1);
|
||||
|
||||
if (pdata->phy_reset) {
|
||||
/* Hold the PHY in RESET for enough time till
|
||||
* PHY is settled and ready
|
||||
*/
|
||||
udelay(10);
|
||||
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[0]))
|
||||
gpio_set_value(pdata->reset_gpio_port[0], 1);
|
||||
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[1]))
|
||||
gpio_set_value(pdata->reset_gpio_port[1], 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_add_hcd:
|
||||
|
|
@ -259,8 +286,9 @@ err_io:
|
|||
*/
|
||||
static int ehci_hcd_omap_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct ehci_hcd_omap_platform_data *pdata = dev->platform_data;
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
disable_put_regulator(dev->platform_data);
|
||||
|
|
@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
|
|||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
if (pdata->phy_reset) {
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[0]))
|
||||
gpio_free(pdata->reset_gpio_port[0]);
|
||||
|
||||
if (gpio_is_valid(pdata->reset_gpio_port[1]))
|
||||
gpio_free(pdata->reset_gpio_port[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue