linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] usb: dwc2: Another attempt handling rk3288's remote wake quirk
@ 2019-04-12 22:41 Douglas Anderson
  2019-04-12 22:41 ` [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup Douglas Anderson
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Douglas Anderson @ 2019-04-12 22:41 UTC (permalink / raw)
  To: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi
  Cc: amstan, linux-rockchip, linux-usb, Randy Li, mka, ryandcase,
	jwerner, Elaine Zhang, Douglas Anderson, devicetree,
	linux-kernel, Greg Kroah-Hartman, Mark Rutland, linux-arm-kernel

This is another attempt to upstream the code to unwedge the rk3288's
"host" USB port when it sees a remote wakeup.  Previously I attempted
this [1] and it appears that Randy Li made some attempts too [2] which
resulted in at least the PHY bindings for the USB PHY landing as well
as the USB PHY support.  Nice!

Hopefully this addresses previous comments and could land this time?

[1] https://lkml.kernel.org/r/1446236275-12698-2-git-send-email-dianders@chromium.org
[2] https://lkml.kernel.org/r/1472939729-15187-4-git-send-email-ayaka@soulik.info


Douglas Anderson (4):
  dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup
  usb: dwc2: optionally assert phy reset when waking up
  ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288.
  ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on
    wakeup

 Documentation/devicetree/bindings/usb/dwc2.txt |  2 ++
 arch/arm/boot/dts/rk3288.dtsi                  |  7 +++++++
 drivers/usb/dwc2/core.h                        |  5 +++++
 drivers/usb/dwc2/core_intr.c                   | 12 ++++++++++++
 drivers/usb/dwc2/hcd.c                         | 16 +++++++++++++---
 drivers/usb/dwc2/platform.c                    |  9 +++++++++
 6 files changed, 48 insertions(+), 3 deletions(-)

-- 
2.21.0.392.gf8f6787159e-goog


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

* [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup
  2019-04-12 22:41 [PATCH 0/4] usb: dwc2: Another attempt handling rk3288's remote wake quirk Douglas Anderson
@ 2019-04-12 22:41 ` Douglas Anderson
  2019-04-12 23:42   ` Matthias Kaehlcke
  2019-04-12 22:41 ` [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up Douglas Anderson
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Douglas Anderson @ 2019-04-12 22:41 UTC (permalink / raw)
  To: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi
  Cc: amstan, linux-rockchip, linux-usb, Randy Li, mka, ryandcase,
	jwerner, Elaine Zhang, Douglas Anderson, devicetree,
	linux-kernel, Greg Kroah-Hartman, Mark Rutland

On Rockchip rk3288 there's a hardware quirk where we need to assert
the reset signal to the PHY when we get a remote wakeup on one of the
two ports.  Document this quirk in the bindings.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

 Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt
index 6dc3c4a34483..f70f3aee4bfc 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.txt
+++ b/Documentation/devicetree/bindings/usb/dwc2.txt
@@ -37,6 +37,8 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties
 - g-rx-fifo-size: size of rx fifo size in gadget mode.
 - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode.
 - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode.
+- snps,reset-phy-on-wake: If present indicates that we need to reset the PHY when
+                          we detect a wakeup.  This is due to a hardware errata.
 
 Deprecated properties:
 - g-use-dma: gadget DMA mode is automatically detected
-- 
2.21.0.392.gf8f6787159e-goog


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

* [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up
  2019-04-12 22:41 [PATCH 0/4] usb: dwc2: Another attempt handling rk3288's remote wake quirk Douglas Anderson
  2019-04-12 22:41 ` [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup Douglas Anderson
@ 2019-04-12 22:41 ` Douglas Anderson
  2019-04-12 23:56   ` Matthias Kaehlcke
  2019-04-12 22:41 ` [PATCH 3/4] ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288 Douglas Anderson
  2019-04-12 22:41 ` [PATCH 4/4] ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on wakeup Douglas Anderson
  3 siblings, 1 reply; 10+ messages in thread
From: Douglas Anderson @ 2019-04-12 22:41 UTC (permalink / raw)
  To: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi
  Cc: amstan, linux-rockchip, linux-usb, Randy Li, mka, ryandcase,
	jwerner, Elaine Zhang, Douglas Anderson, Yunzhi Li,
	Greg Kroah-Hartman, linux-kernel

On the rk3288 USB host-only port (the one that's not the OTG-enabled
port) the PHY can get into a bad state when a wakeup is asserted (not
just a wakeup from full system suspend but also a wakeup from
autosuspend).

We can get the PHY out of its bad state by asserting its "port reset",
but unfortunately that seems to assert a reset onto the USB bus so it
could confuse things if we don't actually deenumerate / reenumerate the
device.

We can also get the PHY out of its bad state by fully resetting it using
the reset from the CRU (clock reset unit), which does a more full
reset.  The CRU-based reset appears to actually cause devices on the bus
to be removed and reinserted, which fixes the problem (albeit in a hacky
way).

It's unfortunate that we need to do a full re-enumeration of devices at
wakeup time, but this is better than alternative of letting the bus get
wedged.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
---

 drivers/usb/dwc2/core.h      |  5 +++++
 drivers/usb/dwc2/core_intr.c | 12 ++++++++++++
 drivers/usb/dwc2/hcd.c       | 16 +++++++++++++---
 drivers/usb/dwc2/platform.c  |  9 +++++++++
 4 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 30bab8463c96..f30748f4fe7e 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -859,6 +859,8 @@ struct dwc2_hregs_backup {
  * @gadget_enabled:	Peripheral mode sub-driver initialization indicator.
  * @ll_hw_enabled:	Status of low-level hardware resources.
  * @hibernated:		True if core is hibernated
+ * @reset_phy_on_wake:	Quirk saying that we should assert PHY reset on a
+ *			remote wakeup.
  * @frame_number:       Frame number read from the core. For both device
  *			and host modes. The value ranges are from 0
  *			to HFNUM_MAX_FRNUM.
@@ -972,6 +974,7 @@ struct dwc2_hregs_backup {
  * @status_buf_dma:     DMA address for status_buf
  * @start_work:         Delayed work for handling host A-cable connection
  * @reset_work:         Delayed work for handling a port reset
+ * @phy_reset_work:     Work structure for doing a PHY reset
  * @otg_port:           OTG port number
  * @frame_list:         Frame list
  * @frame_list_dma:     Frame list DMA address
@@ -1045,6 +1048,7 @@ struct dwc2_hsotg {
 	unsigned int gadget_enabled:1;
 	unsigned int ll_hw_enabled:1;
 	unsigned int hibernated:1;
+	unsigned int reset_phy_on_wake:1;
 	u16 frame_number;
 
 	struct phy *phy;
@@ -1147,6 +1151,7 @@ struct dwc2_hsotg {
 
 	struct delayed_work start_work;
 	struct delayed_work reset_work;
+	struct work_struct phy_reset_work;
 	u8 otg_port;
 	u32 *frame_list;
 	dma_addr_t frame_list_dma;
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 19ae2595f1c3..16ff33574116 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -435,6 +435,18 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 			/* Restart the Phy Clock */
 			pcgcctl &= ~PCGCTL_STOPPCLK;
 			dwc2_writel(hsotg, pcgcctl, PCGCTL);
+
+			/*
+			 * If we've got this quirk then the PHY is stuck upon
+			 * wakeup.  Assert reset.  This will propagate out and
+			 * eventually we'll re-enumerate the device.  Not great
+			 * but the best we can do.  We can't call phy_reset()
+			 * at interrupt time but there's no hurry, so we'll
+			 * schedule it for later.
+			 */
+			if (hsotg->reset_phy_on_wake)
+				schedule_work(&hsotg->phy_reset_work);
+
 			mod_timer(&hsotg->wkp_timer,
 				  jiffies + msecs_to_jiffies(71));
 		} else {
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 3f087962f498..332349148d3f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4376,6 +4376,17 @@ static void dwc2_hcd_reset_func(struct work_struct *work)
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 }
 
+static void dwc2_hcd_phy_reset_func(struct work_struct *work)
+{
+	struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg,
+						phy_reset_work);
+	int ret;
+
+	ret = phy_reset(hsotg->phy);
+	if (ret)
+		dev_warn(hsotg->dev, "PHY reset failed\n");
+}
+
 /*
  * =========================================================================
  *  Linux HC Driver Functions
@@ -5271,11 +5282,10 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
 		hsotg->hc_ptr_array[i] = channel;
 	}
 
-	/* Initialize hsotg start work */
+	/* Initialize work */
 	INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func);
-
-	/* Initialize port reset work */
 	INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func);
+	INIT_WORK(&hsotg->phy_reset_work, dwc2_hcd_phy_reset_func);
 
 	/*
 	 * Allocate space for storing data on status transactions. Normally no
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index c0b64d483552..9b65b766e0b9 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -481,6 +481,15 @@ static int dwc2_driver_probe(struct platform_device *dev)
 		hsotg->gadget_enabled = 1;
 	}
 
+	hsotg->reset_phy_on_wake =
+		of_property_read_bool(dev->dev.of_node,
+				      "snps,reset-phy-on-wake");
+	if (hsotg->reset_phy_on_wake && !hsotg->phy) {
+		dev_warn(hsotg->dev,
+			 "Quirk reset-phy-on-wake only supports generic PHYs\n");
+		hsotg->reset_phy_on_wake = false;
+	}
+
 	if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
 		retval = dwc2_hcd_init(hsotg);
 		if (retval) {
-- 
2.21.0.392.gf8f6787159e-goog


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

* [PATCH 3/4] ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288.
  2019-04-12 22:41 [PATCH 0/4] usb: dwc2: Another attempt handling rk3288's remote wake quirk Douglas Anderson
  2019-04-12 22:41 ` [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup Douglas Anderson
  2019-04-12 22:41 ` [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up Douglas Anderson
@ 2019-04-12 22:41 ` Douglas Anderson
  2019-04-13  0:00   ` Matthias Kaehlcke
  2019-04-12 22:41 ` [PATCH 4/4] ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on wakeup Douglas Anderson
  3 siblings, 1 reply; 10+ messages in thread
From: Douglas Anderson @ 2019-04-12 22:41 UTC (permalink / raw)
  To: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi
  Cc: amstan, linux-rockchip, linux-usb, Randy Li, mka, ryandcase,
	jwerner, Elaine Zhang, Douglas Anderson, devicetree,
	linux-kernel, Mark Rutland, linux-arm-kernel

Let's hook up the resets to the three USB PHYs on rk3288 as per the
bindings.  This is in preparation for a future patch that will set the
"snps,reset-phy-on-wake" on the host port.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

 arch/arm/boot/dts/rk3288.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 2e604f0afa98..92e0600595f8 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -905,6 +905,8 @@
 				clocks = <&cru SCLK_OTGPHY0>;
 				clock-names = "phyclk";
 				#clock-cells = <0>;
+				resets = <&cru SRST_USBOTG_PHY>;
+				reset-names = "phy-reset";
 			};
 
 			usbphy1: usb-phy@334 {
@@ -913,6 +915,8 @@
 				clocks = <&cru SCLK_OTGPHY1>;
 				clock-names = "phyclk";
 				#clock-cells = <0>;
+				resets = <&cru SRST_USBHOST0_PHY>;
+				reset-names = "phy-reset";
 			};
 
 			usbphy2: usb-phy@348 {
@@ -921,6 +925,8 @@
 				clocks = <&cru SCLK_OTGPHY2>;
 				clock-names = "phyclk";
 				#clock-cells = <0>;
+				resets = <&cru SRST_USBHOST1_PHY>;
+				reset-names = "phy-reset";
 			};
 		};
 	};
-- 
2.21.0.392.gf8f6787159e-goog


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

* [PATCH 4/4] ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on wakeup
  2019-04-12 22:41 [PATCH 0/4] usb: dwc2: Another attempt handling rk3288's remote wake quirk Douglas Anderson
                   ` (2 preceding siblings ...)
  2019-04-12 22:41 ` [PATCH 3/4] ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288 Douglas Anderson
@ 2019-04-12 22:41 ` Douglas Anderson
  2019-04-12 23:57   ` Matthias Kaehlcke
  3 siblings, 1 reply; 10+ messages in thread
From: Douglas Anderson @ 2019-04-12 22:41 UTC (permalink / raw)
  To: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi
  Cc: amstan, linux-rockchip, linux-usb, Randy Li, mka, ryandcase,
	jwerner, Elaine Zhang, Douglas Anderson, devicetree,
	linux-kernel, Mark Rutland, linux-arm-kernel

The "host" USB port on rk3288 has a hardware errata where we've got to
assert a PHY reset whenever we see a remote wakeup.  Add that quirk
property to the device tree.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

 arch/arm/boot/dts/rk3288.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 92e0600595f8..6367c1b50fd7 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -617,6 +617,7 @@
 		dr_mode = "host";
 		phys = <&usbphy2>;
 		phy-names = "usb2-phy";
