mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/9] Improve Qualcomm EUD driver and platform support
@ 2026-01-16 23:20 Elson Serrao
  2026-01-16 23:20 ` [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware Elson Serrao
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

The Embedded USB Debugger (EUD) is a High-Speed USB on-chip hub that
provides debug and trace capabilities on Qualcomm platforms. The current
EUD driver, however, lacks essential hardware resources such as PHY
references and support for multi-port configurations. This series
addresses those gaps and introduces the necessary device tree updates
to enable testing and validation of the enhanced functionality.

This work builds upon an earlier EUD driver submission:
https://lore.kernel.org/all/20240730222439.3469-1-quic_eserrao@quicinc.com/
and extends it with support for multi-port use cases and proper handling
of EUD operation across different USB roles.

The series has been validated on the Qualcomm Dragonwing Q6 platform
(RB3 Gen2 board), confirming successful OpenOCD connectivity to the EUD
interface. For detailed usage instructions, refer to Qualcomm’s Linux
kernel debugging guide:
https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-12/debugging_linux_kernel.html#debug-using-openocd

Elson Serrao (9):
  dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  usb: misc: qcom_eud: add sysfs attribute for port selection
  usb: misc: qcom_eud: add per-path High-Speed PHY control
  usb: misc: qcom_eud: add per-path role switch support
  usb: misc: qcom_eud: improve enable_store API
  usb: misc: qcom_eud: add host mode coordination
  usb: misc: qcom_eud: fix virtual attach/detach event handling
  arm64: dts: qcom: kodiak: Align EUD node with binding
  arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality

 Documentation/ABI/testing/sysfs-driver-eud    |  16 +
 .../bindings/soc/qcom/qcom,eud.yaml           |  97 +++--
 arch/arm64/boot/dts/qcom/kodiak.dtsi          |  33 +-
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts  |  20 +-
 drivers/usb/misc/qcom_eud.c                   | 365 +++++++++++++++++-
 5 files changed, 474 insertions(+), 57 deletions(-)

-- 
2.34.1


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

* [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
@ 2026-01-16 23:20 ` Elson Serrao
  2026-01-17 11:57   ` Krzysztof Kozlowski
  2026-01-16 23:20 ` [PATCH 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

The Qualcomm Embedded USB Debugger (EUD) hardware can intercept up to
two independent High-Speed UTMI data paths, depending on the SoC
configuration. Each path operates independently with:

- Dedicated PHY interface
- Distinct USB connector and controller associations
- Role dependent routing

Model these hardware paths as separate eud-path nodes to accurately
represent the physical topology and add below per-path properties:

phys: EUD exposes a High-Speed debug hub that relies on HS-PHY for its
operation. This property references the HS-PHY associated with the UTMI
path.

usb-role-switch: Indicates that the USB port on this UTMI path supports
role switching. In device role, debug mode inserts the EUD hub into the
UTMI path. In host role, the EUD hub is bypassed and UTMI traffic flows
directly between the PHY and the USB controller.

This change breaks backwards compatibility, but the previous binding
omitted critical resources like PHY and did not describe per-path
topology. Without these modifications EUD cannot be guaranteed to
function.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 .../bindings/soc/qcom/qcom,eud.yaml           | 97 ++++++++++++++-----
 1 file changed, 71 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
index 84218636c0d8..a7162560c323 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
@@ -10,8 +10,11 @@ maintainers:
   - Souradeep Chowdhury <quic_schowdhu@quicinc.com>
 
 description:
-  This binding is used to describe the Qualcomm Embedded USB Debugger, which is
-  mini USB-hub implemented on chip to support USB-based debug capabilities.
+  This binding describes the Qualcomm Embedded USB Debugger (EUD), an on-chip
+  mini USB hub that enables USB-based debug capabilities. The EUD block is
+  positioned between the High-Speed USB PHY and the USB controller, where it
+  intercepts the UTMI interface to support debug and bypass modes. EUD can be
+  supported on up to two High-Speed USB ports.
 
 properties:
   compatible:
@@ -29,26 +32,59 @@ properties:
     description: EUD interrupt
     maxItems: 1
 
-  ports:
-    $ref: /schemas/graph.yaml#/properties/ports
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+patternProperties:
+  "^eud-path@[0-1]$":
+    type: object
     description:
-      These ports is to be attached to the endpoint of the DWC3 controller node
-      and type C connector node. The controller has the "usb-role-switch"
-      property.
+      Represents one High-Speed UTMI path that EUD intercepts. This node models
+      the physical data path intercepted by EUD and provides graph endpoints to
+      link the USB controller and the external connector associated with this path.
 
     properties:
-      port@0:
-        $ref: /schemas/graph.yaml#/properties/port
-        description: This port is to be attached to the DWC3 controller.
+      reg:
+        maxItems: 1
+        description: Path number
+
+      phys:
+        maxItems: 1
+        description: High-Speed USB PHY associated with this data path.
+
+      usb-role-switch:
+        type: boolean
+        description:
+          Set this property if the USB port on this path is role switch capable.
+
+      ports:
+        $ref: /schemas/graph.yaml#/properties/ports
+        description:
+          These ports are to be attached to the endpoint of the USB controller node
+          and USB connector node.
+
+        properties:
+          port@0:
+            $ref: /schemas/graph.yaml#/properties/port
+            description: This port is to be attached to the USB controller.
 
-      port@1:
-        $ref: /schemas/graph.yaml#/properties/port
-        description: This port is to be attached to the type C connector.
+          port@1:
+            $ref: /schemas/graph.yaml#/properties/port
+            description: This port is to be attached to the USB connector.
+
+    required:
+      - reg
+      - phys
+      - ports
+
+    additionalProperties: false
 
 required:
   - compatible
   - reg
-  - ports
 
 additionalProperties: false
 
@@ -58,21 +94,30 @@ examples:
         compatible = "qcom,sc7280-eud", "qcom,eud";
         reg = <0x88e0000 0x2000>,
               <0x88e2000 0x1000>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        eud-path@0 {
+            reg = <0>;
+            phys = <&usb_1_hsphy>;
+            usb-role-switch;
 
-        ports {
-            #address-cells = <1>;
-            #size-cells = <0>;
-            port@0 {
-                reg = <0>;
-                eud_ep: endpoint {
-                    remote-endpoint = <&usb2_role_switch>;
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0>;
+                    eud_ep: endpoint {
+                        remote-endpoint = <&usb2_role_switch>;
+                    };
                 };
-            };
 
-            port@1 {
-                reg = <1>;
-                eud_con: endpoint {
-                    remote-endpoint = <&con_eud>;
+                port@1 {
+                    reg = <1>;
+                    eud_con: endpoint {
+                        remote-endpoint = <&con_eud>;
+                    };
                 };
             };
         };
-- 
2.34.1


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

* [PATCH 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
  2026-01-16 23:20 ` [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware Elson Serrao
@ 2026-01-16 23:20 ` Elson Serrao
  2026-01-27 13:30   ` Konrad Dybcio
  2026-01-16 23:21 ` [PATCH 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

EUD can be mapped to either the primary USB port or the secondary USB port
depending on the value of the EUD_PORT_SEL register. Add a 'port' sysfs
attribute to allow userspace to select which port EUD should operate on
and update the ABI documentation. This is needed for systems with dual
USB ports where EUD needs to be accessible on either port depending on the
system configuration and use case.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 Documentation/ABI/testing/sysfs-driver-eud | 16 ++++++++
 drivers/usb/misc/qcom_eud.c                | 43 ++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud
index 2bab0db2d2f0..67223f73ee60 100644
--- a/Documentation/ABI/testing/sysfs-driver-eud
+++ b/Documentation/ABI/testing/sysfs-driver-eud
@@ -7,3 +7,19 @@ Description:
 		EUD based on a 1 or a 0 value. By enabling EUD,
 		the user is able to activate the mini-usb hub of
 		EUD for debug and trace capabilities.
+
+What:		/sys/bus/platform/drivers/qcom_eud/.../port
+Date:		January 2026
+Contact:	Elson Serrao <elson.serrao@oss.qualcomm.com>
+Description:
+		Selects which USB port the Embedded USB Debugger (EUD)
+		is mapped to on platforms providing multiple High-Speed
+		USB ports.
+
+		Valid values:
+		  0 - Primary USB port
+		  1 - Secondary USB port
+
+		The attribute is writable only while EUD is disabled.
+		Reading the attribute returns the currently selected
+		USB port number.
diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 926419ca560f..1a136f8f1ae5 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -23,8 +23,11 @@
 #define EUD_REG_VBUS_INT_CLR	0x0080
 #define EUD_REG_CSR_EUD_EN	0x1014
 #define EUD_REG_SW_ATTACH_DET	0x1018
+#define EUD_REG_PORT_SEL	0x1028
 #define EUD_REG_EUD_EN2		0x0000
 
+#define EUD_MAX_PORTS		2
+
 #define EUD_ENABLE		BIT(0)
 #define EUD_INT_PET_EUD		BIT(0)
 #define EUD_INT_VBUS		BIT(2)
@@ -40,6 +43,7 @@ struct eud_chip {
 	int				irq;
 	bool				enabled;
 	bool				usb_attached;
+	u8				port_idx;
 };
 
 static int enable_eud(struct eud_chip *priv)
@@ -104,8 +108,47 @@ static ssize_t enable_store(struct device *dev,
 
 static DEVICE_ATTR_RW(enable);
 
+static ssize_t port_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct eud_chip *chip = dev_get_drvdata(dev);
+
+	return sysfs_emit(buf, "%u\n", chip->port_idx);
+}
+
+static ssize_t port_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct eud_chip *chip = dev_get_drvdata(dev);
+	u8 port;
+	int ret;
+
+	ret = kstrtou8(buf, 0, &port);
+	if (ret)
+		return ret;
+
+	/* Only port 0 and port 1 are valid */
+	if (port >= EUD_MAX_PORTS)
+		return -EINVAL;
+
+	/* Port selection must be done before enabling EUD */
+	if (chip->enabled) {
+		dev_err(chip->dev, "Cannot change port while EUD is enabled\n");
+		return -EBUSY;
+	}
+
+	writel(port, chip->base + EUD_REG_PORT_SEL);
+	chip->port_idx = port;
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(port);
+
 static struct attribute *eud_attrs[] = {
 	&dev_attr_enable.attr,
+	&dev_attr_port.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(eud);
-- 
2.34.1


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

* [PATCH 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
  2026-01-16 23:20 ` [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware Elson Serrao
  2026-01-16 23:20 ` [PATCH 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  2026-01-16 23:21 ` [PATCH 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

The Embedded USB Debugger (EUD) is a High-Speed USB on-chip hub that
enables debug and trace capabilities on Qualcomm devices. As a HS-USB
hub, the EUD requires High-Speed PHY support for proper operation.

EUD hardware can support more than one High-Speed USB path, each with
its own PHY. The active path is selected via the EUD_PORT_SEL register.
To support this multi-path capability, the driver needs to manage PHY
resources on a per-path basis, initializing and powering the PHY
corresponding to the currently selected port.

This patch restructures the driver to support per-path PHY management.
PHY resources are powered on/off based on which port is active. This
ensures the correct PHY is enabled when EUD is enabled.

This change requires path specifications and corresponding PHY references
to be added in device tree, breaking backward compatibility. However, this
is acceptable since EUD cannot be guaranteed to function without proper
PHY control.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 drivers/usb/misc/qcom_eud.c | 130 +++++++++++++++++++++++++++++++++++-
 1 file changed, 129 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 1a136f8f1ae5..5cebb64f4a67 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
@@ -34,26 +35,96 @@
 #define EUD_INT_SAFE_MODE	BIT(4)
 #define EUD_INT_ALL		(EUD_INT_VBUS | EUD_INT_SAFE_MODE)
 
+struct eud_path {
+	struct eud_chip		*chip;
+	struct phy		*phy;
+	u8			num;
+};
+
 struct eud_chip {
 	struct device			*dev;
 	struct usb_role_switch		*role_sw;
 	void __iomem			*base;
+	struct eud_path			*paths[EUD_MAX_PORTS];
 	phys_addr_t			mode_mgr;
 	unsigned int			int_status;
 	int				irq;
 	bool				enabled;
 	bool				usb_attached;
+	bool				phy_enabled;
 	u8				port_idx;
 };
 
+static int eud_phy_enable(struct eud_chip *chip)
+{
+	struct eud_path *path;
+	struct phy *phy;
+	int ret;
+
+	if (chip->phy_enabled)
+		return 0;
+
+	path = chip->paths[chip->port_idx];
+	if (!path || !path->phy) {
+		dev_err(chip->dev, "No PHY configured for port %u\n", chip->port_idx);
+		return -ENODEV;
+	}
+
+	phy = path->phy;
+
+	ret = phy_init(phy);
+	if (ret) {
+		dev_err(chip->dev, "Failed to initialize USB2 PHY for port %u: %d\n",
+			chip->port_idx, ret);
+		return ret;
+	}
+
+	ret = phy_power_on(phy);
+	if (ret) {
+		dev_err(chip->dev, "Failed to power on USB2 PHY for port %u: %d\n",
+			chip->port_idx, ret);
+		phy_exit(phy);
+		return ret;
+	}
+
+	chip->phy_enabled = true;
+
+	return 0;
+}
+
+static void eud_phy_disable(struct eud_chip *chip)
+{
+	struct eud_path *path;
+	struct phy *phy;
+
+	if (!chip->phy_enabled)
+		return;
+
+	path = chip->paths[chip->port_idx];
+	if (!path || !path->phy)
+		return;
+
+	phy = path->phy;
+
+	phy_power_off(phy);
+	phy_exit(phy);
+	chip->phy_enabled = false;
+}
+
 static int enable_eud(struct eud_chip *priv)
 {
 	int ret;
 
-	ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1);
+	ret = eud_phy_enable(priv);
 	if (ret)
 		return ret;
 
+	ret = qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1);
+	if (ret) {
+		eud_phy_disable(priv);
+		return ret;
+	}
+
 	writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN);
 	writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE,
 			priv->base + EUD_REG_INT1_EN_MASK);
@@ -70,6 +141,8 @@ static int disable_eud(struct eud_chip *priv)
 		return ret;
 
 	writel(0, priv->base + EUD_REG_CSR_EUD_EN);
+	eud_phy_disable(priv);
+
 	return 0;
 }
 
@@ -132,6 +205,12 @@ static ssize_t port_store(struct device *dev,
 	if (port >= EUD_MAX_PORTS)
 		return -EINVAL;
 
+	/* Check if the corresponding path is available */
+	if (!chip->paths[port]) {
+		dev_err(chip->dev, "EUD not supported on selected port\n");
+		return -EOPNOTSUPP;
+	}
+
 	/* Port selection must be done before enabling EUD */
 	if (chip->enabled) {
 		dev_err(chip->dev, "Cannot change port while EUD is enabled\n");
@@ -231,8 +310,45 @@ static void eud_role_switch_release(void *data)
 	usb_role_switch_put(chip->role_sw);
 }
 
+static int eud_init_path(struct eud_chip *chip, struct device_node *np)
+{
+	struct eud_path *path;
+	u32 path_num;
+	int ret;
+
+	ret = of_property_read_u32(np, "reg", &path_num);
+	if (ret) {
+		dev_err(chip->dev, "Missing 'reg' property in path node\n");
+		return ret;
+	}
+
+	if (path_num >= EUD_MAX_PORTS) {
+		dev_err(chip->dev, "Invalid path number: %u (max %d)\n",
+			path_num, EUD_MAX_PORTS - 1);
+		return -EINVAL;
+	}
+
+	path = devm_kzalloc(chip->dev, sizeof(*path), GFP_KERNEL);
+	if (!path)
+		return -ENOMEM;
+
+	path->chip = chip;
+	path->num = path_num;
+
+	path->phy = devm_of_phy_get(chip->dev, np, NULL);
+	if (IS_ERR(path->phy))
+		return dev_err_probe(chip->dev, PTR_ERR(path->phy),
+				     "Failed to get PHY for path %d\n", path_num);
+
+	chip->paths[path_num] = path;
+
+	return 0;
+}
+
 static int eud_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
 	struct eud_chip *chip;
 	struct resource *res;
 	int ret;
@@ -252,6 +368,18 @@ static int eud_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	for_each_child_of_node(np, child) {
+		ret = eud_init_path(chip, child);
+		if (ret) {
+			of_node_put(child);
+			return ret;
+		}
+	}
+
+	/* Primary path is mandatory. Secondary is optional */
+	if (!chip->paths[0])
+		return -ENODEV;
+
 	chip->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(chip->base))
 		return PTR_ERR(chip->base);
-- 
2.34.1


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

* [PATCH 4/9] usb: misc: qcom_eud: add per-path role switch support
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
                   ` (2 preceding siblings ...)
  2026-01-16 23:21 ` [PATCH 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  2026-01-16 23:21 ` [PATCH 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

The EUD hardware can support multiple High-Speed USB paths, each connected
to different USB controllers. The current implementation uses a single
chip-level role switch, which cannot properly handle multi-path
configurations where each path needs independent role management. Since
EUD is physically present between the USB connector and the controller,
it should also relay the role change requests from the connector.

Restructure the driver to support per-path role switches and remove the
chip-level role switch. Additionally, as EUD need not modify the USB
role upon enabling, remove the unnecessary role switch call from
enable_eud().

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 drivers/usb/misc/qcom_eud.c | 80 ++++++++++++++++++++++++++++++++-----
 1 file changed, 70 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 5cebb64f4a67..a58022f50484 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -38,12 +38,15 @@
 struct eud_path {
 	struct eud_chip		*chip;
 	struct phy		*phy;
+	struct usb_role_switch	*controller_sw;
+	struct usb_role_switch	*eud_sw;
+	enum usb_role		curr_role;
+	char			name[16];
 	u8			num;
 };
 
 struct eud_chip {
 	struct device			*dev;
-	struct usb_role_switch		*role_sw;
 	void __iomem			*base;
 	struct eud_path			*paths[EUD_MAX_PORTS];
 	phys_addr_t			mode_mgr;
@@ -129,7 +132,7 @@ static int enable_eud(struct eud_chip *priv)
 	writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE,
 			priv->base + EUD_REG_INT1_EN_MASK);
 
-	return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE);
+	return 0;
 }
 
 static int disable_eud(struct eud_chip *priv)
@@ -287,15 +290,21 @@ static irqreturn_t handle_eud_irq(int irq, void *data)
 static irqreturn_t handle_eud_irq_thread(int irq, void *data)
 {
 	struct eud_chip *chip = data;
+	struct eud_path *path;
 	int ret;
 
+	path = chip->paths[chip->port_idx];
+	if (!path || !path->controller_sw)
+		goto clear_irq;
+
 	if (chip->usb_attached)
-		ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_DEVICE);
+		ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE);
 	else
-		ret = usb_role_switch_set_role(chip->role_sw, USB_ROLE_HOST);
+		ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST);
 	if (ret)
 		dev_err(chip->dev, "failed to set role switch\n");
 
+clear_irq:
 	/* set and clear vbus_int_clr[0] to clear interrupt */
 	writel(BIT(0), chip->base + EUD_REG_VBUS_INT_CLR);
 	writel(0, chip->base + EUD_REG_VBUS_INT_CLR);
@@ -303,15 +312,45 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role)
+{
+	struct eud_path *path = usb_role_switch_get_drvdata(sw);
+	int ret;
+
+	/* Forward the role request to the USB controller */
+	ret = usb_role_switch_set_role(path->controller_sw, role);
+	if (ret) {
+		dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n",
+			usb_role_string(role), path->num, ret);
+		return ret;
+	}
+
+	path->curr_role = role;
+
+	return 0;
+}
+
 static void eud_role_switch_release(void *data)
 {
 	struct eud_chip *chip = data;
+	int i;
 
-	usb_role_switch_put(chip->role_sw);
+	for (i = 0; i < EUD_MAX_PORTS; i++) {
+		struct eud_path *path = chip->paths[i];
+
+		if (!path)
+			continue;
+
+		if (path->eud_sw)
+			usb_role_switch_unregister(path->eud_sw);
+		if (path->controller_sw)
+			usb_role_switch_put(path->controller_sw);
+	}
 }
 
 static int eud_init_path(struct eud_chip *chip, struct device_node *np)
 {
+	struct usb_role_switch_desc role_sw_desc = {};
 	struct eud_path *path;
 	u32 path_num;
 	int ret;
@@ -342,6 +381,32 @@ static int eud_init_path(struct eud_chip *chip, struct device_node *np)
 
 	chip->paths[path_num] = path;
 
+	path->curr_role = USB_ROLE_NONE;
+
+	if (!of_property_read_bool(np, "usb-role-switch"))
+		return 0;
+
+	/* Fetch the USB controller's role switch */
+	path->controller_sw = fwnode_usb_role_switch_get(of_fwnode_handle(np));
+	if (IS_ERR(path->controller_sw))
+		return dev_err_probe(chip->dev, PTR_ERR(path->controller_sw),
+				     "Failed to get controller role switch for path %d\n",
+				     path_num);
+
+	/* Create a role switch */
+	role_sw_desc.fwnode = of_fwnode_handle(np);
+	role_sw_desc.set = eud_role_switch_set;
+	role_sw_desc.driver_data = path;
+	snprintf(path->name, sizeof(path->name), "eud-path%u", path_num);
+	role_sw_desc.name = path->name;
+
+	path->eud_sw = usb_role_switch_register(chip->dev, &role_sw_desc);
+	if (IS_ERR(path->eud_sw)) {
+		dev_err(chip->dev, "Failed to register EUD role switch for path %d: %ld\n",
+			path_num, PTR_ERR(path->eud_sw));
+		return PTR_ERR(path->eud_sw);
+	}
+
 	return 0;
 }
 
@@ -359,11 +424,6 @@ static int eud_probe(struct platform_device *pdev)
 
 	chip->dev = &pdev->dev;
 
-	chip->role_sw = usb_role_switch_get(&pdev->dev);
-	if (IS_ERR(chip->role_sw))
-		return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw),
-					"failed to get role switch\n");
-
 	ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip);
 	if (ret)
 		return ret;
