Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 226968
b: refs/heads/master
c: 8bb6a16
h: refs/heads/master
v: v3
  • Loading branch information
Pavankumar Kondeti authored and Greg Kroah-Hartman committed Dec 10, 2010
1 parent d09fdac commit cecbab0
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b0848aea10da186372582f33152efdda43944f26
refs/heads/master: 8bb6a164b906bb7ca319202f85b30e3ef096cd65
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ config USB_EHCI_MSM
Enables support for the USB Host controller present on the
Qualcomm chipsets. Root Hub has inbuilt TT.
This driver depends on OTG driver for PHY initialization,
clock management, powering up VBUS.
clock management, powering up VBUS, and power management.

config USB_EHCI_HCD_PPC_OF
bool "EHCI support for PPC USB controller on OF platform bus"
Expand Down
57 changes: 56 additions & 1 deletion trunk/drivers/usb/host/ehci-msm.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>

#include <linux/usb/otg.h>
#include <linux/usb/msm_hsusb_hw.h>
Expand Down Expand Up @@ -239,7 +240,8 @@ static int ehci_msm_probe(struct platform_device *pdev)

/*
* OTG driver takes care of PHY initialization, clock management,
* powering up VBUS and mapping of registers address space.
* powering up VBUS, mapping of registers address space and power
* management.
*/
otg = otg_get_transceiver();
if (!otg) {
Expand All @@ -255,6 +257,13 @@ static int ehci_msm_probe(struct platform_device *pdev)
}

device_init_wakeup(&pdev->dev, 1);
/*
* OTG device parent of HCD takes care of putting
* hardware into low power mode.
*/
pm_runtime_no_callbacks(&pdev->dev);
pm_runtime_enable(&pdev->dev);

return 0;

put_transceiver:
Expand All @@ -272,6 +281,8 @@ static int __devexit ehci_msm_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);

device_init_wakeup(&pdev->dev, 0);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);

otg_set_host(otg, NULL);
otg_put_transceiver(otg);
Expand All @@ -281,10 +292,54 @@ static int __devexit ehci_msm_remove(struct platform_device *pdev)
return 0;
}

#ifdef CONFIG_PM
static int ehci_msm_pm_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
bool wakeup = device_may_wakeup(dev);

dev_dbg(dev, "ehci-msm PM suspend\n");

/*
* EHCI helper function has also the same check before manipulating
* port wakeup flags. We do check here the same condition before
* calling the same helper function to avoid bringing hardware
* from Low power mode when there is no need for adjusting port
* wakeup flags.
*/
if (hcd->self.root_hub->do_remote_wakeup && !wakeup) {
pm_runtime_resume(dev);
ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd),
wakeup);
}

return 0;
}

static int ehci_msm_pm_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);

dev_dbg(dev, "ehci-msm PM resume\n");
ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd));

return 0;
}
#else
#define ehci_msm_pm_suspend NULL
#define ehci_msm_pm_resume NULL
#endif

static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
.suspend = ehci_msm_pm_suspend,
.resume = ehci_msm_pm_resume,
};

static struct platform_driver ehci_msm_driver = {
.probe = ehci_msm_probe,
.remove = __devexit_p(ehci_msm_remove),
.driver = {
.name = "msm_hsusb_host",
.pm = &ehci_msm_dev_pm_ops,
},
};

0 comments on commit cecbab0

Please sign in to comment.