| From f9c5ed985271b0573afc49ee9bf334e76fce912d Mon Sep 17 00:00:00 2001 |
| From: Bin Liu <b-liu@ti.com> |
| Date: Tue, 18 Dec 2018 07:58:04 -0600 |
| Subject: usb: musb: dsps: fix otg state machine |
| |
| [ Upstream commit 6010abf2c2c0e382d7e8ee44bd11f343aae90cce ] |
| |
| Due to lack of ID pin interrupt event on AM335x devices, the musb dsps |
| driver uses polling to detect usb device attach for dual-role port. |
| |
| But in the case if a micro-A cable adapter is attached without a USB device |
| attached to the cable, the musb state machine gets stuck in a_wait_vrise |
| state waiting for the MUSB_CONNECT interrupt which won't happen due to the |
| usb device is not attached. The state is stuck in a_wait_vrise even after |
| the micro-A cable is detached, which could cause VBUS retention if then the |
| dual-role port is attached to a host port. |
| |
| To fix the problem, make a_wait_vrise as a transient state, then move the |
| state to either a_wait_bcon for host port or a_idle state for dual-role |
| port, if no usb device is attached to the port. |
| |
| Signed-off-by: Bin Liu <b-liu@ti.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/usb/musb/musb_dsps.c | 9 +++++++-- |
| 1 file changed, 7 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c |
| index dbb482b7e0ba..b7d460adaa61 100644 |
| --- a/drivers/usb/musb/musb_dsps.c |
| +++ b/drivers/usb/musb/musb_dsps.c |
| @@ -242,8 +242,13 @@ static int dsps_check_status(struct musb *musb, void *unused) |
| |
| switch (musb->xceiv->otg->state) { |
| case OTG_STATE_A_WAIT_VRISE: |
| - dsps_mod_timer_optional(glue); |
| - break; |
| + if (musb->port_mode == MUSB_HOST) { |
| + musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; |
| + dsps_mod_timer_optional(glue); |
| + break; |
| + } |
| + /* fall through */ |
| + |
| case OTG_STATE_A_WAIT_BCON: |
| /* keep VBUS on for host-only mode */ |
| if (musb->port_mode == MUSB_PORT_MODE_HOST) { |
| -- |
| 2.19.1 |
| |