linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management
@ 2018-09-05 11:40 Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 1/4] usb: dwc2: get optional vbus-supply regulator once Amelie Delaunay
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Amelie Delaunay @ 2018-09-05 11:40 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier, Amelie Delaunay

This patchset fixes and improves host mode external vbus supply management,
mainly around suspend/resume use cases. It also avoid 'vbus regulator"
to be requested lots of times upon each call to dwc2_vbus_supply_init(),
especially when pm runtime is enabled.

Fabrice Gasnier (4):
  usb: dwc2: get optional vbus-supply regulator once
  usb: dwc2: fix a race with external vbus supply
  usb: dwc2: fix call to vbus supply exit routine, call it unlocked
  usb: dwc2: fix unbalanced use of external vbus-supply

 drivers/usb/dwc2/hcd.c      | 45 ++++++++++++++++++++++++++++++++++-----------
 drivers/usb/dwc2/platform.c |  8 ++++++++
 2 files changed, 42 insertions(+), 11 deletions(-)

-- 
2.7.4


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

* [PATCH 1/4] usb: dwc2: get optional vbus-supply regulator once
  2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
@ 2018-09-05 11:40 ` Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 2/4] usb: dwc2: fix a race with external vbus supply Amelie Delaunay
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Amelie Delaunay @ 2018-09-05 11:40 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier, Amelie Delaunay

From: Fabrice Gasnier <fabrice.gasnier@st.com>

Move devm_regulator_get_optional() call to probe routine. This avoids
'vbus-supply' regulator to be requested lots of times, upon each call
to dwc2_vbus_supply_init(), e.g. like with runtime pm.

Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external
vbus supply")

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/usb/dwc2/hcd.c      | 12 +++---------
 drivers/usb/dwc2/platform.c |  8 ++++++++
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 2bd6e6b..c205cfa 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -358,16 +358,10 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
 
 static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg)
 {
-	int ret;
-
-	hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus");
-	if (IS_ERR(hsotg->vbus_supply)) {
-		ret = PTR_ERR(hsotg->vbus_supply);
-		hsotg->vbus_supply = NULL;
-		return ret == -ENODEV ? 0 : ret;
-	}
+	if (hsotg->vbus_supply)
+		return regulator_enable(hsotg->vbus_supply);
 
-	return regulator_enable(hsotg->vbus_supply);
+	return 0;
 }
 
 static int dwc2_vbus_supply_exit(struct dwc2_hsotg *hsotg)
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 9a53a58..957e342 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -434,6 +434,14 @@ static int dwc2_driver_probe(struct platform_device *dev)
 	if (retval)
 		return retval;
 
+	hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus");
+	if (IS_ERR(hsotg->vbus_supply)) {
+		retval = PTR_ERR(hsotg->vbus_supply);
+		hsotg->vbus_supply = NULL;
+		if (retval != -ENODEV)
+			return retval;
+	}
+
 	retval = dwc2_lowlevel_hw_enable(hsotg);
 	if (retval)
 		return retval;
-- 
2.7.4


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

* [PATCH 2/4] usb: dwc2: fix a race with external vbus supply
  2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 1/4] usb: dwc2: get optional vbus-supply regulator once Amelie Delaunay
@ 2018-09-05 11:40 ` Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 3/4] usb: dwc2: fix call to vbus supply exit routine, call it unlocked Amelie Delaunay
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Amelie Delaunay @ 2018-09-05 11:40 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier, Amelie Delaunay

From: Fabrice Gasnier <fabrice.gasnier@st.com>

There's a race with root hub resume, when using external vbus supply.
Root hub gets resumed, but runtime pm autosuspend runs as external vbus
supply isn't enabled. So, host never exit from power down properly.
Initialize vbus external supply before, rater that after hub resume.

Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external
vbus supply")

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.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 c205cfa..bb72517 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4387,6 +4387,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	struct usb_bus *bus = hcd_to_bus(hcd);
 	unsigned long flags;
+	int ret;
 
 	dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
 
@@ -4402,6 +4403,13 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 
 	dwc2_hcd_reinit(hsotg);
 
