mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] usb: typec: Find a Type-C partner after a warm reboot on the Orange Pi 5
@ 2026-11-10 10:39 Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 1/3] usb: typec: tcpm: Don't cut a pending state delay short on a re-queue Arun Iyengar via B4 Relay
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10 10:39 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Heikki Krogerus, Greg Kroah-Hartman,
	Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner
  Cc: linux-usb, linux-kernel, devicetree, linux-arm-kernel,
	linux-rockchip, Arun Iyengar, stable

After a warm reboot, an Orange Pi 5 (RK3588S, FUSB302) often did not
see a Genesys Logic based USB-C to DisplayPort cable that stayed
plugged in: tcpm toggled in SRC_UNATTACHED, the FUSB302 raised no
interrupt at all, and only a replug at the board brought DisplayPort
back. Three changes fix it:

  1. tcpm: tcpm_init() sets two states back to back with the port lock
     held, so the state machine work is queued twice, and the second
     run applies the PORT_RESET -> PORT_RESET_WAIT_OFF transition at
     once: tErrorRecovery (100 ms) took 6 us. A pending delay is now
     re-armed for the time left. This is generic, with Fixes: and
     Cc: stable.
  2. fusb302: toggle with the default Rp current. The FUSB302 found
     the cable within seconds when it toggled with the default current
     (after another device was detached), never while it toggled with
     Rp 3.0A. tcpm still sets the configured Rp level through set_cc()
     once the port is attached.
  3. arm64: dts: rockchip: the Orange Pi 5/5B Type-C port is
     self-powered (its VBUS comes from vcc5v0_sys, the board runs from
     a separate power input), so tcpm opens CC during error recovery
     and the partner sees a real detach at boot. This one is for the
     Rockchip tree; it does not depend on 1 and 2 to build, but without
     patch 1 the open-CC period at boot is cut short. It is based on
     usb-next; on top of my pending "arm64: dts: rockchip: Add USB-C DP
     AltMode for Orange Pi 5/5B", which adds a node next to the same
     line, it needs git am -3 (no conflict). I can resend it rebased.

Testing, on an Orange Pi 5 with 7.3-based kernels: before, after a
warm reboot the cable was not detected (0 FUSB302 interrupts since
boot) until it was replugged at the board. With the three patches it
was detected on 4/4 boots, the first one starting from that stuck
state, with DP connected 1-2 s after boot; the three were tested
together, not one at a time. The patches have been in every kernel I
have run since; in a later run of 30 reboots with a USB-C DisplayPort
monitor, the partner was attached on 30/30 boots, and the tcpm log of
every boot shows CC opened in PORT_RESET and 100-112 ms spent there
before PORT_RESET_WAIT_OFF. Not tested: other TCPCs (patch 1 is
generic, patch 2 only changes fusb302), and the Orange Pi 5B (same
dtsi). W=1 arm64 builds of drivers/usb/typec at every patch,
CHECK_DTBS for the Orange Pi 5 and 5B and checkpatch --strict are
clean.

This series was developed with Claude (Anthropic) as a coding
assistant: it wrote the code and the commit messages, and I reviewed
and tested every change as described above.

Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
Arun Iyengar (3):
      usb: typec: tcpm: Don't cut a pending state delay short on a re-queue
      usb: typec: fusb302: Toggle with the default Rp current
      arm64: dts: rockchip: Mark the Orange Pi 5/5B Type-C port self-powered

 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-5b.dtsi |  1 +
 drivers/usb/typec/tcpm/fusb302.c                        | 13 +++++++++++--
 drivers/usb/typec/tcpm/tcpm.c                           | 12 ++++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261110-tcpm-attach-reboot-d93d5f36403b

Best regards,
--  
Arun Iyengar <aiyengar1990@gmail.com>



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] usb: typec: tcpm: Don't cut a pending state delay short on a re-queue
  2026-11-10 10:39 [PATCH 0/3] usb: typec: Find a Type-C partner after a warm reboot on the Orange Pi 5 Arun Iyengar via B4 Relay