+		snps,reset-phy-on-wake;
 		status = "disabled";
 	};
 
-- 
2.21.0.392.gf8f6787159e-goog


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

* Re: [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup
  2019-04-12 22:41 ` [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup Douglas Anderson
@ 2019-04-12 23:42   ` Matthias Kaehlcke
  0 siblings, 0 replies; 10+ messages in thread
From: Matthias Kaehlcke @ 2019-04-12 23:42 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi,
	amstan, linux-rockchip, linux-usb, Randy Li, ryandcase, jwerner,
	Elaine Zhang, devicetree, linux-kernel, Greg Kroah-Hartman,
	Mark Rutland

On Fri, Apr 12, 2019 at 03:41:46PM -0700, Douglas Anderson wrote:
> On Rockchip rk3288 there's a hardware quirk where we need to assert
> the reset signal to the PHY when we get a remote wakeup on one of the
> two ports.  Document this quirk in the bindings.
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
>  Documentation/devicetree/bindings/usb/dwc2.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt
> index 6dc3c4a34483..f70f3aee4bfc 100644
> --- a/Documentation/devicetree/bindings/usb/dwc2.txt
> +++ b/Documentation/devicetree/bindings/usb/dwc2.txt
> @@ -37,6 +37,8 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties
>  - g-rx-fifo-size: size of rx fifo size in gadget mode.
>  - g-np-tx-fifo-size: size of non-periodic tx fifo size in gadget mode.
>  - g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0) in gadget mode.
> +- snps,reset-phy-on-wake: If present indicates that we need to reset the PHY when
> +                          we detect a wakeup.  This is due to a hardware errata.
>  
>  Deprecated properties:
>  - g-use-dma: gadget DMA mode is automatically detected

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up
  2019-04-12 22:41 ` [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up Douglas Anderson
@ 2019-04-12 23:56   ` Matthias Kaehlcke
  2019-04-16 21:54     ` Doug Anderson
  0 siblings, 1 reply; 10+ messages in thread
From: Matthias Kaehlcke @ 2019-04-12 23:56 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi,
	amstan, linux-rockchip, linux-usb, Randy Li, ryandcase, jwerner,
	Elaine Zhang, Yunzhi Li, Greg Kroah-Hartman, linux-kernel

On Fri, Apr 12, 2019 at 03:41:47PM -0700, Douglas Anderson wrote:
> On the rk3288 USB host-only port (the one that's not the OTG-enabled
> port) the PHY can get into a bad state when a wakeup is asserted (not
> just a wakeup from full system suspend but also a wakeup from
> autosuspend).
> 
> We can get the PHY out of its bad state by asserting its "port reset",
> but unfortunately that seems to assert a reset onto the USB bus so it
> could confuse things if we don't actually deenumerate / reenumerate the
> device.
> 
> We can also get the PHY out of its bad state by fully resetting it using
> the reset from the CRU (clock reset unit), which does a more full
> reset.  The CRU-based reset appears to actually cause devices on the bus
> to be removed and reinserted, which fixes the problem (albeit in a hacky
> way).
> 
> It's unfortunate that we need to do a full re-enumeration of devices at
> wakeup time, but this is better than alternative of letting the bus get
> wedged.
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
> ---
> 
>  drivers/usb/dwc2/core.h      |  5 +++++
>  drivers/usb/dwc2/core_intr.c | 12 ++++++++++++
>  drivers/usb/dwc2/hcd.c       | 16 +++++++++++++---
>  drivers/usb/dwc2/platform.c  |  9 +++++++++
>  4 files changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
> index 30bab8463c96..f30748f4fe7e 100644
> --- a/drivers/usb/dwc2/core.h
> +++ b/drivers/usb/dwc2/core.h
> @@ -859,6 +859,8 @@ struct dwc2_hregs_backup {
>   * @gadget_enabled:	Peripheral mode sub-driver initialization indicator.
>   * @ll_hw_enabled:	Status of low-level hardware resources.
>   * @hibernated:		True if core is hibernated
> + * @reset_phy_on_wake:	Quirk saying that we should assert PHY reset on a
> + *			remote wakeup.
>   * @frame_number:       Frame number read from the core. For both device
>   *			and host modes. The value ranges are from 0
>   *			to HFNUM_MAX_FRNUM.
> @@ -972,6 +974,7 @@ struct dwc2_hregs_backup {
>   * @status_buf_dma:     DMA address for status_buf
>   * @start_work:         Delayed work for handling host A-cable connection
>   * @reset_work:         Delayed work for handling a port reset
> + * @phy_reset_work:     Work structure for doing a PHY reset
>   * @otg_port:           OTG port number
>   * @frame_list:         Frame list
>   * @frame_list_dma:     Frame list DMA address
> @@ -1045,6 +1048,7 @@ struct dwc2_hsotg {
>  	unsigned int gadget_enabled:1;
>  	unsigned int ll_hw_enabled:1;
>  	unsigned int hibernated:1;
> +	unsigned int reset_phy_on_wake:1;
>  	u16 frame_number;
>  
>  	struct phy *phy;
> @@ -1147,6 +1151,7 @@ struct dwc2_hsotg {
>  
>  	struct delayed_work start_work;
>  	struct delayed_work reset_work;
> +	struct work_struct phy_reset_work;
>  	u8 otg_port;
>  	u32 *frame_list;
>  	dma_addr_t frame_list_dma;
> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
> index 19ae2595f1c3..16ff33574116 100644
> --- a/drivers/usb/dwc2/core_intr.c
> +++ b/drivers/usb/dwc2/core_intr.c
> @@ -435,6 +435,18 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
>  			/* Restart the Phy Clock */
>  			pcgcctl &= ~PCGCTL_STOPPCLK;
>  			dwc2_writel(hsotg, pcgcctl, PCGCTL);
> +
> +			/*
> +			 * If we've got this quirk then the PHY is stuck upon
> +			 * wakeup.  Assert reset.  This will propagate out and
> +			 * eventually we'll re-enumerate the device.  Not great
> +			 * but the best we can do.  We can't call phy_reset()
> +			 * at interrupt time but there's no hurry, so we'll
> +			 * schedule it for later.
> +			 */
> +			if (hsotg->reset_phy_on_wake)
> +				schedule_work(&hsotg->phy_reset_work);
> +
>  			mod_timer(&hsotg->wkp_timer,
>  				  jiffies + msecs_to_jiffies(71));
>  		} else {
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 3f087962f498..332349148d3f 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4376,6 +4376,17 @@ static void dwc2_hcd_reset_func(struct work_struct *work)
>  	spin_unlock_irqrestore(&hsotg->lock, flags);
>  }
>  
> +static void dwc2_hcd_phy_reset_func(struct work_struct *work)
> +{
> +	struct dwc2_hsotg *hsotg = container_of(work, struct dwc2_hsotg,
> +						phy_reset_work);
> +	int ret;
> +
> +	ret = phy_reset(hsotg->phy);
> +	if (ret)
> +		dev_warn(hsotg->dev, "PHY reset failed\n");
> +}
> +
>  /*
>   * =========================================================================
>   *  Linux HC Driver Functions
> @@ -5271,11 +5282,10 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
>  		hsotg->hc_ptr_array[i] = channel;
>  	}
>  
> -	/* Initialize hsotg start work */
> +	/* Initialize work */
>  	INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func);
> -
> -	/* Initialize port reset work */
>  	INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func);
> +	INIT_WORK(&hsotg->phy_reset_work, dwc2_hcd_phy_reset_func);

You also want to make sure that the work is cancelled when the
controller is stopped/removed. It seems dwc2_hcd_stop() would be a
suitable place for that.

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

* Re: [PATCH 4/4] ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on wakeup
  2019-04-12 22:41 ` [PATCH 4/4] ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on wakeup Douglas Anderson