-- 
2.34.1


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

* [PATCH 5/9] usb: misc: qcom_eud: improve enable_store API
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
                   ` (3 preceding siblings ...)
  2026-01-16 23:21 ` [PATCH 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  2026-01-16 23:21 ` [PATCH 6/9] usb: misc: qcom_eud: add host mode coordination Elson Serrao
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

Currently enable_store() allows operations irrespective of the EUD state,
which can result in redundant operations. Avoid this by adding duplicate
state checks to skip requests when EUD is already in the desired state.
Additionally, improve error handling with explicit logging to provide
better feedback.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 drivers/usb/misc/qcom_eud.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index a58022f50484..0ea6491f963c 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -168,18 +168,27 @@ static ssize_t enable_store(struct device *dev,
 	if (kstrtobool(buf, &enable))
 		return -EINVAL;
 
+	/* Skip operation if already in desired state */
+	if (chip->enabled == enable)
+		return count;
+
 	if (enable) {
 		ret = enable_eud(chip);
-		if (!ret)
-			chip->enabled = enable;
-		else
-			disable_eud(chip);
-
+		if (ret) {
+			dev_err(chip->dev, "failed to enable eud\n");
+			return ret;
+		}
 	} else {
 		ret = disable_eud(chip);
+		if (ret) {
+			dev_err(chip->dev, "failed to disable eud\n");
+			return ret;
+		}
 	}
 
-	return ret < 0 ? ret : count;
+	chip->enabled = enable;
+
+	return count;
 }
 
 static DEVICE_ATTR_RW(enable);
-- 
2.34.1


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

* [PATCH 6/9] usb: misc: qcom_eud: add host mode coordination
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
                   ` (4 preceding siblings ...)
  2026-01-16 23:21 ` [PATCH 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  2026-01-16 23:21 ` [PATCH 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

EUD functions by presenting itself as a USB device to the host PC for
debugging, making it incompatible in USB host mode configurations.
Enabling EUD, when in host mode can also cause the USB controller to
misbehave as the EUD hub can only have one upstream facing port.

Handle below two scenarios to prevent these conflicts:
1. Prevent user from enabling EUD via sysfs when the USB port is
   in host mode.
2. Automatically disable EUD when USB port switches to host mode
   and re-enable it when exiting host mode.

This ensures consistent state management without creating conflicts
between the EUD debug hub and the USB controller.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 drivers/usb/misc/qcom_eud.c | 79 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 0ea6491f963c..3f1cc7ea2a6a 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -49,12 +49,15 @@ struct eud_chip {
 	struct device			*dev;
 	void __iomem			*base;
 	struct eud_path			*paths[EUD_MAX_PORTS];
+	/* serializes EUD control operations */
+	struct mutex			state_lock;
 	phys_addr_t			mode_mgr;
 	unsigned int			int_status;
 	int				irq;
 	bool				enabled;
 	bool				usb_attached;
 	bool				phy_enabled;
+	bool				eud_disabled_for_host;
 	u8				port_idx;
 };
 
@@ -162,32 +165,66 @@ static ssize_t enable_store(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct eud_chip *chip = dev_get_drvdata(dev);
+	struct eud_path *path;
 	bool enable;
 	int ret;
 
 	if (kstrtobool(buf, &enable))
 		return -EINVAL;
 
+	mutex_lock(&chip->state_lock);
+
 	/* Skip operation if already in desired state */
-	if (chip->enabled == enable)
+	if (chip->enabled == enable) {
+		mutex_unlock(&chip->state_lock);
 		return count;
+	}
+
+	/*
+	 * Handle double-disable scenario: User is disabling EUD that was already
+	 * disabled due to host mode. Since the hardware is already disabled, we
+	 * only need to clear the host-disabled flag to prevent unwanted re-enabling
+	 * when exiting host mode. This respects the user's explicit disable request.
+	 */
+	if (!enable && chip->eud_disabled_for_host) {
+		chip->eud_disabled_for_host = false;
+		chip->enabled = false;
+		mutex_unlock(&chip->state_lock);
+		return count;
+	}
 
 	if (enable) {
+		/*
+		 * EUD functions by presenting itself as a USB device to the host PC for
+		 * debugging, making it incompatible in USB host mode configuration.
+		 * Prevent enabling EUD in this configuration to avoid hardware conflicts.
+		 */
+		path = chip->paths[chip->port_idx];
+		if (path && path->curr_role == USB_ROLE_HOST) {
+			dev_err(chip->dev, "EUD not usable in host mode configuration\n");
+			mutex_unlock(&chip->state_lock);
+			return -EBUSY;
+		}
+
 		ret = enable_eud(chip);
 		if (ret) {
 			dev_err(chip->dev, "failed to enable eud\n");
+			mutex_unlock(&chip->state_lock);
 			return ret;
 		}
 	} else {
 		ret = disable_eud(chip);
 		if (ret) {
 			dev_err(chip->dev, "failed to disable eud\n");
+			mutex_unlock(&chip->state_lock);
 			return ret;
 		}
 	}
 
 	chip->enabled = enable;
 
+	mutex_unlock(&chip->state_lock);
+
 	return count;
 }
 
@@ -324,18 +361,56 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data)
 static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role)
 {
 	struct eud_path *path = usb_role_switch_get_drvdata(sw);
+	struct eud_chip *chip = path->chip;
 	int ret;
 
+	mutex_lock(&chip->state_lock);
+
+	/*
+	 * EUD must be disabled when USB operates in host mode. EUD functions by
+	 * presenting itself as a USB device to the host PC for debugging, making
+	 * it incompatible in host mode configuration.
+	 *
+	 * chip->enabled preserves user's sysfs configuration and is not modified
+	 * during host mode transitions to maintain user intent.
+	 */
+
+	/* Only act if EUD is enabled and this is the active path */
+	if (chip->enabled && path->num == chip->port_idx) {
+		if (role == USB_ROLE_HOST && !chip->eud_disabled_for_host) {
+			ret = disable_eud(chip);
+			if (ret) {
+				dev_err(chip->dev, "Failed to disable EUD for host mode: %d\n",
+					ret);
+				mutex_unlock(&chip->state_lock);
+				return ret;
+			}
+			chip->eud_disabled_for_host = true;
+		} else if (role != USB_ROLE_HOST && chip->eud_disabled_for_host) {
+			ret = enable_eud(chip);
+			if (ret) {
+				dev_err(chip->dev, "Failed to re-enable EUD after host mode: %d\n",
+					ret);
+				mutex_unlock(&chip->state_lock);
+				return ret;
+			}
+			chip->eud_disabled_for_host = false;
+		}
+	}
+
 	/* Forward the role request to the USB controller */
 	ret = usb_role_switch_set_role(path->controller_sw, role);
 	if (ret) {
 		dev_err(path->chip->dev, "Failed to set role %s for port %u: %d\n",
 			usb_role_string(role), path->num, ret);
+		mutex_unlock(&chip->state_lock);
 		return ret;
 	}
 
 	path->curr_role = role;
 
+	mutex_unlock(&chip->state_lock);
+
 	return 0;
 }
 
