diff options
author | Preetham Chandru <pchandru@nvidia.com> | 2012-04-11 11:07:38 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-04-16 15:02:39 -0700 |
commit | 2378438cb07edff467381770c418461af258e0b6 (patch) | |
tree | dcf668c70bd86c47d769f741f125098de662836f /drivers/usb/host | |
parent | 049d697c3a617479ef9d90a639aca794e6400d30 (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/host')
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 21 |
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 } }; |