From: Elson Serrao <elson.serrao@oss.qualcomm.com>
To: Bjorn Andersson <andersson@kernel.org>,
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Konrad Dybcio <konradybcio@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Rob Herring <robh@kernel.org>, Conor Dooley <conor+dt@kernel.org>,
Souradeep Chowdhury <quic_schowdhu@quicinc.com>
Cc: linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v4 6/9] usb: misc: qcom_eud: add host mode coordination
Date: Fri, 1 May 2026 10:06:32 -0700 [thread overview]
Message-ID: <20260501170635.2641748-7-elson.serrao@oss.qualcomm.com> (raw)
In-Reply-To: <20260501170635.2641748-1-elson.serrao@oss.qualcomm.com>
EUD functions by presenting itself as a USB device to the host PC for
debugging, making it incompatible with USB host mode configurations.
Enabling EUD while in host mode can also cause the USB controller to
misbehave, as the EUD hub supports only a single upstream-facing port.
Handle the following scenarios to prevent these conflicts:
1. Prevent the user from enabling EUD via sysfs when the USB port is in
host mode.
2. Automatically disable EUD when the 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 | 65 ++++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c
index f656ffc8818a..4734b6307a85 100644
--- a/drivers/usb/misc/qcom_eud.c
+++ b/drivers/usb/misc/qcom_eud.c
@@ -55,12 +55,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;
};
@@ -156,17 +159,43 @@ 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;
+ /*
+ * 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;
+ return count;
+ }
+
if (enable) {
+ /*
+ * EUD functions by presenting itself as a USB device to the host PC for
+ * debugging, making it incompatible with USB host mode configuration.
+ * Prevent enabling EUD in this configuration to avoid hardware conflicts.
+ */
+ path = chip->paths[chip->port_idx];
+ if (path->curr_role == USB_ROLE_HOST) {
+ dev_err(chip->dev, "cannot enable EUD: USB port is in host mode\n");
+ return -EBUSY;
+ }
+
ret = enable_eud(chip);
if (ret) {
dev_err(chip->dev, "failed to enable eud\n");
@@ -308,9 +337,41 @@ 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;
- /* Forward the role request to the USB controller */
+ guard(mutex)(&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 with 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);
+ 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);
+ return ret;
+ }
+ chip->eud_disabled_for_host = false;
+ }
+ }
+
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",
@@ -424,6 +485,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
next prev parent reply other threads:[~2026-05-01 17:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-01 17:06 [PATCH v4 0/9] Improve Qualcomm EUD driver and platform support Elson Serrao
2026-05-01 17:06 ` [PATCH v4 1/9] dt-bindings: soc: qcom: eud: Add per-path child nodes for UTMI routing Elson Serrao
2026-05-01 17:06 ` [PATCH v4 2/9] usb: misc: qcom_eud: add sysfs attribute for port selection Elson Serrao
2026-05-01 17:06 ` [PATCH v4 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Elson Serrao
2026-05-01 17:06 ` [PATCH v4 4/9] usb: misc: qcom_eud: add per-path role switch support Elson Serrao
2026-05-01 17:06 ` [PATCH v4 5/9] usb: misc: qcom_eud: improve enable_store API Elson Serrao
2026-05-01 17:06 ` Elson Serrao [this message]
2026-05-01 17:06 ` [PATCH v4 7/9] usb: misc: qcom_eud: fix virtual attach/detach event handling Elson Serrao
2026-05-01 17:06 ` [PATCH v4 8/9] arm64: dts: qcom: kodiak: Describe EUD UTMI path using child node Elson Serrao
2026-05-01 17:06 ` [PATCH v4 9/9] arm64: dts: qcom: Map USB connector to EUD on Kodiak boards Elson Serrao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260501170635.2641748-7-elson.serrao@oss.qualcomm.com \
--to=elson.serrao@oss.qualcomm.com \
--cc=andersson@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=gregkh@linuxfoundation.org \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=quic_schowdhu@quicinc.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox