All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/15] usb: dwc2: Update exit hibernation when port reset is asserted
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
@ 2021-04-15  5:39 ` Artur Petrosyan
  2021-04-15  5:39 ` [PATCH 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
                   ` (29 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:39 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

No need to check for "DWC2_POWER_DOWN_PARAM_HIBERNATION" param
as "hsotg->hibernated" flag is already enough for exiting from
hibernation mode.

- Removes checking of "DWC2_POWER_DOWN_PARAM_HIBERNATION" param.

- For code readability Hibernation exit code moved after
debug message print.

- Added "dwc2_exit_hibernation()" function error checking.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 04a1b53d65af..cda3f931195d 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3668,9 +3668,17 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			break;
 
 		case USB_PORT_FEAT_RESET:
-			if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION &&
-			    hsotg->hibernated)
-				dwc2_exit_hibernation(hsotg, 0, 1, 1);
+			dev_dbg(hsotg->dev,
+				"SetPortFeature - USB_PORT_FEAT_RESET\n");
+
+			hprt0 = dwc2_read_hprt0(hsotg);
+
+			if (hsotg->hibernated) {
+				retval = dwc2_exit_hibernation(hsotg, 0, 1, 1);
+				if (retval)
+					dev_err(hsotg->dev,
+						"exit hibernation failed\n");
+			}
 
 			if (hsotg->in_ppd) {
 				retval = dwc2_exit_partial_power_down(hsotg, 1,
@@ -3684,9 +3692,6 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
 				dwc2_host_exit_clock_gating(hsotg, 0);
 
-			hprt0 = dwc2_read_hprt0(hsotg);
-			dev_dbg(hsotg->dev,
-				"SetPortFeature - USB_PORT_FEAT_RESET\n");
 			pcgctl = dwc2_readl(hsotg, PCGCTL);
 			pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK);
 			dwc2_writel(hsotg, pcgctl, PCGCTL);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
  2021-04-15  5:39 ` [PATCH 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
@ 2021-04-15  5:39 ` Artur Petrosyan
  2021-04-15  5:39 ` [PATCH 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:39 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Initially resetting device address was done in dwc2_hsotg_irq()
interrupt handler. However, when core is hibernated USB RESET
is not handled in dwc2_hsotg_irq() handler, instead USB RESET
interrupt is handled in dwc2_handle_gpwrdn_intr() handler.

- Added reset device address to zero when core exits from gadget
  hibernation.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/gadget.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 2f50f3e62caa..e6bb1bdb2760 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -5305,6 +5305,10 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
 	dwc2_writel(hsotg, dr->dcfg, DCFG);
 	dwc2_writel(hsotg, dr->dctl, DCTL);
 
+	/* On USB Reset, reset device address to zero */
+	if (reset)
+		dwc2_clear_bit(hsotg, DCFG, DCFG_DEVADDR_MASK);
+
 	/* De-assert Wakeup Logic */
 	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 	gpwrdn &= ~GPWRDN_PMUACTV;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
  2021-04-15  5:39 ` [PATCH 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
  2021-04-15  5:39 ` [PATCH 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
@ 2021-04-15  5:39 ` Artur Petrosyan
  2021-04-15  5:39 ` [PATCH 04/15] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:39 UTC (permalink / raw)
  To: John Youn, Felipe Balbi, Greg Kroah-Hartman, Artur Petrosyan,
	Minas Harutyunyan, Vardan Mikayelyan, Grigor Tovmasyan,
	linux-usb, linux-kernel
  Cc: Artur Petrosyan

Added setting "port_connect_status_change" flag to "1" in order
to re-enumerate, because after exit from hibernation port
connection status is not detected.

Fixes: c5c403dc4336 ("usb: dwc2: Add host/device hibernation functions")
Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index cda3f931195d..ff945c40ef8a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5650,7 +5650,15 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
 		return ret;
 	}
 
-	dwc2_hcd_rem_wakeup(hsotg);
+	if (rem_wakeup) {
+		dwc2_hcd_rem_wakeup(hsotg);
+		/*
+		 * Change "port_connect_status_change" flag to re-enumerate,
+		 * because after exit from hibernation port connection status
+		 * is not detected.
+		 */
+		hsotg->flags.b.port_connect_status_change = 1;
+	}
 
 	hsotg->hibernated = 0;
 	hsotg->bus_suspended = 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 04/15] usb: dwc2: Fix hibernation between host and device modes.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (2 preceding siblings ...)
  2021-04-15  5:39 ` [PATCH 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
@ 2021-04-15  5:39 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
                   ` (26 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:39 UTC (permalink / raw)
  To: John Youn, Felipe Balbi, Greg Kroah-Hartman, Artur Petrosyan,
	Minas Harutyunyan, Vardan Mikayelyan, Grigor Tovmasyan,
	linux-usb, linux-kernel
  Cc: Artur Petrosyan, Minas Harutyunyan

When core is in hibernation in host mode and a device cable
was connected then driver exited from device hibernation.
However, registers saved for host mode and when exited from
device hibernation register restore would be done for device
register which was wrong because there was no device registers
stored to restore.

- Added dwc_handle_gpwrdn_disc_det() function which handles
  gpwrdn disconnect detect flow and exits hibernation
  without restoring the registers.
- Updated exiting from hibernation in GPWRDN_STS_CHGINT with
  calling dwc_handle_gpwrdn_disc_det() function. Here no register
  is restored which is the solution described above.

Fixes: 65c9c4c6b01f ("usb: dwc2: Add dwc2_handle_gpwrdn_intr() handler")
Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 154 +++++++++++++++++++----------------
 1 file changed, 83 insertions(+), 71 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 550c52c1a0c7..27d729fad227 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -680,6 +680,71 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
 		return 0;
 }
 
+/**
+ * dwc_handle_gpwrdn_disc_det() - Handles the gpwrdn disconnect detect.
+ * Exits hibernation without restoring registers.
+ *
+ * @hsotg: Programming view of DWC_otg controller
+ * @gpwrdn: GPWRDN register
+ */
+static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
+					      u32 gpwrdn)
+{
+	u32 gpwrdn_tmp;
+
+	/* Switch-on voltage to the core */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Reset core */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Disable Power Down Clamp */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Deassert reset core */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Disable PMU interrupt */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+
+	/* De-assert Wakeup Logic */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PMUACTV;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+
+	hsotg->hibernated = 0;
+	hsotg->bus_suspended = 0;
+
+	if (gpwrdn & GPWRDN_IDSTS) {
+		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
+		dwc2_core_init(hsotg, false);
+		dwc2_enable_global_interrupts(hsotg);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		dwc2_hsotg_core_connect(hsotg);
+	} else {
+		hsotg->op_state = OTG_STATE_A_HOST;
+
+		/* Initialize the Core for Host mode */
+		dwc2_core_init(hsotg, false);
+		dwc2_enable_global_interrupts(hsotg);
+		dwc2_hcd_start(hsotg);
+	}
+}
+
 /*
  * GPWRDN interrupt handler.
  *
@@ -701,64 +766,14 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 
 	if ((gpwrdn & GPWRDN_DISCONN_DET) &&
 	    (gpwrdn & GPWRDN_DISCONN_DET_MSK) && !linestate) {
-		u32 gpwrdn_tmp;
-
 		dev_dbg(hsotg->dev, "%s: GPWRDN_DISCONN_DET\n", __func__);
-
-		/* Switch-on voltage to the core */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Reset core */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Disable Power Down Clamp */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Deassert reset core */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Disable PMU interrupt */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-
-		/* De-assert Wakeup Logic */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PMUACTV;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-
-		hsotg->hibernated = 0;
-
-		if (gpwrdn & GPWRDN_IDSTS) {
-			hsotg->op_state = OTG_STATE_B_PERIPHERAL;
-			dwc2_core_init(hsotg, false);
-			dwc2_enable_global_interrupts(hsotg);
-			dwc2_hsotg_core_init_disconnected(hsotg, false);
-			dwc2_hsotg_core_connect(hsotg);
-		} else {
-			hsotg->op_state = OTG_STATE_A_HOST;
-
-			/* Initialize the Core for Host mode */
-			dwc2_core_init(hsotg, false);
-			dwc2_enable_global_interrupts(hsotg);
-			dwc2_hcd_start(hsotg);
-		}
-	}
-
-	if ((gpwrdn & GPWRDN_LNSTSCHG) &&
-	    (gpwrdn & GPWRDN_LNSTSCHG_MSK) && linestate) {
+		/*
+		 * Call disconnect detect function to exit from
+		 * hibernation
+		 */
+		dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
+	} else if ((gpwrdn & GPWRDN_LNSTSCHG) &&
+		   (gpwrdn & GPWRDN_LNSTSCHG_MSK) && linestate) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_LNSTSCHG\n", __func__);
 		if (hsotg->hw_params.hibernation &&
 		    hsotg->hibernated) {
@@ -769,24 +784,21 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 				dwc2_exit_hibernation(hsotg, 1, 0, 1);
 			}
 		}