@ 2026-11-10 10:39 ` Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 2/3] usb: typec: fusb302: Toggle with the default Rp current Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 3/3] arm64: dts: rockchip: Mark the Orange Pi 5/5B Type-C port self-powered Arun Iyengar via B4 Relay
  2 siblings, 0 replies; 4+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10 10:39 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Heikki Krogerus, Greg Kroah-Hartman,
	Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner
  Cc: linux-usb, linux-kernel, devicetree, linux-arm-kernel,
	linux-rockchip, Arun Iyengar, stable

From: Arun Iyengar <aiyengar1990@gmail.com>

tcpm_state_machine_work() applies port->delayed_state as soon as it
runs, assuming it only runs when the state machine timer fired. The
work can also run because it was queued for another reason while it was
already running.

This happens at every port registration: tcpm_init() runs with the port
lock held and calls tcpm_set_state() twice with no delay (default state,
then PORT_RESET). The first call queues the work, which starts and
blocks on the lock; the second call queues it again. The first run
handles PORT_RESET and schedules PORT_RESET_WAIT_OFF after
PD_T_ERROR_RECOVERY; the second run then applies it at once. On an
Orange Pi 5 (FUSB302) the log shows the 100 ms ErrorRecovery taking
6 us:

  pending state change PORT_RESET -> PORT_RESET_WAIT_OFF @ 100 ms
  state change PORT_RESET -> PORT_RESET_WAIT_OFF [delayed 100 ms]

so the "clean slate" that tcpm_init() asks for never happens.

If the delay has not expired yet, re-arm the timer for the time left
and return, as tcpm_send_queued_message() already does.

Fixes: 3ed8e1c2ac99 ("usb: typec: tcpm: Migrate workqueue to RT priority for processing events")
Cc: stable@vger.kernel.org
Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
 drivers/usb/typec/tcpm/tcpm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index d721baef5210..0a19b7665555 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -6569,6 +6569,18 @@ static void tcpm_state_machine_work(struct kthread_work *work)
 
 	/* If we were queued due to a delayed state change, update it now */
 	if (port->delayed_state) {
+		/*
+		 * The work may have been queued again for another reason
+		 * while it was running, for instance by tcpm_init() at port
+		 * registration, which sets two states in a row with the
+		 * port lock held. Do not cut a pending delay short; re-arm
+		 * the timer for the time that is left.
+		 */
+		if (ktime_after(port->delayed_runtime, ktime_get())) {
+			hrtimer_start(&port->state_machine_timer,
+				      port->delayed_runtime, HRTIMER_MODE_ABS);
+			goto done;
+		}
 		tcpm_log(port, "state change %s -> %s [delayed %ld ms]",
 			 tcpm_states[port->state],
 			 tcpm_states[port->delayed_state], port->delay_ms);

-- 
2.55.0



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] usb: typec: fusb302: Toggle with the default Rp current
  2026-11-10 10:39 [PATCH 0/3] usb: typec: Find a Type-C partner after a warm reboot on the Orange Pi 5 Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 1/3] usb: typec: tcpm: Don't cut a pending state delay short on a re-queue Arun Iyengar via B4 Relay
@ 2026-11-10 10:39 ` Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 3/3] arm64: dts: rockchip: Mark the Orange Pi 5/5B Type-C port self-powered Arun Iyengar via B4 Relay
  2 siblings, 0 replies; 4+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10 10:39 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Heikki Krogerus, Greg Kroah-Hartman,
	Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner
  Cc: linux-usb, linux-kernel, devicetree, linux-arm-kernel,
	linux-rockchip, Arun Iyengar

From: Arun Iyengar <aiyengar1990@gmail.com>

tcpm_start_toggling() programs the Rp current that tcpm asks for, which
is the current of the source PDO (Rp 3.0A on boards that can source
3A) when the port starts toggling from Unattached.SRC, and the default
current when it starts from Unattached.SNK after a detach.

A Genesys Logic based USB-C to DisplayPort cable connected to the
Orange Pi 5 is often not detected after a warm reboot: the FUSB302
toggle state machine raises no interrupt with it while it drives the
high Rp current, but finds it within seconds once toggling restarts
with the default current after another device was detached.