@ 2019-04-12 23:57   ` Matthias Kaehlcke
  0 siblings, 0 replies; 10+ messages in thread
From: Matthias Kaehlcke @ 2019-04-12 23:57 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi,
	amstan, linux-rockchip, linux-usb, Randy Li, ryandcase, jwerner,
	Elaine Zhang, devicetree, linux-kernel, Mark Rutland,
	linux-arm-kernel

On Fri, Apr 12, 2019 at 03:41:49PM -0700, Douglas Anderson wrote:
> The "host" USB port on rk3288 has a hardware errata where we've got to
> assert a PHY reset whenever we see a remote wakeup.  Add that quirk
> property to the device tree.
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
>  arch/arm/boot/dts/rk3288.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 92e0600595f8..6367c1b50fd7 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -617,6 +617,7 @@
>  		dr_mode = "host";
>  		phys = <&usbphy2>;
>  		phy-names = "usb2-phy";
> +		snps,reset-phy-on-wake;
>  		status = "disabled";
>  	};
>  

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH 3/4] ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288.
  2019-04-12 22:41 ` [PATCH 3/4] ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288 Douglas Anderson
@ 2019-04-13  0:00   ` Matthias Kaehlcke
  0 siblings, 0 replies; 10+ messages in thread
From: Matthias Kaehlcke @ 2019-04-13  0:00 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi,
	amstan, linux-rockchip, linux-usb, Randy Li, ryandcase, jwerner,
	Elaine Zhang, devicetree, linux-kernel, Mark Rutland,
	linux-arm-kernel

On Fri, Apr 12, 2019 at 03:41:48PM -0700, Douglas Anderson wrote:
> Let's hook up the resets to the three USB PHYs on rk3288 as per the
> bindings.  This is in preparation for a future patch that will set the
> "snps,reset-phy-on-wake" on the host port.
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
>  arch/arm/boot/dts/rk3288.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 2e604f0afa98..92e0600595f8 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -905,6 +905,8 @@
>  				clocks = <&cru SCLK_OTGPHY0>;
>  				clock-names = "phyclk";
>  				#clock-cells = <0>;
> +				resets = <&cru SRST_USBOTG_PHY>;
> +				reset-names = "phy-reset";
>  			};
>  
>  			usbphy1: usb-phy@334 {
> @@ -913,6 +915,8 @@
>  				clocks = <&cru SCLK_OTGPHY1>;
>  				clock-names = "phyclk";
>  				#clock-cells = <0>;
> +				resets = <&cru SRST_USBHOST0_PHY>;
> +				reset-names = "phy-reset";
>  			};
>  
>  			usbphy2: usb-phy@348 {
> @@ -921,6 +925,8 @@
>  				clocks = <&cru SCLK_OTGPHY2>;
>  				clock-names = "phyclk";
>  				#clock-cells = <0>;
> +				resets = <&cru SRST_USBHOST1_PHY>;
> +				reset-names = "phy-reset";
>  			};
>  		};
>  	};

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up
  2019-04-12 23:56   ` Matthias Kaehlcke