-	}
-	if ((gpwrdn & GPWRDN_RST_DET) && (gpwrdn & GPWRDN_RST_DET_MSK)) {
+	} else if ((gpwrdn & GPWRDN_RST_DET) &&
+		   (gpwrdn & GPWRDN_RST_DET_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
 		if (!linestate && (gpwrdn & GPWRDN_BSESSVLD))
 			dwc2_exit_hibernation(hsotg, 0, 1, 0);
-	}
-	if ((gpwrdn & GPWRDN_STS_CHGINT) &&
-	    (gpwrdn & GPWRDN_STS_CHGINT_MSK) && linestate) {
+	} else if ((gpwrdn & GPWRDN_STS_CHGINT) &&
+		   (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
-		if (hsotg->hw_params.hibernation &&
-		    hsotg->hibernated) {
-			if (gpwrdn & GPWRDN_IDSTS) {
-				dwc2_exit_hibernation(hsotg, 0, 0, 0);
-				call_gadget(hsotg, resume);
-			} else {
-				dwc2_exit_hibernation(hsotg, 1, 0, 1);
-			}
-		}
+		/*
+		 * As GPWRDN_STS_CHGINT exit from hibernation flow is
+		 * the same as in GPWRDN_DISCONN_DET flow. Call
+		 * disconnect detect helper function to exit from
+		 * hibernation.
+		 */
+		dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
 	}
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (3 preceding siblings ...)
  2021-04-15  5:39 ` [PATCH 04/15] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 06/15] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

When device cable is disconnected core receives suspend
interrupt and enters hibernation. After entering
into hibernation GPWRDN_RST_DET and GPWRDN_STS_CHGINT
interrupts are asserted.

Allowed exit from gadget hibernation from
GPWRDN_RST_DET by checking only linestate.

Changed the return type of "dwc2_handle_gpwrdn_intr()"
function from void to int because exit from hibernation
functions have a return value.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 27d729fad227..f8963c0cf6af 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -751,10 +751,11 @@ static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
  * The GPWRDN interrupts are those that occur in both Host and
  * Device mode while core is in hibernated state.
  */
-static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
+static int dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 {
 	u32 gpwrdn;
 	int linestate;
+	int ret = 0;
 
 	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 	/* clear all interrupt */
@@ -778,17 +779,27 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 		if (hsotg->hw_params.hibernation &&
 		    hsotg->hibernated) {
 			if (gpwrdn & GPWRDN_IDSTS) {
-				dwc2_exit_hibernation(hsotg, 0, 0, 0);
+				ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit hibernation failed.\n");
 				call_gadget(hsotg, resume);
 			} else {
-				dwc2_exit_hibernation(hsotg, 1, 0, 1);
+				ret = dwc2_exit_hibernation(hsotg, 1, 0, 1);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit hibernation failed.\n");
 			}
 		}
 	} else if ((gpwrdn & GPWRDN_RST_DET) &&
 		   (gpwrdn & GPWRDN_RST_DET_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
-		if (!linestate && (gpwrdn & GPWRDN_BSESSVLD))
-			dwc2_exit_hibernation(hsotg, 0, 1, 0);
+		if (!linestate) {
+			ret = dwc2_exit_hibernation(hsotg, 0, 1, 0);
+			if (ret)
+				dev_err(hsotg->dev,
+					"exit hibernation failed.\n");
+		}
 	} else if ((gpwrdn & GPWRDN_STS_CHGINT) &&
 		   (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
@@ -800,6 +811,8 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 		 */
 		dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
 	}
+
+	return ret;
 }
 
 /*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 06/15] usb: dwc2: Clear fifo_map when resetting core.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (4 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Switching from device mode to host mode by disconnecting
device cable core enters and exits form hibernation.
However, the fifo map remains not cleared. It results
to a WARNING (WARNING: CPU: 5 PID: 0 at drivers/usb/dwc2/
gadget.c:307 dwc2_hsotg_init_fifo+0x12/0x152 [dwc2])
if in host mode we disconnect the micro a to b host
cable. Because core reset occurs.

To avoid the WARNING, fifo_map should be cleared
in dwc2_core_reset() function by taking into account configs.
fifo_map must be cleared only if driver is configured in
"CONFIG_USB_DWC2_PERIPHERAL" or "CONFIG_USB_DWC2_DUAL_ROLE"
mode.

- Added "static inline void dwc2_clear_fifo_map()" helper
function to clear fifo_map with peripheral or dual role mode.

- Added a dummy version of "dwc2_clear_fifo_map()" helper
for host-only mode.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.c | 16 ++++++++++++++++
 drivers/usb/dwc2/core.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index cb65f7f60573..eccd96fa164e 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -470,6 +470,22 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait)
 		dwc2_writel(hsotg, greset, GRSTCTL);
 	}
 
+	/*
+	 * Switching from device mode to host mode by disconnecting
+	 * device cable core enters and exits form hibernation.
+	 * However, the fifo map remains not cleared. It results
+	 * to a WARNING (WARNING: CPU: 5 PID: 0 at drivers/usb/dwc2/
+	 * gadget.c:307 dwc2_hsotg_init_fifo+0x12/0x152 [dwc2])
+	 * if in host mode we disconnect the micro a to b host
+	 * cable. Because core reset occurs.
+	 * To avoid the WARNING, fifo_map should be cleared
+	 * in dwc2_core_reset() function by taking into account configs.
+	 * fifo_map must be cleared only if driver is configured in
+	 * "CONFIG_USB_DWC2_PERIPHERAL" or "CONFIG_USB_DWC2_DUAL_ROLE"
+	 * mode.
+	 */
+	dwc2_clear_fifo_map(hsotg);
+
 	/* Wait for AHB master IDLE state */
 	if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 10000)) {
 		dev_warn(hsotg->dev, "%s: HANG! AHB Idle timeout GRSTCTL GRSTCTL_AHBIDLE\n",
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 8c12b3061f7f..e1f432095565 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1423,6 +1423,8 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
 void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
 void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg);
+static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg)
+{ hsotg->fifo_map = 0; }
 #else
 static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
 { return 0; }
@@ -1467,6 +1469,7 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {}
 static inline void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) {}
 #endif
 
 #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (5 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 06/15] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

When hibernation exit is performed the dwc2_hib_restore_common()
function is called. In that function we wait until GINTSTS_RESTOREDONE
bit is set. However, after the setting of that bit we get a lot of
(dwc2_hsotg_irq:) interrupts which indicates that (GINTSTS.RstrDoneInt)
restore done interrupt is asserted.

To avoid restore done interrupt storm after restore is generated
clear GINTSTS_RESTOREDONE bit in GINTSTS register.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index eccd96fa164e..576c262dba55 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -299,6 +299,12 @@ void dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup,
 			__func__);
 	} else {
 		dev_dbg(hsotg->dev, "restore done  generated here\n");
+
+		/*
+		 * To avoid restore done interrupt storm after restore is
+		 * generated clear GINTSTS_RESTOREDONE bit.
+		 */
+		dwc2_writel(hsotg, GINTSTS_RESTOREDONE, GINTSTS);
 	}
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (6 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

This move is done to call enter hibernation handler in
"dwc2_port_suspend()" function when core receives port suspend.
Otherwise it could be confusing to enter to hibernation in
"dwc2_hcd_hub_control()" function but other power saving modes
in "dwc2_port_suspend()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index ff945c40ef8a..43a2298b7d42 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3321,6 +3321,18 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 				"enter partial_power_down failed.\n");
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		/*
+		 * Perform spin unlock and lock because in
+		 * "dwc2_host_enter_hibernation()" function there is a spinlock
+		 * logic which prevents servicing of any IRQ during entering
+		 * hibernation.
+		 */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		ret = dwc2_enter_hibernation(hsotg, 1);
+		if (ret)
+			dev_err(hsotg->dev, "enter hibernation failed.\n");
+		spin_lock_irqsave(&hsotg->lock, flags);
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
@@ -3650,10 +3662,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
 			if (windex != hsotg->otg_port)
 				goto error;
-			if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION)
-				dwc2_enter_hibernation(hsotg, 1);
-			else
-				dwc2_port_suspend(hsotg, windex);
+			if (!hsotg->bus_suspended)
+				retval = dwc2_port_suspend(hsotg, windex);
 			break;
 
 		case USB_PORT_FEAT_POWER:
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (7 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

This move is done to call hibernation exit handler in
"dwc2_port_resume()" function when core receives port resume.
Otherwise it could be confusing to exit hibernation in
"dwc2_hcd_hub_control()" function but other power saving modes
in "dwc2_port_resume()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 43a2298b7d42..cc9ad6cf02d9 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3383,6 +3383,11 @@ int dwc2_port_resume(struct dwc2_hsotg *hsotg)
 				"exit partial_power_down failed.\n");
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		/* Exit host hibernation. */
+		ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+		if (ret)
+			dev_err(hsotg->dev, "exit hibernation failed.\n");
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
@@ -3446,12 +3451,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			dev_dbg(hsotg->dev,
 				"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
 
-			if (hsotg->bus_suspended) {
-				if (hsotg->hibernated)
-					dwc2_exit_hibernation(hsotg, 0, 0, 1);
-				else
-					dwc2_port_resume(hsotg);
-			}
+			if (hsotg->bus_suspended)
+				retval = dwc2_port_resume(hsotg);
 			break;
 
 		case USB_PORT_FEAT_POWER:
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (8 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  9:12   ` Sergei Shtylyov
  2021-04-15  5:40 ` [PATCH 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When core is in hibernation state and an external
hub is connected, upper layer sends URB enqueue request,
which results in port reset issue.

- Added exit from hibernation state to avoid port
reset issue and process upper layer request properly.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index cc9ad6cf02d9..3b03b2d73aaa 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4631,12 +4631,29 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 	struct dwc2_qh *qh;
 	bool qh_allocated = false;
 	struct dwc2_qtd *qtd;
+	struct dwc2_gregs_backup *gr;
+
+	gr = &hsotg->gr_backup;
 
 	if (dbg_urb(urb)) {
 		dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
 		dwc2_dump_urb_info(hcd, urb, "urb_enqueue");
 	}
 
+	if (hsotg->hibernated) {
+		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
+			retval = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+			if (retval)
+				dev_err(hsotg->dev,
+					"exit hibernation failed.\n");
+		} else {
+			retval = dwc2_exit_hibernation(hsotg, 0, 0, 0);
+			if (retval)
+				dev_err(hsotg->dev,
+					"exit hibernation failed.\n");
+		}
+	}
+
 	if (hsotg->in_ppd) {
 		retval = dwc2_exit_partial_power_down(hsotg, 0, true);
 		if (retval)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 11/15] usb: dwc2: Add hibernation entering flow by system suspend
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (9 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:40 ` [PATCH 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Adds a new flow of entering hibernation when PC is
hibernated or suspended.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 3b03b2d73aaa..db8eb1940d17 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4387,6 +4387,16 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		/* Enter hibernation */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		ret = dwc2_enter_hibernation(hsotg, 1);
+		if (ret)
+			dev_err(hsotg->dev, "enter hibernation failed\n");
+		spin_lock_irqsave(&hsotg->lock, flags);
+
+		/* After entering suspend, hardware is not accessible */
+		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 12/15] usb: dwc2: Add hibernation exiting flow by system resume
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (10 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
@ 2021-04-15  5:40 ` Artur Petrosyan
  2021-04-15  5:41 ` [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:40 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Adds a new flow of exiting hibernation when PC is resumed
from suspend state.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index db8eb1940d17..c92307775863 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4470,6 +4470,16 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+		if (ret)
+			dev_err(hsotg->dev, "exit hibernation failed.\n");
+
+		/*
+		 * Set HW accessible bit before powering on the controller
+		 * since an interrupt may rise.
+		 */
+		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (11 preceding siblings ...)
  2021-04-15  5:40 ` [PATCH 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
@ 2021-04-15  5:41 ` Artur Petrosyan
  2021-04-15  9:24   ` Sergei Shtylyov
                     ` (2 more replies)
  2021-04-15  5:41 ` [PATCH 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
                   ` (17 subsequent siblings)
  30 siblings, 3 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:41 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When dwc2 core is in hibernation mode loading
driver again causes driver fail. Because in
that mode registers are not accessible.

In order to exit from hibernation checking
dwc2 core power saving state in "dwc2_driver_remove()"
function. If core is in hibernation, then checking the
operational mode of the driver. To check whether dwc2 core
is operating in host mode or device mode there is one way
which is retrieving the backup value of "gotgctl" and compare
the "CurMod" value. If previously core entered hibernation
in host mode then the exit is performed for host if not then
exit is performed for device mode. The introduced checking
is because in hibernation state all registers are not
accessible.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/platform.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index f8b819cfa80e..2ae4748ed5ec 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -316,8 +316,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 static int dwc2_driver_remove(struct platform_device *dev)
 {
 	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
+	struct dwc2_gregs_backup *gr;
 	int ret = 0;
 
+	/* Exit Hibernation when driver is removed. */
+	if (hsotg->hibernated) {
+		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
+			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+			if (ret)
+				dev_err(hsotg->dev,
+					"exit hibernation failed.\n");
+		} else {
+			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
+			if (ret)
+				dev_err(hsotg->dev,
+					"exit hibernation failed.\n");
+		}
+	}
+
 	/* Exit Partial Power Down when driver is removed. */
 	if (hsotg->in_ppd) {
 		ret = dwc2_exit_partial_power_down(hsotg, 0, true);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (12 preceding siblings ...)
  2021-04-15  5:41 ` [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
@ 2021-04-15  5:41 ` Artur Petrosyan
  2021-04-15  5:41 ` [PATCH 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:41 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

To avoid working in two modes (partial power down
and hibernation) changed conditions for entering
partial power down or hibernation.

Instead of checking hw_params.power_optimized and
hw_params.hibernation now checking power_down
param which already set to one of the options
(Hibernation or Partial Power Down) based on
OTG_EN_PWROPT.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index f8963c0cf6af..470458ac664b 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -532,7 +532,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 			return;
 		}
 		if (dsts & DSTS_SUSPSTS) {
-			if (hsotg->hw_params.power_optimized) {
+			switch (hsotg->params.power_down) {
+			case DWC2_POWER_DOWN_PARAM_PARTIAL:
 				ret = dwc2_enter_partial_power_down(hsotg);
 				if (ret) {
 					if (ret != -ENOTSUPP)
@@ -541,21 +542,22 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 							__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);
-			} else if (hsotg->hw_params.hibernation) {
+				break;
+			case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 				ret = dwc2_enter_hibernation(hsotg, 0);
 				if (ret && ret != -ENOTSUPP)
 					dev_err(hsotg->dev,
 						"%s: enter hibernation failed\n",
 						__func__);
-			} else {
+				break;
+			case DWC2_POWER_DOWN_PARAM_NONE:
 				/*
-				 * If not hibernation nor partial power down are supported,
+				 * If neither hibernation nor partial power down are supported,
 				 * clock gating is used to save power.
 				 */
 				dwc2_gadget_enter_clock_gating(hsotg);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (13 preceding siblings ...)
  2021-04-15  5:41 ` [PATCH 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
@ 2021-04-15  5:41 ` Artur Petrosyan
  2021-04-16 12:46 ` [PATCH v2 00/15] usb: dwc2: Fix Hibernation issues Artur Petrosyan
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-15  5:41 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Douglas Anderson

Squashed from Douglas Anderson's suggested commit
"usb: dwc2: Get rid of useless error checks for
hibernation/partial power down"

 - After this commit there should never be any
case where dwc2_enter_partial_power_down() and
dwc2_enter_hibernation() are called when
'params.power_down' is not correct.  Get rid of
the pile of error checking.

- As part of this cleanup some of the error messages
not to have __func__ in them.  That's not needed
for dev_err() calls since they already have the
device name as part of the message.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
 drivers/usb/dwc2/core.c      |  3 ---
 drivers/usb/dwc2/core_intr.c | 18 +++++++-----------
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 576c262dba55..6f70ab9577b4 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -391,9 +391,6 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)
  */
 int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host)
 {
-	if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_HIBERNATION)
-		return -ENOTSUPP;
-
 	if (is_host)
 		return dwc2_host_enter_hibernation(hsotg);
 	else
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 470458ac664b..a5ab03808da6 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -535,13 +535,10 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 			switch (hsotg->params.power_down) {
 			case DWC2_POWER_DOWN_PARAM_PARTIAL:
 				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;
-				}
+				if (ret)
+					dev_err(hsotg->dev,
+						"enter partial_power_down failed\n");
+
 				udelay(100);
 
 				/* Ask phy to be suspended */
@@ -550,10 +547,9 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 				break;
 			case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 				ret = dwc2_enter_hibernation(hsotg, 0);
-				if (ret && ret != -ENOTSUPP)
+				if (ret)
 					dev_err(hsotg->dev,
-						"%s: enter hibernation failed\n",
-						__func__);
+						"enter hibernation failed\n");
 				break;
 			case DWC2_POWER_DOWN_PARAM_NONE:
 				/*
@@ -562,7 +558,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 				 */
 				dwc2_gadget_enter_clock_gating(hsotg);
 			}
-skip_power_saving:
+
 			/*
 			 * Change to L2 (suspend) state before releasing
 			 * spinlock
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue
  2021-04-15  5:40 ` [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
@ 2021-04-15  9:12   ` Sergei Shtylyov
  2021-04-16  5:43     ` Artur Petrosyan
  0 siblings, 1 reply; 50+ messages in thread
From: Sergei Shtylyov @ 2021-04-15  9:12 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

On 15.04.2021 8:40, Artur Petrosyan wrote:

> When core is in hibernation state and an external
> hub is connected, upper layer sends URB enqueue request,
> which results in port reset issue.
> 
> - Added exit from hibernation state to avoid port
> reset issue and process upper layer request properly.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> ---
>   drivers/usb/dwc2/hcd.c | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index cc9ad6cf02d9..3b03b2d73aaa 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4631,12 +4631,29 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
>   	struct dwc2_qh *qh;
>   	bool qh_allocated = false;
>   	struct dwc2_qtd *qtd;
> +	struct dwc2_gregs_backup *gr;
> +
> +	gr = &hsotg->gr_backup;
>   
>   	if (dbg_urb(urb)) {
>   		dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
>   		dwc2_dump_urb_info(hcd, urb, "urb_enqueue");
>   	}
>   
> +	if (hsotg->hibernated) {
> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 1);
> +			if (retval)
> +				dev_err(hsotg->dev,
> +					"exit hibernation failed.\n");
> +		} else {
> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 0);
> +			if (retval)
> +				dev_err(hsotg->dev,
> +					"exit hibernation failed.\n");

    Why not put these identical *if*s outside the the outer *if*?


> +		}
> +	}
> +
>   	if (hsotg->in_ppd) {
>   		retval = dwc2_exit_partial_power_down(hsotg, 0, true);
>   		if (retval)

MBR, Sergei

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
  2021-04-15  5:41 ` [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
@ 2021-04-15  9:24   ` Sergei Shtylyov
  2021-04-16  5:46     ` Artur Petrosyan
  2021-04-15  9:50     ` kernel test robot
  2021-04-15 13:40     ` Dan Carpenter
  2 siblings, 1 reply; 50+ messages in thread
From: Sergei Shtylyov @ 2021-04-15  9:24 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

On 15.04.2021 8:41, Artur Petrosyan wrote:

> When dwc2 core is in hibernation mode loading
> driver again causes driver fail. Because in
> that mode registers are not accessible.
> 
> In order to exit from hibernation checking
> dwc2 core power saving state in "dwc2_driver_remove()"
> function. If core is in hibernation, then checking the
> operational mode of the driver. To check whether dwc2 core
> is operating in host mode or device mode there is one way
> which is retrieving the backup value of "gotgctl" and compare
> the "CurMod" value. If previously core entered hibernation
> in host mode then the exit is performed for host if not then
> exit is performed for device mode. The introduced checking
> is because in hibernation state all registers are not
> accessible.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> ---
>   drivers/usb/dwc2/platform.c | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
> index f8b819cfa80e..2ae4748ed5ec 100644
> --- a/drivers/usb/dwc2/platform.c
> +++ b/drivers/usb/dwc2/platform.c
> @@ -316,8 +316,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
>   static int dwc2_driver_remove(struct platform_device *dev)
>   {
>   	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
> +	struct dwc2_gregs_backup *gr;
>   	int ret = 0;
>   
> +	/* Exit Hibernation when driver is removed. */
> +	if (hsotg->hibernated) {
> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
> +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
> +			if (ret)
> +				dev_err(hsotg->dev,
> +					"exit hibernation failed.\n");
> +		} else {
> +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
> +			if (ret)
> +				dev_err(hsotg->dev,
> +					"exit hibernation failed.\n");

    Again, why duplicate the innermost *if*?

>  +		}
> +	}
> +
>   	/* Exit Partial Power Down when driver is removed. */
>   	if (hsotg->in_ppd) {
>   		ret = dwc2_exit_partial_power_down(hsotg, 0, true);

MBR, Sergei

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
  2021-04-15  5:41 ` [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
@ 2021-04-15  9:50     ` kernel test robot
  2021-04-15  9:50     ` kernel test robot
  2021-04-15 13:40     ` Dan Carpenter
  2 siblings, 0 replies; 50+ messages in thread
From: kernel test robot @ 2021-04-15  9:50 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: kbuild-all, clang-built-linux, John Youn, Artur Petrosyan

[-- Attachment #1: Type: text/plain, Size: 4672 bytes --]

Hi Artur,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on next-20210414]
[cannot apply to peter.chen-usb/for-usb-next linus/master balbi-usb/testing/next v5.12-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-randconfig-a014-20210415 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 6a18cc23efad410db48a3ccfc233d215de7d4cb9)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/8e4dbc0200040af9c752aca4090cd41572e6fb86
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021
        git checkout 8e4dbc0200040af9c752aca4090cd41572e6fb86
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/usb/dwc2/platform.c:324:7: warning: variable 'gr' is uninitialized when used here [-Wuninitialized]
                   if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
                       ^~
   drivers/usb/dwc2/platform.c:319:30: note: initialize the variable 'gr' to silence this warning
           struct dwc2_gregs_backup *gr;
                                       ^
                                        = NULL
   1 warning generated.


vim +/gr +324 drivers/usb/dwc2/platform.c

   304	
   305	/**
   306	 * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
   307	 * DWC_otg driver
   308	 *
   309	 * @dev: Platform device
   310	 *
   311	 * This routine is called, for example, when the rmmod command is executed. The
   312	 * device may or may not be electrically present. If it is present, the driver
   313	 * stops device processing. Any resources used on behalf of this device are
   314	 * freed.
   315	 */
   316	static int dwc2_driver_remove(struct platform_device *dev)
   317	{
   318		struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
   319		struct dwc2_gregs_backup *gr;
   320		int ret = 0;
   321	
   322		/* Exit Hibernation when driver is removed. */
   323		if (hsotg->hibernated) {
 > 324			if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
   325				ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
   326				if (ret)
   327					dev_err(hsotg->dev,
   328						"exit hibernation failed.\n");
   329			} else {
   330				ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
   331				if (ret)
   332					dev_err(hsotg->dev,
   333						"exit hibernation failed.\n");
   334			}
   335		}
   336	
   337		/* Exit Partial Power Down when driver is removed. */
   338		if (hsotg->in_ppd) {
   339			ret = dwc2_exit_partial_power_down(hsotg, 0, true);
   340			if (ret)
   341				dev_err(hsotg->dev,
   342					"exit partial_power_down failed\n");
   343		}
   344	
   345		/* Exit clock gating when driver is removed. */
   346		if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
   347		    hsotg->bus_suspended) {
   348			if (dwc2_is_device_mode(hsotg))
   349				dwc2_gadget_exit_clock_gating(hsotg, 0);
   350			else
   351				dwc2_host_exit_clock_gating(hsotg, 0);
   352		}
   353	
   354		dwc2_debugfs_exit(hsotg);
   355		if (hsotg->hcd_enabled)
   356			dwc2_hcd_remove(hsotg);
   357		if (hsotg->gadget_enabled)
   358			dwc2_hsotg_remove(hsotg);
   359	
   360		dwc2_drd_exit(hsotg);
   361	
   362		if (hsotg->params.activate_stm_id_vb_detection)
   363			regulator_disable(hsotg->usb33d);
   364	
   365		if (hsotg->ll_hw_enabled)
   366			dwc2_lowlevel_hw_disable(hsotg);
   367	
   368		reset_control_assert(hsotg->reset);
   369		reset_control_assert(hsotg->reset_ecc);
   370	
   371		return ret;
   372	}
   373	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 39577 bytes --]

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
@ 2021-04-15  9:50     ` kernel test robot
  0 siblings, 0 replies; 50+ messages in thread
From: kernel test robot @ 2021-04-15  9:50 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4792 bytes --]

Hi Artur,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on next-20210414]
[cannot apply to peter.chen-usb/for-usb-next linus/master balbi-usb/testing/next v5.12-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-randconfig-a014-20210415 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 6a18cc23efad410db48a3ccfc233d215de7d4cb9)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/8e4dbc0200040af9c752aca4090cd41572e6fb86
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021
        git checkout 8e4dbc0200040af9c752aca4090cd41572e6fb86
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/usb/dwc2/platform.c:324:7: warning: variable 'gr' is uninitialized when used here [-Wuninitialized]
                   if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
                       ^~
   drivers/usb/dwc2/platform.c:319:30: note: initialize the variable 'gr' to silence this warning
           struct dwc2_gregs_backup *gr;
                                       ^
                                        = NULL
   1 warning generated.


vim +/gr +324 drivers/usb/dwc2/platform.c

   304	
   305	/**
   306	 * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
   307	 * DWC_otg driver
   308	 *
   309	 * @dev: Platform device
   310	 *
   311	 * This routine is called, for example, when the rmmod command is executed. The
   312	 * device may or may not be electrically present. If it is present, the driver
   313	 * stops device processing. Any resources used on behalf of this device are
   314	 * freed.
   315	 */
   316	static int dwc2_driver_remove(struct platform_device *dev)
   317	{
   318		struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
   319		struct dwc2_gregs_backup *gr;
   320		int ret = 0;
   321	
   322		/* Exit Hibernation when driver is removed. */
   323		if (hsotg->hibernated) {
 > 324			if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
   325				ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
   326				if (ret)
   327					dev_err(hsotg->dev,
   328						"exit hibernation failed.\n");
   329			} else {
   330				ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
   331				if (ret)
   332					dev_err(hsotg->dev,
   333						"exit hibernation failed.\n");
   334			}
   335		}
   336	
   337		/* Exit Partial Power Down when driver is removed. */
   338		if (hsotg->in_ppd) {
   339			ret = dwc2_exit_partial_power_down(hsotg, 0, true);
   340			if (ret)
   341				dev_err(hsotg->dev,
   342					"exit partial_power_down failed\n");
   343		}
   344	
   345		/* Exit clock gating when driver is removed. */
   346		if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
   347		    hsotg->bus_suspended) {
   348			if (dwc2_is_device_mode(hsotg))
   349				dwc2_gadget_exit_clock_gating(hsotg, 0);
   350			else
   351				dwc2_host_exit_clock_gating(hsotg, 0);
   352		}
   353	
   354		dwc2_debugfs_exit(hsotg);
   355		if (hsotg->hcd_enabled)
   356			dwc2_hcd_remove(hsotg);
   357		if (hsotg->gadget_enabled)
   358			dwc2_hsotg_remove(hsotg);
   359	
   360		dwc2_drd_exit(hsotg);
   361	
   362		if (hsotg->params.activate_stm_id_vb_detection)
   363			regulator_disable(hsotg->usb33d);
   364	
   365		if (hsotg->ll_hw_enabled)
   366			dwc2_lowlevel_hw_disable(hsotg);
   367	
   368		reset_control_assert(hsotg->reset);
   369		reset_control_assert(hsotg->reset_ecc);
   370	
   371		return ret;
   372	}
   373	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 39577 bytes --]

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [kbuild] Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
  2021-04-15  5:41 ` [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
  2021-04-15  9:24   ` Sergei Shtylyov
@ 2021-04-15 13:40     ` Dan Carpenter
  2021-04-15 13:40     ` Dan Carpenter
  2 siblings, 0 replies; 50+ messages in thread
From: Dan Carpenter @ 2021-04-15 13:40 UTC (permalink / raw)
  To: kbuild, Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: lkp, kbuild-all, John Youn, Artur Petrosyan

[-- Attachment #1: Type: text/plain, Size: 3257 bytes --]

Hi Artur,

https://git-scm.com/docs/git-format-patch ]

url:    https://github.com/0day-ci/linux/commits/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021 
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git  usb-testing
config: i386-randconfig-m021-20210415 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/usb/dwc2/platform.c:324 dwc2_driver_remove() error: potentially dereferencing uninitialized 'gr'.

vim +/gr +324 drivers/usb/dwc2/platform.c

5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  316  static int dwc2_driver_remove(struct platform_device *dev)
5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  317  {
5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  318  	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  319  	struct dwc2_gregs_backup *gr;
                                                                                                                  ^^
b46b1ef7b0da5c drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-08  320  	int ret = 0;
b46b1ef7b0da5c drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-08  321  
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  322  	/* Exit Hibernation when driver is removed. */
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  323  	if (hsotg->hibernated) {
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15 @324  		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
                                                                                                    ^^^^^^^^^^^
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  325  			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  326  			if (ret)
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  327  				dev_err(hsotg->dev,
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  328  					"exit hibernation failed.\n");
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  329  		} else {
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  330  			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  331  			if (ret)
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  332  				dev_err(hsotg->dev,
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  333  					"exit hibernation failed.\n");
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  334  		}
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  335  	}

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org 

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 39329 bytes --]

[-- Attachment #3: Type: text/plain, Size: 149 bytes --]

_______________________________________________
kbuild mailing list -- kbuild@lists.01.org
To unsubscribe send an email to kbuild-leave@lists.01.org

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
@ 2021-04-15 13:40     ` Dan Carpenter
  0 siblings, 0 replies; 50+ messages in thread
From: Dan Carpenter @ 2021-04-15 13:40 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 3461 bytes --]

