* [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support
@ 2026-08-11 21:36 Elson Serrao
2026-08-11 21:36 ` [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing Elson Serrao
` (8 more replies)
0 siblings, 9 replies; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
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.
Below is a high-level block diagram showing the EUD and its connections.
EUD Block
+------------------------------+
| |
[Conn-0]-->[USB2PHY-0]---->|-------- Path 0 --------------|-->[USBCtrl-0]
| |
[Conn-1]-->[USB2PHY-1]---->|-------- Path 1 --------------|-->[USBCtrl-1]
| |
| +------------------+ |
| | EUD Debug Hub | |
| +------------------+ |
+------------------------------+
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
Testing feedback:
- Konrad Dybcio reported running a slightly modified version of this
series on Agatti with no obvious issues:
https://lore.kernel.org/all/8d4f10ef-602c-4e1e-9711-443a5f3fa7f3@oss.qualcomm.com/
---
Changes in v6:
- [Patch 0001] Fix oneOf schema to properly enforce mutual exclusivity
between 'ports' and 'eud-path@N' (sashiko-bot).
- [Patch 0009] Extend the eud_con remote-endpoint fix to
sm7325-motorola-dubai-common.dtsi and sm7325-xiaomi-taoyao.dts to fix
"not bidirectional" DT graph warning.
- Link to v5: https://lore.kernel.org/all/20260803031534.2942628-1-elson.serrao@oss.qualcomm.com/
Changes in v5:
- [Patch 0001] Add a compatible for a SoC that supports EUD over two
ports, restrict paths based on SoC hardware, and improve the commit
message [Krzysztof/Dmitry]
- [Patch 0002/0003] Document error codes in ABI doc.
- [Patch 0004] Zero-initialize the USB role switch descriptor [Peter].
Add a dr_mode check to handle cases where the USB controller
operates in a fixed role without role-switch support (based on
internal testing).
- [Patch 0006] Drop eud_disabled_for_host flag and control EUD based on
device role entry/exit [Peter]. Allow EUD to be powered on only in
device role and defer enablement in other roles until the port
switches to device role.
- Link to v4: https://lore.kernel.org/all/20260501170635.2641748-1-elson.serrao@oss.qualcomm.com/
Changes in v4:
- [Patch 0001] Restructure the flattened ports representation to a child-node
based model.
- Preserve the top-level 'ports' property and add per-path child nodes,
so that each role-switch path is described using its own OF graph.
(Dmitry).
- Link to the discussion leading to this design decision:
https://lore.kernel.org/all/20260324172916.804229-1-elson.serrao@oss.qualcomm.com/
- [Patch 0002] Use explicit port names when selecting the active EUD
port (Greg)
- [Patch 0003] Use a scoped iterator when looping over child nodes and
drop redundant EUD path validation checks (Konrad). Preserve support
for the legacy top-level ports description.
- [Patch 0004] Register role switch per path and forward the role switch
notifications to the USB controller.
- [Patch 0006] Add host mode co-ordination based on the role changes as
per the new design and drop the custom API that was used to get role
notifications.
- [Patch 0008] Described the UTMI path as a child node with role switch
capability.
- Link to v3: https://lore.kernel.org/all/20260309203337.803986-1-elson.serrao@oss.qualcomm.com/
Changes in RFC v3:
- Replaced the per-path (eud-path@N) model with a flattened ports
representation based on the feedback.
- Added port@2 and port@3 to support dual-port configurations.
- Removed the EUD-local 'phys' and 'usb-role-switch' properties since PHY
and role-switch information is obtained from walking the OF graph.
- Updated PHY discovery logic by fetching the PHY from the controller
node/fwnode, and exported a new API for the controller to report role
changes. The dwc3-qcom driver now uses this API to notify EUD on role
transitions.
- Updated the DTS structure by moving the EUD-to-controller port mapping
into the base SoC DTSI, enabling EUD by default, and adjusting all board
DTS files accordingly, including adding the usb-role-switch provider
link on connector nodes.
- Link to v2: https://lore.kernel.org/all/20260126233830.2193816-1-elson.serrao@oss.qualcomm.com/
Changes in v2:
- Improved commit message of patch 0001 and 0003 with historical context
on why EUD worked without PHY references on single-path systems.
Expanded the usb-role-switch property description in the bindings file.
- Link to v1: https://lore.kernel.org/all/20260116232106.2234978-1-elson.serrao@oss.qualcomm.com/
---
Elson Serrao (9):
dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing
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 role-based EUD control
usb: misc: qcom_eud: fix virtual attach/detach event handling
arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node
arm64: dts: qcom: Map USB connector to EUD on Kodiak boards
Documentation/ABI/testing/sysfs-driver-eud | 19 +
.../bindings/soc/qcom/qcom,eud.yaml | 133 ++++++-
arch/arm64/boot/dts/qcom/kodiak.dtsi | 35 +-
.../boot/dts/qcom/qcm6490-fairphone-fp5.dts | 10 +-
.../dts/qcom/qcm6490-particle-tachyon.dts | 10 +-
.../boot/dts/qcom/qcm6490-shift-otter.dts | 10 +-
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 10 +-
.../qcom/qcs6490-thundercomm-minipc-g1iot.dts | 4 +-
.../dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 10 +-
.../qcom/sm7325-motorola-dubai-common.dtsi | 4 +-
.../boot/dts/qcom/sm7325-motorola-dubai.dts | 4 +-
.../boot/dts/qcom/sm7325-nothing-spacewar.dts | 10 +-
.../boot/dts/qcom/sm7325-xiaomi-taoyao.dts | 4 +-
drivers/usb/misc/qcom_eud.c | 332 ++++++++++++++++--
14 files changed, 522 insertions(+), 73 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 21:50 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
` (7 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel,
Krzysztof Kozlowski
The Qualcomm Embedded USB Debugger (EUD) can intercept one or two
High-Speed UTMI paths depending on the SoC. For example, SC7280 supports
EUD on the primary UTMI path only, while SM8350 supports EUD on both
primary and secondary UTMI paths.
Each UTMI path connects an independent USB controller/connector pair and
forms its own role-switch domain. EUD routes traffic based on USB role.
In device role the debug hub is inserted, while in host role it is
bypassed.
The existing binding models EUD using a flattened ports representation.
While sufficient for fixed device-role configurations, it cannot naturally
associate a controller, connector, and role switch with a specific
EUD-routable path. This is problematic for role-switch capable ports and
becomes more pronounced on SoCs with multiple paths. In such cases, each
path forms an independent role-switch domain and requires per-path role
awareness.
Model each UTMI path as a separate child node with its own OF graph. Add
an SM8350 compatible for dual-path EUD topologies while retaining the
legacy ports representation for backward compatibility.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
.../bindings/soc/qcom/qcom,eud.yaml | 133 +++++++++++++++++-
1 file changed, 132 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
index 84218636c0d8..0e35bc9a9d20 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
@@ -18,6 +18,7 @@ properties:
items:
- enum:
- qcom,sc7280-eud
+ - qcom,sm8350-eud
- const: qcom,eud
reg:
@@ -45,10 +46,87 @@ properties:
$ref: /schemas/graph.yaml#/properties/port
description: This port is to be attached to the type C connector.
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+patternProperties:
+ "^eud-path@[0-1]$":
+ type: object
+ description:
+ Represents one High-Speed UTMI path that EUD intercepts. Use eud-path nodes
+ to associate role-switching behavior with specific port connections, allowing
+ EUD to manage role transitions independently for each UTMI path.
+
+ properties:
+ reg:
+ maxItems: 1
+ description: Path number
+
+ usb-role-switch:
+ type: boolean
+ description:
+ Indicates that EUD relays USB role-switch events for this path and
+ performs role-dependent UTMI routing accordingly. In device role,
+ the EUD hub is inserted into this path to enable debug
+ functionality. In host role, the EUD hub is bypassed and UTMI
+ traffic flows directly between the PHY and the USB controller.
+
+ 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 USB connector.
+
+ required:
+ - reg
+ - ports
+
+ additionalProperties: false
+
required:
- compatible
- reg
- - ports
+
+oneOf:
+ - required:
+ - ports
+ properties:
+ eud-path@0: false
+ eud-path@1: false
+ - allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,sc7280-eud
+ then:
+ required:
+ - eud-path@0
+ properties:
+ eud-path@1: false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,sm8350-eud
+ then:
+ required:
+ - eud-path@0
+ - eud-path@1
+ properties:
+ ports: false
additionalProperties: false
@@ -77,3 +155,56 @@ examples:
};
};
};
+ - |
+ eud@88e0000 {
+ compatible = "qcom,sm8350-eud", "qcom,eud";
+ reg = <0x88e0000 0x2000>,
+ <0x88e2000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eud-path@0 {
+ reg = <0>;
+ usb-role-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ eud_usb0: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ eud_con0: endpoint {
+ remote-endpoint = <&pmic_glink_hs_in>;
+ };
+ };
+ };
+ };
+
+ eud-path@1 {
+ reg = <1>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ eud_usb1: endpoint {
+ remote-endpoint = <&usb_2_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ eud_con1: endpoint {
+ remote-endpoint = <&conn_2_hs_in>;
+ };
+ };
+ };
+ };
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
2026-08-11 21:36 ` [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 21:54 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
` (6 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel, Konrad Dybcio
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.
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
Documentation/ABI/testing/sysfs-driver-eud | 18 ++++++++++
drivers/usb/misc/qcom_eud.c | 39 ++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud
index 2bab0db2d2f0..fb927a003596 100644
--- a/Documentation/ABI/testing/sysfs-driver-eud
+++ b/Documentation/ABI/testing/sysfs-driver-eud
@@ -7,3 +7,21 @@ 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:
+ primary - Primary USB port
+ secondary - Secondary USB port
+
+ Writing any other value returns -EINVAL.
+
+ The attribute is writable only while EUD is disabled.
+ Writing it while EUD is enabled returns -EBUSY. Reading
+ the attribute returns the currently selected USB port.
diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 926419ca560f..25a6a8f110ec 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -23,14 +23,22 @@
#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)
#define EUD_INT_SAFE_MODE BIT(4)
#define EUD_INT_ALL (EUD_INT_VBUS | EUD_INT_SAFE_MODE)
+static const char * const eud_port_names[] = {
+ "primary",
+ "secondary",
+};
+
struct eud_chip {
struct device *dev;
struct usb_role_switch *role_sw;
@@ -40,6 +48,7 @@ struct eud_chip {
int irq;
bool enabled;
bool usb_attached;
+ u8 port_idx;
};
static int enable_eud(struct eud_chip *priv)
@@ -104,8 +113,38 @@ 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, "%s\n", eud_port_names[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);
+ int port;
+
+ port = sysfs_match_string(eud_port_names, buf);
+ if (port < 0)
+ return port;
+
+ /* Port selection must be done before enabling EUD */
+ if (chip->enabled)
+ 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 related [flat|nested] 19+ messages in thread
* [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
2026-08-11 21:36 ` [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing Elson Serrao
2026-08-11 21:36 ` [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 21:56 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
` (5 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel
EUD hardware can support multiple High-Speed USB paths, each routed
through its own PHY. The active path is selected in hardware via the
EUD_PORT_SEL register. As a High-Speed hub, EUD requires access to
the High-Speed PHY associated with the active path. To support this
multi-path capability, the driver must manage PHY resources on a
per-path basis, ensuring that the PHY for the currently selected
path is properly initialized and powered.
This patch restructures the driver to implement per-path PHY management.
The driver now powers the appropriate PHY based on the selected and
enabled UTMI path, ensuring correct operation when EUD is enabled.
Historically, EUD appeared to work on single-path systems because the
USB controller kept the PHY initialized. However, EUD is designed to
operate independently of the USB controller and therefore requires
explicit PHY control for proper operation.
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
Documentation/ABI/testing/sysfs-driver-eud | 3 +-
drivers/usb/misc/qcom_eud.c | 124 ++++++++++++++++++++-
2 files changed, 125 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-driver-eud b/Documentation/ABI/testing/sysfs-driver-eud
index fb927a003596..f20b82b5a38a 100644
--- a/Documentation/ABI/testing/sysfs-driver-eud
+++ b/Documentation/ABI/testing/sysfs-driver-eud
@@ -20,7 +20,8 @@ Description:
primary - Primary USB port
secondary - Secondary USB port
- Writing any other value returns -EINVAL.
+ Writing any other value returns -EINVAL. Writing a port
+ not supported on the current platform returns -EOPNOTSUPP.
The attribute is writable only while EUD is disabled.
Writing it while EUD is enabled returns -EBUSY. Reading
diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 25a6a8f110ec..03d1c200658c 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -11,6 +11,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
@@ -39,26 +41,84 @@ static const char * const eud_port_names[] = {
"secondary",
};
+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 phy *phy;
+ int ret;
+
+ if (chip->phy_enabled)
+ return 0;
+
+ phy = chip->paths[chip->port_idx]->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 phy *phy;
+
+ if (!chip->phy_enabled)
+ return;
+
+ phy = chip->paths[chip->port_idx]->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);
@@ -75,6 +135,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;
}
@@ -130,6 +192,10 @@ static ssize_t port_store(struct device *dev, struct device_attribute *attr,
if (port < 0)
return port;
+ /* Check if the corresponding path is available */
+ if (!chip->paths[port])
+ return -EOPNOTSUPP;
+
/* Port selection must be done before enabling EUD */
if (chip->enabled)
return -EBUSY;
@@ -227,8 +293,54 @@ 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 device_node *controller_node;
+ struct eud_path *path;
+ u32 path_num;
+ int ret;
+
+ ret = of_property_read_u32(np, "reg", &path_num);
+ if (ret) {
+ /* Legacy DT uses 'ports' node without 'reg' property; treat as path 0 */
+ if (of_node_name_eq(np, "ports"))
+ path_num = 0;
+ else
+ return dev_err_probe(chip->dev, ret, "unexpected child node '%s'\n",
+ np->name);
+ }
+
+ if (path_num >= EUD_MAX_PORTS)
+ return dev_err_probe(chip->dev, -EINVAL, "invalid path number: %u (max %d)\n",
+ path_num, EUD_MAX_PORTS - 1);
+
+ path = devm_kzalloc(chip->dev, sizeof(*path), GFP_KERNEL);
+ if (!path)
+ return -ENOMEM;
+
+ path->chip = chip;
+ path->num = path_num;
+
+ controller_node = of_graph_get_remote_node(np, 0, -1);
+ if (!controller_node)
+ return dev_err_probe(chip->dev, -ENODEV,
+ "failed to get controller node for path %u\n", path_num);
+
+ path->phy = devm_of_phy_get_by_index(chip->dev, controller_node, 0);
+ of_node_put(controller_node);
+
+ 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 eud_chip *chip;
struct resource *res;
int ret;
@@ -239,6 +351,16 @@ static int eud_probe(struct platform_device *pdev)
chip->dev = &pdev->dev;
+ for_each_child_of_node_scoped(np, child) {
+ ret = eud_init_path(chip, child);
+ if (ret)
+ return ret;
+ }
+
+ /* Primary path is mandatory. Secondary is optional */
+ if (!chip->paths[0])
+ return dev_err_probe(chip->dev, -ENODEV, "primary path not found\n");
+
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),
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
` (2 preceding siblings ...)
2026-08-11 21:36 ` [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 21:57 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
` (4 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
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().
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
drivers/usb/misc/qcom_eud.c | 100 +++++++++++++++++++++++++++++-------
1 file changed, 81 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index 03d1c200658c..48a4441b0c9c 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -44,12 +44,15 @@ static const char * const eud_port_names[] = {
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;
@@ -123,7 +126,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)
@@ -270,12 +273,15 @@ 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 (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");
@@ -286,17 +292,39 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data)
return IRQ_HANDLED;
}
-static void eud_role_switch_release(void *data)
+static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role role)
{
- struct eud_chip *chip = data;
+ 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;
- usb_role_switch_put(chip->role_sw);
+ return 0;
+}
+
+static void eud_path_role_switch_release(void *data)
+{
+ struct eud_path *path = data;
+
+ usb_role_switch_unregister(path->eud_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 = {NULL};
+ struct usb_role_switch *sw;
struct device_node *controller_node;
struct eud_path *path;
+ const char *dr_mode = "";
u32 path_num;
int ret;
@@ -327,14 +355,57 @@ static int eud_init_path(struct eud_chip *chip, struct device_node *np)
"failed to get controller node for path %u\n", path_num);
path->phy = devm_of_phy_get_by_index(chip->dev, controller_node, 0);
- of_node_put(controller_node);
-
- if (IS_ERR(path->phy))
+ if (IS_ERR(path->phy)) {
+ of_node_put(controller_node);
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;
+ of_property_read_string(controller_node, "dr_mode", &dr_mode);
+
+ if (!strcmp(dr_mode, "host"))
+ path->curr_role = USB_ROLE_HOST;
+ else if (!strcmp(dr_mode, "peripheral"))
+ path->curr_role = USB_ROLE_DEVICE;
+ else
+ path->curr_role = USB_ROLE_NONE;
+
+ /* No role switch needed for fixed role controllers */
+ if (path->curr_role != USB_ROLE_NONE) {
+ of_node_put(controller_node);
+ return 0;
+ }
+
+ sw = usb_role_switch_find_by_fwnode(of_fwnode_handle(controller_node));
+ if (!sw) {
+ of_node_put(controller_node);
+ return dev_err_probe(chip->dev, -EPROBE_DEFER,
+ "Failed to get controller role switch for path %d\n",
+ path_num);
+ }
+ path->controller_sw = sw;
+
+ of_node_put(controller_node);
+
+ 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)) {
+ usb_role_switch_put(path->controller_sw);
+ return dev_err_probe(chip->dev, PTR_ERR(path->eud_sw),
+ "Failed to register EUD role switch for path %d\n", path_num);
+ }
+
+ ret = devm_add_action_or_reset(chip->dev, eud_path_role_switch_release, path);
+ if (ret)
+ return ret;
+
return 0;
}
@@ -361,15 +432,6 @@ static int eud_probe(struct platform_device *pdev)
if (!chip->paths[0])
return dev_err_probe(chip->dev, -ENODEV, "primary path not found\n");
- 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;
-
chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
` (3 preceding siblings ...)
2026-08-11 21:36 ` [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 21:56 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control Elson Serrao
` (3 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel, Konrad Dybcio
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.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Peter Chen <peter.chen@kernel.org>
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 48a4441b0c9c..e83a4402e4b8 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -162,18 +162,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 related [flat|nested] 19+ messages in thread
* [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
` (4 preceding siblings ...)
2026-08-11 21:36 ` [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 21:54 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
` (2 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel
EUD functions by presenting itself as a USB device to the host PC and is
therefore only applicable when the port operates in device role. Keeping
EUD enabled in other roles provides no benefit and unnecessarily keeps
the associated PHY resources enabled. Furthermore, enabling EUD in host
role can cause the USB controller to misbehave because the EUD hub
supports only a single upstream-facing port.
Address this by treating EUD as usable only in device role. The
role-switch callback enables or disables EUD as the port enters or
leaves device role. A sysfs enable request made outside device role is
recorded and honored when the port subsequently switches to device role.
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
drivers/usb/misc/qcom_eud.c | 46 ++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index e83a4402e4b8..538e070cc140 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -15,6 +15,7 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <linux/sysfs.h>
#include <linux/usb/role.h>
#include <linux/firmware/qcom/qcom_scm.h>
@@ -55,6 +56,8 @@ 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;
@@ -156,17 +159,33 @@ 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;
+ guard(mutex)(&chip->state_lock);
+
/* Skip operation if already in desired state */
if (chip->enabled == enable)
return count;
if (enable) {
+ path = chip->paths[chip->port_idx];
+
+ /*
+ * If not yet in device role, honor the userspace request and defer
+ * EUD enablement until the port transitions to device role in the
+ * set_role callback.
+ */
+ if (path->curr_role != USB_ROLE_DEVICE) {
+ dev_info(chip->dev, "Deferring EUD enable until port enters device mode\n");
+ chip->enabled = enable;
+ return count;
+ }
+
ret = enable_eud(chip);
if (ret) {
dev_err(chip->dev, "failed to enable eud\n");
@@ -304,7 +323,30 @@ 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);
- int ret;
+ struct eud_chip *chip = path->chip;
+ int ret = 0;
+
+ guard(mutex)(&chip->state_lock);
+
+ /*
+ * EUD is usable only in device role. Power it down for every other
+ * role to avoid keeping an unusable module 'ON'. chip->enabled
+ * preserves user's sysfs configuration and is not modified across
+ * role transitions.
+ */
+ if (chip->enabled && path->num == chip->port_idx && role != path->curr_role) {
+ if (role == USB_ROLE_DEVICE)
+ ret = enable_eud(chip);
+ else if (path->curr_role == USB_ROLE_DEVICE)
+ ret = disable_eud(chip);
+
+ if (ret) {
+ dev_err(chip->dev, "failed to %s EUD for role %s: %d\n",
+ str_enable_disable(role == USB_ROLE_DEVICE),
+ usb_role_string(role), ret);
+ return ret;
+ }
+ }
/* Forward the role request to the USB controller */
ret = usb_role_switch_set_role(path->controller_sw, role);
@@ -431,6 +473,8 @@ static int eud_probe(struct platform_device *pdev)
chip->dev = &pdev->dev;
+ mutex_init(&chip->state_lock);
+
for_each_child_of_node_scoped(np, child) {
ret = eud_init_path(chip, child);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
` (5 preceding siblings ...)
2026-08-11 21:36 ` [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 22:00 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node Elson Serrao
2026-08-11 21:36 ` [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards Elson Serrao
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel, Konrad Dybcio
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.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Peter Chen <peter.chen@kernel.org>
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 538e070cc140..a02f3535956d 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -306,10 +306,26 @@ static irqreturn_t handle_eud_irq_thread(int irq, void *data)
path = chip->paths[chip->port_idx];
+ /*
+ * 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 related [flat|nested] 19+ messages in thread
* [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
` (6 preceding siblings ...)
2026-08-11 21:36 ` [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 22:05 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards Elson Serrao
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel
The existing EUD description uses a legacy single-path representation
that assumes uniform UTMI routing. This was sufficient for minimal
configurations where the USB port operated only in device mode and role
switching was not considered.
Update the description to explicitly model the topology using eud path
child node and add a role-switch declaration to reflect role-dependent
UTMI routing. Also on this SoC, the EUD hardware intercepts only the
primary UTMI path. So remove the USB endpoint mapping to the secondary
controller and associate it with the primary controller.
With the UTMI path now accurately described, enable the EUD by default.
The connector side of the path is left unspecified, allowing board-level
DTS files to describe the physical connector mapping.
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kodiak.dtsi | 35 +++++++++++++++++-----------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
index f2da3706d5c8..30b62b406906 100644
--- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
+++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -4421,12 +4421,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 {
@@ -4753,16 +4747,28 @@ eud: eud@88e0000 {
<0 0x88e2000 0 0x1000>;
interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
+ eud0: eud-path@0 {
+ reg = <0>;
+ usb-role-switch;
- port@0 {
- reg = <0>;
- eud_ep: endpoint {
- remote-endpoint = <&usb2_role_switch>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ eud_usb: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ eud_con: endpoint {
+ };
};
};
};
@@ -4989,6 +4995,7 @@ port@0 {
reg = <0>;
usb_1_dwc3_hs: endpoint {
+ remote-endpoint = <&eud_usb>;
};
};
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
` (7 preceding siblings ...)
2026-08-11 21:36 ` [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node Elson Serrao
@ 2026-08-11 21:36 ` Elson Serrao
2026-08-11 22:06 ` sashiko-bot
8 siblings, 1 reply; 19+ messages in thread
From: Elson Serrao @ 2026-08-11 21:36 UTC (permalink / raw)
To: Bjorn Andersson, Dmitry Baryshkov, Greg Kroah-Hartman,
Konrad Dybcio, Krzysztof Kozlowski, Peter Chen, Rob Herring,
Conor Dooley
Cc: linux-arm-msm, devicetree, linux-usb, linux-kernel
On Kodiak-based boards, the primary USB connector is connected through
the EUD on the High-Speed path. Update the board-level descriptions to
map the USB connector endpoint to EUD, reflecting the intended hardware
topology.
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts | 10 +++++-----
arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts | 10 +++++-----
arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts | 10 +++++-----
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 10 +++++-----
.../boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts | 4 ++--
.../boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts | 10 +++++-----
.../boot/dts/qcom/sm7325-motorola-dubai-common.dtsi | 4 ++--
arch/arm64/boot/dts/qcom/sm7325-motorola-dubai.dts | 4 ++--
arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts | 10 +++++-----
arch/arm64/boot/dts/qcom/sm7325-xiaomi-taoyao.dts | 4 ++--
10 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
index f41ad446a39e..b1f1ff6b99e6 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
@@ -98,7 +98,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1530,10 +1530,6 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
- remote-endpoint = <&pmic_glink_hs_in>;
-};
-
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l10c>;
vdda18-supply = <&vreg_l1c>;
@@ -1573,3 +1569,7 @@ &wifi {
qcom,calibration-variant = "Fairphone_5";
status = "okay";
};
+
+&eud_con {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts
index 5bb33a8a9830..41836afd3acd 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts
@@ -74,7 +74,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -828,10 +828,6 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
- remote-endpoint = <&pmic_glink_hs_in>;
-};
-
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l10c_0p88>;
vdda33-supply = <&vreg_l2b_3p072>;
@@ -864,3 +860,7 @@ &usb_2_hsphy {
&usb_dp_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
+
+&eud_con {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts
index cf74b3664cf5..45b9318ab54e 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts
@@ -84,7 +84,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -951,10 +951,6 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
- remote-endpoint = <&pmic_glink_hs_in>;
-};
-
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l10c>;
vdda18-supply = <&vreg_l1c>;
@@ -985,6 +981,10 @@ &usb_dp_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
+&eud_con {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
&venus {
firmware-name = "qcom/qcm6490/SHIFT/otter/venus.mbn";
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index a13315bf0fb0..6520e920a844 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -211,7 +211,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1402,14 +1402,14 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
- remote-endpoint = <&pmic_glink_hs_in>;
-};
-
&usb_1_dwc3_ss {
remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
+&eud_con {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l10c_0p88>;
vdda33-supply = <&vreg_l2b_3p072>;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
index 31bafa2cf51d..4c4afe691d64 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
@@ -77,7 +77,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1052,7 +1052,7 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
+&eud_con {
remote-endpoint = <&pmic_glink_hs_in>;
};
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
index 13e8e62f6205..b9f92bcf84ab 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
@@ -93,7 +93,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1098,10 +1098,6 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
- remote-endpoint = <&pmic_glink_hs_in>;
-};
-
&usb_1_hsphy {
vdda-pll-supply = <&vreg_l10c_0p88>;
vdda33-supply = <&vreg_l2b_3p072>;
@@ -1135,6 +1131,10 @@ &usb_dp_qmpphy_out {
remote-endpoint = <&pmic_glink_ss_in>;
};
+&eud_con {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
+
&ufs_mem_hc {
reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
vcc-supply = <&vreg_l7b_2p952>;
diff --git a/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai-common.dtsi b/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai-common.dtsi
index 3860ab8508a0..2a90de989dad 100644
--- a/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai-common.dtsi
@@ -96,7 +96,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1429,7 +1429,7 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
+&eud_con {
remote-endpoint = <&pmic_glink_hs_in>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai.dts b/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai.dts
index d94571c05a59..7a97a3eedd5f 100644
--- a/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai.dts
+++ b/arch/arm64/boot/dts/qcom/sm7325-motorola-dubai.dts
@@ -98,7 +98,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1428,7 +1428,7 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
+&eud_con {
remote-endpoint = <&pmic_glink_hs_in>;
};
diff --git a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts
index 7db9ae1c3cef..4729779d50a0 100644
--- a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts
+++ b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts
@@ -99,7 +99,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -1438,10 +1438,6 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
- remote-endpoint = <&pmic_glink_hs_in>;
-};
-
&usb_1_hsphy {
vdda-pll-supply = <&vdd_a_usbhs_core>;
vdda18-supply = <&vdd_a_usbhs_1p8>;
@@ -1457,3 +1453,7 @@ &venus {
&wifi {
status = "okay";
};
+
+&eud_con {
+ remote-endpoint = <&pmic_glink_hs_in>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm7325-xiaomi-taoyao.dts b/arch/arm64/boot/dts/qcom/sm7325-xiaomi-taoyao.dts
index 87f267aaeec0..b0bdbcd47503 100644
--- a/arch/arm64/boot/dts/qcom/sm7325-xiaomi-taoyao.dts
+++ b/arch/arm64/boot/dts/qcom/sm7325-xiaomi-taoyao.dts
@@ -94,7 +94,7 @@ port@0 {
reg = <0>;
pmic_glink_hs_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_hs>;
+ remote-endpoint = <&eud_con>;
};
};
@@ -882,7 +882,7 @@ &usb_1 {
status = "okay";
};
-&usb_1_dwc3_hs {
+&eud_con {
remote-endpoint = <&pmic_glink_hs_in>;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing
2026-08-11 21:36 ` [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing Elson Serrao
@ 2026-08-11 21:50 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 21:50 UTC (permalink / raw)
To: Elson Serrao; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The `oneOf` block allows the new `qcom,sm8350-eud` compatible string to bypass its dual-path requirements by incorrectly matching the legacy single-path `ports` representation.
--
--- Patch [1]: [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing ---
commit de56d6ae0c4dbc79f8a9aa462280cdd2113649b0
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing
The Qualcomm Embedded USB Debugger (EUD) can intercept one or two High-Speed
UTMI paths depending on the SoC. This commit models each UTMI path as a
separate child node with its own OF graph, adding an SM8350 compatible
while retaining the legacy ports representation for backward compatibility.
> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
> index 84218636c0d8d..0e35bc9a9d20d 100644
> --- a/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
[ ... ]
> @@ -45,10 +46,87 @@ properties:
> $ref: /schemas/graph.yaml#/properties/port
> description: This port is to be attached to the type C connector.
>
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 0
[ ... ]
> required:
> - compatible
> - reg
> - - ports
> +
> +oneOf:
> + - required:
> + - ports
> + properties:
> + eud-path@0: false
> + eud-path@1: false
[Severity: Medium]
Does this first branch of the oneOf block allow the new qcom,sm8350-eud
compatible string to bypass its dual-path requirements?
Because this branch only checks for the presence of the legacy 'ports'
property and the absence of 'eud-path@X', it doesn't restrict the legacy
representation strictly to the legacy qcom,sc7280-eud compatible string.
If a device tree is written for the new SM8350 hardware variant using
the deprecated, single-path 'ports' layout instead of the required
eud-path nodes, it appears it would erroneously pass schema validation by
matching this first branch, entirely avoiding the compatible-based
constraints in the second branch.
> + - allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: qcom,sc7280-eud
> + then:
> + required:
> + - eud-path@0
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control
2026-08-11 21:36 ` [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control Elson Serrao
@ 2026-08-11 21:54 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 21:54 UTC (permalink / raw)
To: Elson Serrao; +Cc: robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Incorrect devres ordering causes a use-after-unmap vulnerability during driver removal.
- [Medium] Missing rollback on downstream USB role switch failure causes permanent state desynchronization and PHY power leak.
--
--- Patch [6]: [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control ---
commit bc0de19142343d10fe6a60512025d0e334d88fb3
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
usb: misc: qcom_eud: add role-based EUD control
EUD functions by presenting itself as a USB device to the host PC and is
therefore only applicable when the port operates in device role. This patch
updates the driver to treat EUD as usable only in device role, modifying the
role-switch callback to enable or disable EUD accordingly.
> diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
> index e83a4402e4b84..538e070cc140a 100644
> --- a/drivers/usb/misc/qcom_eud.c
> +++ b/drivers/usb/misc/qcom_eud.c
[ ... ]
> @@ -304,7 +323,30 @@ 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);
> - int ret;
> + struct eud_chip *chip = path->chip;
> + int ret = 0;
> +
> + guard(mutex)(&chip->state_lock);
> +
> + /*
> + * EUD is usable only in device role. Power it down for every other
> + * role to avoid keeping an unusable module 'ON'. chip->enabled
> + * preserves user's sysfs configuration and is not modified across
> + * role transitions.
> + */
> + if (chip->enabled && path->num == chip->port_idx && role != path->curr_role) {
> + if (role == USB_ROLE_DEVICE)
> + ret = enable_eud(chip);
> + else if (path->curr_role == USB_ROLE_DEVICE)
> + ret = disable_eud(chip);
> +
> + if (ret) {
> + dev_err(chip->dev, "failed to %s EUD for role %s: %d\n",
> + str_enable_disable(role == USB_ROLE_DEVICE),
> + usb_role_string(role), ret);
> + return ret;
> + }
> + }
>
> /* Forward the role request to the USB controller */
> ret = usb_role_switch_set_role(path->controller_sw, role);
[Severity: Medium]
If the downstream controller rejects the role switch and returns an error,
does this leave the EUD hardware state out of sync?
Looking at eud_role_switch_set(), if we were transitioning to USB_ROLE_DEVICE,
we already called enable_eud(). If usb_role_switch_set_role() then fails,
the function returns without updating path->curr_role or rolling back the
physical enable:
ret = usb_role_switch_set_role(path->controller_sw, role);
if (ret) {
dev_err(...);
return ret;
}
Since path->curr_role remains out of sync with the physical state, will future
transitions to USB_ROLE_NONE evaluate (role != path->curr_role) as false and
permanently skip calling disable_eud(), leaving the PHY powered on?
[ ... ]
> @@ -431,6 +473,8 @@ static int eud_probe(struct platform_device *pdev)
>
> chip->dev = &pdev->dev;
>
> + mutex_init(&chip->state_lock);
> +
> for_each_child_of_node_scoped(np, child) {
> ret = eud_init_path(chip, child);
> if (ret)
[Severity: High]
Does registering the role switch here create a devres ordering issue with the
I/O memory mapping?
In eud_probe(), the USB role switch is registered via eud_init_path() before
chip->base is mapped via devm_platform_ioremap_resource() later in the probe
function.
Since devres callbacks run in strictly reverse order, during driver teardown
chip->base will be unmapped before the role switch is unregistered. If a
concurrent role switch event arrives during this window, eud_role_switch_set()
could see chip->enabled == true and call enable_eud(), which writes to the
already unmapped chip->base.
Could this lead to a panic or page fault during driver removal?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=6
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection
2026-08-11 21:36 ` [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
@ 2026-08-11 21:54 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 21:54 UTC (permalink / raw)
To: Elson Serrao; +Cc: robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Medium] The `port` attribute unconditionally allows selecting a secondary port on single-port hardware platforms.
- [Medium] The initial software state of `port_idx` is not synchronized with the hardware configuration during device probe.
Pre-existing issues:
- [High] The `chip->enabled` flag is never cleared when EUD is disabled, permanently blocking subsequent port changes.
- [High] Simultaneous active interrupts cause an unhandled interrupt storm in `handle_eud_irq`.
--
--- Patch [2]: [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection ---
commit 6f4483594010ca910c4a59bd283f5067e4e3b31e
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
usb: misc: qcom_eud: add sysfs attribute for port selection
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.
[ ... ]
> diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
> index 926419ca560fc..25a6a8f110ec8 100644
> --- a/drivers/usb/misc/qcom_eud.c
> +++ b/drivers/usb/misc/qcom_eud.c
> @@ -104,8 +113,38 @@ 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, "%s\n", eud_port_names[chip->port_idx]);
[Severity: Medium]
Could the initial software state of chip->port_idx be out of sync with the
hardware?
If the bootloader configures EUD_REG_PORT_SEL to the secondary port prior
to kernel boot, eud_probe() leaves port_idx as 0 from its initial
allocation.
Will port_show() erroneously return "primary" while the hardware is
actually configured for the secondary port?
> +}
> +
> +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);
> + int port;
> +
> + port = sysfs_match_string(eud_port_names, buf);
> + if (port < 0)
> + return port;
> +
> + /* Port selection must be done before enabling EUD */
> + if (chip->enabled)
> + return -EBUSY;
[Severity: High]
This is a pre-existing issue, but since the new port_store() function
relies on chip->enabled, does the driver ever clear this flag when EUD is
disabled?
Looking at enable_store(), when a user writes '0', it calls disable_eud()
but it doesn't appear to set chip->enabled to false:
drivers/usb/misc/qcom_eud.c:enable_store() {
...
} else {
ret = disable_eud(chip);
}
...
}
Once enabled, will chip->enabled stay true forever and permanently block
subsequent port changes?
> +
> + writel(port, chip->base + EUD_REG_PORT_SEL);
> + chip->port_idx = port;
[Severity: Medium]
Does this code allow selecting a secondary port on hardware platforms that
only physically support a single port?
I don't see a check against device tree capabilities or a mechanism like
is_visible() to hide this attribute on single-port devices. Unconditionally
configuring the hardware register to a non-existent port could lead to
undefined behavior.
> +
> + return count;
> +}
> +
[ ... ]
While reviewing the rest of the file, I noticed another detail:
[Severity: High]
This is a pre-existing issue, but can the interrupt handler experience an
unhandled interrupt storm if multiple statuses are asserted?
If both EUD_INT_VBUS and EUD_INT_SAFE_MODE are asserted simultaneously,
the switch statement in handle_eud_irq() looks like it might fail to handle
the combined bitmask:
drivers/usb/misc/qcom_eud.c:handle_eud_irq() {
...
switch (reg & EUD_INT_ALL) {
case EUD_INT_VBUS:
usb_attach_detach(chip);
return IRQ_WAKE_THREAD;
case EUD_INT_SAFE_MODE:
pet_eud(chip);
return IRQ_HANDLED;
default:
return IRQ_NONE;
}
}
Since EUD_INT_ALL includes both bits, wouldn't reg & EUD_INT_ALL evaluate
to 0x14, fall through to the default case, and return IRQ_NONE without
clearing either interrupt?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=2
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API
2026-08-11 21:36 ` [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
@ 2026-08-11 21:56 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 21:56 UTC (permalink / raw)
To: Elson Serrao; +Cc: robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] The early return optimization in `enable_store` causes a state desynchronization if the hardware was left enabled before probe (e.g., by the bootloader), preventing userspace from disabling it.
Pre-existing issues:
- [High] `pet_eud()` calls the sleeping function `readl_poll_timeout()` while executing in the top-half hardirq handler, which causes a kernel panic.
--
--- Patch [5]: [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API ---
commit ba15c5168dac3d6c5421e3601396a69dd6a1abdb
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
usb: misc: qcom_eud: improve enable_store API
This commit adds duplicate state checks to skip redundant enable or disable
requests when the EUD is already in the desired state. It also adds explicit
error logging to provide better feedback.
> diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
> index 48a4441b0c9c0..e83a4402e4b84 100644
> --- a/drivers/usb/misc/qcom_eud.c
> +++ b/drivers/usb/misc/qcom_eud.c
> @@ -162,18 +162,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;
> +
[Severity: High]
Does this early return risk a state desynchronization if the hardware was
left enabled before probe?
Since chip is allocated via devm_kzalloc(), chip->enabled initializes to false
without reading the actual hardware state. If the bootloader or a previous
instance leaves the EUD active, and a boot script subsequently writes '0' to
the sysfs enable attribute to explicitly disable it, this check will evaluate
to false == false and return immediately without actually disabling the
hardware.
[ ... ]
Additionally, while reviewing this file, I noticed a pre-existing issue in the
interrupt handling path:
drivers/usb/misc/qcom_eud.c:handle_eud_irq() {
...
case EUD_INT_SAFE_MODE:
pet_eud(chip);
return IRQ_HANDLED;
...
}
drivers/usb/misc/qcom_eud.c:pet_eud() {
...
ret = readl_poll_timeout(chip->base + EUD_REG_SW_ATTACH_DET,
reg, (reg == 0), 1, 100);
...
}
[Severity: High]
This isn't a bug introduced by this patch, but does pet_eud() call a sleeping
function while executing in a top-half hardirq context?
When the EUD_INT_SAFE_MODE interrupt is asserted, the primary IRQ handler
handle_eud_irq() is invoked in hardirq context. It calls pet_eud(), which
uses readl_poll_timeout() with a sleep_us parameter of 1. This invokes
usleep_range(), forcing a sleep in an atomic context and likely causing a
scheduling while atomic panic.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control
2026-08-11 21:36 ` [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
@ 2026-08-11 21:56 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 21:56 UTC (permalink / raw)
To: Elson Serrao; +Cc: devicetree, conor+dt, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Lack of locking in sysfs handlers allows concurrent execution and TOCTOU races, leading to unbalanced PHY operations and driver state corruption.
--
--- Patch [3]: [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control ---
commit 0126e533bbae398f1f9f6831389bcefdb1ad1252
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
usb: misc: qcom_eud: add per-path High-Speed PHY control
This patch restructures the EUD driver to implement per-path PHY management,
powering the appropriate PHY based on the selected UTMI path. This ensures
the PHY is explicitly initialized and powered when EUD is enabled.
> diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
> index 25a6a8f110ec8..03d1c200658c8 100644
> --- a/drivers/usb/misc/qcom_eud.c
> +++ b/drivers/usb/misc/qcom_eud.c
[ ... ]
> @@ -130,6 +192,10 @@ static ssize_t port_store(struct device *dev, struct device_attribute *attr,
> if (port < 0)
> return port;
>
> + /* Check if the corresponding path is available */
> + if (!chip->paths[port])
> + return -EOPNOTSUPP;
> +
> /* Port selection must be done before enabling EUD */
> if (chip->enabled)
> return -EBUSY;
[Severity: High]
Is there a lock missing here in port_store() to synchronize with enable_store()?
Looking at enable_store(), it uses guard(mutex)(&chip->state_lock) before
checking chip->enabled, but port_store() appears to check chip->enabled and
mutate chip->port_idx without holding this lock.
Could this allow a race where port_store() changes chip->port_idx while
enable_store() is midway through enablement?
For example, if port_store() executes right after enable_eud() initializes
the PHY in enable_store() but before chip->enabled is set to true:
Thread 1 in enable_store():
guard(mutex)(&chip->state_lock);
enable_eud(chip);
Thread 2 in port_store():
if (chip->enabled)
return -EBUSY;
chip->port_idx = port;
Thread 1 in enable_store():
chip->enabled = true;
Would this cause subsequent disablements to read the new port_idx in
eud_phy_disable(), leaving the original PHY powered on and attempting to
power off the new PHY?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support
2026-08-11 21:36 ` [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
@ 2026-08-11 21:57 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 21:57 UTC (permalink / raw)
To: Elson Serrao; +Cc: robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Writing '0' to the 'enable' sysfs attribute disables the hardware but fails to update the internal `chip->enabled` state to false.
- [High] The hardirq handler calls `readl_poll_timeout()`, which internally uses `usleep_range()` and causes a 'scheduling while atomic' panic.
- [High] Concurrent sysfs writes to 'enable' can cause PHY reference count leaks due to missing state locking.
--
--- Patch [4]: [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support ---
commit 815da4bb92fc6ba59cfd8252e67e13ba90e1b715
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
usb: misc: qcom_eud: add per-path role switch support
The EUD hardware can support multiple High-Speed USB paths, each connected
to different USB controllers. This commit restructures the driver to support
per-path role switches and removes the single chip-level role switch. It
also removes the role switch call from enable_eud().
> diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
> index 03d1c200658c8..48a4441b0c9c0 100644
> --- a/drivers/usb/misc/qcom_eud.c
> +++ b/drivers/usb/misc/qcom_eud.c
[ ... ]
> @@ -123,7 +126,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;
> }
[Severity: High]
This isn't a bug introduced by this patch, but does writing '0' to the
'enable' sysfs attribute leave the software state permanently enabled?
Looking at enable_store() in drivers/usb/misc/qcom_eud.c, it calls
disable_eud() but fails to update the internal chip->enabled state to false:
} else {
ret = disable_eud(chip);
}
Because port_store() checks if chip->enabled is true and returns -EBUSY,
does this lock the user out of changing the port configuration after the
EUD is enabled and disabled once?
[Severity: High]
This isn't a bug introduced by this patch, but can concurrent sysfs writes
to 'enable' cause PHY reference count leaks?
Looking at enable_store() in drivers/usb/misc/qcom_eud.c, it calls
enable_eud() without acquiring any state lock:
if (enable) {
ret = enable_eud(chip);
Inside eud_phy_enable(), chip->phy_enabled is checked and modified without
locking:
if (chip->phy_enabled)
return 0;
phy = chip->paths[chip->port_idx]->phy;
If two threads simultaneously write '1' to the 'enable' sysfs attribute,
both could observe chip->phy_enabled as false and initialize the PHY
multiple times. When disable_eud() is later called, it will only power
off the PHY once.
Does this leak the PHY reference counts and leave the hardware permanently
powered on?
[ ... ]
> @@ -270,12 +273,15 @@ static irqreturn_t handle_eud_irq(int irq, void *data)
[Severity: High]
This isn't a bug introduced by this patch, but does the hardirq handler call
a sleeping function?
When the EUD_INT_SAFE_MODE interrupt triggers, the primary interrupt handler
handle_eud_irq() in drivers/usb/misc/qcom_eud.c (which executes in hardirq
context) invokes pet_eud():
case EUD_INT_SAFE_MODE:
pet_eud(chip);
return IRQ_HANDLED;
Inside pet_eud(), it calls readl_poll_timeout() with a non-zero delay_us:
ret = readl_poll_timeout(chip->base + EUD_REG_SW_ATTACH_DET,
reg, (reg == 0), 1, 100);
Since a non-zero delay_us causes readl_poll_timeout() to internally call
usleep_range(), will this cause a 'scheduling while atomic' panic?
> static irqreturn_t handle_eud_irq_thread(int irq, void *data)
> {
> struct eud_chip *chip = data;
> + struct eud_path *path;
> int ret;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=4
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling
2026-08-11 21:36 ` [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
@ 2026-08-11 22:00 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 22:00 UTC (permalink / raw)
To: Elson Serrao; +Cc: conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The top-half interrupt handler attempts to sleep by calling `readl_poll_timeout()`, which relies on `usleep_range()` and will trigger a scheduling-while-atomic BUG.
- [High] The hardirq handler silently ignores concurrent interrupts because it uses a `switch` statement on a bitmask, falling through to `default` when multiple bits are set.
--
--- Patch [7]: [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling ---
Note: The format of this report has been altered to provide a free-form summary of the findings due to recitation restrictions. The inline quoting style has been omitted.
commit a8a02ef8fd7fc3586fa115aa0dd7a40742fbcfe8
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
usb: misc: qcom_eud: Fix virtual detach USB role
This commit fixes the EUD virtual detach handling by setting the USB role
to NONE instead of HOST. This correctly represents the disconnected state
when a virtual detach event occurs.
[Severity: High]
This isn't a bug introduced by this patch, but looking at the top-half
interrupt handler handle_eud_irq() in drivers/usb/misc/qcom_eud.c, it
calls pet_eud() for the EUD_INT_SAFE_MODE case. The pet_eud() function uses
readl_poll_timeout() with a delay of 1us, which relies on usleep_range()
and might sleep. Is it safe to call this sleeping function from a hardirq
context, or should it use readl_poll_timeout_atomic() instead to avoid a
scheduling-while-atomic BUG?
[Severity: High]
This is also a pre-existing issue, but does the switch statement in
handle_eud_irq() in drivers/usb/misc/qcom_eud.c correctly handle concurrent
interrupts? It switches on the bitmask (reg & EUD_INT_ALL). If both
EUD_INT_VBUS and EUD_INT_SAFE_MODE are asserted simultaneously, the value
won't match either case, falling through to the default label and returning
IRQ_NONE without clearing the device interrupt. Could this leave the
interrupts unhandled and potentially lead to an interrupt storm where the
kernel disables the IRQ line?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=7
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node
2026-08-11 21:36 ` [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node Elson Serrao
@ 2026-08-11 22:05 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 22:05 UTC (permalink / raw)
To: Elson Serrao; +Cc: conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Nesting the OF graph inside `eud-path@0` breaks the existing `qcom_eud` driver's ability to find the USB role switch, and violates the current device tree binding.
--
--- Patch [8]: [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node ---
commit 760fcd42e7f50583cc87820f4812ba19895c4e27
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
arm64: dts: qcom: kodiak: Update EUD device tree graph
This commit updates the EUD description to explicitly model the topology
using an eud path child node. It also associates the endpoint mapping
with the primary controller and enables the EUD by default.
> diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
> index f2da3706d5c8..30b62b406906 100644
> --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
> +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
[ ... ]
> @@ -4753,16 +4747,28 @@ eud: eud@88e0000 {
> <0 0x88e2000 0 0x1000>;
> interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
>
> - status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
>
> - ports {
> - #address-cells = <1>;
> - #size-cells = <0>;
> + eud0: eud-path@0 {
> + reg = <0>;
> + usb-role-switch;
>
> - port@0 {
> - reg = <0>;
> - eud_ep: endpoint {
> - remote-endpoint = <&usb2_role_switch>;
> + ports {
[Severity: High]
Will this nested structure prevent the qcom_eud driver from finding the
USB role switch?
In drivers/usb/misc/qcom_eud.c:eud_probe(), the driver calls
usb_role_switch_get(), which traverses the OF graph to locate the switch:
chip->role_sw = usb_role_switch_get(&pdev->dev);
if (IS_ERR(chip->role_sw))
The graph traversal functions look specifically for immediate child nodes
named "port" or "ports". Because this patch nests the "ports" node inside
an "eud-path@0" child, the traversal will find zero endpoints. This will
cause usb_role_switch_get() to silently return NULL and leave the debugging
functionality non-functional.
Additionally, does this change violate the current device tree bindings for
the EUD?
The schema in Documentation/devicetree/bindings/soc/qcom/qcom,eud.yaml
specifies "additionalProperties: false", which will reject properties like
"eud-path@0", "#address-cells", and "#size-cells" at the root of the eud
node.
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> + eud_usb: endpoint {
> + remote-endpoint = <&usb_1_dwc3_hs>;
> + };
> + };
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=8
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards
2026-08-11 21:36 ` [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards Elson Serrao
@ 2026-08-11 22:06 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-08-11 22:06 UTC (permalink / raw)
To: Elson Serrao; +Cc: conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Rerouting the Type-C High-Speed endpoint to EUD breaks USB enumeration and role-switching because the required `eud` and `usb_2` nodes are left disabled.
- [Low] The patch references an undefined devicetree label `&eud_con`, which will cause a fatal `dtc` compilation error.
--
--- Patch [9]: [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards ---
commit 2fda8aaa91eca6e348e83f602c927ebd7362e954
Author: Elson Serrao <elson.serrao@oss.qualcomm.com>
arm64: dts: qcom: map USB connector endpoint to EUD on Kodiak boards
This commit updates board-level descriptions for Kodiak-based boards to map
the primary USB connector's High-Speed path through the Embedded USB Debugger
(EUD). It replaces the existing remote-endpoint mapping to usb_1_dwc3_hs with
eud_con to reflect the intended hardware topology.
> diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
> index f41ad446a39e..b1f1ff6b99e6 100644
> --- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
> +++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
> @@ -98,7 +98,7 @@ port@0 {
> reg = <0>;
>
> pmic_glink_hs_in: endpoint {
> - remote-endpoint = <&usb_1_dwc3_hs>;
> + remote-endpoint = <&eud_con>;
> };
> };
>
[Severity: Low]
Will this compile cleanly? In the baseline kodiak.dtsi, the eud node
defines port@0, but it doesn't appear to define the eud_con label:
arch/arm64/boot/dts/qcom/kodiak.dtsi:
eud: eud@88e0000 {
...
port@0 {
eud_ep: endpoint {
...
Does the eud_con label need to be added to the SoC dtsi first to avoid a
device tree compiler syntax error?
[ ... ]
> @@ -1573,3 +1569,7 @@ &wifi {
> qcom,calibration-variant = "Fairphone_5";
> status = "okay";
> };
> +
> +&eud_con {
> + remote-endpoint = <&pmic_glink_hs_in>;
> +};
[Severity: High]
Does routing this connector through the EUD strand the primary USB controller
without a role switch provider?
The usb_1 node in this file is configured for usb-role-switch, but it is
severed from its High-Speed endpoint by this patch.
Additionally, in kodiak.dtsi, both the eud node and the secondary usb_2
controller it relies on have their status disabled by default:
arch/arm64/boot/dts/qcom/kodiak.dtsi:
eud: eud@88e0000 {
...
status = "disabled";
...
usb_2: usb@a6f8800 {
...
status = "disabled";
Since the board files don't override these to "okay", will this prevent the
graph traversal via fwnode_usb_role_switch_get() and break USB enumeration
entirely upon boot?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260811213610.2956147-1-elson.serrao@oss.qualcomm.com?part=9
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-08-11 22:06 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 21:36 [PATCH v6 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
2026-08-11 21:36 ` [PATCH v6 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing Elson Serrao
2026-08-11 21:50 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
2026-08-11 21:54 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
2026-08-11 21:56 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
2026-08-11 21:57 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
2026-08-11 21:56 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 6/9] usb: misc: qcom_eud: add role-based EUD control Elson Serrao
2026-08-11 21:54 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
2026-08-11 22:00 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node Elson Serrao
2026-08-11 22:05 ` sashiko-bot
2026-08-11 21:36 ` [PATCH v6 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards Elson Serrao
2026-08-11 22:06 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox