summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/core_intr.c
diff options
context:
space:
mode:
authorVardan Mikayelyan2018-02-16 11:11:07 +0100
committerFelipe Balbi2018-03-13 09:47:56 +0100
commit97861781dafffe5a9c9cbd0d2a14c9e7ae81d27b (patch)
treedf758764292af7b87a2dffcd3f70f9207600e30b /drivers/usb/dwc2/core_intr.c
parentusb: dwc2: Add dwc2_enter_hibernation(), dwc2_exit_hibernation() (diff)
downloadkernel-qcow2-linux-97861781dafffe5a9c9cbd0d2a14c9e7ae81d27b.tar.gz
kernel-qcow2-linux-97861781dafffe5a9c9cbd0d2a14c9e7ae81d27b.tar.xz
kernel-qcow2-linux-97861781dafffe5a9c9cbd0d2a14c9e7ae81d27b.zip
usb: dwc2: Allow entering hibernation from USB_SUSPEND interrupt
Do changes to allow entering hibernated state from USB_SUSPEND interrupt. All code is added under if conditions and mustn't impact existing functionality. Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com> Signed-off-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc2/core_intr.c')
-rw-r--r--drivers/usb/dwc2/core_intr.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 41d7dda40cb1..d01581594ce5 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -484,32 +484,44 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
* state is active
*/
dsts = dwc2_readl(hsotg->regs + DSTS);
- dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts);
+ dev_dbg(hsotg->dev, "%s: DSTS=0x%0x\n", __func__, dsts);
dev_dbg(hsotg->dev,
- "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n",
+ "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d HWCFG4.Hibernation=%d\n",
!!(dsts & DSTS_SUSPSTS),
- hsotg->hw_params.power_optimized);
- if ((dsts & DSTS_SUSPSTS) && hsotg->hw_params.power_optimized) {
- /* Ignore suspend request before enumeration */
- if (!dwc2_is_device_connected(hsotg)) {
- dev_dbg(hsotg->dev,
- "ignore suspend request before enumeration\n");
- return;
+ hsotg->hw_params.power_optimized,
+ hsotg->hw_params.hibernation);
+
+ /* Ignore suspend request before enumeration */
+ if (!dwc2_is_device_connected(hsotg)) {
+ dev_dbg(hsotg->dev,
+ "ignore suspend request before enumeration\n");
+ return;
+ }
+ if (dsts & DSTS_SUSPSTS) {
+ if (hsotg->hw_params.power_optimized) {
+ ret = dwc2_enter_partial_power_down(hsotg);
+ if (ret) {
+ if (ret != -ENOTSUPP)
+ dev_err(hsotg->dev,
+ "%s: enter partial_power_down failed\n",
+ __func__);
+ goto skip_power_saving;
+ }
+
+ udelay(100);
+
+ /* Ask phy to be suspended */
+ if (!IS_ERR_OR_NULL(hsotg->uphy))
+ usb_phy_set_suspend(hsotg->uphy, true);
}
- ret = dwc2_enter_partial_power_down(hsotg);
- if (ret) {
- if (ret != -ENOTSUPP)
+ if (hsotg->hw_params.hibernation) {
+ ret = dwc2_enter_hibernation(hsotg, 0);
+ if (ret && ret != -ENOTSUPP)
dev_err(hsotg->dev,
- "enter power_down failed\n");
- goto skip_power_saving;
+ "%s: enter hibernation failed\n",
+ __func__);
}
-
- udelay(100);
-
- /* Ask phy to be suspended */
- if (!IS_ERR_OR_NULL(hsotg->uphy))
- usb_phy_set_suspend(hsotg->uphy, true);
skip_power_saving:
/*
* Change to L2 (suspend) state before releasing