Unattached sources may advertise any Rp level, and tcpm sets the
configured level through set_cc() once the port is attached, so always
toggle with the default current.

Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
 drivers/usb/typec/tcpm/fusb302.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
index 3319f6a2b0c9..53c5671fe45b 100644
--- a/drivers/usb/typec/tcpm/fusb302.c
+++ b/drivers/usb/typec/tcpm/fusb302.c
@@ -942,10 +942,19 @@ static int tcpm_start_toggling(struct tcpc_dev *dev,
 	}
 
 	mutex_lock(&chip->lock);
-	ret = fusb302_set_src_current(chip, cc_src_current[cc]);
+	/*
+	 * Look for a partner with the default USB current advertisement.
+	 * Some sinks (seen with a Genesys Logic based USB-C to DisplayPort
+	 * cable) present an Rd that the FUSB302 toggle state machine does
+	 * not detect while it drives the high (3.0 A) Rp current, so they
+	 * are only found when toggling starts from the sink side. Unattached
+	 * sources may advertise any Rp level, and tcpm sets the configured
+	 * level through set_cc() once the port is attached.
+	 */
+	ret = fusb302_set_src_current(chip, SRC_CURRENT_DEFAULT);
 	if (ret < 0) {
 		fusb302_log(chip, "unable to set src current %s, ret=%d",
-			    typec_cc_status_name[cc], ret);
+			    typec_cc_status_name[TYPEC_CC_RP_DEF], ret);
 		goto done;
 	}
 	ret = fusb302_set_toggling(chip, mode);

-- 
2.55.0



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] arm64: dts: rockchip: Mark the Orange Pi 5/5B Type-C port self-powered
  2026-11-10 10:39 [PATCH 0/3] usb: typec: Find a Type-C partner after a warm reboot on the Orange Pi 5 Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 1/3] usb: typec: tcpm: Don't cut a pending state delay short on a re-queue Arun Iyengar via B4 Relay
  2026-11-10 10:39 ` [PATCH 2/3] usb: typec: fusb302: Toggle with the default Rp current Arun Iyengar via B4 Relay
@ 2026-11-10 10:39 ` Arun Iyengar via B4 Relay
  2 siblings, 0 replies; 4+ messages in thread
From: Arun Iyengar via B4 Relay @ 2026-11-10 10:39 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Heikki Krogerus, Greg Kroah-Hartman,
	Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner
  Cc: linux-usb, linux-kernel, devicetree, linux-arm-kernel,
	linux-rockchip, Arun Iyengar

From: Arun Iyengar <aiyengar1990@gmail.com>

The board is powered from its separate power-only USB-C input. The
FUSB302 port's VBUS comes from vcc5v0_sys through a load switch, so the
board never runs from this port's VBUS.

Without self-powered, tcpm keeps Rp on CC during PORT_RESET (error
recovery), because opening CC on a port-powered device would remove its
own supply. With self-powered, the port opens CC for tErrorRecovery
whenever it resets, including at boot. A partner left in a stale state
by a warm reboot then sees a real detach.

Signed-off-by: Arun Iyengar <aiyengar1990@gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-5b.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-5b.dtsi
index 6e081bc06cfe..b621fc8638c7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-5b.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-5b.dtsi
@@ -117,6 +117,7 @@ usb_con: connector {
 				<PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
 			source-pdos =
 				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+			self-powered;
 			try-power-role = "source";
 
 			ports {

-- 
2.55.0



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-11-10 10:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10 10:39 [PATCH 0/3] usb: typec: Find a Type-C partner after a warm reboot on the Orange Pi 5 Arun Iyengar via B4 Relay
2026-11-10 10:39 ` [PATCH 1/3] usb: typec: tcpm: Don't cut a pending state delay short on a re-queue Arun Iyengar via B4 Relay
2026-11-10 10:39 ` [PATCH 2/3] usb: typec: fusb302: Toggle with the default Rp current Arun Iyengar via B4 Relay
2026-11-10 10:39 ` [PATCH 3/3] arm64: dts: rockchip: Mark the Orange Pi 5/5B Type-C port self-powered Arun Iyengar via B4 Relay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®