Skip to content
/ linux Public
forked from torvalds/linux

Commit 113f86d

Browse files
Artur Petrosyangregkh
Artur Petrosyan
authored andcommitted
usb: dwc2: Update partial power down entering by system suspend
With current implementation the port power is being disabled, which is not required by the programming guide. Also, if there is a system which works only in "DWC2_POWER_DOWN_PARAM_NONE" (clock gating) mode the current implementation does not set Gate hclk bit in pcgctl register. Rearranges and updates the implementation of entering to partial power down power saving mode when PC is suspended to get rid of many "if" statements and removes disabling of port power. NOTE: Switch case statement is used for hibernation partial power down and clock gating mode determination. In this patch only Partial Power Down is implemented the Hibernation and clock gating implementations are planned to be added. Acked-by: Minas Harutyunyan <[email protected]> Signed-off-by: Artur Petrosyan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 42b32b1 commit 113f86d

File tree

1 file changed

+18
-35
lines changed

1 file changed

+18
-35
lines changed

drivers/usb/dwc2/hcd.c

+18-35
Original file line numberDiff line numberDiff line change
@@ -4367,8 +4367,6 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
43674367
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
43684368
unsigned long flags;
43694369
int ret = 0;
4370-
u32 hprt0;
4371-
u32 pcgctl;
43724370

43734371
spin_lock_irqsave(&hsotg->lock, flags);
43744372

@@ -4384,47 +4382,32 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
43844382
if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
43854383
goto unlock;
43864384

4387-
if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL ||
4388-
hsotg->flags.b.port_connect_status == 0)
4385+
if (hsotg->bus_suspended)
43894386
goto skip_power_saving;
43904387

4391-
/*
4392-
* Drive USB suspend and disable port Power
4393-
* if usb bus is not suspended.
4394-
*/
4395-
if (!hsotg->bus_suspended) {
4396-
hprt0 = dwc2_read_hprt0(hsotg);
4397-
if (hprt0 & HPRT0_CONNSTS) {
4398-
hprt0 |= HPRT0_SUSP;
4399-
if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL)
4400-
hprt0 &= ~HPRT0_PWR;
4401-
dwc2_writel(hsotg, hprt0, HPRT0);
4402-
}
4403-
if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) {
4404-
spin_unlock_irqrestore(&hsotg->lock, flags);
4405-
dwc2_vbus_supply_exit(hsotg);
4406-
spin_lock_irqsave(&hsotg->lock, flags);
4407-
} else {
4408-
pcgctl = readl(hsotg->regs + PCGCTL);
4409-
pcgctl |= PCGCTL_STOPPCLK;
4410-
writel(pcgctl, hsotg->regs + PCGCTL);
4411-
}
4412-
}
4388+
if (hsotg->flags.b.port_connect_status == 0)
4389+
goto skip_power_saving;
44134390

4414-
if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) {
4391+
switch (hsotg->params.power_down) {
4392+
case DWC2_POWER_DOWN_PARAM_PARTIAL:
44154393
/* Enter partial_power_down */
44164394
ret = dwc2_enter_partial_power_down(hsotg);
4417-
if (ret) {
4418-
if (ret != -ENOTSUPP)
4419-
dev_err(hsotg->dev,
4420-
"enter partial_power_down failed\n");
4421-
goto skip_power_saving;
4422-
}
4423-
4424-
/* After entering partial_power_down, hardware is no more accessible */
4395+
if (ret)
4396+
dev_err(hsotg->dev,
4397+
"enter partial_power_down failed\n");
4398+
/* After entering suspend, hardware is not accessible */
44254399
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
4400+
break;
4401+
case DWC2_POWER_DOWN_PARAM_HIBERNATION:
4402+
case DWC2_POWER_DOWN_PARAM_NONE:
4403+
default:
4404+
goto skip_power_saving;
44264405
}
44274406

4407+
spin_unlock_irqrestore(&hsotg->lock, flags);
4408+
dwc2_vbus_supply_exit(hsotg);
4409+
spin_lock_irqsave(&hsotg->lock, flags);
4410+
44284411
/* Ask phy to be suspended */
44294412
if (!IS_ERR_OR_NULL(hsotg->uphy)) {
44304413
spin_unlock_irqrestore(&hsotg->lock, flags);

0 commit comments

Comments
 (0)