1 From 3de4f996a0b5412aa451729008130a488f71563e Mon Sep 17 00:00:00 2001
2 From: "Christian A. Ehrhardt" <lk@c--e.de>
3 Date: Wed, 20 Mar 2024 08:39:26 +0100
4 Subject: usb: typec: ucsi: Clear UCSI_CCI_RESET_COMPLETE before reset
6 From: Christian A. Ehrhardt <lk@c--e.de>
8 commit 3de4f996a0b5412aa451729008130a488f71563e upstream.
10 Check the UCSI_CCI_RESET_COMPLETE complete flag before starting
11 another reset. Use a UCSI_SET_NOTIFICATION_ENABLE command to clear
12 the flag if it is set.
14 Signed-off-by: Christian A. Ehrhardt <lk@c--e.de>
15 Cc: stable <stable@kernel.org>
16 Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
17 Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
18 Link: https://lore.kernel.org/r/20240320073927.1641788-6-lk@c--e.de
19 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21 drivers/usb/typec/ucsi/ucsi.c | 36 +++++++++++++++++++++++++++++++++++-
22 1 file changed, 35 insertions(+), 1 deletion(-)
24 --- a/drivers/usb/typec/ucsi/ucsi.c
25 +++ b/drivers/usb/typec/ucsi/ucsi.c
26 @@ -852,13 +852,47 @@ static int ucsi_reset_connector(struct u
28 static int ucsi_reset_ppm(struct ucsi *ucsi)
30 - u64 command = UCSI_PPM_RESET;
36 mutex_lock(&ucsi->ppm_lock);
38 + ret = ucsi->ops->read(ucsi, UCSI_CCI, &cci, sizeof(cci));
43 + * If UCSI_CCI_RESET_COMPLETE is already set we must clear
44 + * the flag before we start another reset. Send a
45 + * UCSI_SET_NOTIFICATION_ENABLE command to achieve this.
46 + * Ignore a timeout and try the reset anyway if this fails.
48 + if (cci & UCSI_CCI_RESET_COMPLETE) {
49 + command = UCSI_SET_NOTIFICATION_ENABLE;
50 + ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command,
55 + tmo = jiffies + msecs_to_jiffies(UCSI_TIMEOUT_MS);
57 + ret = ucsi->ops->read(ucsi, UCSI_CCI,
61 + if (cci & UCSI_CCI_COMMAND_COMPLETE)
63 + if (time_is_before_jiffies(tmo))
68 + WARN_ON(cci & UCSI_CCI_RESET_COMPLETE);
71 + command = UCSI_PPM_RESET;
72 ret = ucsi->ops->async_write(ucsi, UCSI_CONTROL, &command,