Hi Artur,

https://git-scm.com/docs/git-format-patch ]

url:    https://github.com/0day-ci/linux/commits/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021 
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git  usb-testing
config: i386-randconfig-m021-20210415 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/usb/dwc2/platform.c:324 dwc2_driver_remove() error: potentially dereferencing uninitialized 'gr'.

vim +/gr +324 drivers/usb/dwc2/platform.c

5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  316  static int dwc2_driver_remove(struct platform_device *dev)
5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  317  {
5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  318  	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  319  	struct dwc2_gregs_backup *gr;
                                                                                                                  ^^
b46b1ef7b0da5c drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-08  320  	int ret = 0;
b46b1ef7b0da5c drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-08  321  
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  322  	/* Exit Hibernation when driver is removed. */
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  323  	if (hsotg->hibernated) {
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15 @324  		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
                                                                                                    ^^^^^^^^^^^
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  325  			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  326  			if (ret)
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  327  				dev_err(hsotg->dev,
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  328  					"exit hibernation failed.\n");
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  329  		} else {
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  330  			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  331  			if (ret)
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  332  				dev_err(hsotg->dev,
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  333  					"exit hibernation failed.\n");
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  334  		}
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  335  	}

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org 

_______________________________________________
kbuild mailing list -- kbuild(a)lists.01.org
To unsubscribe send an email to kbuild-leave(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 39329 bytes --]

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [kbuild] Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
@ 2021-04-15 13:40     ` Dan Carpenter
  0 siblings, 0 replies; 50+ messages in thread
From: Dan Carpenter @ 2021-04-15 13:40 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3461 bytes --]

Hi Artur,

https://git-scm.com/docs/git-format-patch ]

url:    https://github.com/0day-ci/linux/commits/Artur-Petrosyan/usb-dwc2-Update-exit-hibernation-when-port-reset-is-asserted/20210415-144021 
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git  usb-testing
config: i386-randconfig-m021-20210415 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/usb/dwc2/platform.c:324 dwc2_driver_remove() error: potentially dereferencing uninitialized 'gr'.

vim +/gr +324 drivers/usb/dwc2/platform.c

5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  316  static int dwc2_driver_remove(struct platform_device *dev)
5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  317  {
5b9974b13e3648 drivers/staging/dwc2/platform.c Matthijs Kooijman  2013-04-22  318  	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  319  	struct dwc2_gregs_backup *gr;
                                                                                                                  ^^
b46b1ef7b0da5c drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-08  320  	int ret = 0;
b46b1ef7b0da5c drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-08  321  
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  322  	/* Exit Hibernation when driver is removed. */
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  323  	if (hsotg->hibernated) {
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15 @324  		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
                                                                                                    ^^^^^^^^^^^
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  325  			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  326  			if (ret)
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  327  				dev_err(hsotg->dev,
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  328  					"exit hibernation failed.\n");
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  329  		} else {
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  330  			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  331  			if (ret)
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  332  				dev_err(hsotg->dev,
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  333  					"exit hibernation failed.\n");
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  334  		}
8e4dbc0200040a drivers/usb/dwc2/platform.c     Artur Petrosyan    2021-04-15  335  	}

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org 

_______________________________________________
kbuild mailing list -- kbuild(a)lists.01.org
To unsubscribe send an email to kbuild-leave(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 39329 bytes --]

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue
  2021-04-15  9:12   ` Sergei Shtylyov
