diff options
Diffstat (limited to 'drivers/usb/dwc2/platform.c')
-rw-r--r-- | drivers/usb/dwc2/platform.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index d10a7f8daec3..3e6c3c8a32ff 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c | |||
@@ -447,6 +447,10 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
447 | if (retval) | 447 | if (retval) |
448 | goto error; | 448 | goto error; |
449 | 449 | ||
450 | hsotg->need_phy_for_wake = | ||
451 | of_property_read_bool(dev->dev.of_node, | ||
452 | "snps,need-phy-for-wake"); | ||
453 | |||
450 | /* | 454 | /* |
451 | * Reset before dwc2_get_hwparams() then it could get power-on real | 455 | * Reset before dwc2_get_hwparams() then it could get power-on real |
452 | * reset value form registers. | 456 | * reset value form registers. |
@@ -478,6 +482,14 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
478 | hsotg->gadget_enabled = 1; | 482 | hsotg->gadget_enabled = 1; |
479 | } | 483 | } |
480 | 484 | ||
485 | /* | ||
486 | * If we need PHY for wakeup we must be wakeup capable. | ||
487 | * When we have a device that can wake without the PHY we | ||
488 | * can adjust this condition. | ||
489 | */ | ||
490 | if (hsotg->need_phy_for_wake) | ||
491 | device_set_wakeup_capable(&dev->dev, true); | ||
492 | |||
481 | hsotg->reset_phy_on_wake = | 493 | hsotg->reset_phy_on_wake = |
482 | of_property_read_bool(dev->dev.of_node, | 494 | of_property_read_bool(dev->dev.of_node, |
483 | "snps,reset-phy-on-wake"); | 495 | "snps,reset-phy-on-wake"); |
@@ -516,13 +528,17 @@ error: | |||
516 | static int __maybe_unused dwc2_suspend(struct device *dev) | 528 | static int __maybe_unused dwc2_suspend(struct device *dev) |
517 | { | 529 | { |
518 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); | 530 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); |
531 | bool is_device_mode = dwc2_is_device_mode(dwc2); | ||
519 | int ret = 0; | 532 | int ret = 0; |
520 | 533 | ||
521 | if (dwc2_is_device_mode(dwc2)) | 534 | if (is_device_mode) |
522 | dwc2_hsotg_suspend(dwc2); | 535 | dwc2_hsotg_suspend(dwc2); |
523 | 536 | ||
524 | if (dwc2->ll_hw_enabled) | 537 | if (dwc2->ll_hw_enabled && |
538 | (is_device_mode || dwc2_host_can_poweroff_phy(dwc2))) { | ||
525 | ret = __dwc2_lowlevel_hw_disable(dwc2); | 539 | ret = __dwc2_lowlevel_hw_disable(dwc2); |
540 | dwc2->phy_off_for_suspend = true; | ||
541 | } | ||
526 | 542 | ||
527 | return ret; | 543 | return ret; |
528 | } | 544 | } |
@@ -532,11 +548,12 @@ static int __maybe_unused dwc2_resume(struct device *dev) | |||
532 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); | 548 | struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); |
533 | int ret = 0; | 549 | int ret = 0; |
534 | 550 | ||
535 | if (dwc2->ll_hw_enabled) { | 551 | if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { |
536 | ret = __dwc2_lowlevel_hw_enable(dwc2); | 552 | ret = __dwc2_lowlevel_hw_enable(dwc2); |
537 | if (ret) | 553 | if (ret) |
538 | return ret; | 554 | return ret; |
539 | } | 555 | } |
556 | dwc2->phy_off_for_suspend = false; | ||
540 | 557 | ||
541 | if (dwc2_is_device_mode(dwc2)) | 558 | if (dwc2_is_device_mode(dwc2)) |
542 | ret = dwc2_hsotg_resume(dwc2); | 559 | ret = dwc2_hsotg_resume(dwc2); |