diff options
author | Preetham Chandru <pchandru@nvidia.com> | 2012-04-18 11:30:18 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2012-04-18 11:30:18 +0530 |
commit | e8ed42b02221c3fdbd59c82e374d6bb1d75d410a (patch) | |
tree | 1b9aef799578c38c86c78a709a68218ac8d191c3 /drivers/usb/host/ehci-tegra.c | |
parent | 2cee226c6bcfb4856e477a57bc1856fb7e7bba8f (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>
Conflicts:
drivers/usb/host/ehci-tegra.c
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'drivers/usb/host/ehci-tegra.c')
-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 66e083451e59..7f17c2c4d319 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 @@ -1305,8 +1305,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; @@ -1327,8 +1328,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; @@ -1366,6 +1368,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) @@ -1430,13 +1438,12 @@ static struct of_device_id tegra_ehci_of_match[] __devinitdata = { 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", .of_match_table = tegra_ehci_of_match, +#ifdef CONFIG_PM + .pm = &tegra_ehci_dev_pm_ops, +#endif } }; |