@ 2019-04-16 21:54     ` Doug Anderson
  0 siblings, 0 replies; 10+ messages in thread
From: Doug Anderson @ 2019-04-16 21:54 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: Rob Herring, Minas Harutyunyan, Heiko Stuebner, Felipe Balbi,
	Alexandru M Stan, open list:ARM/Rockchip SoC...,
	linux-usb, Randy Li, Ryan Case, Julius Werner, Elaine Zhang,
	Yunzhi Li, Greg Kroah-Hartman, LKML

Hi,

On Fri, Apr 12, 2019 at 4:56 PM Matthias Kaehlcke <mka@chromium.org> wrote:
> > @@ -5271,11 +5282,10 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
> >               hsotg->hc_ptr_array[i] = channel;
> >       }
> >
> > -     /* Initialize hsotg start work */
> > +     /* Initialize work */
> >       INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func);
> > -
> > -     /* Initialize port reset work */
> >       INIT_DELAYED_WORK(&hsotg->reset_work, dwc2_hcd_reset_func);
> > +     INIT_WORK(&hsotg->phy_reset_work, dwc2_hcd_phy_reset_func);
>
> You also want to make sure that the work is cancelled when the
> controller is stopped/removed. It seems dwc2_hcd_stop() would be a
> suitable place for that.

Good point.  dwc2_hcd_stop() doesn't work though because it's called
with interrupts disabled (because it's holding the hsotg->lock
spinlock).  I put it in dwc2_hcd_free() where there's another similar
cancel.

-Doug

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

end of thread, other threads:[~2019-04-16 21:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-12 22:41 [PATCH 0/4] usb: dwc2: Another attempt handling rk3288's remote wake quirk Douglas Anderson
2019-04-12 22:41 ` [PATCH 1/4] dt-bindings: usb: dwc2: Document quirk to reset PHY upon wakeup Douglas Anderson
2019-04-12 23:42   ` Matthias Kaehlcke
2019-04-12 22:41 ` [PATCH 2/4] usb: dwc2: optionally assert phy reset when waking up Douglas Anderson
2019-04-12 23:56   ` Matthias Kaehlcke
2019-04-16 21:54     ` Doug Anderson
2019-04-12 22:41 ` [PATCH 3/4] ARM: dts: rockchip: Hook resets up to USB PHYs on rk3288 Douglas Anderson
2019-04-13  0:00   ` Matthias Kaehlcke
2019-04-12 22:41 ` [PATCH 4/4] ARM: dts: rockchip: Add quirk for resetting rk3288's dwc2 host on wakeup Douglas Anderson
2019-04-12 23:57   ` Matthias Kaehlcke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).