@ 2021-04-16  5:43     ` Artur Petrosyan
  2021-04-16  7:05       ` Artur Petrosyan
  0 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16  5:43 UTC (permalink / raw)
  To: Sergei Shtylyov, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

Hi Sergei,

On 4/15/2021 13:12, Sergei Shtylyov wrote:
> On 15.04.2021 8:40, Artur Petrosyan wrote:
> 
>> When core is in hibernation state and an external
>> hub is connected, upper layer sends URB enqueue request,
>> which results in port reset issue.
>>
>> - Added exit from hibernation state to avoid port
>> reset issue and process upper layer request properly.
>>
>> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
>> ---
>>    drivers/usb/dwc2/hcd.c | 17 +++++++++++++++++
>>    1 file changed, 17 insertions(+)
>>
>> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
>> index cc9ad6cf02d9..3b03b2d73aaa 100644
>> --- a/drivers/usb/dwc2/hcd.c
>> +++ b/drivers/usb/dwc2/hcd.c
>> @@ -4631,12 +4631,29 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
>>    	struct dwc2_qh *qh;
>>    	bool qh_allocated = false;
>>    	struct dwc2_qtd *qtd;
>> +	struct dwc2_gregs_backup *gr;
>> +
>> +	gr = &hsotg->gr_backup;
>>    
>>    	if (dbg_urb(urb)) {
>>    		dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
>>    		dwc2_dump_urb_info(hcd, urb, "urb_enqueue");
>>    	}
>>    
>> +	if (hsotg->hibernated) {
>> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
>> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 1);
>> +			if (retval)
>> +				dev_err(hsotg->dev,
>> +					"exit hibernation failed.\n");
>> +		} else {
>> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 0);
>> +			if (retval)
>> +				dev_err(hsotg->dev,
>> +					"exit hibernation failed.\n");
> 
>      Why not put these identical *if*s outside the the outer *if*?
> 
Well the reason that the conditions are implemented like they are, is 
that the inner if checks whether core operates in host mode or device 
mode and the outside if checks if the core is hibernated or not.

So now imagine that the ifs are combined and core is not hibernated but 
the operational mode of the driver is let's say gadget. If the case is 
such then the driver will try to exit from gadget hibernation because of 
the else condition as the if condition will be false again because core 
is not hibernated. As a result if we combine the outside and inner ifs 
then it will try to exit from gadget hibernation but core is not 
hibernated and that would be an issue.


> 
>> +		}
>> +	}
>> +
>>    	if (hsotg->in_ppd) {
>>    		retval = dwc2_exit_partial_power_down(hsotg, 0, true);
>>    		if (retval)
> 
> MBR, Sergei
> 

Regards,
Artur

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive
  2021-04-15  9:24   ` Sergei Shtylyov
@ 2021-04-16  5:46     ` Artur Petrosyan
  0 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16  5:46 UTC (permalink / raw)
  To: Sergei Shtylyov, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

Hi Sergei,

On 4/15/2021 13:24, Sergei Shtylyov wrote:
> On 15.04.2021 8:41, Artur Petrosyan wrote:
> 
>> When dwc2 core is in hibernation mode loading
>> driver again causes driver fail. Because in
>> that mode registers are not accessible.
>>
>> In order to exit from hibernation checking
>> dwc2 core power saving state in "dwc2_driver_remove()"
>> function. If core is in hibernation, then checking the
>> operational mode of the driver. To check whether dwc2 core
>> is operating in host mode or device mode there is one way
>> which is retrieving the backup value of "gotgctl" and compare
>> the "CurMod" value. If previously core entered hibernation
>> in host mode then the exit is performed for host if not then
>> exit is performed for device mode. The introduced checking
>> is because in hibernation state all registers are not
>> accessible.
>>
>> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
>> ---
>>    drivers/usb/dwc2/platform.c | 16 ++++++++++++++++
>>    1 file changed, 16 insertions(+)
>>
>> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
>> index f8b819cfa80e..2ae4748ed5ec 100644
>> --- a/drivers/usb/dwc2/platform.c
>> +++ b/drivers/usb/dwc2/platform.c
>> @@ -316,8 +316,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
>>    static int dwc2_driver_remove(struct platform_device *dev)
>>    {
>>    	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
>> +	struct dwc2_gregs_backup *gr;
>>    	int ret = 0;
>>    
>> +	/* Exit Hibernation when driver is removed. */
>> +	if (hsotg->hibernated) {
>> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
>> +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
>> +			if (ret)
>> +				dev_err(hsotg->dev,
>> +					"exit hibernation failed.\n");
>> +		} else {
>> +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
>> +			if (ret)
>> +				dev_err(hsotg->dev,
>> +					"exit hibernation failed.\n");
> 
>      Again, why duplicate the innermost *if*?
Again the reason is that combination of inner and outside ifs would give 
as a situation when core would not be hibernated but driver would try to 
exit from host or device hibernation.

> 
>>   +		}
>> +	}
>> +
>>    	/* Exit Partial Power Down when driver is removed. */
>>    	if (hsotg->in_ppd) {
>>    		ret = dwc2_exit_partial_power_down(hsotg, 0, true);
> 
> MBR, Sergei
> 
Regards,
Artur

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue
  2021-04-16  5:43     ` Artur Petrosyan
@ 2021-04-16  7:05       ` Artur Petrosyan
  0 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16  7:05 UTC (permalink / raw)
  To: Artur Petrosyan, Sergei Shtylyov, Felipe Balbi,
	Greg Kroah-Hartman, Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

Hi Sergei,

On 4/16/2021 09:43, Artur Petrosyan wrote:
> Hi Sergei,
> 
> On 4/15/2021 13:12, Sergei Shtylyov wrote:
>> On 15.04.2021 8:40, Artur Petrosyan wrote:
>>
>>> When core is in hibernation state and an external
>>> hub is connected, upper layer sends URB enqueue request,
>>> which results in port reset issue.
>>>
>>> - Added exit from hibernation state to avoid port
>>> reset issue and process upper layer request properly.
>>>
>>> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
>>> ---
>>>     drivers/usb/dwc2/hcd.c | 17 +++++++++++++++++
>>>     1 file changed, 17 insertions(+)
>>>
>>> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
>>> index cc9ad6cf02d9..3b03b2d73aaa 100644
>>> --- a/drivers/usb/dwc2/hcd.c
>>> +++ b/drivers/usb/dwc2/hcd.c
>>> @@ -4631,12 +4631,29 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
>>>     	struct dwc2_qh *qh;
>>>     	bool qh_allocated = false;
>>>     	struct dwc2_qtd *qtd;
>>> +	struct dwc2_gregs_backup *gr;
>>> +
>>> +	gr = &hsotg->gr_backup;
>>>     
>>>     	if (dbg_urb(urb)) {
>>>     		dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
>>>     		dwc2_dump_urb_info(hcd, urb, "urb_enqueue");
>>>     	}
>>>     
>>> +	if (hsotg->hibernated) {
>>> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST) {
>>> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 1);
>>> +			if (retval)
>>> +				dev_err(hsotg->dev,
>>> +					"exit hibernation failed.\n");
>>> +		} else {
>>> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 0);
>>> +			if (retval)
>>> +				dev_err(hsotg->dev,
>>> +					"exit hibernation failed.\n");
>>
>>       Why not put these identical *if*s outside the the outer *if*?
>>
> Well the reason that the conditions are implemented like they are, is
> that the inner if checks whether core operates in host mode or device
> mode and the outside if checks if the core is hibernated or not.
> 
> So now imagine that the ifs are combined and core is not hibernated but
> the operational mode of the driver is let's say gadget. If the case is
> such then the driver will try to exit from gadget hibernation because of
> the else condition as the if condition will be false again because core
> is not hibernated. As a result if we combine the outside and inner ifs
> then it will try to exit from gadget hibernation but core is not
> hibernated and that would be an issue.
> 

Sorry I got your point wrong there. You meant the ifs for dev_err().
Thank you for the review I will update them.

> 
>>
>>> +		}
>>> +	}
>>> +
>>>     	if (hsotg->in_ppd) {
>>>     		retval = dwc2_exit_partial_power_down(hsotg, 0, true);
>>>     		if (retval)
>>
>> MBR, Sergei
>>
> 
> Regards,
> Artur
> 

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v2 00/15] usb: dwc2: Fix Hibernation issues.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (14 preceding siblings ...)
  2021-04-15  5:41 ` [PATCH 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
@ 2021-04-16 12:46 ` Artur Petrosyan
  2021-04-16 12:46 ` [PATCH v2 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:46 UTC (permalink / raw)
  To: John Youn, Felipe Balbi, Greg Kroah-Hartman, Artur Petrosyan,
	Minas Harutyunyan, Vardan Mikayelyan, Grigor Tovmasyan,
	linux-usb, linux-kernel
  Cc: Artur Petrosyan, Minas Harutyunyan, Douglas Anderson

This patch set fixes and improves hibernation mode for dwc2 core.
It adds support for the following cases
    1. Hibernation entering/exiting flow by system suspend/resume.
    2. Exiting hibernation mode before removing driver and urb enqueue.
    3. Exiting hibernation from gpwrdn rst detect.

It updates the implementation of dwc2 entering and exiting
hibernation mode when a port is suspended or resumed or reset asserted.

It fixes hibernation issues between host and device mode when core
enters to hibernation in host mode and mode change happens. Also, a fix
is introduced for remote wakeup flow.

The patch set also improves implementation of entering to hibernation
from dwc2_handle_usb_suspend_intr() handler.

Changes since V1:
Updated bellow patches. Moved duplicated error checking *if* conditions
from innermost to outside if.
1. usb: dwc2: Add exit hibernation mode before removing drive
2. usb: dwc2: Allow exit hibernation in urb enqueue

Fixed an uninitialized pointer variable which was reported by
kernel test robot in "usb: dwc2: Add exit hibernation mode before
removing drive" patch. After fixing added Reported-by tags for
kernel test robot and Dan Carpenter.

Also removed some text from cover letter because I think that is
why vger.kernel.org was rejecting it.


Artur Petrosyan (15):
  usb: dwc2: Update exit hibernation when port reset is asserted
  usb: dwc2: Reset DEVADDR after exiting gadget hibernation.
  usb: dwc2: Fix host mode hibernation exit with remote wakeup flow.
  usb: dwc2: Fix hibernation between host and device modes.
  usb: dwc2: Allow exiting hibernation from gpwrdn rst detect
  usb: dwc2: Clear fifo_map when resetting core.
  usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated.
  usb: dwc2: Move enter hibernation to dwc2_port_suspend() function
  usb: dwc2: Move exit hibernation to dwc2_port_resume() function
  usb: dwc2: Allow exit hibernation in urb enqueue
  usb: dwc2: Add hibernation entering flow by system suspend
  usb: dwc2: Add hibernation exiting flow by system resume
  usb: dwc2: Add exit hibernation mode before removing drive
  usb: dwc2: Update dwc2_handle_usb_suspend_intr function.
  usb: dwc2: Get rid of useless error checks in suspend interrupt

 drivers/usb/dwc2/core.c      |  25 ++++-
 drivers/usb/dwc2/core.h      |   3 +
 drivers/usb/dwc2/core_intr.c | 205 +++++++++++++++++++----------------
 drivers/usb/dwc2/gadget.c    |   4 +
 drivers/usb/dwc2/hcd.c       |  92 +++++++++++++---
 drivers/usb/dwc2/platform.c  |  15 +++
 6 files changed, 233 insertions(+), 111 deletions(-)


base-commit: 4b853c236c7b5161a2e444bd8b3c76fe5aa5ddcb
-- 
2.25.1


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v2 01/15] usb: dwc2: Update exit hibernation when port reset is asserted
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (15 preceding siblings ...)
  2021-04-16 12:46 ` [PATCH v2 00/15] usb: dwc2: Fix Hibernation issues Artur Petrosyan
