usb: gadget: Link state changes
Subsystems (2)
Thinh Nguyen
maintainercover usb: gadget: Link state changes
This patch series adds some fixes to how dwc3 handles cases related to link state changes.
Thinh Nguyen (4):
usb: dwc3: gadget: Don't send unintended link state change
usb: dwc3: gadget: Set link state to RX_Detect on disconnect
usb: dwc3: gadget: Clear DCTL.ULSTCHNGREQ before set
usb: dwc3: debug: Remove newline printout
drivers/usb/dwc3/debug.h | 4 ++-- drivers/usb/dwc3/gadget.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-)
Signature · 1 line
2.11.0
Thinh Nguyen
maintainerPATCH 1/4 usb: dwc3: gadget: Don't send unintended link state change
DCTL.ULSTCHNGREQ is a write-only field. When doing a read-modify-write to DCTL, the driver must make sure that there's no unintended link state change request from whatever is read from DCTL.ULSTCHNGREQ. Set link state change to no-action when the driver writes to DCTL.
--- drivers/usb/dwc3/gadget.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
drivers/usb/dwc3/gadget.c +21 -0
@@ -57,6 +57,8 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)return -EINVAL ; } +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ;dwc3_writel (dwc->regs,DWC3_DCTL , reg);return 0 ;
@@ -1822,6 +1824,9 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) dwc->pullups_connected = false; } +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ; +dwc3_writel (dwc->regs,DWC3_DCTL , reg); do {
@@ -2744,6 +2749,10 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)int reg; reg =dwc3_readl (dwc->regs,DWC3_DCTL ); + +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ; + reg &= ~DWC3_DCTL_INITU1ENA ;dwc3_writel (dwc->regs,DWC3_DCTL , reg);
@@ -2799,6 +2808,10 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)dwc3_reset_gadget (dwc); reg =dwc3_readl (dwc->regs,DWC3_DCTL ); + +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ; + reg &= ~DWC3_DCTL_TSTCTRL_MASK ;dwc3_writel (dwc->regs,DWC3_DCTL , reg); dwc->test_mode = false;
@@ -2904,10 +2917,15 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)if (dwc->has_lpm_erratum && dwc->revision >=DWC3_REVISION_240A ) reg |=DWC3_DCTL_NYET_THRES (dwc->lpm_nyet_threshold); +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ;dwc3_writel (dwc->regs,DWC3_DCTL , reg); }else { reg =dwc3_readl (dwc->regs,DWC3_DCTL ); reg &= ~DWC3_DCTL_HIRD_THRES_MASK ; + +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ;dwc3_writel (dwc->regs,DWC3_DCTL , reg); }
@@ -3017,6 +3035,9 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, reg &= ~u1u2; +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ; +dwc3_writel (dwc->regs,DWC3_DCTL , reg);break ;default :
Signature · 1 line
2.11.0
Re: [PATCH 1/4] usb: dwc3: gadget: Don't send unintended link state change
Hi Thinh,
Quoted 6 lines · Thinh Nguyen
DCTL.ULSTCHNGREQ is a write-only field. When doing a read-modify-write to DCTL, the driver must make sure that there's no unintended link state change request from whatever is read from DCTL.ULSTCHNGREQ. Set link state change to no-action when the driver writes to DCTL.
Signed-off-by Thinh Nguyen <[email protected]>
WHAT A GREAT CATCH!!! However, let's do one small change here:
Quoted 9 lines
--- drivers/usb/dwc3/gadget.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)drivers/usb/dwc3/gadget.c +0
-0
drivers/usb/dwc3/gadget.c int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) · line 62
Quoted 6 lines
drivers/usb/dwc3/gadget.c +2
-0@@ -57,6 +57,8 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)return -EINVAL ; } +/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ;dwc3_writel (dwc->regs,DWC3_DCTL , reg);
Let's a small macro or a little function to wrap this. Something dwc3_dctl_write_safe() or something long those line.
Then that macro/function will make sure to clear those bits.
Signature · 1 line
balbi
Thinh Nguyen
maintainerRe: [PATCH 1/4] usb: dwc3: gadget: Don't send unintended link state change
Hi,
Quoted 21 lines · Felipe Balbi
Quoted 6 lines · Thinh Nguyen
DCTL.ULSTCHNGREQ is a write-only field. When doing a read-modify-write to DCTL, the driver must make sure that there's no unintended link state change request from whatever is read from DCTL.ULSTCHNGREQ. Set link state change to no-action when the driver writes to DCTL.
Signed-off-by Thinh Nguyen <[email protected]>WHAT A GREAT CATCH!!! However, let's do one small change here:
Quoted 12 lines
--- drivers/usb/dwc3/gadget.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)drivers/usb/dwc3/gadget.c +0
-0@@ -57,6 +57,8 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)return -EINVAL ; }
Quoted 7 lines
drivers/usb/dwc3/gadget.c int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) · line 62
Quoted 3 lines
drivers/usb/dwc3/gadget.c +2
-0+/* Don't send link state change request */ + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ;dwc3_writel (dwc->regs,DWC3_DCTL , reg);Let's a small macro or a little function to wrap this. Something
dwc3_dctl_write_safe()or something long those line.Then that macro/function will make sure to clear those bits.
Sure. I'll resend with the change.
Thanks,
Thinh
Thinh Nguyen
maintainerPATCH 2/4 usb: dwc3: gadget: Set link state to RX_Detect on disconnect
In reply to Thinh NguyenWhen DWC3 receives disconnect event, it needs to set the link state to RX_Detect.
DWC_usb3 3.30a programming guide 4.1.7
--- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/dwc3/gadget.c +2 -0
@@ -2748,6 +2748,8 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) {int reg; +dwc3_gadget_set_link_state (dwc,DWC3_LINK_STATE_RX_DET ); + reg =dwc3_readl (dwc->regs,DWC3_DCTL );/* Don't send link state change request */
Signature · 1 line
2.11.0
Thinh Nguyen
maintainerPATCH 3/4 usb: dwc3: gadget: Clear DCTL.ULSTCHNGREQ before set
In reply to Thinh NguyenSend a no-action link state change request before the actual request so DWC3 can send the same request whenever we call dwc3_gadget_set_link_state().
--- drivers/usb/dwc3/gadget.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/dwc3/gadget.c +3 -0
@@ -113,6 +113,9 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) reg =dwc3_readl (dwc->regs,DWC3_DCTL ); reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK ; +/* set no action before sending new link state change */ +dwc3_writel (dwc->regs,DWC3_DCTL , reg); +/* set requested state */ reg |=DWC3_DCTL_ULSTCHNGREQ (state);dwc3_writel (dwc->regs,DWC3_DCTL , reg);
Signature · 1 line
2.11.0
Thinh Nguyen
maintainerPATCH 4/4 usb: dwc3: debug: Remove newline printout
In reply to Thinh NguyenThe newline from the unknown link state tracepoint doesn't follow the other tracepoints, and it looks unsightly. Let's remove it.
--- drivers/usb/dwc3/debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/dwc3/debug.h +2 -2
@@ -112,7 +112,7 @@ dwc3_gadget_link_string(enum dwc3_link_state link_state)case DWC3_LINK_STATE_RESUME :return "Resume" ;default : -return "UNKNOWN link state\n" ; +return "UNKNOWN link state" ; } }
@@ -141,7 +141,7 @@ dwc3_gadget_hs_link_string(enum dwc3_link_state link_state)case DWC3_LINK_STATE_RESUME :return "Resume" ;default : -return "UNKNOWN link state\n" ; +return "UNKNOWN link state" ; } }
Signature · 1 line
2.11.0