summaryrefslogtreecommitdiff
path: root/drivers/usb/typec/tcpm/tcpm.c
diff options
context:
space:
mode:
authorChiYuan Huang <cy_huang@richtek.com>2023-01-09 15:19:50 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-01-17 17:09:27 +0100
commit36f78477ac2c89e9a2eed4a31404a291a3450b5d (patch)
tree39e0a68d25773f1bc115394531bec8e247e10620 /drivers/usb/typec/tcpm/tcpm.c
parente95765e97d9cb93258a4840440d410fa6ff7e819 (diff)
usb: typec: tcpm: Fix altmode re-registration causes sysfs create fail
There's the altmode re-registeration issue after data role swap (DR_SWAP). Comparing to USBPD 2.0, in USBPD 3.0, it loose the limit that only DFP can initiate the VDM command to get partner identity information. For a USBPD 3.0 UFP device, it may already get the identity information from its port partner before DR_SWAP. If DR_SWAP send or receive at the mean time, 'send_discover' flag will be raised again. It causes discover identify action restart while entering ready state. And after all discover actions are done, the 'tcpm_register_altmodes' will be called. If old altmode is not unregistered, this sysfs create fail can be found. In 'DR_SWAP_CHANGE_DR' state case, only DFP will unregister altmodes. For UFP, the original altmodes keep registered. This patch fix the logic that after DR_SWAP, 'tcpm_unregister_altmodes' must be called whatever the current data role is. Reviewed-by: Macpaul Lin <macpaul.lin@mediatek.com> Fixes: ae8a2ca8a221 ("usb: typec: Group all TCPCI/TCPM code together") Reported-by: TommyYl Chen <tommyyl.chen@mediatek.com> Cc: stable@vger.kernel.org Signed-off-by: ChiYuan Huang <cy_huang@richtek.com> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/1673248790-15794-1-git-send-email-cy_huang@richtek.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/typec/tcpm/tcpm.c')
-rw-r--r--drivers/usb/typec/tcpm/tcpm.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 904c7b4ce2f0..59b366b5c614 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -4594,14 +4594,13 @@ static void run_state_machine(struct tcpm_port *port)
tcpm_set_state(port, ready_state(port), 0);
break;
case DR_SWAP_CHANGE_DR:
- if (port->data_role == TYPEC_HOST) {
- tcpm_unregister_altmodes(port);
+ tcpm_unregister_altmodes(port);
+ if (port->data_role == TYPEC_HOST)
tcpm_set_roles(port, true, port->pwr_role,
TYPEC_DEVICE);
- } else {
+ else
tcpm_set_roles(port, true, port->pwr_role,
TYPEC_HOST);
- }
tcpm_ams_finish(port);
tcpm_set_state(port, ready_state(port), 0);
break;