diff options
author | Anshul Jain <anshulj@nvidia.com> | 2013-06-20 18:49:06 -0700 |
---|---|---|
committer | Harshada Kale <hkale@nvidia.com> | 2013-07-09 00:15:19 -0700 |
commit | a86069c9d23df06958e7f109dee8a35ffb5aa05c (patch) | |
tree | 4beda54522fdabcc78075e278db5f14ed3658057 /arch | |
parent | 5e6ad8db18b81de2f8d357b1c39443054059cad6 (diff) |
misc: issp: Add usb js recovery mechanism
This change recovery the JS uC after USB resume failure by
unloading USB, resetting uC from ISSP and then reloading USB
Bug 1306389
Change-Id: I086636d4b7b91e3a2874f584fa6efbfd2cae6014
Signed-off-by: Michael Hsu <mhsu@nvidia.com>
Signed-off-by: Anshul Jain <anshulj@nvidia.com>
(cherry picked from commit e10f9579dbd6e3d37b127995520b9dee036be199)
Reviewed-on: http://git-master/r/246314
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/board-roth.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-roth.c b/arch/arm/mach-tegra/board-roth.c index 3b1fa1adebf7..a7af001d4e35 100644 --- a/arch/arm/mach-tegra/board-roth.c +++ b/arch/arm/mach-tegra/board-roth.c @@ -568,6 +568,54 @@ static struct tegra_usb_otg_data tegra_otg_pdata = { .ehci_pdata = &tegra_ehci1_utmi_pdata, }; +static struct platform_device * +tegra_usb_hsic_host_register(struct platform_device *ehci_dev) +{ + struct platform_device *pdev; + int val; + + pdev = platform_device_alloc(ehci_dev->name, ehci_dev->id); + if (!pdev) + return NULL; + + val = platform_device_add_resources(pdev, ehci_dev->resource, + ehci_dev->num_resources); + if (val) + goto error; + + pdev->dev.dma_mask = ehci_dev->dev.dma_mask; + pdev->dev.coherent_dma_mask = ehci_dev->dev.coherent_dma_mask; + + val = platform_device_add_data(pdev, &tegra_ehci3_utmi_pdata, + sizeof(struct tegra_usb_platform_data)); + if (val) + goto error; + + val = platform_device_add(pdev); + if (val) + goto error; + + return pdev; + +error: + pr_err("%s: failed to add the host contoller device\n", __func__); + platform_device_put(pdev); + return NULL; +} + +static void tegra_usb_hsic_host_unregister(struct platform_device **platdev) +{ + struct platform_device *pdev = *platdev; + + if (pdev && &pdev->dev) { + platform_device_unregister(pdev); + *platdev = NULL; + } else + pr_err("%s: no platform device\n", __func__); +} + +static struct platform_device *roth_usb_ehci3; + static void roth_usb_init(void) { tegra_otg_device.dev.platform_data = &tegra_otg_pdata; @@ -576,10 +624,28 @@ static void roth_usb_init(void) /* Setup the udc platform data */ tegra_udc_device.dev.platform_data = &tegra_udc_pdata; +#if 0 tegra_ehci3_device.dev.platform_data = &tegra_ehci3_utmi_pdata; platform_device_register(&tegra_ehci3_device); +#else + roth_usb_ehci3 = tegra_usb_hsic_host_register(&tegra_ehci3_device); +#endif +} + +void roth_usb_unload(void) +{ + pr_info("%s\n", __func__); + + /* unload ehci3 usb host controller */ + tegra_usb_hsic_host_unregister(&roth_usb_ehci3); + } +void roth_usb_reload(void) +{ + pr_info("%s\n", __func__); + roth_usb_ehci3 = tegra_usb_hsic_host_register(&tegra_ehci3_device); +} #else static void roth_usb_init(void) { } #endif |