@@ -433,6 +508,8 @@ static int eud_probe(struct platform_device *pdev)
 
 	chip->dev = &pdev->dev;
 
+	mutex_init(&chip->state_lock);
+
 	ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip);
 	if (ret)
 		return ret;
-- 
2.34.1


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

* [PATCH 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
                   ` (5 preceding siblings ...)
  2026-01-16 23:21 ` [PATCH 6/9] usb: misc: qcom_eud: add host mode coordination Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  2026-01-16 23:21 ` [PATCH 8/9] arm64: dts: qcom: kodiak: Align EUD node with binding Elson Serrao
  2026-01-16 23:21 ` [PATCH 9/9] arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality Elson Serrao
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

EUD provides virtual USB attach/detach events to simulate cable
plug/unplug while maintaining the physical debug connection. However,
the current implementation incorrectly sets the USB role to HOST on
virtual detach, which doesn't represent the disconnected state.

Fix the virtual detach handling by setting the USB role to NONE
instead of HOST, correctly representing the disconnected state.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 drivers/usb/misc/qcom_eud.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 3f1cc7ea2a6a..60f566427abe 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -343,10 +343,26 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data)
 	if (!path || !path->controller_sw)
 		goto clear_irq;
 
+	/*
+	 * EUD virtual attach/detach event handling for low power debugging:
+	 *
+	 * When EUD is enabled in debug mode, the device remains physically
+	 * connected to the PC throughout the debug session, keeping the USB
+	 * controller active. This prevents testing of low power scenarios that
+	 * require USB disconnection.
+	 *
+	 * EUD solves this by providing virtual USB attach/detach events while
+	 * maintaining the physical connection. These events are triggered from
+	 * the Host PC via the enumerated EUD control interface and delivered
+	 * to the EUD driver as interrupts.
+	 *
+	 * These notifications are forwarded to the USB controller through role
+	 * switch framework.
+	 */
 	if (chip->usb_attached)
 		ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE);
 	else