+	/* enable external vbus supply before resuming root hub */
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+	ret = dwc2_vbus_supply_init(hsotg);
+	if (ret)
+		return ret;
+	spin_lock_irqsave(&hsotg->lock, flags);
+
 	/* Initialize and connect root hub if one is not already attached */
 	if (bus->root_hub) {
 		dev_dbg(hsotg->dev, "DWC OTG HCD Has Root Hub\n");
@@ -4411,7 +4419,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 
-	return dwc2_vbus_supply_init(hsotg);
+	return 0;
 }
 
 /*
-- 
2.7.4


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

* [PATCH 3/4] usb: dwc2: fix call to vbus supply exit routine, call it unlocked
  2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 1/4] usb: dwc2: get optional vbus-supply regulator once Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 2/4] usb: dwc2: fix a race with external vbus supply Amelie Delaunay
@ 2018-09-05 11:40 ` Amelie Delaunay
  2018-09-05 11:40 ` [PATCH 4/4] usb: dwc2: fix unbalanced use of external vbus-supply Amelie Delaunay
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Amelie Delaunay @ 2018-09-05 11:40 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier, Amelie Delaunay

From: Fabrice Gasnier <fabrice.gasnier@st.com>

dwc2_vbus_supply_exit() may call regulator_disable(). It shouldn't be
called with interrupts disabled as it might sleep.
This is seen with DEBUG_ATOMIC_SLEEP=y.

Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external
vbus supply")

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/usb/dwc2/hcd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index bb72517..e8a480e 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4484,7 +4484,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 		hprt0 |= HPRT0_SUSP;
 		hprt0 &= ~HPRT0_PWR;
 		dwc2_writel(hsotg, hprt0, HPRT0);
+		spin_unlock_irqrestore(&hsotg->lock, flags);
 		dwc2_vbus_supply_exit(hsotg);
+		spin_lock_irqsave(&hsotg->lock, flags);
 	}
 
 	/* Enter partial_power_down */
-- 
2.7.4


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

* [PATCH 4/4] usb: dwc2: fix unbalanced use of external vbus-supply
  2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
                   ` (2 preceding siblings ...)
  2018-09-05 11:40 ` [PATCH 3/4] usb: dwc2: fix call to vbus supply exit routine, call it unlocked Amelie Delaunay
