diff options
author | Preetham Chandru <pchandru@nvidia.com> | 2012-04-26 15:54:14 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-05-15 15:07:18 -0700 |
commit | 4c5a8859490c249ce8a7310f04053d5a4741833f (patch) | |
tree | ef416e61ace750ffd5afb8ef43696495aa79a996 | |
parent | 0172fb19ebf3e5fb667b37e64bf3473ccdd1bc35 (diff) |
usb: ehci: tegra: Split resume & suspend call appropriately
tegra_ehci_suspend_noirq/tegra_ehci_resume_noirq breaks
the modem suspend call as it does a regulator_disable()/regulator_enable
call which in turn requires the irqs to be enabled.
Hence maintain a normal suspend call i.e with irqs enabled but
split the resume to normal resume and noirq resume.
Spliting the resume in this way takes care of the below erros in
lp0/lp1
"tegra-ehci tegra-ehci.2:fatal error"
"tegra-ehci tegra-ehci.2: HC died; cleaning up"
Originally resume_noirq & suspend_noirq were added to avoid the above
errors but since it breaks the modem suspend call splitting the suspend
and resume in this way
Bug 954564
Signed-off-by: Preetham Chandru R <pchandru@nvidia.com>
Change-Id: I630b3dbe2ca66d194857dc71ababa3e5955785b1
Reviewed-on: http://git-master/r/99100
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 9981414b5790..5e646b65b3f0 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -1257,8 +1257,6 @@ static int tegra_ehci_resume_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - int ret; mutex_lock(&tegra->tegra_ehci_hcd_mutex); if ((tegra->bus_suspended) && (tegra->power_down_on_bus_suspend)) { @@ -1271,12 +1269,29 @@ static int tegra_ehci_resume_noirq(struct device *dev) if (tegra->default_enable) clk_enable(tegra->clk); + mutex_unlock(&tegra->tegra_ehci_hcd_mutex); + return 0; +} + +static int tegra_ehci_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + int ret; + + mutex_lock(&tegra->tegra_ehci_hcd_mutex); + if ((tegra->bus_suspended) && (tegra->power_down_on_bus_suspend)) { + mutex_unlock(&tegra->tegra_ehci_hcd_mutex); + return 0; + } + ret = tegra_usb_resume(hcd, true); mutex_unlock(&tegra->tegra_ehci_hcd_mutex); return ret; } -static int tegra_ehci_suspend_noirq(struct device *dev) +static int tegra_ehci_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); @@ -1318,8 +1333,9 @@ static int tegra_ehci_suspend_noirq(struct device *dev) } static struct dev_pm_ops tegra_ehci_dev_pm_ops = { - .suspend_noirq = tegra_ehci_suspend_noirq, - .resume_noirq = tegra_ehci_resume_noirq, + .suspend = tegra_ehci_suspend, + .resume = tegra_ehci_resume, + .resume_noirq = tegra_ehci_resume_noirq, }; #endif |