--- /dev/null
+From 8a50da849151e7e12b43c1d8fe7ad302223aef6b Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Fri, 4 Apr 2025 00:43:06 +0200
+Subject: usb: typec: tcpm: allow switching to mode accessory to mux properly
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 8a50da849151e7e12b43c1d8fe7ad302223aef6b upstream.
+
+The funciton tcpm_acc_attach is not setting the proper state when
+calling tcpm_set_role. The function tcpm_set_role is currently only
+handling TYPEC_STATE_USB. For the tcpm_acc_attach to switch into other
+modal states tcpm_set_role needs to be extended by an extra state
+parameter. This patch is handling the proper state change when calling
+tcpm_acc_attach.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250404-ml-topic-tcpm-v1-3-b99f44badce8@pengutronix.de
+Stable-dep-of: bec15191d523 ("usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 27 ++++++++++++++++++---------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1024,7 +1024,7 @@ static int tcpm_set_attached_state(struc
+ port->data_role);
+ }
+
+-static int tcpm_set_roles(struct tcpm_port *port, bool attached,
++static int tcpm_set_roles(struct tcpm_port *port, bool attached, int state,
+ enum typec_role role, enum typec_data_role data)
+ {
+ enum typec_orientation orientation;
+@@ -1061,7 +1061,7 @@ static int tcpm_set_roles(struct tcpm_po
+ }
+ }
+
+- ret = tcpm_mux_set(port, TYPEC_STATE_USB, usb_role, orientation);
++ ret = tcpm_mux_set(port, state, usb_role, orientation);
+ if (ret < 0)
+ return ret;
+
+@@ -3622,7 +3622,8 @@ static int tcpm_src_attach(struct tcpm_p
+
+ tcpm_enable_auto_vbus_discharge(port, true);
+
+- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_source(port));
++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB,
++ TYPEC_SOURCE, tcpm_data_role_for_source(port));
+ if (ret < 0)
+ return ret;
+
+@@ -3772,7 +3773,8 @@ static int tcpm_snk_attach(struct tcpm_p
+
+ tcpm_enable_auto_vbus_discharge(port, true);
+
+- ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port));
++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB,
++ TYPEC_SINK, tcpm_data_role_for_sink(port));
+ if (ret < 0)
+ return ret;
+
+@@ -3796,6 +3798,7 @@ static int tcpm_acc_attach(struct tcpm_p
+ int ret;
+ enum typec_role role;
+ enum typec_data_role data;
++ int state = TYPEC_STATE_USB;
+
+ if (port->attached)
+ return 0;
+@@ -3804,7 +3807,13 @@ static int tcpm_acc_attach(struct tcpm_p
+ data = tcpm_port_is_sink(port) ? tcpm_data_role_for_sink(port)
+ : tcpm_data_role_for_source(port);
+
+- ret = tcpm_set_roles(port, true, role, data);
++ if (tcpm_port_is_audio(port))
++ state = TYPEC_MODE_AUDIO;
++
++ if (tcpm_port_is_debug(port))
++ state = TYPEC_MODE_DEBUG;
++
++ ret = tcpm_set_roles(port, true, state, role, data);
+ if (ret < 0)
+ return ret;
+
+@@ -4484,7 +4493,7 @@ static void run_state_machine(struct tcp
+ */
+ tcpm_set_vconn(port, false);
+ tcpm_set_vbus(port, false);
+- tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
++ tcpm_set_roles(port, port->self_powered, TYPEC_STATE_USB, TYPEC_SOURCE,
+ tcpm_data_role_for_source(port));
+ /*
+ * If tcpc fails to notify vbus off, TCPM will wait for PD_T_SAFE_0V +
+@@ -4516,7 +4525,7 @@ static void run_state_machine(struct tcp
+ tcpm_set_vconn(port, false);
+ if (port->pd_capable)
+ tcpm_set_charge(port, false);
+- tcpm_set_roles(port, port->self_powered, TYPEC_SINK,
++ tcpm_set_roles(port, port->self_powered, TYPEC_STATE_USB, TYPEC_SINK,
+ tcpm_data_role_for_sink(port));
+ /*
+ * VBUS may or may not toggle, depending on the adapter.
+@@ -4615,10 +4624,10 @@ static void run_state_machine(struct tcp
+ case DR_SWAP_CHANGE_DR:
+ tcpm_unregister_altmodes(port);
+ if (port->data_role == TYPEC_HOST)
+- tcpm_set_roles(port, true, port->pwr_role,
++ tcpm_set_roles(port, true, TYPEC_STATE_USB, port->pwr_role,
+ TYPEC_DEVICE);
+ else
+- tcpm_set_roles(port, true, port->pwr_role,
++ tcpm_set_roles(port, true, TYPEC_STATE_USB, port->pwr_role,
+ TYPEC_HOST);
+ tcpm_ams_finish(port);
+ tcpm_set_state(port, ready_state(port), 0);
--- /dev/null
+From 64843d0ba96d3eae297025562111d57585273366 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Fri, 4 Apr 2025 00:43:04 +0200
+Subject: usb: typec: tcpm: allow to use sink in accessory mode
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 64843d0ba96d3eae297025562111d57585273366 upstream.
+
+Since the function tcpm_acc_attach is not setting the data and role for
+for the sink case we extend it to check for it first.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250404-ml-topic-tcpm-v1-1-b99f44badce8@pengutronix.de
+Stable-dep-of: bec15191d523 ("usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -3794,12 +3794,17 @@ static void tcpm_snk_detach(struct tcpm_
+ static int tcpm_acc_attach(struct tcpm_port *port)
+ {
+ int ret;
++ enum typec_role role;
++ enum typec_data_role data;
+
+ if (port->attached)
+ return 0;
+
+- ret = tcpm_set_roles(port, true, TYPEC_SOURCE,
+- tcpm_data_role_for_source(port));
++ role = tcpm_port_is_sink(port) ? TYPEC_SINK : TYPEC_SOURCE;
++ data = tcpm_port_is_sink(port) ? tcpm_data_role_for_sink(port)
++ : tcpm_data_role_for_source(port);
++
++ ret = tcpm_set_roles(port, true, role, data);
+ if (ret < 0)
+ return ret;
+
--- /dev/null
+From bec15191d52300defa282e3fd83820f69e447116 Mon Sep 17 00:00:00 2001
+From: RD Babiera <rdbabiera@google.com>
+Date: Wed, 18 Jun 2025 23:06:04 +0000
+Subject: usb: typec: tcpm: apply vbus before data bringup in tcpm_src_attach
+
+From: RD Babiera <rdbabiera@google.com>
+
+commit bec15191d52300defa282e3fd83820f69e447116 upstream.
+
+This patch fixes Type-C compliance test TD 4.7.6 - Try.SNK DRP Connect
+SNKAS.
+
+tVbusON has a limit of 275ms when entering SRC_ATTACHED. Compliance
+testers can interpret the TryWait.Src to Attached.Src transition after
+Try.Snk as being in Attached.Src the entire time, so ~170ms is lost
+to the debounce timer.
+
+Setting the data role can be a costly operation in host mode, and when
+completed after 100ms can cause Type-C compliance test check TD 4.7.5.V.4
+to fail.
+
+Turn VBUS on before tcpm_set_roles to meet timing requirement.
+
+Fixes: f0690a25a140 ("staging: typec: USB Type-C Port Manager (tcpm)")
+Cc: stable <stable@kernel.org>
+Signed-off-by: RD Babiera <rdbabiera@google.com>
+Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20250618230606.3272497-2-rdbabiera@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 34 +++++++++++++++++-----------------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -3622,17 +3622,6 @@ static int tcpm_src_attach(struct tcpm_p
+
+ tcpm_enable_auto_vbus_discharge(port, true);
+
+- ret = tcpm_set_roles(port, true, TYPEC_STATE_USB,
+- TYPEC_SOURCE, tcpm_data_role_for_source(port));
+- if (ret < 0)
+- return ret;
+-
+- if (port->pd_supported) {
+- ret = port->tcpc->set_pd_rx(port->tcpc, true);
+- if (ret < 0)
+- goto out_disable_mux;
+- }
+-
+ /*
+ * USB Type-C specification, version 1.2,
+ * chapter 4.5.2.2.8.1 (Attached.SRC Requirements)
+@@ -3642,13 +3631,24 @@ static int tcpm_src_attach(struct tcpm_p
+ (polarity == TYPEC_POLARITY_CC2 && port->cc1 == TYPEC_CC_RA)) {
+ ret = tcpm_set_vconn(port, true);
+ if (ret < 0)
+- goto out_disable_pd;
++ return ret;
+ }
+
+ ret = tcpm_set_vbus(port, true);
+ if (ret < 0)
+ goto out_disable_vconn;
+
++ ret = tcpm_set_roles(port, true, TYPEC_STATE_USB, TYPEC_SOURCE,
++ tcpm_data_role_for_source(port));
++ if (ret < 0)
++ goto out_disable_vbus;
++
++ if (port->pd_supported) {
++ ret = port->tcpc->set_pd_rx(port->tcpc, true);
++ if (ret < 0)
++ goto out_disable_mux;
++ }
++
+ port->pd_capable = false;
+
+ port->partner = NULL;
+@@ -3658,14 +3658,14 @@ static int tcpm_src_attach(struct tcpm_p
+
+ return 0;
+
+-out_disable_vconn:
+- tcpm_set_vconn(port, false);
+-out_disable_pd:
+- if (port->pd_supported)
+- port->tcpc->set_pd_rx(port->tcpc, false);
+ out_disable_mux:
+ tcpm_mux_set(port, TYPEC_STATE_SAFE, USB_ROLE_NONE,
+ TYPEC_ORIENTATION_NONE);
++out_disable_vbus:
++ tcpm_set_vbus(port, false);
++out_disable_vconn:
++ tcpm_set_vconn(port, false);
++
+ return ret;
+ }
+