diff options
author | Pavankumar Kondeti <pkondeti@codeaurora.org> | 2010-12-07 07:23:57 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-10 17:23:32 -0500 |
commit | 8bb6a164b906bb7ca319202f85b30e3ef096cd65 (patch) | |
tree | 25405ae8262dde87ea8ccf19277067c10095999f /drivers/usb | |
parent | b0848aea10da186372582f33152efdda43944f26 (diff) |
USB: EHCI: msm: Add support for power management
Enable runtime PM and mark no_callbacks flag. OTG device, parent of
HCD takes care of putting hardware into low power mode. Adjust port
power wakeup flags during system suspend and resume.
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-msm.c | 57 |
2 files changed, 57 insertions, 2 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d8665ec0565b..b9cc31172fbd 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -150,7 +150,7 @@ config USB_EHCI_MSM | |||
150 | Enables support for the USB Host controller present on the | 150 | Enables support for the USB Host controller present on the |
151 | Qualcomm chipsets. Root Hub has inbuilt TT. | 151 | Qualcomm chipsets. Root Hub has inbuilt TT. |
152 | This driver depends on OTG driver for PHY initialization, | 152 | This driver depends on OTG driver for PHY initialization, |
153 | clock management, powering up VBUS. | 153 | clock management, powering up VBUS, and power management. |
154 | 154 | ||
155 | config USB_EHCI_HCD_PPC_OF | 155 | config USB_EHCI_HCD_PPC_OF |
156 | bool "EHCI support for PPC USB controller on OF platform bus" | 156 | bool "EHCI support for PPC USB controller on OF platform bus" |
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 9ed855986599..413f4deca532 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/pm_runtime.h> | ||
28 | 29 | ||
29 | #include <linux/usb/otg.h> | 30 | #include <linux/usb/otg.h> |
30 | #include <linux/usb/msm_hsusb_hw.h> | 31 | #include <linux/usb/msm_hsusb_hw.h> |
@@ -239,7 +240,8 @@ static int ehci_msm_probe(struct platform_device *pdev) | |||
239 | 240 | ||
240 | /* | 241 | /* |
241 | * OTG driver takes care of PHY initialization, clock management, | 242 | * OTG driver takes care of PHY initialization, clock management, |
242 | * powering up VBUS and mapping of registers address space. | 243 | * powering up VBUS, mapping of registers address space and power |
244 | * management. | ||
243 | */ | 245 | */ |
244 | otg = otg_get_transceiver(); | 246 | otg = otg_get_transceiver(); |
245 | if (!otg) { | 247 | if (!otg) { |
@@ -255,6 +257,13 @@ static int ehci_msm_probe(struct platform_device *pdev) | |||
255 | } | 257 | } |
256 | 258 | ||
257 | device_init_wakeup(&pdev->dev, 1); | 259 | device_init_wakeup(&pdev->dev, 1); |
260 | /* | ||
261 | * OTG device parent of HCD takes care of putting | ||
262 | * hardware into low power mode. | ||
263 | */ | ||
264 | pm_runtime_no_callbacks(&pdev->dev); | ||
265 | pm_runtime_enable(&pdev->dev); | ||
266 | |||
258 | return 0; | 267 | return 0; |
259 | 268 | ||
260 | put_transceiver: | 269 | put_transceiver: |
@@ -272,6 +281,8 @@ static int __devexit ehci_msm_remove(struct platform_device *pdev) | |||
272 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 281 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
273 | 282 | ||
274 | device_init_wakeup(&pdev->dev, 0); | 283 | device_init_wakeup(&pdev->dev, 0); |
284 | pm_runtime_disable(&pdev->dev); | ||
285 | pm_runtime_set_suspended(&pdev->dev); | ||
275 | 286 | ||
276 | otg_set_host(otg, NULL); | 287 | otg_set_host(otg, NULL); |
277 | otg_put_transceiver(otg); | 288 | otg_put_transceiver(otg); |
@@ -281,10 +292,54 @@ static int __devexit ehci_msm_remove(struct platform_device *pdev) | |||
281 | return 0; | 292 | return 0; |
282 | } | 293 | } |
283 | 294 | ||
295 | #ifdef CONFIG_PM | ||
296 | static int ehci_msm_pm_suspend(struct device *dev) | ||
297 | { | ||
298 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
299 | bool wakeup = device_may_wakeup(dev); | ||
300 | |||
301 | dev_dbg(dev, "ehci-msm PM suspend\n"); | ||
302 | |||
303 | /* | ||
304 | * EHCI helper function has also the same check before manipulating | ||
305 | * port wakeup flags. We do check here the same condition before | ||
306 | * calling the same helper function to avoid bringing hardware | ||
307 | * from Low power mode when there is no need for adjusting port | ||
308 | * wakeup flags. | ||
309 | */ | ||
310 | if (hcd->self.root_hub->do_remote_wakeup && !wakeup) { | ||
311 | pm_runtime_resume(dev); | ||
312 | ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), | ||
313 | wakeup); | ||
314 | } | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static int ehci_msm_pm_resume(struct device *dev) | ||
320 | { | ||
321 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
322 | |||
323 | dev_dbg(dev, "ehci-msm PM resume\n"); | ||
324 | ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd)); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | #else | ||
329 | #define ehci_msm_pm_suspend NULL | ||
330 | #define ehci_msm_pm_resume NULL | ||
331 | #endif | ||
332 | |||
333 | static const struct dev_pm_ops ehci_msm_dev_pm_ops = { | ||
334 | .suspend = ehci_msm_pm_suspend, | ||
335 | .resume = ehci_msm_pm_resume, | ||
336 | }; | ||
337 | |||
284 | static struct platform_driver ehci_msm_driver = { | 338 | static struct platform_driver ehci_msm_driver = { |
285 | .probe = ehci_msm_probe, | 339 | .probe = ehci_msm_probe, |
286 | .remove = __devexit_p(ehci_msm_remove), | 340 | .remove = __devexit_p(ehci_msm_remove), |
287 | .driver = { | 341 | .driver = { |
288 | .name = "msm_hsusb_host", | 342 | .name = "msm_hsusb_host", |
343 | .pm = &ehci_msm_dev_pm_ops, | ||
289 | }, | 344 | }, |
290 | }; | 345 | }; |