-		ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST);
+		ret = usb_role_switch_set_role(path->controller_sw, USB_ROLE_NONE);
 	if (ret)
 		dev_err(chip->dev, "failed to set role switch\n");
 
-- 
2.34.1


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

* [PATCH 8/9] arm64: dts: qcom: kodiak: Align EUD node with binding
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
                   ` (6 preceding siblings ...)
  2026-01-16 23:21 ` [PATCH 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  2026-01-16 23:21 ` [PATCH 9/9] arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality Elson Serrao
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

The EUD node does not match the current binding and maps USB endpoints
to the secondary controller. This SoC supports EUD only on the primary
High-Speed USB path. The binding also requires a per-path PHY reference.

Model the primary UTMI path as a child node with the required PHY and an
empty ports graph. Leave endpoint mapping to board DTS files, and remove
the secondary mapping and associated ports so the description conforms
to the binding.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/kodiak.dtsi | 33 +++++++++++++++++-----------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
index c2ccbb67f800..35c47a6b03f7 100644
--- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
+++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -4284,12 +4284,6 @@ usb_2: usb@8c00000 {
 			phy-names = "usb2-phy";
 			maximum-speed = "high-speed";
 			usb-role-switch;
-
-			port {
-				usb2_role_switch: endpoint {
-					remote-endpoint = <&eud_ep>;
-				};
-			};
 		};
 
 		qspi: spi@88dc000 {
@@ -4610,16 +4604,29 @@ eud: eud@88e0000 {
 			      <0 0x88e2000 0 0x1000>;
 			interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
 
+			#address-cells = <1>;
+			#size-cells = <0>;
+
 			status = "disabled";
 
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
+			eud0: eud-path@0 {
+				reg = <0>;
+				phys = <&usb_1_hsphy>;
 
-				port@0 {
-					reg = <0>;
-					eud_ep: endpoint {
-						remote-endpoint = <&usb2_role_switch>;
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						eud_usb0: endpoint {
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						eud_con0: endpoint {
+						};
 					};
 				};
 			};
-- 
2.34.1


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

* [PATCH 9/9] arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality
  2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
                   ` (7 preceding siblings ...)
  2026-01-16 23:21 ` [PATCH 8/9] arm64: dts: qcom: kodiak: Align EUD node with binding Elson Serrao
@ 2026-01-16 23:21 ` Elson Serrao
  8 siblings, 0 replies; 16+ messages in thread
From: Elson Serrao @ 2026-01-16 23:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

On this board, EUD resides on the primary High-Speed USB data path between
the connector and the DWC3 controller. Update the device tree connections
to correctly map the connector and controller endpoints, and describe
role-switch capability on the EUD primary path.

Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index f29a352b0288..2fc2d0aed8dd 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -194,7 +194,7 @@ port@0 {
 					reg = <0>;
 
 					pmic_glink_hs_in: endpoint {
-						remote-endpoint = <&usb_1_dwc3_hs>;
+						remote-endpoint = <&eud_con0>;
 					};
 				};
 
@@ -1176,13 +1176,29 @@ &usb_1 {
 };
 
 &usb_1_dwc3_hs {
-	remote-endpoint = <&pmic_glink_hs_in>;
+	remote-endpoint = <&eud_usb0>;
 };
 
 &usb_1_dwc3_ss {
 	remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
 };
 
+&eud_con0 {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&eud_usb0 {
+	remote-endpoint = <&usb_1_dwc3_hs>;
+};
+
+&eud {
+	status = "okay";
+};
+
+&eud0 {
+	usb-role-switch;
+};
+
 &usb_1_hsphy {
 	vdda-pll-supply = <&vreg_l10c_0p88>;
 	vdda33-supply = <&vreg_l2b_3p072>;
-- 
2.34.1


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

* Re: [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  2026-01-16 23:20 ` [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware Elson Serrao
@ 2026-01-17 11:57   ` Krzysztof Kozlowski
  2026-01-19 19:58     ` Bjorn Andersson
  0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-17 11:57 UTC (permalink / raw)
  To: Elson Serrao
  Cc: Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury,
	linux-arm-msm, devicetree, linux-usb, linux-kernel

On Fri, Jan 16, 2026 at 03:20:58PM -0800, Elson Serrao wrote:
> The Qualcomm Embedded USB Debugger (EUD) hardware can intercept up to
> two independent High-Speed UTMI data paths, depending on the SoC
> configuration. Each path operates independently with:
> 
> - Dedicated PHY interface
> - Distinct USB connector and controller associations
> - Role dependent routing
> 
> Model these hardware paths as separate eud-path nodes to accurately
> represent the physical topology and add below per-path properties:
> 
> phys: EUD exposes a High-Speed debug hub that relies on HS-PHY for its
> operation. This property references the HS-PHY associated with the UTMI
> path.
> 
> usb-role-switch: Indicates that the USB port on this UTMI path supports
> role switching. In device role, debug mode inserts the EUD hub into the
> UTMI path. In host role, the EUD hub is bypassed and UTMI traffic flows
> directly between the PHY and the USB controller.
> 
> This change breaks backwards compatibility, but the previous binding
> omitted critical resources like PHY and did not describe per-path
> topology. Without these modifications EUD cannot be guaranteed to
> function.

It was working for 3 years, so your guarantees are just imprecise. FUD
is not an argument.

Qualcomm task at 2022 was to post complete bindings. These were posted
and accepted. Three years later you say that previous posting was
bollocks and this cannot even work?

Nah, take responsibility of what you did in the past.

Best regards,
Krzysztof


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

* Re: [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  2026-01-17 11:57   ` Krzysztof Kozlowski
@ 2026-01-19 19:58     ` Bjorn Andersson
  2026-01-20  7:20       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 16+ messages in thread
From: Bjorn Andersson @ 2026-01-19 19:58 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Elson Serrao, Greg Kroah-Hartman, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury,
	linux-arm-msm, devicetree, linux-usb, linux-kernel

On Sat, Jan 17, 2026 at 12:57:58PM +0100, Krzysztof Kozlowski wrote:
> On Fri, Jan 16, 2026 at 03:20:58PM -0800, Elson Serrao wrote:
> > The Qualcomm Embedded USB Debugger (EUD) hardware can intercept up to
> > two independent High-Speed UTMI data paths, depending on the SoC
> > configuration. Each path operates independently with:
> > 
> > - Dedicated PHY interface
> > - Distinct USB connector and controller associations
> > - Role dependent routing
> > 
> > Model these hardware paths as separate eud-path nodes to accurately
> > represent the physical topology and add below per-path properties:
> > 
> > phys: EUD exposes a High-Speed debug hub that relies on HS-PHY for its
> > operation. This property references the HS-PHY associated with the UTMI
> > path.
> > 
> > usb-role-switch: Indicates that the USB port on this UTMI path supports
> > role switching. In device role, debug mode inserts the EUD hub into the
> > UTMI path. In host role, the EUD hub is bypassed and UTMI traffic flows
> > directly between the PHY and the USB controller.
> > 
> > This change breaks backwards compatibility, but the previous binding
> > omitted critical resources like PHY and did not describe per-path
> > topology. Without these modifications EUD cannot be guaranteed to
> > function.
> 
> It was working for 3 years, so your guarantees are just imprecise. FUD
> is not an argument.
> 
> Qualcomm task at 2022 was to post complete bindings. These were posted
> and accepted. Three years later you say that previous posting was
> bollocks and this cannot even work?
> 

That is correct. The description of the hardware that was provided when
this was upstreamed and the binding that was accepted based on this
description is wrong.

There's absolutely a value in maintainting backwards compatibility in
general, but is this one of those cases?

> Nah, take responsibility of what you did in the past.
> 

In my view the responsible thing is to accept that we got it wrong and
make sure EUD is enabled end-to-end so people can actually use it.

Regards,
Bjorn

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

* Re: [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  2026-01-19 19:58     ` Bjorn Andersson
@ 2026-01-20  7:20       ` Krzysztof Kozlowski
  2026-01-20 22:16         ` Elson Serrao
  0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-20  7:20 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Elson Serrao, Greg Kroah-Hartman, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury,
	linux-arm-msm, devicetree, linux-usb, linux-kernel

On 19/01/2026 20:58, Bjorn Andersson wrote:
> On Sat, Jan 17, 2026 at 12:57:58PM +0100, Krzysztof Kozlowski wrote:
>> On Fri, Jan 16, 2026 at 03:20:58PM -0800, Elson Serrao wrote:
>>> The Qualcomm Embedded USB Debugger (EUD) hardware can intercept up to
>>> two independent High-Speed UTMI data paths, depending on the SoC
>>> configuration. Each path operates independently with:
>>>
>>> - Dedicated PHY interface
>>> - Distinct USB connector and controller associations
>>> - Role dependent routing
>>>
>>> Model these hardware paths as separate eud-path nodes to accurately
>>> represent the physical topology and add below per-path properties:
>>>
>>> phys: EUD exposes a High-Speed debug hub that relies on HS-PHY for its
>>> operation. This property references the HS-PHY associated with the UTMI
>>> path.
>>>
>>> usb-role-switch: Indicates that the USB port on this UTMI path supports
>>> role switching. In device role, debug mode inserts the EUD hub into the
>>> UTMI path. In host role, the EUD hub is bypassed and UTMI traffic flows
>>> directly between the PHY and the USB controller.
>>>
>>> This change breaks backwards compatibility, but the previous binding
>>> omitted critical resources like PHY and did not describe per-path
>>> topology. Without these modifications EUD cannot be guaranteed to
>>> function.
>>
>> It was working for 3 years, so your guarantees are just imprecise. FUD
>> is not an argument.
>>
>> Qualcomm task at 2022 was to post complete bindings. These were posted
>> and accepted. Three years later you say that previous posting was
>> bollocks and this cannot even work?
>>
> 
> That is correct. The description of the hardware that was provided when
> this was upstreamed and the binding that was accepted based on this
> description is wrong.
> 
> There's absolutely a value in maintainting backwards compatibility in
> general, but is this one of those cases?
> 
>> Nah, take responsibility of what you did in the past.
>>
> 
> In my view the responsible thing is to accept that we got it wrong and
> make sure EUD is enabled end-to-end so people can actually use it.

I would expect to see what is not working. This is in mainline for three
years, so the assumption is that it was working for these three years.
If it wasn't, this should be described and "cannot be guaranteed to
function" is just imprecise.

Best regards,
Krzysztof

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

* Re: [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  2026-01-20  7:20       ` Krzysztof Kozlowski
@ 2026-01-20 22:16         ` Elson Serrao
  2026-01-21  2:21           ` Bjorn Andersson
  0 siblings, 1 reply; 16+ messages in thread
From: Elson Serrao @ 2026-01-20 22:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Bjorn Andersson
  Cc: Greg Kroah-Hartman, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Souradeep Chowdhury,
	linux-arm-msm, devicetree, linux-usb, linux-kernel



On 1/19/2026 11:20 PM, Krzysztof Kozlowski wrote:
> On 19/01/2026 20:58, Bjorn Andersson wrote:
>> On Sat, Jan 17, 2026 at 12:57:58PM +0100, Krzysztof Kozlowski wrote:
>>> On Fri, Jan 16, 2026 at 03:20:58PM -0800, Elson Serrao wrote:
>>>> The Qualcomm Embedded USB Debugger (EUD) hardware can intercept up to
>>>> two independent High-Speed UTMI data paths, depending on the SoC
>>>> configuration. Each path operates independently with:
>>>>
>>>> - Dedicated PHY interface
>>>> - Distinct USB connector and controller associations
>>>> - Role dependent routing
>>>>
>>>> Model these hardware paths as separate eud-path nodes to accurately
>>>> represent the physical topology and add below per-path properties:
>>>>
>>>> phys: EUD exposes a High-Speed debug hub that relies on HS-PHY for its
>>>> operation. This property references the HS-PHY associated with the UTMI
>>>> path.
>>>>
>>>> usb-role-switch: Indicates that the USB port on this UTMI path supports
>>>> role switching. In device role, debug mode inserts the EUD hub into the
>>>> UTMI path. In host role, the EUD hub is bypassed and UTMI traffic flows
>>>> directly between the PHY and the USB controller.
>>>>
>>>> This change breaks backwards compatibility, but the previous binding
>>>> omitted critical resources like PHY and did not describe per-path
>>>> topology. Without these modifications EUD cannot be guaranteed to
>>>> function.
>>>
>>> It was working for 3 years, so your guarantees are just imprecise. FUD
>>> is not an argument.
>>>
>>> Qualcomm task at 2022 was to post complete bindings. These were posted
>>> and accepted. Three years later you say that previous posting was
>>> bollocks and this cannot even work?
>>>
>>
>> That is correct. The description of the hardware that was provided when
>> this was upstreamed and the binding that was accepted based on this
>> description is wrong.
>>
>> There's absolutely a value in maintainting backwards compatibility in
>> general, but is this one of those cases?
>>
>>> Nah, take responsibility of what you did in the past.
>>>
>>
>> In my view the responsible thing is to accept that we got it wrong and
>> make sure EUD is enabled end-to-end so people can actually use it.
> 
> I would expect to see what is not working. This is in mainline for three
> years, so the assumption is that it was working for these three years.
> If it wasn't, this should be described and "cannot be guaranteed to
> function" is just imprecise.
> 
Thanks, Bjorn and Krzysztof, for the feedback.

Let me clarify what I meant by “cannot be guaranteed to work”, as I agree
the phrasing can be improved to more precisely convey the intent.

The concern is not that EUD did not or could not work historically.
Rather, the issue is that the hardware description provided by the
binding does not explicitly describe ownership and control of hardware
resources that EUD depends on. As a result, correctness of EUD operation
relies on behavior outside of what is expressed in the description.

Concretely, the binding does not reference the HS-PHY. In practice,
EUD may function because the USB controller (e.g. DWC3) keeps the
PHY powered and configured.

However, this relationship is not described as a contract in the
binding. The USB controller may legitimately relinquish PHY control as
part of its own power-management or low-power transitions. The EUD
hardware is capable of operating independently, but doing so requires
EUD to have explicit control of the PHY.

The hardware specification lists the PHY as a required resource of the
EUD debug hub. Not modeling it in the binding therefore leaves the
description incomplete, because EUD resource requirements are being met
implicitly through another hardware block (USB controller) rather than
being described directly.

In addition, the hardware can expose multiple UTMI paths (dual-port
EUD), which the current binding cannot represent.

The intent of this patch is therefore to correct and tighten the
binding so that the hardware resources and topology EUD depends on are
explicitly modeled, rather than relying on side effects of USB controller.

I will update the backwards compatibility justification accordingly.

Thanks
Elson

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

* Re: [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware
  2026-01-20 22:16         ` Elson Serrao
@ 2026-01-21  2:21           ` Bjorn Andersson
  0 siblings, 0 replies; 16+ messages in thread
From: Bjorn Andersson @ 2026-01-21  2:21 UTC (permalink / raw)
  To: Elson Serrao
  Cc: Krzysztof Kozlowski, Greg Kroah-Hartman, Konrad Dybcio,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Souradeep Chowdhury, linux-arm-msm, devicetree, linux-usb,
	linux-kernel

On Tue, Jan 20, 2026 at 02:16:17PM -0800, Elson Serrao wrote:
> 
> 
> On 1/19/2026 11:20 PM, Krzysztof Kozlowski wrote:
> > On 19/01/2026 20:58, Bjorn Andersson wrote:
> >> On Sat, Jan 17, 2026 at 12:57:58PM +0100, Krzysztof Kozlowski wrote:
> >>> On Fri, Jan 16, 2026 at 03:20:58PM -0800, Elson Serrao wrote:
> >>>> The Qualcomm Embedded USB Debugger (EUD) hardware can intercept up to
> >>>> two independent High-Speed UTMI data paths, depending on the SoC
> >>>> configuration. Each path operates independently with:
> >>>>
> >>>> - Dedicated PHY interface
> >>>> - Distinct USB connector and controller associations
> >>>> - Role dependent routing
> >>>>
> >>>> Model these hardware paths as separate eud-path nodes to accurately
> >>>> represent the physical topology and add below per-path properties:
> >>>>
> >>>> phys: EUD exposes a High-Speed debug hub that relies on HS-PHY for its
> >>>> operation. This property references the HS-PHY associated with the UTMI
> >>>> path.
> >>>>
> >>>> usb-role-switch: Indicates that the USB port on this UTMI path supports
> >>>> role switching. In device role, debug mode inserts the EUD hub into the
> >>>> UTMI path. In host role, the EUD hub is bypassed and UTMI traffic flows
> >>>> directly between the PHY and the USB controller.
> >>>>
> >>>> This change breaks backwards compatibility, but the previous binding
> >>>> omitted critical resources like PHY and did not describe per-path
> >>>> topology. Without these modifications EUD cannot be guaranteed to
> >>>> function.
> >>>
> >>> It was working for 3 years, so your guarantees are just imprecise. FUD
> >>> is not an argument.
> >>>
> >>> Qualcomm task at 2022 was to post complete bindings. These were posted
> >>> and accepted. Three years later you say that previous posting was
> >>> bollocks and this cannot even work?
> >>>
> >>
> >> That is correct. The description of the hardware that was provided when
> >> this was upstreamed and the binding that was accepted based on this
> >> description is wrong.
> >>
> >> There's absolutely a value in maintainting backwards compatibility in
> >> general, but is this one of those cases?
> >>
> >>> Nah, take responsibility of what you did in the past.
> >>>
> >>
> >> In my view the responsible thing is to accept that we got it wrong and
> >> make sure EUD is enabled end-to-end so people can actually use it.
> > 
> > I would expect to see what is not working. This is in mainline for three
> > years, so the assumption is that it was working for these three years.
> > If it wasn't, this should be described and "cannot be guaranteed to
> > function" is just imprecise.
> > 

I see, that I agree with.

> Thanks, Bjorn and Krzysztof, for the feedback.
> 
> Let me clarify what I meant by “cannot be guaranteed to work”, as I agree
> the phrasing can be improved to more precisely convey the intent.
> 
> The concern is not that EUD did not or could not work historically.
> Rather, the issue is that the hardware description provided by the
> binding does not explicitly describe ownership and control of hardware
> resources that EUD depends on. As a result, correctness of EUD operation
> relies on behavior outside of what is expressed in the description.
> 
> Concretely, the binding does not reference the HS-PHY. In practice,
> EUD may function because the USB controller (e.g. DWC3) keeps the
> PHY powered and configured.
> 
> However, this relationship is not described as a contract in the
> binding. The USB controller may legitimately relinquish PHY control as
> part of its own power-management or low-power transitions. The EUD
> hardware is capable of operating independently, but doing so requires
> EUD to have explicit control of the PHY.
> 
> The hardware specification lists the PHY as a required resource of the
> EUD debug hub. Not modeling it in the binding therefore leaves the
> description incomplete, because EUD resource requirements are being met
> implicitly through another hardware block (USB controller) rather than
> being described directly.
> 
> In addition, the hardware can expose multiple UTMI paths (dual-port
> EUD), which the current binding cannot represent.
> 
> The intent of this patch is therefore to correct and tighten the
> binding so that the hardware resources and topology EUD depends on are
> explicitly modeled, rather than relying on side effects of USB controller.
> 
> I will update the backwards compatibility justification accordingly.
> 

Please try to consolidate this whole explanation a bit and include it in
the commit message.

Regards,
Bjorn

> Thanks
> Elson

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

* Re: [PATCH 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection
  2026-01-16 23:20 ` [PATCH 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
@ 2026-01-27 13:30   ` Konrad Dybcio
  0 siblings, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2026-01-27 13:30 UTC (permalink / raw)
  To: Elson Serrao, Greg Kroah-Hartman, Bjorn Andersson, Konrad Dybcio,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Souradeep Chowdhury
  Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel

On 1/17/26 12:20 AM, Elson Serrao wrote:
> EUD can be mapped to either the primary USB port or the secondary USB port
> depending on the value of the EUD_PORT_SEL register. Add a 'port' sysfs
> attribute to allow userspace to select which port EUD should operate on
> and update the ABI documentation. This is needed for systems with dual
> USB ports where EUD needs to be accessible on either port depending on the
> system configuration and use case.
> 
> Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

end of thread, other threads:[~2026-01-27 13:30 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-16 23:20 [PATCH 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
2026-01-16 23:20 ` [PATCH 1/9] dt-bindings: soc: qcom: eud: Restructure to model multi-path hardware Elson Serrao
2026-01-17 11:57   ` Krzysztof Kozlowski
2026-01-19 19:58     ` Bjorn Andersson
2026-01-20  7:20       ` Krzysztof Kozlowski
2026-01-20 22:16         ` Elson Serrao
2026-01-21  2:21           ` Bjorn Andersson
2026-01-16 23:20 ` [PATCH 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
2026-01-27 13:30   ` Konrad Dybcio
2026-01-16 23:21 ` [PATCH 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
2026-01-16 23:21 ` [PATCH 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
2026-01-16 23:21 ` [PATCH 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
2026-01-16 23:21 ` [PATCH 6/9] usb: misc: qcom_eud: add host mode coordination Elson Serrao
2026-01-16 23:21 ` [PATCH 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
2026-01-16 23:21 ` [PATCH 8/9] arm64: dts: qcom: kodiak: Align EUD node with binding Elson Serrao
2026-01-16 23:21 ` [PATCH 9/9] arm64: dts: qcom: qcs6490-rb3gen2: Enable EUD debug functionality Elson Serrao

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®