From nobody Mon Feb 9 16:13:09 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.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 46EF430FC08 for ; Mon, 26 Jan 2026 23:38:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769470719; cv=none; b=HbY4POOcQSOEdPgTwMxfau450/hWgvJzWo+x20qfysJa6Akac6rkSDXCQh59rjD2wBWVt3Qt0m8kYLeC9bkkB/24KEx37qJ2aXkgby+sFK+bwMwY+87OZBjrKOKwwOJowmOLzRTaGi4HcN5NVZNONYDcyT93S3lEI2lVNa63z5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769470719; c=relaxed/simple; bh=5phvMczW78qApnyZMBz0Y6XZX66r7Hm9w2Slz3QFyWs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ADVaW/Vn0DkSnzLwnPL00cUncPC4c5eYmQNjDaxyF8H06TBtCcdDCzFjSWnWrwW0Rmj0KQhiVVrgcPUocY3Ief/ry/Vb5ip2AYlJ3Vsr60mfrs/H3oA4oN0A/awHkSLf0/NiEBYVJAvj2p0gpkWnxvEdM6wNLzgi8CXTMfhja0U= 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=ePVjyov4; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=HfLHNtx2; arc=none smtp.client-ip=205.220.180.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="ePVjyov4"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="HfLHNtx2" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 60QKgcPD286903 for ; Mon, 26 Jan 2026 23:38:36 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=e+sGwixJamM 1RIjCRMV4pknYrlBFL8y0TztEEJmTrNE=; b=ePVjyov4p+J8zRQWfrg2h2VQo2B 6ZZBa5DhPNlZUtrrj+6OKmM9QkyTljxO/jgChgxwQvbMUdcpXeuFmWFEVkvIEYxm hMPH7vDfHpwsaue7ZBTelDLUxsOarWYDeYiiag26WtqqgpZuYR/NG6+5ULE2aD0D faeB3k/2aI2e4JjIDPBiuBu0KS7JBwSs24syOVhlF9SQ53pVkiUIpF4UOhcdDv9k LsMm2OWsuJQEIppd4RR+voRLeX6d/jeO2BhyUjG2IARyFzSkAHP21toIc2IN4GVo aor0HpXpnLM9zvvLkmF3TvQEyl/4zmgKMJvmKlF0/a1+JM8qCMvTbEnyolA== Received: from mail-dy1-f200.google.com (mail-dy1-f200.google.com [74.125.82.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bxdva0qyd-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 26 Jan 2026 23:38:36 +0000 (GMT) Received: by mail-dy1-f200.google.com with SMTP id 5a478bee46e88-2b70d8095daso4787633eec.1 for ; Mon, 26 Jan 2026 15:38:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1769470715; x=1770075515; 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=e+sGwixJamM1RIjCRMV4pknYrlBFL8y0TztEEJmTrNE=; b=HfLHNtx2XXKP7mFlZg6W7e4VG7lXdZ4iwHS3Ys3XuxMSLnwBWmcGp+xwFns4slo+iG b8+bTZrQqExQUToKzJVYVlSZJvaxyfY3Yng+kPEGnLcKlxCc+TzV2OWDXeEkRX6s2Sp8 W4tw1aYbENk1HR0q65K7e1bhEy7eOJV53/wzc6KHk3NdOqfSAttDFNNWwPh/9HuAnH8t kUMQ6dUzeserNOtTAIaEL5HlIiTizxnL5Bc5MvC1CUNhPhw2miGNiE+9zYb2PhC66yO1 u7xWkJlggzfUEeeTAoQck0aI/QSPRKwjcJy8zUDz/92OTl7y+bG7WnW8jWG675KkaXYO CALA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769470715; x=1770075515; 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=e+sGwixJamM1RIjCRMV4pknYrlBFL8y0TztEEJmTrNE=; b=WKsEZP1v1jc7C0WxAGXfp1/dYLDGOCB+q1DL4hbhATeeATNFvEqh/Yviti4DreRRgA gOelbX4RqQljKn0YPI8WLCVLbKHgm2xFDqTlAzpYHVf9mvcP5FrCNRM+OessCI9jleye lWaS0/o43BuSdOXk+XtcKYGJPz0GtrWbofWcRA80YDF5VAAIyMLCTgpkBTxV2LGir2mS zHubUfnsKAajhm4+FY6HU9+gt//c/QWQT4zbiH0cN0J52Ln/FZ5UEu6Dmw+oBwShIyBs 34eVZrmxXxx9g90NLarvSuvCOmh2GLrM4GBVxl62SdkoWeagO5pQVv/10w2MDFoIhiJQ iArg== X-Forwarded-Encrypted: i=1; AJvYcCXsQSyIdP5DbdRz0P+YfRq59VkLO5NRTgBcqeXvW4Ywvpk4EToEMor43jAHToGp3WbTkQDJcQEJKDvdMXI=@vger.kernel.org X-Gm-Message-State: AOJu0YxvnGdkx3zPdEHxAi1eyJEUMCGdjFlYPNSy6zgZ9FGMfbIRBX8o gQEfUzsrH+VqYT77DAQ5rtVISTL1u0s6OHvCeV7QNaUdwHbKAer7h/my89z+q2AR/xkGoVH0EoH V1hZjm2PSCTa0qs/PILpu6P9hDB1CksdZ5y7mSSdRbjaig7yEAeWeZoA6NMKIh/BaHC0= X-Gm-Gg: AZuq6aInOHDlmOpA3qCFLYhK4zWpRa5OBhK1R3GlMB5s8vlznfvAroKkDWU22ZHAPM5 0NX6wbyI3Glkteojb0Zj64cEyYGt3FuPj8SiRu4BSO1XnLDh5j+GCtmsIAKrQdX7sniMO/+L/0A BMefStIrGjffozq3GXqqkgWFYhsZPY4q1Q0E9ouMDPUUn3ZyXR7Iad7VkuXXSHAE8IzLo+IqpKd znFvpIsMc4IRMGtLlmLt8hL2OhsocUl+q96mFEqMmtiWixzNKS4Lfwm/QLGTgUNWNx8eIumYDrP fU0GqbxqPo0TdCzmkfpg0He8fvvfw6AxNwqvaJxhqvOfUenBlOr5xNJQ1vjqikHTpWH2GKkytLm ODUPLmBl4BWQe/9INrlv7aA8gJbMZ+k9/3+Saig15mCdNwFTVTNQqyGdpD000Vxs= X-Received: by 2002:a05:7022:2484:b0:11b:b3a1:714a with SMTP id a92af1059eb24-1248ebe982amr2761238c88.12.1769470715209; Mon, 26 Jan 2026 15:38:35 -0800 (PST) X-Received: by 2002:a05:7022:2484:b0:11b:b3a1:714a with SMTP id a92af1059eb24-1248ebe982amr2761217c88.12.1769470714569; Mon, 26 Jan 2026 15:38:34 -0800 (PST) Received: from hu-eserrao-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-1247d90ce0dsm19948967c88.4.2026.01.26.15.38.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jan 2026 15:38:34 -0800 (PST) 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 v2 3/9] usb: misc: qcom_eud: add per-path High-Speed PHY control Date: Mon, 26 Jan 2026 15:38:24 -0800 Message-Id: <20260126233830.2193816-4-elson.serrao@oss.qualcomm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260126233830.2193816-1-elson.serrao@oss.qualcomm.com> References: <20260126233830.2193816-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-ORIG-GUID: PsU8AtYMBsqnpSiRECyPBXtwxGBBKvjw X-Proofpoint-GUID: PsU8AtYMBsqnpSiRECyPBXtwxGBBKvjw X-Authority-Analysis: v=2.4 cv=I+5ohdgg c=1 sm=1 tr=0 ts=6977fafc cx=c_pps a=PfFC4Oe2JQzmKTvty2cRDw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=2YOFDtW_yV4_c3kXKk8A:9 a=6Ab_bkdmUrQuMsNx7PHu:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTI2MDIwMiBTYWx0ZWRfX6OJi7ZykUCwI Pyb4kX0kS3F9K4Rw+Gy6146nAE6kQi4mfIiHhM3sSokj3K1rm8uAnXYz90SdlbFseaAx1D+4O8Q 3ii+7DuGEP668961F+p+VU8w50RvznHY4/Nh5umpzKbC4I4e/OYuPAgYPpItOsKDqQpNKIkQXsM 7n7lv4ZUIhx79nhcANXqwBMon7neExkTeCmHT1ExuEWLzGyj/vvd8JzeXvySvoU094mED7jxZgB c4j3g+9k70/kIc69oZpYiYb+ca1Ze+tBvSL5RGzR1AQP4uKkTYsoQBonM0w+Zgh0qbvxbod1igC l8j+khcleh34D7LQMDLdouDClMZnY3pc5uT1ibATfOWs/TmwzPNODmIHaqd2+rtvBsH7QTMt1HG h63oIwxFVyiZHVq+GaqOz7q6DZQ/ufbZt+Jl74lx7e07h+507aEQslwHMIJ4PZLLbBf7ArAvYsz bYV6EEwQAF0oPaSUzIQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.20,FMLib:17.12.100.49 definitions=2026-01-26_04,2026-01-26_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 adultscore=0 priorityscore=1501 impostorscore=0 lowpriorityscore=0 suspectscore=0 bulkscore=0 clxscore=1015 phishscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2601150000 definitions=main-2601260202 Content-Type: text/plain; charset="utf-8" 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 UTMI 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. Supporting this requires describing the available UTMI paths and their corresponding PHYs in Device Tree. This updates DT requirements and is not backward compatible with older DTs that lacked this description. 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. Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 130 +++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 1a136f8f1ae5..5cebb64f4a67 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -34,26 +35,96 @@ #define EUD_INT_SAFE_MODE BIT(4) #define EUD_INT_ALL (EUD_INT_VBUS | EUD_INT_SAFE_MODE) =20 +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; }; =20 +static int eud_phy_enable(struct eud_chip *chip) +{ + struct eud_path *path; + struct phy *phy; + int ret; + + if (chip->phy_enabled) + return 0; + + path =3D chip->paths[chip->port_idx]; + if (!path || !path->phy) { + dev_err(chip->dev, "No PHY configured for port %u\n", chip->port_idx); + return -ENODEV; + } + + phy =3D path->phy; + + ret =3D 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 =3D 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 =3D true; + + return 0; +} + +static void eud_phy_disable(struct eud_chip *chip) +{ + struct eud_path *path; + struct phy *phy; + + if (!chip->phy_enabled) + return; + + path =3D chip->paths[chip->port_idx]; + if (!path || !path->phy) + return; + + phy =3D path->phy; + + phy_power_off(phy); + phy_exit(phy); + chip->phy_enabled =3D false; +} + static int enable_eud(struct eud_chip *priv) { int ret; =20 - ret =3D qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + ret =3D eud_phy_enable(priv); if (ret) return ret; =20 + ret =3D qcom_scm_io_writel(priv->mode_mgr + EUD_REG_EUD_EN2, 1); + if (ret) { + eud_phy_disable(priv); + return ret; + } + writel(EUD_ENABLE, priv->base + EUD_REG_CSR_EUD_EN); writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); @@ -70,6 +141,8 @@ static int disable_eud(struct eud_chip *priv) return ret; =20 writel(0, priv->base + EUD_REG_CSR_EUD_EN); + eud_phy_disable(priv); + return 0; } =20 @@ -132,6 +205,12 @@ static ssize_t port_store(struct device *dev, if (port >=3D EUD_MAX_PORTS) return -EINVAL; =20 + /* Check if the corresponding path is available */ + if (!chip->paths[port]) { + dev_err(chip->dev, "EUD not supported on selected port\n"); + return -EOPNOTSUPP; + } + /* Port selection must be done before enabling EUD */ if (chip->enabled) { dev_err(chip->dev, "Cannot change port while EUD is enabled\n"); @@ -231,8 +310,45 @@ static void eud_role_switch_release(void *data) usb_role_switch_put(chip->role_sw); } =20 +static int eud_init_path(struct eud_chip *chip, struct device_node *np) +{ + struct eud_path *path; + u32 path_num; + int ret; + + ret =3D of_property_read_u32(np, "reg", &path_num); + if (ret) { + dev_err(chip->dev, "Missing 'reg' property in path node\n"); + return ret; + } + + if (path_num >=3D EUD_MAX_PORTS) { + dev_err(chip->dev, "Invalid path number: %u (max %d)\n", + path_num, EUD_MAX_PORTS - 1); + return -EINVAL; + } + + path =3D devm_kzalloc(chip->dev, sizeof(*path), GFP_KERNEL); + if (!path) + return -ENOMEM; + + path->chip =3D chip; + path->num =3D path_num; + + path->phy =3D devm_of_phy_get(chip->dev, np, NULL); + if (IS_ERR(path->phy)) + return dev_err_probe(chip->dev, PTR_ERR(path->phy), + "Failed to get PHY for path %d\n", path_num); + + chip->paths[path_num] =3D path; + + return 0; +} + static int eud_probe(struct platform_device *pdev) { + struct device_node *np =3D pdev->dev.of_node; + struct device_node *child; struct eud_chip *chip; struct resource *res; int ret; @@ -252,6 +368,18 @@ static int eud_probe(struct platform_device *pdev) if (ret) return ret; =20 + for_each_child_of_node(np, child) { + ret =3D eud_init_path(chip, child); + if (ret) { + of_node_put(child); + return ret; + } + } + + /* Primary path is mandatory. Secondary is optional */ + if (!chip->paths[0]) + return -ENODEV; + chip->base =3D devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chip->base)) return PTR_ERR(chip->base); --=20 2.34.1