summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorPreetham Chandru <pchandru@nvidia.com>2012-04-11 11:07:38 +0530
committerSimone Willett <swillett@nvidia.com>2012-04-16 15:02:39 -0700
commit2378438cb07edff467381770c418461af258e0b6 (patch)
treedcf668c70bd86c47d769f741f125098de662836f /drivers/usb
parent049d697c3a617479ef9d90a639aca794e6400d30 (diff)
usb: ehci: tegra: use suspend_noirq()/resume_noirq()
usb driver needs to be suspended late and resumed early even before irqs are disabled/enabled. Without this change the following two issues are seen during lp0 and lp1 states. In lp0, when there is a usb wakeup event (by unplugging the usb device) we get the following error: "tegra-ehci tegra-ehci.2:fatal error" "tegra-ehci tegra-ehci.2: HC died; cleaning up" The above error comes because an irq is generated even before the usb_resume was called. A similar issue is seen in lp1 as well. Bug 954564 Signed-off-by: Preetham Chandru R <pchandru@nvidia.com> Change-Id: Id25fd2588ec034bd6aa54c17607e322f412adc5c Reviewed-on: http://git-master/r/95778 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ehci-tegra.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 11e69c058a21..324fc7ad9522 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -2,7 +2,7 @@
* EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs
*
* Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2009 - 2011 NVIDIA Corporation
+ * Copyright (C) 2009 - 2012 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -1244,8 +1244,9 @@ fail_hcd:
}
#ifdef CONFIG_PM
-static int tegra_ehci_resume(struct platform_device *pdev)
+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;
@@ -1266,8 +1267,9 @@ static int tegra_ehci_resume(struct platform_device *pdev)
return ret;
}
-static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state)
+static int tegra_ehci_suspend_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;
@@ -1305,6 +1307,12 @@ static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state)
mutex_unlock(&tegra->tegra_ehci_hcd_mutex);
return ret;
}
+
+static struct dev_pm_ops tegra_ehci_dev_pm_ops = {
+ .suspend_noirq = tegra_ehci_suspend_noirq,
+ .resume_noirq = tegra_ehci_resume_noirq,
+};
+
#endif
static int tegra_ehci_remove(struct platform_device *pdev)
@@ -1364,12 +1372,11 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev)
static struct platform_driver tegra_ehci_driver = {
.probe = tegra_ehci_probe,
.remove = tegra_ehci_remove,
-#ifdef CONFIG_PM
- .suspend = tegra_ehci_suspend,
- .resume = tegra_ehci_resume,
-#endif
.shutdown = tegra_ehci_hcd_shutdown,
.driver = {
.name = "tegra-ehci",
+#ifdef CONFIG_PM
+ .pm = &tegra_ehci_dev_pm_ops,
+#endif
}
};