@ 2021-04-16 12:46 ` Artur Petrosyan
  2021-04-19  7:30   ` Minas Harutyunyan
  2021-04-16 12:46 ` [PATCH v2 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
                   ` (13 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:46 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

No need to check for "DWC2_POWER_DOWN_PARAM_HIBERNATION" param
as "hsotg->hibernated" flag is already enough for exiting from
hibernation mode.

- Removes checking of "DWC2_POWER_DOWN_PARAM_HIBERNATION" param.

- For code readability Hibernation exit code moved after
debug message print.

- Added "dwc2_exit_hibernation()" function error checking.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 04a1b53d65af..cda3f931195d 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3668,9 +3668,17 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			break;
 
 		case USB_PORT_FEAT_RESET:
-			if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION &&
-			    hsotg->hibernated)
-				dwc2_exit_hibernation(hsotg, 0, 1, 1);
+			dev_dbg(hsotg->dev,
+				"SetPortFeature - USB_PORT_FEAT_RESET\n");
+
+			hprt0 = dwc2_read_hprt0(hsotg);
+
+			if (hsotg->hibernated) {
+				retval = dwc2_exit_hibernation(hsotg, 0, 1, 1);
+				if (retval)
+					dev_err(hsotg->dev,
+						"exit hibernation failed\n");
+			}
 
 			if (hsotg->in_ppd) {
 				retval = dwc2_exit_partial_power_down(hsotg, 1,
@@ -3684,9 +3692,6 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
 				dwc2_host_exit_clock_gating(hsotg, 0);
 
-			hprt0 = dwc2_read_hprt0(hsotg);
-			dev_dbg(hsotg->dev,
-				"SetPortFeature - USB_PORT_FEAT_RESET\n");
 			pcgctl = dwc2_readl(hsotg, PCGCTL);
 			pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK);
 			dwc2_writel(hsotg, pcgctl, PCGCTL);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (16 preceding siblings ...)
  2021-04-16 12:46 ` [PATCH v2 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
@ 2021-04-16 12:46 ` Artur Petrosyan
  2021-04-16 12:47 ` [PATCH v2 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:46 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Initially resetting device address was done in dwc2_hsotg_irq()
interrupt handler. However, when core is hibernated USB RESET
is not handled in dwc2_hsotg_irq() handler, instead USB RESET
interrupt is handled in dwc2_handle_gpwrdn_intr() handler.

- Added reset device address to zero when core exits from gadget
  hibernation.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/gadget.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 2f50f3e62caa..e6bb1bdb2760 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -5305,6 +5305,10 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
 	dwc2_writel(hsotg, dr->dcfg, DCFG);
 	dwc2_writel(hsotg, dr->dctl, DCTL);
 
+	/* On USB Reset, reset device address to zero */
+	if (reset)
+		dwc2_clear_bit(hsotg, DCFG, DCFG_DEVADDR_MASK);
+
 	/* De-assert Wakeup Logic */
 	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 	gpwrdn &= ~GPWRDN_PMUACTV;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (17 preceding siblings ...)
  2021-04-16 12:46 ` [PATCH v2 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-19  7:30   ` Minas Harutyunyan
  2021-04-16 12:47 ` [PATCH v2 04/15] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
                   ` (11 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: John Youn, Felipe Balbi, Greg Kroah-Hartman, Artur Petrosyan,
	Minas Harutyunyan, Vardan Mikayelyan, Grigor Tovmasyan,
	linux-usb, linux-kernel
  Cc: Artur Petrosyan

Added setting "port_connect_status_change" flag to "1" in order
to re-enumerate, because after exit from hibernation port
connection status is not detected.

Fixes: c5c403dc4336 ("usb: dwc2: Add host/device hibernation functions")
Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index cda3f931195d..ff945c40ef8a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5650,7 +5650,15 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
 		return ret;
 	}
 
-	dwc2_hcd_rem_wakeup(hsotg);
+	if (rem_wakeup) {
+		dwc2_hcd_rem_wakeup(hsotg);
+		/*
+		 * Change "port_connect_status_change" flag to re-enumerate,
+		 * because after exit from hibernation port connection status
+		 * is not detected.
+		 */
+		hsotg->flags.b.port_connect_status_change = 1;
+	}
 
 	hsotg->hibernated = 0;
 	hsotg->bus_suspended = 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 04/15] usb: dwc2: Fix hibernation between host and device modes.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (18 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-16 12:47 ` [PATCH v2 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Artur Petrosyan,
	Minas Harutyunyan, Vardan Mikayelyan, Grigor Tovmasyan,
	linux-usb, linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

When core is in hibernation in host mode and a device cable
was connected then driver exited from device hibernation.
However, registers saved for host mode and when exited from
device hibernation register restore would be done for device
register which was wrong because there was no device registers
stored to restore.

- Added dwc_handle_gpwrdn_disc_det() function which handles
  gpwrdn disconnect detect flow and exits hibernation
  without restoring the registers.
- Updated exiting from hibernation in GPWRDN_STS_CHGINT with
  calling dwc_handle_gpwrdn_disc_det() function. Here no register
  is restored which is the solution described above.

Fixes: 65c9c4c6b01f ("usb: dwc2: Add dwc2_handle_gpwrdn_intr() handler")
Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 154 +++++++++++++++++++----------------
 1 file changed, 83 insertions(+), 71 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 550c52c1a0c7..27d729fad227 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -680,6 +680,71 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
 		return 0;
 }
 
+/**
+ * dwc_handle_gpwrdn_disc_det() - Handles the gpwrdn disconnect detect.
+ * Exits hibernation without restoring registers.
+ *
+ * @hsotg: Programming view of DWC_otg controller
+ * @gpwrdn: GPWRDN register
+ */
+static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
+					      u32 gpwrdn)
+{
+	u32 gpwrdn_tmp;
+
+	/* Switch-on voltage to the core */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Reset core */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Disable Power Down Clamp */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Deassert reset core */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+	udelay(5);
+
+	/* Disable PMU interrupt */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+
+	/* De-assert Wakeup Logic */
+	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
+	gpwrdn_tmp &= ~GPWRDN_PMUACTV;
+	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
+
+	hsotg->hibernated = 0;
+	hsotg->bus_suspended = 0;
+
+	if (gpwrdn & GPWRDN_IDSTS) {
+		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
+		dwc2_core_init(hsotg, false);
+		dwc2_enable_global_interrupts(hsotg);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		dwc2_hsotg_core_connect(hsotg);
+	} else {
+		hsotg->op_state = OTG_STATE_A_HOST;
+
+		/* Initialize the Core for Host mode */
+		dwc2_core_init(hsotg, false);
+		dwc2_enable_global_interrupts(hsotg);
+		dwc2_hcd_start(hsotg);
+	}
+}
+
 /*
  * GPWRDN interrupt handler.
  *
@@ -701,64 +766,14 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 
 	if ((gpwrdn & GPWRDN_DISCONN_DET) &&
 	    (gpwrdn & GPWRDN_DISCONN_DET_MSK) && !linestate) {
-		u32 gpwrdn_tmp;
-
 		dev_dbg(hsotg->dev, "%s: GPWRDN_DISCONN_DET\n", __func__);
-
-		/* Switch-on voltage to the core */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Reset core */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Disable Power Down Clamp */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Deassert reset core */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-		udelay(10);
-
-		/* Disable PMU interrupt */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-
-		/* De-assert Wakeup Logic */
-		gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
-		gpwrdn_tmp &= ~GPWRDN_PMUACTV;
-		dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
-
-		hsotg->hibernated = 0;
-
-		if (gpwrdn & GPWRDN_IDSTS) {
-			hsotg->op_state = OTG_STATE_B_PERIPHERAL;
-			dwc2_core_init(hsotg, false);
-			dwc2_enable_global_interrupts(hsotg);
-			dwc2_hsotg_core_init_disconnected(hsotg, false);
-			dwc2_hsotg_core_connect(hsotg);
-		} else {
-			hsotg->op_state = OTG_STATE_A_HOST;
-
-			/* Initialize the Core for Host mode */
-			dwc2_core_init(hsotg, false);
-			dwc2_enable_global_interrupts(hsotg);
-			dwc2_hcd_start(hsotg);
-		}
-	}
-
-	if ((gpwrdn & GPWRDN_LNSTSCHG) &&
-	    (gpwrdn & GPWRDN_LNSTSCHG_MSK) && linestate) {
+		/*
+		 * Call disconnect detect function to exit from
+		 * hibernation
+		 */
+		dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
+	} else if ((gpwrdn & GPWRDN_LNSTSCHG) &&
+		   (gpwrdn & GPWRDN_LNSTSCHG_MSK) && linestate) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_LNSTSCHG\n", __func__);
 		if (hsotg->hw_params.hibernation &&
 		    hsotg->hibernated) {
@@ -769,24 +784,21 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 				dwc2_exit_hibernation(hsotg, 1, 0, 1);
 			}
 		}