@ 2018-09-05 11:40 ` Amelie Delaunay
  2018-09-10 10:18 ` [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Artur Petrosyan
  2018-09-13  6:22 ` Minas Harutyunyan
  5 siblings, 0 replies; 7+ messages in thread
From: Amelie Delaunay @ 2018-09-05 11:40 UTC (permalink / raw)
  To: Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier, Amelie Delaunay

From: Fabrice Gasnier <fabrice.gasnier@st.com>

When using external vbus supply regulator, it should be enabled
synchronously with PWR bit in HPRT register. This also fixes
unbalanced use of this optional regulator (This can be reproduced
easily when unbinding the driver).

Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external
vbus supply")

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/usb/dwc2/hcd.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index e8a480e..8efbb45 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3558,6 +3558,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 	u32 port_status;
 	u32 speed;
 	u32 pcgctl;
+	u32 pwr;
 
 	switch (typereq) {
 	case ClearHubFeature:
@@ -3606,8 +3607,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			dev_dbg(hsotg->dev,
 				"ClearPortFeature USB_PORT_FEAT_POWER\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
+			pwr = hprt0 & HPRT0_PWR;
 			hprt0 &= ~HPRT0_PWR;
 			dwc2_writel(hsotg, hprt0, HPRT0);
+			if (pwr)
+				dwc2_vbus_supply_exit(hsotg);
 			break;
 
 		case USB_PORT_FEAT_INDICATOR:
@@ -3817,8 +3821,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			dev_dbg(hsotg->dev,
 				"SetPortFeature - USB_PORT_FEAT_POWER\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
+			pwr = hprt0 & HPRT0_PWR;
 			hprt0 |= HPRT0_PWR;
 			dwc2_writel(hsotg, hprt0, HPRT0);
+			if (!pwr)
+				dwc2_vbus_supply_init(hsotg);
 			break;
 
 		case USB_PORT_FEAT_RESET:
@@ -3835,6 +3842,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			dwc2_writel(hsotg, 0, PCGCTL);
 
 			hprt0 = dwc2_read_hprt0(hsotg);
+			pwr = hprt0 & HPRT0_PWR;
 			/* Clear suspend bit if resetting from suspend state */
 			hprt0 &= ~HPRT0_SUSP;
 
@@ -3848,6 +3856,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				dev_dbg(hsotg->dev,
 					"In host mode, hprt0=%08x\n", hprt0);
 				dwc2_writel(hsotg, hprt0, HPRT0);
+				if (!pwr)
+					dwc2_vbus_supply_init(hsotg);
 			}
 
 			/* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
@@ -4387,6 +4397,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	struct usb_bus *bus = hcd_to_bus(hcd);
 	unsigned long flags;
+	u32 hprt0;
 	int ret;
 
 	dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
@@ -4403,12 +4414,16 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 
 	dwc2_hcd_reinit(hsotg);
 
-	/* enable external vbus supply before resuming root hub */
-	spin_unlock_irqrestore(&hsotg->lock, flags);
-	ret = dwc2_vbus_supply_init(hsotg);
-	if (ret)
-		return ret;
-	spin_lock_irqsave(&hsotg->lock, flags);
+	hprt0 = dwc2_read_hprt0(hsotg);
+	/* Has vbus power been turned on in dwc2_core_host_init ? */
+	if (hprt0 & HPRT0_PWR) {
+		/* Enable external vbus supply before resuming root hub */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		ret = dwc2_vbus_supply_init(hsotg);
+		if (ret)
+			return ret;
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
 
 	/* Initialize and connect root hub if one is not already attached */
 	if (bus->root_hub) {
@@ -4430,6 +4445,7 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 {
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	unsigned long flags;
+	u32 hprt0;
 
 	/* Turn off all host-specific interrupts */
 	dwc2_disable_host_interrupts(hsotg);
@@ -4438,6 +4454,7 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 	synchronize_irq(hcd->irq);
 
 	spin_lock_irqsave(&hsotg->lock, flags);
+	hprt0 = dwc2_read_hprt0(hsotg);
 	/* Ensure hcd is disconnected */
 	dwc2_hcd_disconnect(hsotg, true);
 	dwc2_hcd_stop(hsotg);
@@ -4446,7 +4463,9 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 
-	dwc2_vbus_supply_exit(hsotg);
+	/* keep balanced supply init/exit by checking HPRT0_PWR */
+	if (hprt0 & HPRT0_PWR)
+		dwc2_vbus_supply_exit(hsotg);
 
 	usleep_range(1000, 3000);
 }
-- 
2.7.4


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

* Re: [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management
  2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
                   ` (3 preceding siblings ...)
  2018-09-05 11:40 ` [PATCH 4/4] usb: dwc2: fix unbalanced use of external vbus-supply Amelie Delaunay
@ 2018-09-10 10:18 ` Artur Petrosyan
  2018-09-13  6:22 ` Minas Harutyunyan
  5 siblings, 0 replies; 7+ messages in thread
From: Artur Petrosyan @ 2018-09-10 10:18 UTC (permalink / raw)
  To: Amelie Delaunay, Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier

Hi,

On 9/5/2018 15:41, Amelie Delaunay wrote:
> This patchset fixes and improves host mode external vbus supply management,
> mainly around suspend/resume use cases. It also avoid 'vbus regulator"
> to be requested lots of times upon each call to dwc2_vbus_supply_init(),
> especially when pm runtime is enabled.
> 
> Fabrice Gasnier (4):
>    usb: dwc2: get optional vbus-supply regulator once
>    usb: dwc2: fix a race with external vbus supply
>    usb: dwc2: fix call to vbus supply exit routine, call it unlocked
>    usb: dwc2: fix unbalanced use of external vbus-supply
> 
>   drivers/usb/dwc2/hcd.c      | 45 ++++++++++++++++++++++++++++++++++-----------
>   drivers/usb/dwc2/platform.c |  8 ++++++++
>   2 files changed, 42 insertions(+), 11 deletions(-)
> 
Tested-by: Artur Petrosyan <arturp@synopsys.com>

The patchset has been tested on Synopsys HAPS-DX platform.

Thanks,
Artur

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

* Re: [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management
  2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
                   ` (4 preceding siblings ...)
  2018-09-10 10:18 ` [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Artur Petrosyan
@ 2018-09-13  6:22 ` Minas Harutyunyan
  5 siblings, 0 replies; 7+ messages in thread
From: Minas Harutyunyan @ 2018-09-13  6:22 UTC (permalink / raw)
  To: Amelie Delaunay, Minas Harutyunyan, Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, linux-stm32, Fabrice Gasnier

On 9/5/2018 3:40 PM, Amelie Delaunay wrote:
> This patchset fixes and improves host mode external vbus supply management,
> mainly around suspend/resume use cases. It also avoid 'vbus regulator"
> to be requested lots of times upon each call to dwc2_vbus_supply_init(),
> especially when pm runtime is enabled.
> 
> Fabrice Gasnier (4):
>    usb: dwc2: get optional vbus-supply regulator once
>    usb: dwc2: fix a race with external vbus supply
>    usb: dwc2: fix call to vbus supply exit routine, call it unlocked
>    usb: dwc2: fix unbalanced use of external vbus-supply
> 
>   drivers/usb/dwc2/hcd.c      | 45 ++++++++++++++++++++++++++++++++++-----------
>   drivers/usb/dwc2/platform.c |  8 ++++++++
>   2 files changed, 42 insertions(+), 11 deletions(-)
> 
Tested-by: Artur Petrosyan <arturp@synopsys.com>
Acked-by: Minas Harutyunyan <hminas@synopsys.com>

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

end of thread, other threads:[~2018-09-13  6:23 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-05 11:40 [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Amelie Delaunay
2018-09-05 11:40 ` [PATCH 1/4] usb: dwc2: get optional vbus-supply regulator once Amelie Delaunay
2018-09-05 11:40 ` [PATCH 2/4] usb: dwc2: fix a race with external vbus supply Amelie Delaunay
2018-09-05 11:40 ` [PATCH 3/4] usb: dwc2: fix call to vbus supply exit routine, call it unlocked Amelie Delaunay
2018-09-05 11:40 ` [PATCH 4/4] usb: dwc2: fix unbalanced use of external vbus-supply Amelie Delaunay
2018-09-10 10:18 ` [PATCH 0/4] usb: dwc2: fix host mode external vbus supply management Artur Petrosyan
2018-09-13  6:22 ` Minas Harutyunyan

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).