From nobody Mon Feb 9 10:12:39 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 5B5F6311C1D for ; Mon, 26 Jan 2026 23:38:38 +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=1769470720; cv=none; b=EoTHhiUcjYdMwpMmZ2sOfcTqxt2cOtW5YAZZBGyvqqdGIDrhfzMDWGdaiiQQqsUsU1GPMr36O2IaG0dnw5lf9+ehQxFLUVB6F2AH+b8xQolPxMCiPxbXNT/BTA7ERgeqPwWKGUl2zKdWNi3L/qvWOFlL/QFO1gYo8IcHF9LaYzU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769470720; c=relaxed/simple; bh=8QuxfXdYRJcE3fyNR6NyT4XaseLCItGHgJZH0P+Yloc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UnGZAyzGZO8hG3zODizzpJLhQWmK7OGF0JjOBYQOWRPCW8FpfGfCSqetq6eWUc4al87yiaAXFSL890pfFPg2U8lFreo0pEyDqpOtcKPha87aPN1YCG0SZM+F7Pe0E+WpH2wH+42DqujJRIzAY5jKbKborOmLgIMKToj8CdHJMmM= 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=pLeeNpmo; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=ZQ7caOR+; 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="pLeeNpmo"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="ZQ7caOR+" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 60QKgZ302943058 for ; Mon, 26 Jan 2026 23:38:37 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=VKaYciJerw3 mJBDnc7jGWgSPFPx7Co7DTR1b7g2zoXc=; b=pLeeNpmojZkTBxn5u7o150Eu3z6 4cxiNJIl7nDThgv6WeYvyZ56HyNhHb5vhn4FnTh1z1HA80y13PSPg0JM3OCWd0Km QzwaHjU3l5GH8C2qNqCBGAS+M+wmJAQuV+Z20BrM8WvmrIqZN6ji28hZHIe2A973 oRzbulbsqb9Im8aRDzD7DUYFf7q29Yks1nJeg/XLBu4MCGuzn2DTjNDxpO7nDjgB o5jVMHSQTUXgZ1V+sJkHntznhijIfKAnGi67QKSuGLm77qz/TLZSxHSpqSaA35CN DHJKTqfarnTrbx8RI9crgVTHrfl5MO0QynwADyl/XgMVhRjYb6dXsaoW5bA== 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 4bx2682ub7-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 26 Jan 2026 23:38:37 +0000 (GMT) Received: by mail-dy1-f200.google.com with SMTP id 5a478bee46e88-2b71c5826fbso5335343eec.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=1769470716; x=1770075516; 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=VKaYciJerw3mJBDnc7jGWgSPFPx7Co7DTR1b7g2zoXc=; b=ZQ7caOR+g5CBQPFASca3Qbku61HvR0bnS0hqqT3MbpxbReTrl+gAH9nREveaOjyqg6 n5fyN+i9hTSGi0ata4F11hmdTqUZ+fvLFzU14ju0y9Sqo+1T/QoUSlzXJgbB1mhsxbMI sswtdvsqKGk/2AyOVXoVCiZo71jQ/u5dh5TTaz2ZUWDKvX8kVL8wmMwpr2BIjQ8IGVcl OkMpuVAOY9hvg7rjcT0ckUGt2//prftYmgOKa/Ek2ILTEPR7o8iki7lthlxFKR/hqEF2 oPXIxga3RiQ1HubVlkNaugN4fZ7UPxWXMPsMnGKDD8hQcRJMQ8Zx06xUkU3SASJsDJ1z utDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769470716; x=1770075516; 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=VKaYciJerw3mJBDnc7jGWgSPFPx7Co7DTR1b7g2zoXc=; b=uISEUW5sy+sTrFwPIHwlXLG4kWz+cB2xp9Jkzi0hYy7WcmmbxcDF0zPvHnFiIln+JB 6bO9tnK3PC52B2Y+68iQcZH8Qo29RU+JjTHfE0cdcxzCLL9INKqdDLPxz8364XEukOyV ha9Fawycu6BNb0lWClG8RX7bOm3VQhbq1UnyatWMZ08ujlGUtRtwTu5kQreknznPnxvo wygEPfu2sLLQc5oXWHAtLzcXAMvDxtMd6aHcaaewKNMX133+ZbxoGddzgjiE/Se3Vxjl W/SsAzhDX2QiJyaOXz1jmvKNJ5hJz4a0G9z8jWcTpXX+/kvWeWtANi3GTNBcYfmZTh3P W07Q== X-Forwarded-Encrypted: i=1; AJvYcCVMs3HAO+8NuG5AVQBOpED0b2Nwoq3lRmR2cVMG6he7ekRUSPck1SU/Ih1sFSFc0uujEQGQXde90faaDR4=@vger.kernel.org X-Gm-Message-State: AOJu0YysQQYExvh7lv6WhcnPz1Uxr4xeHbMfvxdIG+5ghV4HaIHsYL6O wbuvXotUg1t+T6jc9ksl7tBUrB7UlGpa1Nn1szHEnd9YthvSsRXU7Yy3ZTCJFcr9xnDTKSPg/5j BT1bV+tx4CvFrSZB9Hvb/reQjHOsCLZFbtdipJvtJaBUqZVflVjFfW8lgB7xhI8MsJtM= X-Gm-Gg: AZuq6aLCrkJTkGcwjAMRsth7V9yKutYYIrNTQwEkJ7pRbHZlsTOvHqUc60jUe3oG+M+ SQE9T/Pn+3lxzdvJ8sjT9pMoztwrqoILdsr39ys0d1ORwiMS21QsAjocHK58CIWMpzPBIx+yMF8 aAL7U3VKAayyqtq0Iw8EOv7PdH9xa1AQ6gN4+IutklwVdpPFGDvzUqksrrUeS8Gym4t2o5+R1Ty vf/GueBhv1EtPulWw5e7J+lKyBo+Zda1tx25nrT011z2Xy6DibgbLLjxv2tVUxFjnBdyeqpFTUD VAwjdxFuNiN9MGuQoSv35RCVFt5Kyu7dz5UgoyBj7sufJW1rkMo8TffBG1GEmGq8DvQHzY+8MVZ DXmahxTvAkJHQw4q1Rpu3arDbVp+ZLz9/+iIthM4eImUp4N+eolRzbJnQuZLlv1o= X-Received: by 2002:a05:7300:cb15:b0:2ae:59d3:46d3 with SMTP id 5a478bee46e88-2b7644f9a2amr3597643eec.25.1769470716063; Mon, 26 Jan 2026 15:38:36 -0800 (PST) X-Received: by 2002:a05:7300:cb15:b0:2ae:59d3:46d3 with SMTP id 5a478bee46e88-2b7644f9a2amr3597615eec.25.1769470715403; Mon, 26 Jan 2026 15:38:35 -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.34 (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 4/9] usb: misc: qcom_eud: add per-path role switch support Date: Mon, 26 Jan 2026 15:38:25 -0800 Message-Id: <20260126233830.2193816-5-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-Authority-Analysis: v=2.4 cv=bIEb4f+Z c=1 sm=1 tr=0 ts=6977fafd 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=_OGk7KolV25BrENr9Q4A:9 a=6Ab_bkdmUrQuMsNx7PHu:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTI2MDIwMiBTYWx0ZWRfXzEEk/XfyXgAC j6PD6GcewyA7T1RVrZx1ADY/yj18XJCWv7IJGSeVojlLfb6z84FerL2B0cCU6UovHO8mkkFbqYa w+j+5XENlPd0HwKCo9HwL40UlSLitGz0XW6Xv+zQqJscNDnmMNKtU3ceMMxqNFCoMVMhLkj5V+A 5gcvz9wDZxEwzlx5pUYVr8jVjq54x3iJZl6K93pL4s7Tdz+ztLwxNaPeIUxAgb05EuTNcnn+gm0 7idrpE+bEFDLILUH5gFUDaGns91ZkprytSvrqMp2150TpT3UFFPlr7HwKTAD+nSG+46AVvuronz bMDRvlp1BU9iQls5m0xKfccYrVD+x+nT1iLQPk6ETz9kFFrYhfQmmj5qoVLneeKpQFS8JL5s90k txRt0KU4lR6VPeyYURgFtYOX8OGJ4nH03JtK9eRRLJoZqHcLmkQzt7R2G+PJk965jHj2avmK7S2 xgNpNWjLmGYkSmSs8fQ== X-Proofpoint-ORIG-GUID: owkFobBJcVG7qlf45SM5Q9Zv2s8Co-Bo X-Proofpoint-GUID: owkFobBJcVG7qlf45SM5Q9Zv2s8Co-Bo 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 bulkscore=0 lowpriorityscore=0 malwarescore=0 priorityscore=1501 clxscore=1015 spamscore=0 impostorscore=0 suspectscore=0 adultscore=0 phishscore=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" The EUD hardware can support multiple High-Speed USB paths, each connected to different USB controllers. The current implementation uses a single chip-level role switch, which cannot properly handle multi-path configurations where each path needs independent role management. Since EUD is physically present between the USB connector and the controller, it should also relay the role change requests from the connector. Restructure the driver to support per-path role switches and remove the chip-level role switch. Additionally, as EUD need not modify the USB role upon enabling, remove the unnecessary role switch call from enable_eud(). Signed-off-by: Elson Serrao --- drivers/usb/misc/qcom_eud.c | 80 ++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/drivers/usb/misc/qcom_eud.c b/drivers/usb/misc/qcom_eud.c index 5cebb64f4a67..a58022f50484 100644 --- a/drivers/usb/misc/qcom_eud.c +++ b/drivers/usb/misc/qcom_eud.c @@ -38,12 +38,15 @@ struct eud_path { struct eud_chip *chip; struct phy *phy; + struct usb_role_switch *controller_sw; + struct usb_role_switch *eud_sw; + enum usb_role curr_role; + char name[16]; u8 num; }; =20 struct eud_chip { struct device *dev; - struct usb_role_switch *role_sw; void __iomem *base; struct eud_path *paths[EUD_MAX_PORTS]; phys_addr_t mode_mgr; @@ -129,7 +132,7 @@ static int enable_eud(struct eud_chip *priv) writel(EUD_INT_VBUS | EUD_INT_SAFE_MODE, priv->base + EUD_REG_INT1_EN_MASK); =20 - return usb_role_switch_set_role(priv->role_sw, USB_ROLE_DEVICE); + return 0; } =20 static int disable_eud(struct eud_chip *priv) @@ -287,15 +290,21 @@ static irqreturn_t handle_eud_irq(int irq, void *data) static irqreturn_t handle_eud_irq_thread(int irq, void *data) { struct eud_chip *chip =3D data; + struct eud_path *path; int ret; =20 + path =3D chip->paths[chip->port_idx]; + if (!path || !path->controller_sw) + goto clear_irq; + if (chip->usb_attached) - ret =3D usb_role_switch_set_role(chip->role_sw, USB_ROLE_DEVICE); + ret =3D usb_role_switch_set_role(path->controller_sw, USB_ROLE_DEVICE); else - ret =3D usb_role_switch_set_role(chip->role_sw, USB_ROLE_HOST); + ret =3D usb_role_switch_set_role(path->controller_sw, USB_ROLE_HOST); if (ret) dev_err(chip->dev, "failed to set role switch\n"); =20 +clear_irq: /* set and clear vbus_int_clr[0] to clear interrupt */ writel(BIT(0), chip->base + EUD_REG_VBUS_INT_CLR); writel(0, chip->base + EUD_REG_VBUS_INT_CLR); @@ -303,15 +312,45 @@ static irqreturn_t handle_eud_irq_thread(int irq, voi= d *data) return IRQ_HANDLED; } =20 +static int eud_role_switch_set(struct usb_role_switch *sw, enum usb_role r= ole) +{ + struct eud_path *path =3D usb_role_switch_get_drvdata(sw); + int ret; + + /* Forward the role request to the USB controller */ + ret =3D 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 =3D role; + + return 0; +} + static void eud_role_switch_release(void *data) { struct eud_chip *chip =3D data; + int i; =20 - usb_role_switch_put(chip->role_sw); + for (i =3D 0; i < EUD_MAX_PORTS; i++) { + struct eud_path *path =3D chip->paths[i]; + + if (!path) + continue; + + if (path->eud_sw) + usb_role_switch_unregister(path->eud_sw); + if (path->controller_sw) + usb_role_switch_put(path->controller_sw); + } } =20 static int eud_init_path(struct eud_chip *chip, struct device_node *np) { + struct usb_role_switch_desc role_sw_desc =3D {}; struct eud_path *path; u32 path_num; int ret; @@ -342,6 +381,32 @@ static int eud_init_path(struct eud_chip *chip, struct= device_node *np) =20 chip->paths[path_num] =3D path; =20 + path->curr_role =3D USB_ROLE_NONE; + + if (!of_property_read_bool(np, "usb-role-switch")) + return 0; + + /* Fetch the USB controller's role switch */ + path->controller_sw =3D fwnode_usb_role_switch_get(of_fwnode_handle(np)); + if (IS_ERR(path->controller_sw)) + return dev_err_probe(chip->dev, PTR_ERR(path->controller_sw), + "Failed to get controller role switch for path %d\n", + path_num); + + /* Create a role switch */ + role_sw_desc.fwnode =3D of_fwnode_handle(np); + role_sw_desc.set =3D eud_role_switch_set; + role_sw_desc.driver_data =3D path; + snprintf(path->name, sizeof(path->name), "eud-path%u", path_num); + role_sw_desc.name =3D path->name; + + path->eud_sw =3D usb_role_switch_register(chip->dev, &role_sw_desc); + if (IS_ERR(path->eud_sw)) { + dev_err(chip->dev, "Failed to register EUD role switch for path %d: %ld\= n", + path_num, PTR_ERR(path->eud_sw)); + return PTR_ERR(path->eud_sw); + } + return 0; } =20 @@ -359,11 +424,6 @@ static int eud_probe(struct platform_device *pdev) =20 chip->dev =3D &pdev->dev; =20 - chip->role_sw =3D 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 =3D devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip= ); if (ret) return ret; --=20 2.34.1