From nobody Fri Apr 3 06:11:33 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB5B0421890 for ; Mon, 9 Mar 2026 20:33:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773088432; cv=none; b=F0wgXwXlnOy8sKRNT3Q+JwmNurap3kksBaTQdn/+Zm0G0NnZHBdVfgFt2ZY+Ntlb3ArduLAx7P7JzZbtWSLx8OoZi900n18e2IaqQN60lRgJNDPsoaKlM+cw/gj4qC7agOVA15gl432KoAIKVQLqDzXSCGoGrINgo4Kbnv0ka6M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773088432; c=relaxed/simple; bh=61qZa5oPb5FYhnLtNGgCYyVGAuKr4dTLYSSjg3McuLM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=D0+Im4nd6fS6aF/jZmO3MPsCGuSk23RlTOGVxZA9eQyUj1zHDCfwCsjUZ9uY6Tp7riDKN/HWW7HrV/ufIYkCfI30e3h2Rrr7clPzhrimiGZkN2qDzfnVxQgELZzGTFe36/vpNVDnhjRipoGyZkDCPXzgIyXpNKHY9hKiJrljK5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=QxPlxkFG; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Oita/X5G; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="QxPlxkFG"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Oita/X5G" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 629HCN6X2428827 for ; Mon, 9 Mar 2026 20:33:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=Vm8K1x7aKvC TkjAgk/WSBFUkXkkqg22NG+Ug1hXiRPg=; b=QxPlxkFGkNe4ktku4RmDEu69bww VXpqXA3bSn9fwcF43Y3mqlunHUGTqjetTsblclnLh9bh9ynYQBZe/zQXDDyn00H+ C/6SXRRsS4XWPoJTaW8H3qhjVATATAqeXrScNMOfuh/mZi2426KVKFFnicQHrVWR de3/vl5nTtNPYpU5syHgCAo4tBiuBsrafVc80qtKpf0vh9aN7St4TQI/KhKgnMAX a3aEyxKFSP1hguIlTumNUHU6xa0kutsWfHSpX2bTv2/bOVPJcoILXCvvAKOBK1Qo 8CTtCSHaZugORWoe/VrhCTG+Fb5KOapqgkCu1fYsg+y1MlvjNMJOrzRv65g== Received: from mail-ot1-f70.google.com (mail-ot1-f70.google.com [209.85.210.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ct1ekrwjx-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 09 Mar 2026 20:33:49 +0000 (GMT) Received: by mail-ot1-f70.google.com with SMTP id 46e09a7af769-7d73c71f9faso17688121a34.3 for ; Mon, 09 Mar 2026 13:33:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1773088429; x=1773693229; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Vm8K1x7aKvCTkjAgk/WSBFUkXkkqg22NG+Ug1hXiRPg=; b=Oita/X5GeZBxP2YTLqVdECm1WpEBVLdFu8bR7tA+ayV6QUkLvDiR6GAMl10GczX4lj ELaKsO+FR5dI8qg3eImAyYT7X/CBfD0vzAUcEgv0zA1yGeH20E237U8lk3Fh7+eH30SH +uy0nD7yAxoZe8RnO1Q2sXGEs+4iHl8+hz+9acgV9nSsWYVXk8eG1G1PNMqyp/O3Mb5f h6B8leNjAyollH+6lk4UVHHADGv009IkdYXvQY9mwTPsE4vwbu4dLj5CM3nEWvOigpae BQBWaNIQqD7X27BXF16KA6bkS/vm8+VllBFBiyqHijiOu97R102DD8nwuXBllsnb6fXq Vb2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773088429; x=1773693229; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Vm8K1x7aKvCTkjAgk/WSBFUkXkkqg22NG+Ug1hXiRPg=; b=tt2u62W7zPeHlGoVOzP8VkHV/m4mCi1ygLY9I+Y+KAREZtPzd8NmZx266yAW56H+08 Fir8JKMaMAlLPyvkqwXAzSW6UqorpVfmHHYDA95ILnBs8+J7HTypeoN7DyqjSkjg/6cZ pDvC6VynJC0e80dIrG70qey08Esr1eE+UAp5hzj/9r6d4WfYBip1Gy1pNRZd4hrVFjUE jTuXFcFJdRslUPU7a8UeXquQ6HejpEmQIiWRsKaJFSRrUAbmgtrL7XPdv4ISKCv4bYVk ldjt+IW0l4AbT6+W2Nu3cC1F9hHnpgYUOo/DM22BVLRjX9C5q6138mc0tH77fUxuCBAO fzCQ== X-Forwarded-Encrypted: i=1; AJvYcCUvrK8HNPJwn3cBMoRQjeMPnYQ1G/a7JTZkI4F0tx8Y8HH17kceixEQAlGCTIdIg2sn5W8G3GQ0xIaMBX0=@vger.kernel.org X-Gm-Message-State: AOJu0YxcqVYDDGf5UQLNKn4fM2Tg/2eXKbB3P3UpprE6ckapHQ3uEK6O tN03UI5TA8/NXVBvLirkxSTcS4t22SlAx5MbEXC1YkTaa1iz0tkmnAVMnGWeGruSgalxv082PB6 6PA+Cj4OaxsCheY9JrktW+8ldyO9OaaoQnE+AoXBdlmOIbwDirhPCyy6dEmuj5qDG3ho= X-Gm-Gg: ATEYQzwc9MES2njhb+Ui9rJZidQVc16v9756FD5sj7ZFGUKZkLqWVXMsh3y+0J/66UY el98pkVf41Ge/f2Ac+axR3t4IZHHrszGgy612e62/sATRzFEmJQwrSisYmaWmN6RTms1IH0qbqQ 4fO2LD/ahQLt5vOtzrJPPkAmWo1Wh/7hbWgyw0vESz0S9khsySVnc+c54Ow4p5zch/fBT7zktgZ vfotQ6DKi0Vaqp8zq79quqSjBoy1sxPF4XFVx1dIJgCS5AsZtl3IvzDkbtVHq8l4DyeXZ3T8NTG SwptmE/Y0noCJYES4EX6dBXO276Kjtz0j2GG/gJcgCa12NZOwJP2XM+i+U8xmW25NvSRsqFjPH+ +fs5+IG6hue+3Z/g4BH029dKCAAtfeBM5MKIx0kZ12ZeZsoa9MWQH2RcxGwIH8NLDTdz8XXtSTI A= X-Received: by 2002:a05:6830:f97:b0:7d7:57c4:367b with SMTP id 46e09a7af769-7d757c445b5mr1048635a34.28.1773088428643; Mon, 09 Mar 2026 13:33:48 -0700 (PDT) X-Received: by 2002:a05:6830:f97:b0:7d7:57c4:367b with SMTP id 46e09a7af769-7d757c445b5mr1048615a34.28.1773088428186; Mon, 09 Mar 2026 13:33:48 -0700 (PDT) Received: from hu-eserrao-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7d74885b5a4sm3036494a34.23.2026.03.09.13.33.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 13:33:47 -0700 (PDT) From: Elson Serrao To: Greg Kroah-Hartman , Bjorn Andersson , Konrad Dybcio , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Souradeep Chowdhury Cc: linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC v3 07/10] usb: misc: qcom_eud: add host mode coordination Date: Mon, 9 Mar 2026 13:33:34 -0700 Message-Id: <20260309203337.803986-8-elson.serrao@oss.qualcomm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260309203337.803986-1-elson.serrao@oss.qualcomm.com> References: <20260309203337.803986-1-elson.serrao@oss.qualcomm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: dwWvhCH1c9LUYN70xsG0QHKXxBNklJHB X-Proofpoint-ORIG-GUID: dwWvhCH1c9LUYN70xsG0QHKXxBNklJHB X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA5MDE4MiBTYWx0ZWRfX64tOECE6JHnW dTZdREZkBUZaxnIBzCC2JnUuvHBLFF51hetf5T5suM5q9vLg8W6IEMg3hv2Dy7YheUp/Fai5x0h wRxRubc1A/NbzVYJGBoTOBadyBJRjgNJcP3444QCsE5Vze/+XeiegdAhrfSrkfgGTkJdrTBp06a gBa/PW2yC/hSc5W4oAgPJ71e3YA7E6/1zc5FR2Fyr5mM6j/CO7W3WsVhaDt9x/2b+5/mkQKm7W7 tg1C0/PdtKEQN5rxEaCfpVrBewZ+EAECBsngLE1T7MsTZ2+5vQ9uY0NpPJiLbqLtVMSqmOMlbN+ jUktgVkGlg9VmXsYAFmGzDDd40XpUX7uCSJuosX+nOfiOPOnxxSVlpUR1/n/2Z+lqhsUqz/91qi 7sLy5tDHvXfT9vxlu9P+SKrP75Vx3EK7asnsrAZW8kPYTTDp2CHflZ9ynfrt08uXdExvvw2mj2+ bj7M2Qv268/wH5U7Bqg== X-Authority-Analysis: v=2.4 cv=eIEeTXp1 c=1 sm=1 tr=0 ts=69af2ead cx=c_pps a=7uPEO8VhqeOX8vTJ3z8K6Q==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=TY8paCK9AY_MSZsb9aIA:9 a=EXS-LbY8YePsIyqnH6vw:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-03-09_05,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 bulkscore=0 lowpriorityscore=0 adultscore=0 suspectscore=0 spamscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603090182 Content-Type: text/plain; charset="utf-8" EUD functions by presenting itself as a USB device to the host PC for debugging, making it incompatible with USB host mode configurations. 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 is achieved via the exported qcom_eud_usb_role_notify() API that allows the USB controller driver to notify EUD of role changes. This ensures consistent state management without creating conflicts between the EUD debug hub and the USB controller. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 110 ++++++++++++++++++++++++++++++++++- include/linux/usb/qcom_eud.h | 21 +++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 include/linux/usb/qcom_eud.h diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 3a71a0d27b5e..e01605e1dac8 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -12,11 +12,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include =20 #define EUD_REG_INT1_EN_MASK 0x0024 @@ -42,11 +44,14 @@ struct eud_chip { struct phy *phy[EUD_MAX_PORTS]; void __iomem *base; phys_addr_t mode_mgr; + /* serializes EUD control operations */ + struct mutex state_lock; unsigned int int_status; int irq; bool enabled; bool usb_attached; bool phy_enabled; + bool eud_disabled_for_host; u8 port_idx; }; =20 @@ -142,17 +147,43 @@ static ssize_t enable_store(struct device *dev, const char *buf, size_t count) { struct eud_chip *chip =3D dev_get_drvdata(dev); + enum usb_role role; bool enable; int ret; =20 if (kstrtobool(buf, &enable)) return -EINVAL; =20 + guard(mutex)(&chip->state_lock); + /* Skip operation if already in desired state */ if (chip->enabled =3D=3D enable) return count; =20 + /* + * 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-enabl= ing + * when exiting host mode. This respects the user's explicit disable requ= est. + */ + if (!enable && chip->eud_disabled_for_host) { + chip->eud_disabled_for_host =3D false; + chip->enabled =3D 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 conflict= s. + */ + role =3D usb_role_switch_get_role(chip->role_sw[chip->port_idx]); + if (role =3D=3D USB_ROLE_HOST) { + dev_err(chip->dev, "Cannot enable EUD: USB port is in host mode\n"); + return -EBUSY; + } + ret =3D enable_eud(chip); if (ret) { dev_err(chip->dev, "failed to enable eud\n"); @@ -353,6 +384,75 @@ static int eud_parse_dt_port(struct eud_chip *chip, u8= port_id) return 0; } =20 +/** + * qcom_eud_usb_role_notify - Notify EUD of USB role change + * @eud_node: Device node of the EUD device + * @phy: HSUSB PHY of the port changing role + * @role: New role being set + * + * Notifies EUD that a USB port is changing roles. EUD will disable itself + * if the port is switching to HOST mode, as EUD is incompatible with host + * mode operation. This API should be called by the USB controller driver + * when it switches the USB role. + * + * The PHY parameter is used to identify which physical USB port is changi= ng + * roles. This is important in multi-port systems where EUD may be active = on + * one port while another port changes roles. + * + * This is a best-effort notification - failures are logged but do not aff= ect + * the role change operation. + */ +void qcom_eud_usb_role_notify(struct device_node *eud_node, struct phy *ph= y, + enum usb_role role) +{ + struct platform_device *pdev; + struct eud_chip *chip; + int ret; + + if (!of_device_is_compatible(eud_node, "qcom,eud")) + return; + + pdev =3D of_find_device_by_node(eud_node); + if (!pdev) + return; + + chip =3D platform_get_drvdata(pdev); + if (!chip) + goto put_dev; + + mutex_lock(&chip->state_lock); + + /* Only act if this notification is for the currently active EUD port */ + if (!chip->enabled || chip->phy[chip->port_idx] !=3D phy) { + mutex_unlock(&chip->state_lock); + goto put_dev; + } + + /* + * chip->enabled preserves user's sysfs configuration and is not modified + * during host mode transitions to preserve user intent. + */ + if (role =3D=3D USB_ROLE_HOST && !chip->eud_disabled_for_host) { + ret =3D disable_eud(chip); + if (ret) + dev_err(chip->dev, "Failed to disable EUD for host mode: %d\n", ret); + else + chip->eud_disabled_for_host =3D true; + } else if (role !=3D USB_ROLE_HOST && chip->eud_disabled_for_host) { + ret =3D enable_eud(chip); + if (ret) + dev_err(chip->dev, "Failed to re-enable EUD after host mode: %d\n", ret= ); + else + chip->eud_disabled_for_host =3D false; + } + + mutex_unlock(&chip->state_lock); + +put_dev: + platform_device_put(pdev); +} +EXPORT_SYMBOL_GPL(qcom_eud_usb_role_notify); + static void eud_role_switch_release(void *data) { struct eud_chip *chip =3D data; @@ -374,6 +474,8 @@ static int eud_probe(struct platform_device *pdev) =20 chip->dev =3D &pdev->dev; =20 + mutex_init(&chip->state_lock); + /* * Parse the DT resources for primary port. * This is the default EUD port and is mandatory. @@ -418,8 +520,14 @@ static void eud_remove(struct platform_device *pdev) { struct eud_chip *chip =3D platform_get_drvdata(pdev); =20 - if (chip->enabled) + platform_set_drvdata(pdev, NULL); + + mutex_lock(&chip->state_lock); + if (chip->enabled) { disable_eud(chip); + chip->enabled =3D false; + } + mutex_unlock(&chip->state_lock); =20 device_init_wakeup(&pdev->dev, false); disable_irq_wake(chip->irq); diff --git a/include/linux/usb/qcom_eud.h b/include/linux/usb/qcom_eud.h new file mode 100644 index 000000000000..57e86056303c --- /dev/null +++ b/include/linux/usb/qcom_eud.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __LINUX_USB_QCOM_EUD_H +#define __LINUX_USB_QCOM_EUD_H + +#include + +#if IS_ENABLED(CONFIG_USB_QCOM_EUD) +void qcom_eud_usb_role_notify(struct device_node *eud_node, struct phy *ph= y, + enum usb_role role); +#else +static inline void qcom_eud_usb_role_notify(struct device_node *eud_node, = struct phy *phy, + enum usb_role role) +{ +} +#endif + +#endif /* __LINUX_USB_QCOM_EUD_H */ --=20 2.34.1