Patch "usb: typec: ucsi: Fix race between typec_switch and role_switch" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    usb: typec: ucsi: Fix race between typec_switch and role_switch

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     usb-typec-ucsi-fix-race-between-typec_switch-and-rol.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 222b5f39b0fe07ab66466c8449150bc76fa04908
Author: Krishna Kurapati <quic_kriskura@xxxxxxxxxxx>
Date:   Fri Mar 1 09:39:14 2024 +0530

    usb: typec: ucsi: Fix race between typec_switch and role_switch
    
    [ Upstream commit f5e9bda03aa50ffad36eccafe893d004ef213c43 ]
    
    When orientation switch is enabled in ucsi glink, there is a xhci
    probe failure seen when booting up in host mode in reverse
    orientation.
    
    During bootup the following things happen in multiple drivers:
    
    a) DWC3 controller driver initializes the core in device mode when the
    dr_mode is set to DRD. It relies on role_switch call to change role to
    host.
    
    b) QMP driver initializes the lanes to TYPEC_ORIENTATION_NORMAL as a
    normal routine. It relies on the typec_switch_set call to get notified
    of orientation changes.
    
    c) UCSI core reads the UCSI_GET_CONNECTOR_STATUS via the glink and
    provides initial role switch to dwc3 controller.
    
    When booting up in host mode with orientation TYPEC_ORIENTATION_REVERSE,
    then we see the following things happening in order:
    
    a) UCSI gives initial role as host to dwc3 controller ucsi_register_port.
    Upon receiving this notification, the dwc3 core needs to program GCTL from
    PRTCAP_DEVICE to PRTCAP_HOST and as part of this change, it asserts GCTL
    Core soft reset and waits for it to be  completed before shifting it to
    host. Only after the reset is done will the dwc3_host_init be invoked and
    xhci is probed. DWC3 controller expects that the usb phy's are stable
    during this process i.e., the phy init is already done.
    
    b) During the 100ms wait for GCTL core soft reset, the actual notification
    from PPM is received by ucsi_glink via pmic glink for changing role to
    host. The pmic_glink_ucsi_notify routine first sends the orientation
    change to QMP and then sends role to dwc3 via ucsi framework. This is
    happening exactly at the time GCTL core soft reset is being processed.
    
    c) When QMP driver receives typec switch to TYPEC_ORIENTATION_REVERSE, it
    then re-programs the phy at the instant GCTL core soft reset has been
    asserted by dwc3 controller due to which the QMP PLL lock fails in
    qmp_combo_usb_power_on.
    
    d) After the 100ms of GCTL core soft reset is completed, the dwc3 core
    goes for initializing the host mode and invokes xhci probe. But at this
    point the QMP is non-responsive and as a result, the xhci plat probe fails
    during xhci_reset.
    
    Fix this by passing orientation switch to available ucsi instances if
    their gpio configuration is available before ucsi_register is invoked so
    that by the time, the pmic_glink_ucsi_notify provides typec_switch to QMP,
    the lane is already configured and the call would be a NOP thus not racing
    with role switch.
    
    Cc: stable@xxxxxxxxxxxxxxx
    Fixes: c6165ed2f425 ("usb: ucsi: glink: use the connector orientation GPIO to provide switch events")
    Suggested-by: Wesley Cheng <quic_wcheng@xxxxxxxxxxx>
    Signed-off-by: Krishna Kurapati <quic_kriskura@xxxxxxxxxxx>
    Acked-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240301040914.458492-1-quic_kriskura@xxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c
index 4853141cd10c8..894622b6556a6 100644
--- a/drivers/usb/typec/ucsi/ucsi_glink.c
+++ b/drivers/usb/typec/ucsi/ucsi_glink.c
@@ -254,6 +254,20 @@ static void pmic_glink_ucsi_notify(struct work_struct *work)
 static void pmic_glink_ucsi_register(struct work_struct *work)
 {
 	struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work);
+	int orientation;
+	int i;
+
+	for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) {
+		if (!ucsi->port_orientation[i])
+			continue;
+		orientation = gpiod_get_value(ucsi->port_orientation[i]);
+
+		if (orientation >= 0) {
+			typec_switch_set(ucsi->port_switch[i],
+					 orientation ? TYPEC_ORIENTATION_REVERSE
+					     : TYPEC_ORIENTATION_NORMAL);
+		}
+	}
 
 	ucsi_register(ucsi->ucsi);
 }




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux