|
@@ -25,6 +25,7 @@
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
#include <linux/spinlock.h>
|
|
|
+#include <linux/gpio.h>
|
|
|
#include <plat/cpu.h>
|
|
|
#include <plat/usb.h>
|
|
|
#include <linux/pm_runtime.h>
|
|
@@ -500,8 +501,21 @@ static void omap_usbhs_init(struct device *dev)
|
|
|
dev_dbg(dev, "starting TI HSUSB Controller\n");
|
|
|
|
|
|
pm_runtime_get_sync(dev);
|
|
|
- spin_lock_irqsave(&omap->lock, flags);
|
|
|
|
|
|
+ if (pdata->ehci_data->phy_reset) {
|
|
|
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
|
|
+ gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
|
|
|
+ GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
|
|
|
+
|
|
|
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
|
|
+ gpio_request_one(pdata->ehci_data->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);
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock_irqsave(&omap->lock, flags);
|
|
|
omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
|
|
|
dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
|
|
|
|
|
@@ -581,9 +595,39 @@ static void omap_usbhs_init(struct device *dev)
|
|
|
}
|
|
|
|
|
|
spin_unlock_irqrestore(&omap->lock, flags);
|
|
|
+
|
|
|
+ if (pdata->ehci_data->phy_reset) {
|
|
|
+ /* Hold the PHY in RESET for enough time till
|
|
|
+ * PHY is settled and ready
|
|
|
+ */
|
|
|
+ udelay(10);
|
|
|
+
|
|
|
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
|
|
+ gpio_set_value_cansleep
|
|
|
+ (pdata->ehci_data->reset_gpio_port[0], 1);
|
|
|
+
|
|
|
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
|
|
+ gpio_set_value_cansleep
|
|
|
+ (pdata->ehci_data->reset_gpio_port[1], 1);
|
|
|
+ }
|
|
|
+
|
|
|
pm_runtime_put_sync(dev);
|
|
|
}
|
|
|
|
|
|
+static void omap_usbhs_deinit(struct device *dev)
|
|
|
+{
|
|
|
+ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
|
|
|
+ struct usbhs_omap_platform_data *pdata = &omap->platdata;
|
|
|
+
|
|
|
+ if (pdata->ehci_data->phy_reset) {
|
|
|
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
|
|
|
+ gpio_free(pdata->ehci_data->reset_gpio_port[0]);
|
|
|
+
|
|
|
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
|
|
|
+ gpio_free(pdata->ehci_data->reset_gpio_port[1]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* usbhs_omap_probe - initialize TI-based HCDs
|
|
@@ -767,6 +811,7 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
|
|
|
goto end_probe;
|
|
|
|
|
|
err_alloc:
|
|
|
+ omap_usbhs_deinit(&pdev->dev);
|
|
|
iounmap(omap->tll_base);
|
|
|
|
|
|
err_tll:
|
|
@@ -818,6 +863,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
|
|
|
|
|
|
+ omap_usbhs_deinit(&pdev->dev);
|
|
|
iounmap(omap->tll_base);
|
|
|
iounmap(omap->uhh_base);
|
|
|
clk_put(omap->init_60m_fclk);
|