-	}
-	if ((gpwrdn & GPWRDN_RST_DET) && (gpwrdn & GPWRDN_RST_DET_MSK)) {
+	} else if ((gpwrdn & GPWRDN_RST_DET) &&
+		   (gpwrdn & GPWRDN_RST_DET_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
 		if (!linestate && (gpwrdn & GPWRDN_BSESSVLD))
 			dwc2_exit_hibernation(hsotg, 0, 1, 0);
-	}
-	if ((gpwrdn & GPWRDN_STS_CHGINT) &&
-	    (gpwrdn & GPWRDN_STS_CHGINT_MSK) && linestate) {
+	} else if ((gpwrdn & GPWRDN_STS_CHGINT) &&
+		   (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
-		if (hsotg->hw_params.hibernation &&
-		    hsotg->hibernated) {
-			if (gpwrdn & GPWRDN_IDSTS) {
-				dwc2_exit_hibernation(hsotg, 0, 0, 0);
-				call_gadget(hsotg, resume);
-			} else {
-				dwc2_exit_hibernation(hsotg, 1, 0, 1);
-			}
-		}
+		/*
+		 * As GPWRDN_STS_CHGINT exit from hibernation flow is
+		 * the same as in GPWRDN_DISCONN_DET flow. Call
+		 * disconnect detect helper function to exit from
+		 * hibernation.
+		 */
+		dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
 	}
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (19 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 04/15] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-16 12:47 ` [PATCH v2 06/15] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

When device cable is disconnected core receives suspend
interrupt and enters hibernation. After entering
into hibernation GPWRDN_RST_DET and GPWRDN_STS_CHGINT
interrupts are asserted.

Allowed exit from gadget hibernation from
GPWRDN_RST_DET by checking only linestate.

Changed the return type of "dwc2_handle_gpwrdn_intr()"
function from void to int because exit from hibernation
functions have a return value.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 27d729fad227..f8963c0cf6af 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -751,10 +751,11 @@ static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
  * The GPWRDN interrupts are those that occur in both Host and
  * Device mode while core is in hibernated state.
  */
-static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
+static int dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 {
 	u32 gpwrdn;
 	int linestate;
+	int ret = 0;
 
 	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 	/* clear all interrupt */
@@ -778,17 +779,27 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 		if (hsotg->hw_params.hibernation &&
 		    hsotg->hibernated) {
 			if (gpwrdn & GPWRDN_IDSTS) {
-				dwc2_exit_hibernation(hsotg, 0, 0, 0);
+				ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit hibernation failed.\n");
 				call_gadget(hsotg, resume);
 			} else {
-				dwc2_exit_hibernation(hsotg, 1, 0, 1);
+				ret = dwc2_exit_hibernation(hsotg, 1, 0, 1);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit hibernation failed.\n");
 			}
 		}
 	} else if ((gpwrdn & GPWRDN_RST_DET) &&
 		   (gpwrdn & GPWRDN_RST_DET_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
-		if (!linestate && (gpwrdn & GPWRDN_BSESSVLD))
-			dwc2_exit_hibernation(hsotg, 0, 1, 0);
+		if (!linestate) {
+			ret = dwc2_exit_hibernation(hsotg, 0, 1, 0);
+			if (ret)
+				dev_err(hsotg->dev,
+					"exit hibernation failed.\n");
+		}
 	} else if ((gpwrdn & GPWRDN_STS_CHGINT) &&
 		   (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
 		dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
@@ -800,6 +811,8 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
 		 */
 		dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
 	}
+
+	return ret;
 }
 
 /*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 06/15] usb: dwc2: Clear fifo_map when resetting core.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (20 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-16 12:47 ` [PATCH v2 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Switching from device mode to host mode by disconnecting
device cable core enters and exits form hibernation.
However, the fifo map remains not cleared. It results
to a WARNING (WARNING: CPU: 5 PID: 0 at drivers/usb/dwc2/
gadget.c:307 dwc2_hsotg_init_fifo+0x12/0x152 [dwc2])
if in host mode we disconnect the micro a to b host
cable. Because core reset occurs.

To avoid the WARNING, fifo_map should be cleared
in dwc2_core_reset() function by taking into account configs.
fifo_map must be cleared only if driver is configured in
"CONFIG_USB_DWC2_PERIPHERAL" or "CONFIG_USB_DWC2_DUAL_ROLE"
mode.

- Added "static inline void dwc2_clear_fifo_map()" helper
function to clear fifo_map with peripheral or dual role mode.

- Added a dummy version of "dwc2_clear_fifo_map()" helper
for host-only mode.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.c | 16 ++++++++++++++++
 drivers/usb/dwc2/core.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index cb65f7f60573..eccd96fa164e 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -470,6 +470,22 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait)
 		dwc2_writel(hsotg, greset, GRSTCTL);
 	}
 
+	/*
+	 * Switching from device mode to host mode by disconnecting
+	 * device cable core enters and exits form hibernation.
+	 * However, the fifo map remains not cleared. It results
+	 * to a WARNING (WARNING: CPU: 5 PID: 0 at drivers/usb/dwc2/
+	 * gadget.c:307 dwc2_hsotg_init_fifo+0x12/0x152 [dwc2])
+	 * if in host mode we disconnect the micro a to b host
+	 * cable. Because core reset occurs.
+	 * To avoid the WARNING, fifo_map should be cleared
+	 * in dwc2_core_reset() function by taking into account configs.
+	 * fifo_map must be cleared only if driver is configured in
+	 * "CONFIG_USB_DWC2_PERIPHERAL" or "CONFIG_USB_DWC2_DUAL_ROLE"
+	 * mode.
+	 */
+	dwc2_clear_fifo_map(hsotg);
+
 	/* Wait for AHB master IDLE state */
 	if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 10000)) {
 		dev_warn(hsotg->dev, "%s: HANG! AHB Idle timeout GRSTCTL GRSTCTL_AHBIDLE\n",
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 8c12b3061f7f..e1f432095565 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1423,6 +1423,8 @@ int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
 void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
 void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg);
+static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg)
+{ hsotg->fifo_map = 0; }
 #else
 static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
 { return 0; }
@@ -1467,6 +1469,7 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {}
 static inline void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_clear_fifo_map(struct dwc2_hsotg *hsotg) {}
 #endif
 
 #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (21 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 06/15] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-16 12:47 ` [PATCH v2 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

When hibernation exit is performed the dwc2_hib_restore_common()
function is called. In that function we wait until GINTSTS_RESTOREDONE
bit is set. However, after the setting of that bit we get a lot of
(dwc2_hsotg_irq:) interrupts which indicates that (GINTSTS.RstrDoneInt)
restore done interrupt is asserted.

To avoid restore done interrupt storm after restore is generated
clear GINTSTS_RESTOREDONE bit in GINTSTS register.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index eccd96fa164e..576c262dba55 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -299,6 +299,12 @@ void dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup,
 			__func__);
 	} else {
 		dev_dbg(hsotg->dev, "restore done  generated here\n");
+
+		/*
+		 * To avoid restore done interrupt storm after restore is
+		 * generated clear GINTSTS_RESTOREDONE bit.
+		 */
+		dwc2_writel(hsotg, GINTSTS_RESTOREDONE, GINTSTS);
 	}
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (22 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-19  7:31   ` Minas Harutyunyan
  2021-04-16 12:47 ` [PATCH v2 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

This move is done to call enter hibernation handler in
"dwc2_port_suspend()" function when core receives port suspend.
Otherwise it could be confusing to enter to hibernation in
"dwc2_hcd_hub_control()" function but other power saving modes
in "dwc2_port_suspend()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index ff945c40ef8a..43a2298b7d42 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3321,6 +3321,18 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 				"enter partial_power_down failed.\n");
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		/*
+		 * Perform spin unlock and lock because in
+		 * "dwc2_host_enter_hibernation()" function there is a spinlock
+		 * logic which prevents servicing of any IRQ during entering
+		 * hibernation.
+		 */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		ret = dwc2_enter_hibernation(hsotg, 1);
+		if (ret)
+			dev_err(hsotg->dev, "enter hibernation failed.\n");
+		spin_lock_irqsave(&hsotg->lock, flags);
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
@@ -3650,10 +3662,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
 			if (windex != hsotg->otg_port)
 				goto error;
-			if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION)
-				dwc2_enter_hibernation(hsotg, 1);
-			else
-				dwc2_port_suspend(hsotg, windex);
+			if (!hsotg->bus_suspended)
+				retval = dwc2_port_suspend(hsotg, windex);
 			break;
 
 		case USB_PORT_FEAT_POWER:
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (23 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
@ 2021-04-16 12:47 ` Artur Petrosyan
  2021-04-19  7:31   ` Minas Harutyunyan
  2021-04-16 12:48 ` [PATCH v2 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:47 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

This move is done to call hibernation exit handler in
"dwc2_port_resume()" function when core receives port resume.
Otherwise it could be confusing to exit hibernation in
"dwc2_hcd_hub_control()" function but other power saving modes
in "dwc2_port_resume()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 43a2298b7d42..cc9ad6cf02d9 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3383,6 +3383,11 @@ int dwc2_port_resume(struct dwc2_hsotg *hsotg)
 				"exit partial_power_down failed.\n");
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		/* Exit host hibernation. */
+		ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+		if (ret)
+			dev_err(hsotg->dev, "exit hibernation failed.\n");
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
@@ -3446,12 +3451,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			dev_dbg(hsotg->dev,
 				"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
 
-			if (hsotg->bus_suspended) {
-				if (hsotg->hibernated)
-					dwc2_exit_hibernation(hsotg, 0, 0, 1);
-				else
-					dwc2_port_resume(hsotg);
-			}
+			if (hsotg->bus_suspended)
+				retval = dwc2_port_resume(hsotg);
 			break;
 
 		case USB_PORT_FEAT_POWER:
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 10/15] usb: dwc2: Allow exit hibernation in urb enqueue
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (24 preceding siblings ...)
  2021-04-16 12:47 ` [PATCH v2 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
@ 2021-04-16 12:48 ` Artur Petrosyan
  2021-04-19  7:31   ` Minas Harutyunyan
  2021-04-16 12:48 ` [PATCH v2 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:48 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When core is in hibernation state and an external
hub is connected, upper layer sends URB enqueue request,
which results in port reset issue.

- Added exit from hibernation state to avoid port
reset issue and process upper layer request properly.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - Moved duplicated error checking *if* conditions from innermost to outside if.

 drivers/usb/dwc2/hcd.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index cc9ad6cf02d9..093b1717df01 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4631,12 +4631,26 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 	struct dwc2_qh *qh;
 	bool qh_allocated = false;
 	struct dwc2_qtd *qtd;
+	struct dwc2_gregs_backup *gr;
+
+	gr = &hsotg->gr_backup;
 
 	if (dbg_urb(urb)) {
 		dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
 		dwc2_dump_urb_info(hcd, urb, "urb_enqueue");
 	}
 
+	if (hsotg->hibernated) {
+		if (gr->gotgctl & GOTGCTL_CURMODE_HOST)
+			retval = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+		else
+			retval = dwc2_exit_hibernation(hsotg, 0, 0, 0);
+
+		if (retval)
+			dev_err(hsotg->dev,
+				"exit hibernation failed.\n");
+	}
+
 	if (hsotg->in_ppd) {
 		retval = dwc2_exit_partial_power_down(hsotg, 0, true);
 		if (retval)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 11/15] usb: dwc2: Add hibernation entering flow by system suspend
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (25 preceding siblings ...)
  2021-04-16 12:48 ` [PATCH v2 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
@ 2021-04-16 12:48 ` Artur Petrosyan
  2021-04-19  7:31   ` Minas Harutyunyan
  2021-04-16 12:48 ` [PATCH v2 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:48 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Adds a new flow of entering hibernation when PC is
hibernated or suspended.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 093b1717df01..92848629cc61 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4387,6 +4387,16 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		/* Enter hibernation */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		ret = dwc2_enter_hibernation(hsotg, 1);
+		if (ret)
+			dev_err(hsotg->dev, "enter hibernation failed\n");
+		spin_lock_irqsave(&hsotg->lock, flags);
+
+		/* After entering suspend, hardware is not accessible */
+		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 12/15] usb: dwc2: Add hibernation exiting flow by system resume
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (26 preceding siblings ...)
  2021-04-16 12:48 ` [PATCH v2 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
@ 2021-04-16 12:48 ` Artur Petrosyan
  2021-04-19  7:31   ` Minas Harutyunyan
  2021-04-16 12:48 ` [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:48 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Adds a new flow of exiting hibernation when PC is resumed
from suspend state.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 92848629cc61..035d4911a3c3 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4470,6 +4470,16 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+		if (ret)
+			dev_err(hsotg->dev, "exit hibernation failed.\n");
+
+		/*
+		 * Set HW accessible bit before powering on the controller
+		 * since an interrupt may rise.
+		 */
+		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	case DWC2_POWER_DOWN_PARAM_NONE:
 		/*
 		 * If not hibernation nor partial power down are supported,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (27 preceding siblings ...)
  2021-04-16 12:48 ` [PATCH v2 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
@ 2021-04-16 12:48 ` Artur Petrosyan
  2021-04-19  7:32   ` Minas Harutyunyan
  2021-04-16 12:48 ` [PATCH v2 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
  2021-04-16 12:48 ` [PATCH v2 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:48 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When dwc2 core is in hibernation mode loading
driver again causes driver fail. Because in
that mode registers are not accessible.

In order to exit from hibernation checking
dwc2 core power saving state in "dwc2_driver_remove()"
function. If core is in hibernation, then checking the
operational mode of the driver. To check whether dwc2 core
is operating in host mode or device mode there is one way
which is retrieving the backup value of "gotgctl" and compare
the "CurMod" value. If previously core entered hibernation
in host mode then the exit is performed for host if not then
exit is performed for device mode. The introduced checking
is because in hibernation state all registers are not
accessible.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
---
 drivers/usb/dwc2/platform.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index f8b819cfa80e..8ad33e042a14 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -316,8 +316,23 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 static int dwc2_driver_remove(struct platform_device *dev)
 {
 	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
+	struct dwc2_gregs_backup *gr;
 	int ret = 0;
 
+	gr = &hsotg->gr_backup;
+
+	/* Exit Hibernation when driver is removed. */
+	if (hsotg->hibernated) {
+		if (gr->gotgctl & GOTGCTL_CURMODE_HOST)
+			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
+		else
+			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
+
+		if (ret)
+			dev_err(hsotg->dev,
+				"exit hibernation failed.\n");
+	}
+
 	/* Exit Partial Power Down when driver is removed. */
 	if (hsotg->in_ppd) {
 		ret = dwc2_exit_partial_power_down(hsotg, 0, true);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function.
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (28 preceding siblings ...)
  2021-04-16 12:48 ` [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
@ 2021-04-16 12:48 ` Artur Petrosyan
  2021-04-16 12:48 ` [PATCH v2 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
  30 siblings, 0 replies; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:48 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

To avoid working in two modes (partial power down
and hibernation) changed conditions for entering
partial power down or hibernation.

Instead of checking hw_params.power_optimized and
hw_params.hibernation now checking power_down
param which already set to one of the options
(Hibernation or Partial Power Down) based on
OTG_EN_PWROPT.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index f8963c0cf6af..470458ac664b 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -532,7 +532,8 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 			return;
 		}
 		if (dsts & DSTS_SUSPSTS) {
-			if (hsotg->hw_params.power_optimized) {
+			switch (hsotg->params.power_down) {
+			case DWC2_POWER_DOWN_PARAM_PARTIAL:
 				ret = dwc2_enter_partial_power_down(hsotg);
 				if (ret) {
 					if (ret != -ENOTSUPP)
@@ -541,21 +542,22 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 							__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);
-			} else if (hsotg->hw_params.hibernation) {
+				break;
+			case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 				ret = dwc2_enter_hibernation(hsotg, 0);
 				if (ret && ret != -ENOTSUPP)
 					dev_err(hsotg->dev,
 						"%s: enter hibernation failed\n",
 						__func__);
-			} else {
+				break;
+			case DWC2_POWER_DOWN_PARAM_NONE:
 				/*
-				 * If not hibernation nor partial power down are supported,
+				 * If neither hibernation nor partial power down are supported,
 				 * clock gating is used to save power.
 				 */
 				dwc2_gadget_enter_clock_gating(hsotg);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v2 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt
       [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
                   ` (29 preceding siblings ...)
  2021-04-16 12:48 ` [PATCH v2 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
@ 2021-04-16 12:48 ` Artur Petrosyan
  2021-04-19  7:32   ` Minas Harutyunyan
  30 siblings, 1 reply; 50+ messages in thread
From: Artur Petrosyan @ 2021-04-16 12:48 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Douglas Anderson

Squashed from Douglas Anderson's suggested commit
"usb: dwc2: Get rid of useless error checks for
hibernation/partial power down"

 - After this commit there should never be any
case where dwc2_enter_partial_power_down() and
dwc2_enter_hibernation() are called when
'params.power_down' is not correct.  Get rid of
the pile of error checking.

- As part of this cleanup some of the error messages
not to have __func__ in them.  That's not needed
for dev_err() calls since they already have the
device name as part of the message.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/core.c      |  3 ---
 drivers/usb/dwc2/core_intr.c | 18 +++++++-----------
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 576c262dba55..6f70ab9577b4 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -391,9 +391,6 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)
  */
 int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host)
 {
-	if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_HIBERNATION)
-		return -ENOTSUPP;
-
 	if (is_host)
 		return dwc2_host_enter_hibernation(hsotg);
 	else
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 470458ac664b..a5ab03808da6 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -535,13 +535,10 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 			switch (hsotg->params.power_down) {
 			case DWC2_POWER_DOWN_PARAM_PARTIAL:
 				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;
-				}
+				if (ret)
+					dev_err(hsotg->dev,
+						"enter partial_power_down failed\n");
+
 				udelay(100);
 
 				/* Ask phy to be suspended */
@@ -550,10 +547,9 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 				break;
 			case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 				ret = dwc2_enter_hibernation(hsotg, 0);
-				if (ret && ret != -ENOTSUPP)
+				if (ret)
 					dev_err(hsotg->dev,
-						"%s: enter hibernation failed\n",
-						__func__);
+						"enter hibernation failed\n");
 				break;
 			case DWC2_POWER_DOWN_PARAM_NONE:
 				/*
@@ -562,7 +558,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 				 */
 				dwc2_gadget_enter_clock_gating(hsotg);
 			}
-skip_power_saving:
+
 			/*
 			 * Change to L2 (suspend) state before releasing
 			 * spinlock
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 01/15] usb: dwc2: Update exit hibernation when port reset is asserted
  2021-04-16 12:46 ` [PATCH v2 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
@ 2021-04-19  7:30   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:30 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:46 PM, Artur Petrosyan wrote:
> No need to check for "DWC2_POWER_DOWN_PARAM_HIBERNATION" param
> as "hsotg->hibernated" flag is already enough for exiting from
> hibernation mode.
> 
> - Removes checking of "DWC2_POWER_DOWN_PARAM_HIBERNATION" param.
> 
> - For code readability Hibernation exit code moved after
> debug message print.
> 
> - Added "dwc2_exit_hibernation()" function error checking.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 17 +++++++++++------
>   1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 04a1b53d65af..cda3f931195d 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -3668,9 +3668,17 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
>   			break;
>   
>   		case USB_PORT_FEAT_RESET:
> -			if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION &&
> -			    hsotg->hibernated)
> -				dwc2_exit_hibernation(hsotg, 0, 1, 1);
> +			dev_dbg(hsotg->dev,
> +				"SetPortFeature - USB_PORT_FEAT_RESET\n");
> +
> +			hprt0 = dwc2_read_hprt0(hsotg);
> +
> +			if (hsotg->hibernated) {
> +				retval = dwc2_exit_hibernation(hsotg, 0, 1, 1);
> +				if (retval)
> +					dev_err(hsotg->dev,
> +						"exit hibernation failed\n");
> +			}
>   
>   			if (hsotg->in_ppd) {
>   				retval = dwc2_exit_partial_power_down(hsotg, 1,
> @@ -3684,9 +3692,6 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
>   			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
>   				dwc2_host_exit_clock_gating(hsotg, 0);
>   
> -			hprt0 = dwc2_read_hprt0(hsotg);
> -			dev_dbg(hsotg->dev,
> -				"SetPortFeature - USB_PORT_FEAT_RESET\n");
>   			pcgctl = dwc2_readl(hsotg, PCGCTL);
>   			pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK);
>   			dwc2_writel(hsotg, pcgctl, PCGCTL);
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow.
  2021-04-16 12:47 ` [PATCH v2 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
@ 2021-04-19  7:30   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:30 UTC (permalink / raw)
  To: Artur Petrosyan, John Youn, Felipe Balbi, Greg Kroah-Hartman,
	Artur Petrosyan, Vardan Mikayelyan, Grigor Tovmasyan, linux-usb,
	linux-kernel

On 4/16/2021 4:47 PM, Artur Petrosyan wrote:
> Added setting "port_connect_status_change" flag to "1" in order
> to re-enumerate, because after exit from hibernation port
> connection status is not detected.
> 
> Fixes: c5c403dc4336 ("usb: dwc2: Add host/device hibernation functions")
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 10 +++++++++-
>   1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index cda3f931195d..ff945c40ef8a 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -5650,7 +5650,15 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
>   		return ret;
>   	}
>   
> -	dwc2_hcd_rem_wakeup(hsotg);
> +	if (rem_wakeup) {
> +		dwc2_hcd_rem_wakeup(hsotg);
> +		/*
> +		 * Change "port_connect_status_change" flag to re-enumerate,
> +		 * because after exit from hibernation port connection status
> +		 * is not detected.
> +		 */
> +		hsotg->flags.b.port_connect_status_change = 1;
> +	}
>   
>   	hsotg->hibernated = 0;
>   	hsotg->bus_suspended = 0;
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function
  2021-04-16 12:47 ` [PATCH v2 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
@ 2021-04-19  7:31   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:31 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:47 PM, Artur Petrosyan wrote:
> This move is done to call enter hibernation handler in
> "dwc2_port_suspend()" function when core receives port suspend.
> Otherwise it could be confusing to enter to hibernation in
> "dwc2_hcd_hub_control()" function but other power saving modes
> in "dwc2_port_suspend()" function.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 18 ++++++++++++++----
>   1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index ff945c40ef8a..43a2298b7d42 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -3321,6 +3321,18 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
>   				"enter partial_power_down failed.\n");
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
> +		/*
> +		 * Perform spin unlock and lock because in
> +		 * "dwc2_host_enter_hibernation()" function there is a spinlock
> +		 * logic which prevents servicing of any IRQ during entering
> +		 * hibernation.
> +		 */
> +		spin_unlock_irqrestore(&hsotg->lock, flags);
> +		ret = dwc2_enter_hibernation(hsotg, 1);
> +		if (ret)
> +			dev_err(hsotg->dev, "enter hibernation failed.\n");
> +		spin_lock_irqsave(&hsotg->lock, flags);
> +		break;
>   	case DWC2_POWER_DOWN_PARAM_NONE:
>   		/*
>   		 * If not hibernation nor partial power down are supported,
> @@ -3650,10 +3662,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
>   				"SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
>   			if (windex != hsotg->otg_port)
>   				goto error;
> -			if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION)
> -				dwc2_enter_hibernation(hsotg, 1);
> -			else
> -				dwc2_port_suspend(hsotg, windex);
> +			if (!hsotg->bus_suspended)
> +				retval = dwc2_port_suspend(hsotg, windex);
>   			break;
>   
>   		case USB_PORT_FEAT_POWER:
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function
  2021-04-16 12:47 ` [PATCH v2 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
@ 2021-04-19  7:31   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:31 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:47 PM, Artur Petrosyan wrote:
> This move is done to call hibernation exit handler in
> "dwc2_port_resume()" function when core receives port resume.
> Otherwise it could be confusing to exit hibernation in
> "dwc2_hcd_hub_control()" function but other power saving modes
> in "dwc2_port_resume()" function.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 13 +++++++------
>   1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 43a2298b7d42..cc9ad6cf02d9 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -3383,6 +3383,11 @@ int dwc2_port_resume(struct dwc2_hsotg *hsotg)
>   				"exit partial_power_down failed.\n");
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
> +		/* Exit host hibernation. */
> +		ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
> +		if (ret)
> +			dev_err(hsotg->dev, "exit hibernation failed.\n");
> +		break;
>   	case DWC2_POWER_DOWN_PARAM_NONE:
>   		/*
>   		 * If not hibernation nor partial power down are supported,
> @@ -3446,12 +3451,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
>   			dev_dbg(hsotg->dev,
>   				"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
>   
> -			if (hsotg->bus_suspended) {
> -				if (hsotg->hibernated)
> -					dwc2_exit_hibernation(hsotg, 0, 0, 1);
> -				else
> -					dwc2_port_resume(hsotg);
> -			}
> +			if (hsotg->bus_suspended)
> +				retval = dwc2_port_resume(hsotg);
>   			break;
>   
>   		case USB_PORT_FEAT_POWER:
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 10/15] usb: dwc2: Allow exit hibernation in urb enqueue
  2021-04-16 12:48 ` [PATCH v2 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
@ 2021-04-19  7:31   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:31 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:48 PM, Artur Petrosyan wrote:
> When core is in hibernation state and an external
> hub is connected, upper layer sends URB enqueue request,
> which results in port reset issue.
> 
> - Added exit from hibernation state to avoid port
> reset issue and process upper layer request properly.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - Moved duplicated error checking *if* conditions from innermost to outside if.
> 
>   drivers/usb/dwc2/hcd.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index cc9ad6cf02d9..093b1717df01 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4631,12 +4631,26 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
>   	struct dwc2_qh *qh;
>   	bool qh_allocated = false;
>   	struct dwc2_qtd *qtd;
> +	struct dwc2_gregs_backup *gr;
> +
> +	gr = &hsotg->gr_backup;
>   
>   	if (dbg_urb(urb)) {
>   		dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
>   		dwc2_dump_urb_info(hcd, urb, "urb_enqueue");
>   	}
>   
> +	if (hsotg->hibernated) {
> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST)
> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 1);
> +		else
> +			retval = dwc2_exit_hibernation(hsotg, 0, 0, 0);
> +
> +		if (retval)
> +			dev_err(hsotg->dev,
> +				"exit hibernation failed.\n");
> +	}
> +
>   	if (hsotg->in_ppd) {
>   		retval = dwc2_exit_partial_power_down(hsotg, 0, true);
>   		if (retval)
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 11/15] usb: dwc2: Add hibernation entering flow by system suspend
  2021-04-16 12:48 ` [PATCH v2 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
@ 2021-04-19  7:31   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:31 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:48 PM, Artur Petrosyan wrote:
> Adds a new flow of entering hibernation when PC is
> hibernated or suspended.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 093b1717df01..92848629cc61 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4387,6 +4387,16 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
>   		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
> +		/* Enter hibernation */
> +		spin_unlock_irqrestore(&hsotg->lock, flags);
> +		ret = dwc2_enter_hibernation(hsotg, 1);
> +		if (ret)
> +			dev_err(hsotg->dev, "enter hibernation failed\n");
> +		spin_lock_irqsave(&hsotg->lock, flags);
> +
> +		/* After entering suspend, hardware is not accessible */
> +		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
> +		break;
>   	case DWC2_POWER_DOWN_PARAM_NONE:
>   		/*
>   		 * If not hibernation nor partial power down are supported,
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 12/15] usb: dwc2: Add hibernation exiting flow by system resume
  2021-04-16 12:48 ` [PATCH v2 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
@ 2021-04-19  7:31   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:31 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:48 PM, Artur Petrosyan wrote:
> Adds a new flow of exiting hibernation when PC is resumed
> from suspend state.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 92848629cc61..035d4911a3c3 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4470,6 +4470,16 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
>   		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
> +		ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
> +		if (ret)
> +			dev_err(hsotg->dev, "exit hibernation failed.\n");
> +
> +		/*
> +		 * Set HW accessible bit before powering on the controller
> +		 * since an interrupt may rise.
> +		 */
> +		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
> +		break;
>   	case DWC2_POWER_DOWN_PARAM_NONE:
>   		/*
>   		 * If not hibernation nor partial power down are supported,
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive
  2021-04-16 12:48 ` [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
@ 2021-04-19  7:32   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:32 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn

On 4/16/2021 4:48 PM, Artur Petrosyan wrote:
> When dwc2 core is in hibernation mode loading
> driver again causes driver fail. Because in
> that mode registers are not accessible.
> 
> In order to exit from hibernation checking
> dwc2 core power saving state in "dwc2_driver_remove()"
> function. If core is in hibernation, then checking the
> operational mode of the driver. To check whether dwc2 core
> is operating in host mode or device mode there is one way
> which is retrieving the backup value of "gotgctl" and compare
> the "CurMod" value. If previously core entered hibernation
> in host mode then the exit is performed for host if not then
> exit is performed for device mode. The introduced checking
> is because in hibernation state all registers are not
> accessible.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> Reported-by: kernel test robot <lkp@intel.com>
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   drivers/usb/dwc2/platform.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
> index f8b819cfa80e..8ad33e042a14 100644
> --- a/drivers/usb/dwc2/platform.c
> +++ b/drivers/usb/dwc2/platform.c
> @@ -316,8 +316,23 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
>   static int dwc2_driver_remove(struct platform_device *dev)
>   {
>   	struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
> +	struct dwc2_gregs_backup *gr;
>   	int ret = 0;
>   
> +	gr = &hsotg->gr_backup;
> +
> +	/* Exit Hibernation when driver is removed. */
> +	if (hsotg->hibernated) {
> +		if (gr->gotgctl & GOTGCTL_CURMODE_HOST)
> +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 1);
> +		else
> +			ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
> +
> +		if (ret)
> +			dev_err(hsotg->dev,
> +				"exit hibernation failed.\n");
> +	}
> +
>   	/* Exit Partial Power Down when driver is removed. */
>   	if (hsotg->in_ppd) {
>   		ret = dwc2_exit_partial_power_down(hsotg, 0, true);
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v2 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt
  2021-04-16 12:48 ` [PATCH v2 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
@ 2021-04-19  7:32   ` Minas Harutyunyan
  0 siblings, 0 replies; 50+ messages in thread
From: Minas Harutyunyan @ 2021-04-19  7:32 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman, linux-usb,
	linux-kernel
  Cc: John Youn, Douglas Anderson

On 4/16/2021 4:48 PM, Artur Petrosyan wrote:
> Squashed from Douglas Anderson's suggested commit
> "usb: dwc2: Get rid of useless error checks for
> hibernation/partial power down"
> 
>   - After this commit there should never be any
> case where dwc2_enter_partial_power_down() and
> dwc2_enter_hibernation() are called when
> 'params.power_down' is not correct.  Get rid of
> the pile of error checking.
> 
> - As part of this cleanup some of the error messages
> not to have __func__ in them.  That's not needed
> for dev_err() calls since they already have the
> device name as part of the message.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/core.c      |  3 ---
>   drivers/usb/dwc2/core_intr.c | 18 +++++++-----------
>   2 files changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
> index 576c262dba55..6f70ab9577b4 100644
> --- a/drivers/usb/dwc2/core.c
> +++ b/drivers/usb/dwc2/core.c
> @@ -391,9 +391,6 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg *hsotg)
>    */
>   int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host)
>   {
> -	if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_HIBERNATION)
> -		return -ENOTSUPP;
> -
>   	if (is_host)
>   		return dwc2_host_enter_hibernation(hsotg);
>   	else
> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
> index 470458ac664b..a5ab03808da6 100644
> --- a/drivers/usb/dwc2/core_intr.c
> +++ b/drivers/usb/dwc2/core_intr.c
> @@ -535,13 +535,10 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
>   			switch (hsotg->params.power_down) {
>   			case DWC2_POWER_DOWN_PARAM_PARTIAL:
>   				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;
> -				}
> +				if (ret)
> +					dev_err(hsotg->dev,
> +						"enter partial_power_down failed\n");
> +
>   				udelay(100);
>   
>   				/* Ask phy to be suspended */
> @@ -550,10 +547,9 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
>   				break;
>   			case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>   				ret = dwc2_enter_hibernation(hsotg, 0);
> -				if (ret && ret != -ENOTSUPP)
> +				if (ret)
>   					dev_err(hsotg->dev,
> -						"%s: enter hibernation failed\n",
> -						__func__);
> +						"enter hibernation failed\n");
>   				break;
>   			case DWC2_POWER_DOWN_PARAM_NONE:
>   				/*
> @@ -562,7 +558,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
>   				 */
>   				dwc2_gadget_enter_clock_gating(hsotg);
>   			}
> -skip_power_saving:
> +
>   			/*
>   			 * Change to L2 (suspend) state before releasing
>   			 * spinlock
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2021-04-19  7:32 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1618464534.git.Arthur.Petrosyan@synopsys.com>
2021-04-15  5:39 ` [PATCH 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
2021-04-15  5:39 ` [PATCH 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
2021-04-15  5:39 ` [PATCH 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
2021-04-15  5:39 ` [PATCH 04/15] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
2021-04-15  5:40 ` [PATCH 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
2021-04-15  5:40 ` [PATCH 06/15] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
2021-04-15  5:40 ` [PATCH 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
2021-04-15  5:40 ` [PATCH 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
2021-04-15  5:40 ` [PATCH 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
2021-04-15  5:40 ` [PATCH 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
2021-04-15  9:12   ` Sergei Shtylyov
2021-04-16  5:43     ` Artur Petrosyan
2021-04-16  7:05       ` Artur Petrosyan
2021-04-15  5:40 ` [PATCH 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
2021-04-15  5:40 ` [PATCH 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
2021-04-15  5:41 ` [PATCH 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
2021-04-15  9:24   ` Sergei Shtylyov
2021-04-16  5:46     ` Artur Petrosyan
2021-04-15  9:50   ` kernel test robot
2021-04-15  9:50     ` kernel test robot
2021-04-15 13:40   ` [kbuild] " Dan Carpenter
2021-04-15 13:40     ` Dan Carpenter
2021-04-15 13:40     ` Dan Carpenter
2021-04-15  5:41 ` [PATCH 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
2021-04-15  5:41 ` [PATCH 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
2021-04-16 12:46 ` [PATCH v2 00/15] usb: dwc2: Fix Hibernation issues Artur Petrosyan
2021-04-16 12:46 ` [PATCH v2 01/15] usb: dwc2: Update exit hibernation when port reset is asserted Artur Petrosyan
2021-04-19  7:30   ` Minas Harutyunyan
2021-04-16 12:46 ` [PATCH v2 02/15] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
2021-04-16 12:47 ` [PATCH v2 03/15] usb: dwc2: Fix host mode hibernation exit with remote wakeup flow Artur Petrosyan
2021-04-19  7:30   ` Minas Harutyunyan
2021-04-16 12:47 ` [PATCH v2 04/15] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
2021-04-16 12:47 ` [PATCH v2 05/15] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
2021-04-16 12:47 ` [PATCH v2 06/15] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
2021-04-16 12:47 ` [PATCH v2 07/15] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
2021-04-16 12:47 ` [PATCH v2 08/15] usb: dwc2: Move enter hibernation to dwc2_port_suspend() function Artur Petrosyan
2021-04-19  7:31   ` Minas Harutyunyan
2021-04-16 12:47 ` [PATCH v2 09/15] usb: dwc2: Move exit hibernation to dwc2_port_resume() function Artur Petrosyan
2021-04-19  7:31   ` Minas Harutyunyan
2021-04-16 12:48 ` [PATCH v2 10/15] usb: dwc2: Allow exit hibernation in urb enqueue Artur Petrosyan
2021-04-19  7:31   ` Minas Harutyunyan
2021-04-16 12:48 ` [PATCH v2 11/15] usb: dwc2: Add hibernation entering flow by system suspend Artur Petrosyan
2021-04-19  7:31   ` Minas Harutyunyan
2021-04-16 12:48 ` [PATCH v2 12/15] usb: dwc2: Add hibernation exiting flow by system resume Artur Petrosyan
2021-04-19  7:31   ` Minas Harutyunyan
2021-04-16 12:48 ` [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive Artur Petrosyan
2021-04-19  7:32   ` Minas Harutyunyan
2021-04-16 12:48 ` [PATCH v2 14/15] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
2021-04-16 12:48 ` [PATCH v2 15/15] usb: dwc2: Get rid of useless error checks in suspend interrupt Artur Petrosyan
2021-04-19  7:32   ` Minas Harutyunyan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.