From nobody Sat Sep 26 05:35:54 2026 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B65EC46AEF4 for ; Fri, 4 Sep 2026 11:53:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522795; cv=none; b=as/qZx67aZuRO74OpYtKSBkR2Z/6qOsknR8bJBCl3IEonBqmF1HYC/xxEBJT5Cp/saYA+RGVrU+slV0+IV/daDwlPLeoWTJE6Q5gT4YK9Eq3woORWyZOivisYh6+RsBLg5EwQQavKZB+biHPmz7s16mt8ruUkghJgTkUpsWVYqk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522795; c=relaxed/simple; bh=SScZXkbAnXgnt8nSkpe9dZOfqBXgsPZesshLBsUkf8E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nE9f85+1S9e2JqrrnZxVd8/5iTdibarM+vI8qvuKMlgOplTXME7Gncj5TUbHIeoRR6D59uQ7J3ywWSla2d3bmE3PPFVlRLIh+fI5yfUS+dFwuKbrt8KGDb5O154N2jzmJpD5f2ZTvHg5TD56rXZhXBCNCKsd62Y89fHMJD0VSOc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=zR9taRaz; arc=none smtp.client-ip=209.85.221.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="zR9taRaz" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-48441a2ba1bso577820f8f.1 for ; Fri, 04 Sep 2026 04:53:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1788522785; x=1789127585; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=0Gn3T5GKQVsKNu5CjSN12Pg6Gz0nGtd35pevkWP3bfA=; b=zR9taRazJnaPqXzNK6lv6wXtMcHKShcA8UM3tO+bQiF6sx9C1GelPm17hU1hc+wN+l twBmYU/2pcU/M2N3yuK27qzjxWMnkarz1eC3iPV1QW2E6YyNuV7TEPcftkWZKqu3IYMw oz12HtEGKDDSmWw5YxY3GC0Kz5XE9NNp62/ljlT34PLQbFDiSgUoAAf2LTD+eOiTCWTz rX+3FwczaWpQyBOi5kqabtkFymUg/HcPIhJnOvuAfetApSmWaMrqjN7UjUEbBs9Upoto iJeBcxkZAF+7Wz+krlfkWLuwR7ihE5gPln1rKeNj8m6Fi12h+u5XZCXnxHS6lnuNt6jW p5cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788522785; x=1789127585; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=0Gn3T5GKQVsKNu5CjSN12Pg6Gz0nGtd35pevkWP3bfA=; b=aI7+QIKX9ZklIiibwzmvTVgYhSWJGd+0X4QJw5ooOPNvByYR3aeWX9qVtSzAwb3x/U TkxkmCI5JgA1xoOHcONCFG9wzFcr3IbU3T9QQ5diA0H/NLZinlwTFB1sOuTmVaKkHg/0 N3sJ1XTWm7AMJhhwsSl/7074No5Swes0MjGe1lxOTvOJ8bKZ4l3VrVNN2llhvRdkn6KX maDP0G8N3EmHLWd7soWf6IgdnJXgd28XYrmCZr5Pp18e2OxnuF0vCPlPVuEu4QsMRXBz AIvbyG4cHiMUiIua9z72uwvZJDbjCw1RfO2vKZ9raikJA8uyK+UKL2mIxXicw3USj0q6 FJpA== X-Forwarded-Encrypted: i=1; AKwUvBy1BSokA8ZloQ+A/YaVgEOKmQ/f1st1CcAGSL9/+F4LTdJrYcXY2HY/s1uOquwiJfprZ1YrcuuvYvD11Xw=@vger.kernel.org X-Gm-Message-State: AFuF++ngkSEHvQDYC1JuPGCOAVVbRNtpb1O433OaslkS2kHzmagYfHkM lGFSfIpZQcVtWoUo+/AjxhsRJQkoxYwS41NQG3YY1zXMQYNcjcbRnOYeSBsxkX8SBXg= X-Gm-Gg: AYBFou1d1k3MqQEG2Fv/eb/Xo/c9kCltFTwCmeREyvbJ4OSQ45Pl6EfBJZK2aVH1hBR 1APxXidzIDpr9MoAVLgztsVabvnUxKRnSdQj7CJX3LRZkvwjpf3CS6MaY7Q7Cyeb/UU00j599XP 5Fz04ewHUWODefAKkf9i8HElwVmP4fUV67wv/8VpmsWTeXE5vyUpNBH+GC8ESHTHVD+NZCXctYa /se5q17DNCy2a6+ZCckAWmXDZCHNvQ6alT2wDKEoaFVVk3AQeWsGCSct1lAnYIK23z752/6HoVy x+xTEwHDeO2HOuWedGGUjLoCZHqz4d3WNPGNyJlVn2nTyR5N0LOuvM3qce8SZT7nSis1F3l2Ieu 36gVX1eSIs8f4SvG5iGT2Ze2TG0u9NRDhU2rhmstLO2pEDv7VWpezyU0yO7E5v18JHj1Dmo1xtF U5wBn8hYOBhU3KmeYpLh+fivzRegsyeIZHiAud2JyfthHjdpiW/nlHO1AYSMA67CyAGm6PyiIC X-Received: by 2002:a5d:5d02:0:b0:485:8c16:a35a with SMTP id ffacd0b85a97d-4858c16a5f9mr2923096f8f.50.1788522785044; Fri, 04 Sep 2026 04:53:05 -0700 (PDT) Received: from [192.168.0.35] ([109.76.237.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-485885c5bbdsm5474207f8f.36.2026.09.04.04.53.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Sep 2026 04:53:04 -0700 (PDT) From: Bryan O'Donoghue Date: Fri, 04 Sep 2026 12:52:58 +0100 Subject: [PATCH v15 1/4] phy: core: Fix use-after-free in phy_get paths Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-1-68b7916e7a3f@linaro.org> References: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> In-Reply-To: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> To: Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Robert Foss , Todor Tomov , Mauro Carvalho Chehab , Konrad Dybcio , Vladimir Zapolskiy , Bryan O'Donoghue , Loic Poulain , Vinod Koul , Neil Armstrong , Greg Kroah-Hartman , Kishon Vijay Abraham I , Felipe Balbi Cc: linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-phy@lists.infradead.org, Bryan O'Donoghue , Krzysztof Kozlowski , stable@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5238; i=bryan.odonoghue@linaro.org; h=from:subject:message-id; bh=SScZXkbAnXgnt8nSkpe9dZOfqBXgsPZesshLBsUkf8E=; b=owEBbQKS/ZANAwAKASJxO7Ohjcg6AcsmYgBqmrEcRRwG+Yi5Zk7Lrt1BMPnkhCjlvn3VMIIzK BkC/hH62jGJAjMEAAEKAB0WIQTmk/sqq6Nt4Rerb7QicTuzoY3IOgUCapqxHAAKCRAicTuzoY3I OkyVD/0ZJAcLsU1XsHqDMb70c/J8/RnY0iJ9KDXjiaBsC/hPi9OkMLpMqpeEtVnj7y0MwZcxpk5 7cxvGhdk+2/L/wsH0HmD4l2eyJxJMPVMq15Xs7ulS9X0vpdW/o3574Xvz9MOlv+0Ki0Thd+zY9q GVeVe06Kk07GJfs1VdpgGL9GyPUp+OWKFQML0FoFVsqPdzPRRvR3mTrBtneZdtVBHAPjIyjIjoY THd+0ouYoS3lEzLQ99nxkH/Z6QBDTKv9qG4z3vEivXxMYr6u0CLgDCYbDskyClUsbX5VOoAbafl TD8XcA3D/9EaODdsLayLeRNm4/auXmijSKatzdRMPVbunt6MfaRDz8lZ7r1ZakxZwN1PUV6Eauh XS3RrvnowEhIvrpNQ959rX+CgdUYDqzz1kq3B7B+Qco+ZOkCb1PRY1dUljE8u/AaAr3hmFcHj3l dH2pyfko9J8zQRF9lhu73sPgt2HhZ6uiDE6IF4aga+VnoBr2h7QCAW3E1vY6o13ESssUcnzVWv/ kDO5G6IWlmxOYy25fR03muU+1a2cEoEspMfQGk+vWKvFZEP5ih9cO1xq+5+fkwVnkMVlLlVVJSI MO9S57sgq8Rh5beNrNPCQxX6ot9+4BWV/0/YfdFjw/d6U8+96RV3pSX4r+wYcDgTC5NNu1J3kZT SiBA0RjaoV1GKGw== X-Developer-Key: i=bryan.odonoghue@linaro.org; a=openpgp; fpr=E693FB2AABA36DE117AB6FB422713BB3A18DC83A Sashiko asked during a patch review if the existing usage pattern had a race condition; specifically in of_phy_get() if it was possible between returning from _of_phy_get() and running try_module_get() that a module might be unbound leading to use-after-free. Looking at the code this appears to be so, there is no linkage between the phy and module under a synchronisation primitive. Using the phy_provider_mutex in phy_get() will ensure there is a link betwe= en the returned phy pointer and the module_get() bumping the module reference count. Amend phy_get(), of_phy_get() and devm_of_phy_get_by_index() to fix the same usage pattern. phy_provider_unregister() must take the phy_provider_mutex so amending phy_get()/of_phy_get() to take that same mutex guarantees there is no use-after-free. Fixes: ff764963479a1 ("drivers: phy: add generic PHY framework") Cc: stable@vger.kernel.org Signed-off-by: Bryan O'Donoghue Reviewed-by: Loic Poulain --- drivers/phy/phy-core.c | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 21aaf2f76e53e..89addd732bff3 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -124,13 +124,13 @@ static struct phy *phy_find(struct device *dev, const= char *con_id) const char *dev_id =3D dev_name(dev); struct phy_lookup *p, *pl =3D NULL; =20 - mutex_lock(&phy_provider_mutex); + lockdep_assert_held(&phy_provider_mutex); + list_for_each_entry(p, &phys, node) if (!strcmp(p->dev_id, dev_id) && !strcmp(p->con_id, con_id)) { pl =3D p; break; } - mutex_unlock(&phy_provider_mutex); =20 return pl ? pl->phy : ERR_PTR(-ENODEV); } @@ -624,6 +624,8 @@ static struct phy *_of_phy_get(struct device_node *np, = int index) struct phy *phy =3D NULL; struct of_phandle_args args; =20 + lockdep_assert_held(&phy_provider_mutex); + ret =3D of_parse_phandle_with_args(np, "phys", "#phy-cells", index, &args); if (ret) @@ -635,11 +637,10 @@ static struct phy *_of_phy_get(struct device_node *np= , int index) goto out_put_node; } =20 - mutex_lock(&phy_provider_mutex); phy_provider =3D of_phy_provider_lookup(args.np); if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { phy =3D ERR_PTR(-EPROBE_DEFER); - goto out_unlock; + goto out_put_node; } =20 if (!of_device_is_available(args.np)) { @@ -653,8 +654,6 @@ static struct phy *_of_phy_get(struct device_node *np, = int index) out_put_module: module_put(phy_provider->owner); =20 -out_unlock: - mutex_unlock(&phy_provider_mutex); out_put_node: of_node_put(args.np); =20 @@ -678,15 +677,21 @@ struct phy *of_phy_get(struct device_node *np, const = char *con_id) if (con_id) index =3D of_property_match_string(np, "phy-names", con_id); =20 + mutex_lock(&phy_provider_mutex); + phy =3D _of_phy_get(np, index); if (IS_ERR(phy)) - return phy; + goto out_unlock; =20 - if (!try_module_get(phy->ops->owner)) - return ERR_PTR(-EPROBE_DEFER); + if (!try_module_get(phy->ops->owner)) { + phy =3D ERR_PTR(-EPROBE_DEFER); + goto out_unlock; + } =20 get_device(&phy->dev); =20 +out_unlock: + mutex_unlock(&phy_provider_mutex); return phy; } EXPORT_SYMBOL_GPL(of_phy_get); @@ -786,6 +791,7 @@ struct phy *phy_get(struct device *dev, const char *str= ing) struct phy *phy; struct device_link *link; =20 + mutex_lock(&phy_provider_mutex); if (dev->of_node) { if (string) index =3D of_property_match_string(dev->of_node, "phy-names", @@ -796,15 +802,18 @@ struct phy *phy_get(struct device *dev, const char *s= tring) } else { if (string =3D=3D NULL) { dev_WARN(dev, "missing string\n"); - return ERR_PTR(-EINVAL); + phy =3D ERR_PTR(-EINVAL); + goto out_unlock; } phy =3D phy_find(dev, string); } if (IS_ERR(phy)) - return phy; + goto out_unlock; =20 - if (!try_module_get(phy->ops->owner)) - return ERR_PTR(-EPROBE_DEFER); + if (!try_module_get(phy->ops->owner)) { + phy =3D ERR_PTR(-EPROBE_DEFER); + goto out_unlock; + } =20 get_device(&phy->dev); =20 @@ -813,6 +822,8 @@ struct phy *phy_get(struct device *dev, const char *str= ing) dev_dbg(dev, "failed to create device link to %s\n", dev_name(phy->dev.parent)); =20 +out_unlock: + mutex_unlock(&phy_provider_mutex); return phy; } EXPORT_SYMBOL_GPL(phy_get); @@ -961,15 +972,17 @@ struct phy *devm_of_phy_get_by_index(struct device *d= ev, struct device_node *np, if (!ptr) return ERR_PTR(-ENOMEM); =20 + mutex_lock(&phy_provider_mutex); phy =3D _of_phy_get(np, index); if (IS_ERR(phy)) { devres_free(ptr); - return phy; + goto out_unlock; } =20 if (!try_module_get(phy->ops->owner)) { devres_free(ptr); - return ERR_PTR(-EPROBE_DEFER); + phy =3D ERR_PTR(-EPROBE_DEFER); + goto out_unlock; } =20 get_device(&phy->dev); @@ -982,6 +995,8 @@ struct phy *devm_of_phy_get_by_index(struct device *dev= , struct device_node *np, dev_dbg(dev, "failed to create device link to %s\n", dev_name(phy->dev.parent)); =20 +out_unlock: + mutex_unlock(&phy_provider_mutex); return phy; } EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index); --=20 2.55.0 From nobody Sat Sep 26 05:35:54 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93D0547F772 for ; Fri, 4 Sep 2026 11:53:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522795; cv=none; b=mcQV10oPcuweb2JH0UmvBlm7jidhTR9YxPkdMz0ZxuLW+/DXobh4m3n+beP/bYDj0NodEUZE6lnIXhnWHqNAEZ/8GDjexy8W8QhUhpO2Yj7VPYZK7zOmKlSHkNEWfHAvaHepFJi2PSYEHvC4ZrBHptj1o+sqIvyvXfZ3VDVJOME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522795; c=relaxed/simple; bh=jvWI5bCo2G0nPMiyIWWUCCvc8PV85ddqSgmXfNNkRqI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pwv6UrQcaFfWLkRzxXl4apvQuaoAsAToELS53UtyGqv6Vz2yf6zeOxRUV6rG3KGJEgKKOllzDN1PmnPScD/17650p6K/S+iJI9OkyLxVheu+KGDI9MC3XtYQS/PfF+QXTmKt79El+c3uRjYr3QZVxc526pxAsg+jFfKpM1h3dMI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=yo2lJ6dC; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="yo2lJ6dC" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-49b965570d7so10314875e9.0 for ; Fri, 04 Sep 2026 04:53:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1788522787; x=1789127587; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=P6nCQrtjn5sjZ36INdWU9AmImwt4exmEpBcYwRBKS5A=; b=yo2lJ6dCgTfbAsNuitp7U1FgvBSC/dscNy4lI6uXIOWBGvP9s5+T15IVcSFuKfRZm2 sDY35EaFD1d+socaAa2v1WEE0zRsbO+oOa7/gAi7oQSQISQUlOIbfKSRUThhknI12Y+C 5+TuYbY1rlNq0SW28Pl33qsA4i4XJ3kDYHU/Xe+SaAuCub7ObpW0+QLI82Q8Ym/LyKB6 IZHNWnH6XNjauwUfQekc9fRw2yPY0EjlI1ljqK7UVmX0oRPAz4BmCBsX2V0kvhu5PGfA 6UCUzElBBUoInSt6RzkiOzebaKCRkhxQwTWP7JZirjR+Aedmv0QuBCuQTalg9g9yamKD wC3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788522787; x=1789127587; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=P6nCQrtjn5sjZ36INdWU9AmImwt4exmEpBcYwRBKS5A=; b=XpfTKSUe9kPs4VS4ZZQ0okjdEtK/llk3nH8pEG4C/tG6kqn2Nco/mczqH5XUPL+9EP v2Wyu67dqoQalMjsuPG8ienHK64R1WFvhtC3HQT3wXG99EfDlGA8uR5Md2wKyI74n+dk wQwZ284mLvL4JJEIp0sZkuYvfXF0TXSO6tqLz2iVSNIhR0vhIPTr+S9sJOLgFgNXxOdx 1NPOVgYmlAsmLa7ulhyLXiy2tHclLmgx9+oZ1GCS27HNf931DjKxwbb/liJ/FHoEqIkm tbsqFqPbXFkjjlAH8tPX80EDoDpSnv/Kgd3Gu95I+sM2BLdfgmj/0cj5XvU1B3TGR7t2 GBAg== X-Forwarded-Encrypted: i=1; AKwUvByZGb9IyHXuGhwjA4zBCw4BPmW3xhzQT5FjqFiTIdTywiaOkARz1R0WvLrKRZ+1dDz8+9v3GexhQN6t56I=@vger.kernel.org X-Gm-Message-State: AFuF++lXrDTJhMKXo7r3qfp2KnzVs0Ja2BIbYOIBnYg37mhUBQZ74WFh rGbslwwjXW8UKpMlzGomNA7WhdTty+oVRpby3knske9HZ1P8+CgnqOpU9QEZWj9V51A= X-Gm-Gg: AYBFou28pfAVhdijBS65qKlye0/KJpaDF15USiSyf3M8wMstQs+icrD3m1lNyZtbIH3 kvWhU2zoHVBxn4qxK7DDD72ze+RiCkxpGrsc6+rKa0ALEq834DZ9i8033P9ZRUXKEXFKXfDn9Dk w+veUaNHFl9MZieZEiVG7jg4VSH4iDlJOtoVp5Djd8k9+VZ69phyHPTvvh7SkSJChE8MA2G5iej 97GbHF5jAakzKMDuH6b2wwtRV5D4n2dVyKjsW1D/1qkzbdE9WOH/etcuCDe2jcUoDZXKmQbZSHF 6F08de2M8pqJ4fNG7gE2E7MpP5HAn6/aDIlq8MbjBFxYfoAkWm6j5u1iIG6CtJWzUWf+Qcn0pMu 6y713Xq3jmLeWKY+8TdixQ9fmL7tzYGj7aovrc5qZlLU1VLu9U3FmAf3O9NdzBAbQnZKzasBv+A Qn6IXo6+GVmTRrAuQSIufxv5o50U6W3mG5hjKR35d0+u9gJNVTerKURslUgfdo9btKrzH4wpOg X-Received: by 2002:a05:600c:4fc9:b0:49c:fc6e:8cb9 with SMTP id 5b1f17b1804b1-49cfc6e8e1emr26351795e9.29.1788522786683; Fri, 04 Sep 2026 04:53:06 -0700 (PDT) Received: from [192.168.0.35] ([109.76.237.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-485885c5bbdsm5474207f8f.36.2026.09.04.04.53.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Sep 2026 04:53:06 -0700 (PDT) From: Bryan O'Donoghue Date: Fri, 04 Sep 2026 12:52:59 +0100 Subject: [PATCH v15 2/4] phy: core: Add phy_get_by_of_node() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-2-68b7916e7a3f@linaro.org> References: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> In-Reply-To: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> To: Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Robert Foss , Todor Tomov , Mauro Carvalho Chehab , Konrad Dybcio , Vladimir Zapolskiy , Bryan O'Donoghue , Loic Poulain , Vinod Koul , Neil Armstrong , Greg Kroah-Hartman , Kishon Vijay Abraham I , Felipe Balbi Cc: linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-phy@lists.infradead.org, Bryan O'Donoghue , Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5277; i=bryan.odonoghue@linaro.org; h=from:subject:message-id; bh=jvWI5bCo2G0nPMiyIWWUCCvc8PV85ddqSgmXfNNkRqI=; b=owEBbQKS/ZANAwAKASJxO7Ohjcg6AcsmYgBqmrEcz6YX2Qfye+Tuh289sTURyVPCK9pk4RNQN BviaddB7NyJAjMEAAEKAB0WIQTmk/sqq6Nt4Rerb7QicTuzoY3IOgUCapqxHAAKCRAicTuzoY3I Oln2D/wN3GaKgADkAMxwwdkbuS+Mn5CoPHU4MH9e8qSHKrmL1okdAu1Io0zfudgzLNIbNwaoLR4 bm5c3d15ckYQW13zIMAgiW49AOzP5Rbch9LC0MZN2W+C5E0rZEyxXpzIPkPm9374C6upY6ky+8R 51WqFeEKzHnA3+moQ+upkojdoua18kAsb5qEN36YiTXCb9E/KfFViv517IrRk+l+sMbx7wKIKdF KhhWYIl90Ba2WN3Sk67JeDyH3DwXL2H/2CtIW2IDfXSiY58s4YqJsR6q1ilvwgJAS1B9+d33rY/ /bMvGOVs5UKKJAGC1s9OLIMIj5yqtHiEoMuD17JclxBK8+/5P2gxPlU0n3h9h0yBOr9a991Bdby eHG4bs1RzQTuFBV5qzMubfpaRQj67jreuXOwhi51G0jSDdLCGaEco7pfkahW3de4XSN/NY6cGAd BV8DDUY8sxdcOH7ETQhXW0lvO1F0sbkeCvcXQ+4tEPv6CCDW50Sdju40xf70UuEflLIF8GFNrOg nh6Wi8edqmTFxGh4GoGTZJi0WJFt+RbhrMd0UwyZhbd+peWbCJUH6KZZrTA7OxzvNi1iM+PgFPH DVY1c3ed3MdyKLn79soDGQhWuImRVBid+55HhymfDq3tatQxc0BbfjbnBwwtIEyI3e1/h0Mrfu6 1mG1BTveYnk0mEg== X-Developer-Key: i=bryan.odonoghue@linaro.org; a=openpgp; fpr=E693FB2AABA36DE117AB6FB422713BB3A18DC83A Add new function phy_get_by_of_node() allowing lookup of a phy by device_node. Separates existing logic in _of_phy_get() into an internal helper method _of_phy_get_with_args() to allow for reuse in new method. Signed-off-by: Bryan O'Donoghue --- drivers/phy/phy-core.c | 95 +++++++++++++++++++++++++++++++++++++--------= ---- include/linux/phy/phy.h | 6 ++++ 2 files changed, 78 insertions(+), 23 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 89addd732bff3..490a7cde6d40a 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -606,22 +606,51 @@ int phy_validate(struct phy *phy, enum phy_mode mode,= int submode, } EXPORT_SYMBOL_GPL(phy_validate); =20 +/** + * _of_phy_get_with_args() - lookup and obtain a reference to a phy by of_= phandle_args + * @args: of_phandle_args to the phy + * + * Returns the phy from the provider's of_xlate, -ENODEV if disabled, + * -EPROBE_DEFER if the provider is not yet registered. + */ +static struct phy *_of_phy_get_with_args(struct of_phandle_args *args) +{ + struct phy *phy; + struct phy_provider *phy_provider; + + lockdep_assert_held(&phy_provider_mutex); + + phy_provider =3D of_phy_provider_lookup(args->np); + if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) + return ERR_PTR(-EPROBE_DEFER); + + if (!of_device_is_available(args->np)) { + dev_warn(phy_provider->dev, "Requested PHY is disabled\n"); + phy =3D ERR_PTR(-ENODEV); + goto out_put_module; + } + + phy =3D phy_provider->of_xlate(phy_provider->dev, args); + +out_put_module: + module_put(phy_provider->owner); + + return phy; +} + /** * _of_phy_get() - lookup and obtain a reference to a phy by phandle * @np: device_node for which to get the phy * @index: the index of the phy * - * Returns the phy associated with the given phandle value, - * after getting a refcount to it or -ENODEV if there is no such phy or - * -EPROBE_DEFER if there is a phandle to the phy, but the device is - * not yet loaded. This function uses of_xlate call back function provided - * while registering the phy_provider to find the phy instance. + * Returns the phy associated with the given phandle value after getting + * a refcount to it; -ENODEV if there is no such phy or the phy is + * disabled; -EPROBE_DEFER if the phy provider is not yet available. */ static struct phy *_of_phy_get(struct device_node *np, int index) { int ret; - struct phy_provider *phy_provider; - struct phy *phy =3D NULL; + struct phy *phy; struct of_phandle_args args; =20 lockdep_assert_held(&phy_provider_mutex); @@ -637,22 +666,7 @@ static struct phy *_of_phy_get(struct device_node *np,= int index) goto out_put_node; } =20 - phy_provider =3D of_phy_provider_lookup(args.np); - if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) { - phy =3D ERR_PTR(-EPROBE_DEFER); - goto out_put_node; - } - - if (!of_device_is_available(args.np)) { - dev_warn(phy_provider->dev, "Requested PHY is disabled\n"); - phy =3D ERR_PTR(-ENODEV); - goto out_put_module; - } - - phy =3D phy_provider->of_xlate(phy_provider->dev, &args); - -out_put_module: - module_put(phy_provider->owner); + phy =3D _of_phy_get_with_args(&args); =20 out_put_node: of_node_put(args.np); @@ -1001,6 +1015,41 @@ struct phy *devm_of_phy_get_by_index(struct device *= dev, struct device_node *np, } EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index); =20 +/** + * phy_get_by_of_node() - lookup and obtain a reference to a phy by device= _node + * @np: node containing the phy + * + * Returns the phy associated with the device node or ERR_PTR. + */ +struct phy *phy_get_by_of_node(struct device_node *np) +{ + struct of_phandle_args args =3D { .np =3D np, .args_count =3D 0 }; + struct phy *phy; + + if (!np) + return ERR_PTR(-EINVAL); + + mutex_lock(&phy_provider_mutex); + + phy =3D _of_phy_get_with_args(&args); + + if (IS_ERR(phy)) + goto out_unlock; + + if (!try_module_get(phy->ops->owner)) { + phy =3D ERR_PTR(-EPROBE_DEFER); + goto out_unlock; + } + + get_device(&phy->dev); + +out_unlock: + mutex_unlock(&phy_provider_mutex); + + return phy; +} +EXPORT_SYMBOL_GPL(phy_get_by_of_node); + /** * phy_create() - create a new phy * @dev: device that is creating the new phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index ea47975e288ae..71c2e16397130 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -284,6 +284,7 @@ struct phy *devm_of_phy_optional_get(struct device *dev= , struct device_node *np, const char *con_id); struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_nod= e *np, int index); +struct phy *phy_get_by_of_node(struct device_node *np); void of_phy_put(struct phy *phy); void phy_put(struct device *dev, struct phy *phy); void devm_phy_put(struct device *dev, struct phy *phy); @@ -493,6 +494,11 @@ static inline struct phy *devm_of_phy_get_by_index(str= uct device *dev, return ERR_PTR(-ENOSYS); } =20 +static inline struct phy *phy_get_by_of_node(struct device_node *np) +{ + return ERR_PTR(-ENOSYS); +} + static inline void of_phy_put(struct phy *phy) { } --=20 2.55.0 From nobody Sat Sep 26 05:35:54 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09ED747A0B7 for ; Fri, 4 Sep 2026 11:53:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522794; cv=none; b=f5NnyqdFd+gp2WJD90zq6+vXneTJM7tObl4y++YLy/WW4kUT2opt6aaMqToakWUvAxK+GDBU005K+0/GszCDsyv5aMsYZm2ZedqDk8X9Iv2GKwPgScxkz8CUh45SUAhLPRLxn3ijJMOFk3GryhMvDES1nL1n4M/FwsbyJyeaSxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522794; c=relaxed/simple; bh=ov6l6XYXYWQFGwdR6skU1nY1vxsBWDotX7Kg0ih6rxA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N/UFqFgCjrg9e4fmnOAAiPW24oIcV1+CCZi88nouBUvaomoqNyMBbOKRnNTqBvxeKKRj2+AbI5drDCCdXh2Y7rrYvbXhbLhg31cCC2I9Jn3rmTHNdywJJDojbpzTABdjK3hrJ6Lq2qC4vf49NHg6AWnY5S5Rgryo2qhacqPDPC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=BYVr1ugP; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="BYVr1ugP" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4921eed3fa2so10008695e9.0 for ; Fri, 04 Sep 2026 04:53:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1788522788; x=1789127588; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+LoCl+EbBl/1yupzEbeoWPgLAsEGydOXRIOMMFAJTXk=; b=BYVr1ugP76EaArfin5AIFoi/luiRR4VfChYm86kx3IPXJAiIaE4jWypYxZT0HaO8s2 HCywPntQoktYFkgGyd2tuafSbNn27S0Dl3K+6rzmugy92HTo1uLPHNCaoW3FB062Jj8F eASHsRJ9B79N7YKkCDngm740W27VwsmKepLP4Ek/KxUj3FF2vuqQ/L1isd1nsZoxNBpg ZIrCHpCRkwWwwM5N711B8pmpAOS9V2/yAwGtfoW2E/pBmXPHkGLLXlSyrYGJatf22hxE 9wEkaUoCSDiWt1pQfG53V8isEKIYSRjYfnPl8LnLaMGERIE6ZxVUA8KJ8iBAsdTDV9FL GEuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788522788; x=1789127588; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=+LoCl+EbBl/1yupzEbeoWPgLAsEGydOXRIOMMFAJTXk=; b=RZIdyYEmm0tyEW1EqNngRfjhqzYWDmyY7ZZgR7m22yBUKwT0WDBykatEsmJCIQhWcm vjL9YOqgRZERe981h9LtiUPcKJCq09Zt9QUz+yY1zv0pY8ddYn66yXjbayf38MKiim5D JjB61r1WFXsEpvz1bgcft1hyGNBBeZxusupD+4O62naKPZ3f/IeSChcuEAP6hq4bKmc+ 3pz5HUfZe9OFE5LdWfFtd5ADuaVJoNLAEs7QDBsTulZo/9ennKyhwia9TgiBu10PY3hv VK8GuOiXKlCGWDZVZMsMz9oH1kdS5T+PAtXAp2CAlbgR9ZN0e1HJIv8gMGphbK7T1YFP zZCw== X-Forwarded-Encrypted: i=1; AKwUvBylhIfp/3Sf3yx26i37S2onuvkuglaPt1eZnNN6SgoWp7WJCvUBbcIGdm+qf4FWATWl3m9U5rA558Z1bx8=@vger.kernel.org X-Gm-Message-State: AFuF++mRlTqU6RzJ8ThrHl/jnTGwruwUzjotwtf09dkYNsZAwiKb5lQJ 43ORFMyDIpGYCXOLhTX+3LQbF7CULF8EF3rKhLX/kZ9TNWIBUB9RKBLfUoIFFDuSJBc= X-Gm-Gg: AYBFou3EyuMd6e/Z+zt2mfiQYhjQkIvLidzG3QEjpgxETdi1f8+roVY4MWtjHGgD1kI dlzD2bgpAB4iGUya6VHiLBmJgaAa4zBuZjlVsbju/phDDSPwAbOTxKYr3PG5ij0TToLc4bCxbDg F2rkeeTnD/hzv8wE231mu/8YpoM4/Uhctbo0XaQpv8MrytsHMGi6d84G0AQgXVV1T/Aq5mi/5ed B/opnGaGj9aXamGNMSGp7KwrfJENCqYkI8ZLr58SBoB3WNKQg9sZ47SFmZKTCrdKsH0eIKsfwKr tBMIsqDkYD3iSlnNv6R/2Jae0zbxO420Y82cahf2NmWUDh8VgSchZIra6GCEhq7UTF8C8nN5QhF GhktkBPzqKhKqyZ9/eWYneZ+8qMMSf/U2xfTxdFDdHRwAaCkOM8Yhhbk9sVWIEK25gSblKHLcRb Me65L53o0wIocMzNYpuPmz57pwkwz5D48glXitRG7Ap1fJAJkq+zvviPkZthHsG+mFxl1Zgpo/U 8+8ziSHc5FeWiFhtLcqCRA= X-Received: by 2002:a05:600c:6819:b0:49c:de80:b833 with SMTP id 5b1f17b1804b1-49cf81fb1acmr54922535e9.2.1788522788268; Fri, 04 Sep 2026 04:53:08 -0700 (PDT) Received: from [192.168.0.35] ([109.76.237.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-485885c5bbdsm5474207f8f.36.2026.09.04.04.53.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Sep 2026 04:53:07 -0700 (PDT) From: Bryan O'Donoghue Date: Fri, 04 Sep 2026 12:53:00 +0100 Subject: [PATCH v15 3/4] phy: core: Add devm_phy_get_by_of_node() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-3-68b7916e7a3f@linaro.org> References: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> In-Reply-To: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> To: Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Robert Foss , Todor Tomov , Mauro Carvalho Chehab , Konrad Dybcio , Vladimir Zapolskiy , Bryan O'Donoghue , Loic Poulain , Vinod Koul , Neil Armstrong , Greg Kroah-Hartman , Kishon Vijay Abraham I , Felipe Balbi Cc: linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-phy@lists.infradead.org, Bryan O'Donoghue , Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2684; i=bryan.odonoghue@linaro.org; h=from:subject:message-id; bh=ov6l6XYXYWQFGwdR6skU1nY1vxsBWDotX7Kg0ih6rxA=; b=owEBbQKS/ZANAwAKASJxO7Ohjcg6AcsmYgBqmrEcsnrGBJeocLVI+O9+brnUFW6FqlooZlsl7 ZQrlZxFXwiJAjMEAAEKAB0WIQTmk/sqq6Nt4Rerb7QicTuzoY3IOgUCapqxHAAKCRAicTuzoY3I Oh1cD/4x23nTIQZWK3SoWzTz69RZm5zv2SQvYRXMjI/nTAsWspK6u3DZytcTIZvNrPbSfUX3IOh 03tILSVIul2ljDB/mLHI5ISqXnWDwFSZrw5TPGhQAwuLk3eSb2shn7Rpy6+gyGH2gJJyYAamMrb S9wnHssvLy1A37Adohv7PxZNC0woy6kZrPzZWbsWw+xrc3tLoTAW6Nk7twCcbnYNdNurrBGaY8P EldjRAd+h7toDSC88y8Z/NsbepmHVPJIYt+B4QDcDeVZVzp4IWW98+SlokPKjDwK7aHGUQv55Vo 0SmqSTbXfbej0xA1J3Ey7yJQyj0DyLaz4mEuvalyTzEFC7zrHGRuZLLkGiNOatAr91JRawxt7PE t5WYUNGg47apx/Usr6MBKDiFJcg2vOObOITZSgN3uyEIRlY1plfy1+TrlDchN3dnbLoS/cCxW4R ABtFaPiEfa8GpcUTRIX57wDOZ6ntwgxpWS4JqufJenxB4+08/7oXqv94mfwXT5LroFCQ/7kMVWB /yKwZqPHMA4d19ViDg10ZLSCIPRsx+dp64FfoHJwszTQxrIImNLphq0gKyQKc9rqPWM9468Wlvy 1+Vg4ExvzOos48xua7GCdEegUfYaJag2LOU3kB2fY41GNScmAfODvW8m4HpCF0nFLN36sgLfLqf aF+qLSyR77k9s1A== X-Developer-Key: i=bryan.odonoghue@linaro.org; a=openpgp; fpr=E693FB2AABA36DE117AB6FB422713BB3A18DC83A Add a devm variant of phy_get_by_of_node() to allow for the familiar pattern of having devres automatically release resources on the driver's exit path. Signed-off-by: Bryan O'Donoghue --- drivers/phy/phy-core.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/phy/phy.h | 7 +++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 490a7cde6d40a..2e3581ecb42ee 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1050,6 +1050,40 @@ struct phy *phy_get_by_of_node(struct device_node *n= p) } EXPORT_SYMBOL_GPL(phy_get_by_of_node); =20 +/** + * devm_phy_get_by_of_node() - devm managed lookup and obtain phy referenc= e by device node + * @dev: device requesting the PHY + * @np: device_node of the PHY provider + * + * Returns phy associated with the device_node or ERR_PTR. devres manages + * releasing resources. + */ +struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node= *np) +{ + struct phy **ptr, *phy; + struct device_link *link; + + ptr =3D devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + phy =3D phy_get_by_of_node(np); + if (IS_ERR(phy)) { + devres_free(ptr); + return phy; + } + + *ptr =3D phy; + devres_add(dev, ptr); + link =3D device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); + if (!link) + dev_dbg(dev, "failed to create device link to %s\n", + dev_name(phy->dev.parent)); + + return phy; +} +EXPORT_SYMBOL_GPL(devm_phy_get_by_of_node); + /** * phy_create() - create a new phy * @dev: device that is creating the new phy diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 71c2e16397130..14b924a88411f 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -285,6 +285,7 @@ struct phy *devm_of_phy_optional_get(struct device *dev= , struct device_node *np, struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_nod= e *np, int index); struct phy *phy_get_by_of_node(struct device_node *np); +struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node= *np); void of_phy_put(struct phy *phy); void phy_put(struct device *dev, struct phy *phy); void devm_phy_put(struct device *dev, struct phy *phy); @@ -499,6 +500,12 @@ static inline struct phy *phy_get_by_of_node(struct de= vice_node *np) return ERR_PTR(-ENOSYS); } =20 +static inline struct phy *devm_phy_get_by_of_node(struct device *dev, + struct device_node *np) +{ + return ERR_PTR(-ENOSYS); +} + static inline void of_phy_put(struct phy *phy) { } --=20 2.55.0 From nobody Sat Sep 26 05:35:54 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7535448097C for ; Fri, 4 Sep 2026 11:53:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522802; cv=none; b=CBR4mtx8ev2ecAdHZqF6O1vc4ZVbRMXchZAlVOQlOGLiwoaaRyuWRPQS2dLc0nZ8vNzq2Po8AD/F4azBq+6O+vWHTJNRpaw47aV8f3nm2+ozCMY7G8FRcNfSPMOd7dAJ5CIHf6tJOmZXCWwNuA5feqVDY+JCL2ZjLZMRMmkicSo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788522802; c=relaxed/simple; bh=YIJJdG8F7qvkpKCTmBVhA8FGxfejNI1V+jwzJ32M+4o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DvoiU/tsPty/ZnuU0/rR/1Lz84ArT4SljX/bFP28Nr1FOagXstul+nx32/Ry9KCDM6FJipqAgU3qRp/TYO1J53eHhGf3wDNQ+ZBXPCOKYBIBMBuMVSyLrBHlW5sTOiWXUciuqWD1Ffsuql/vH+RSIt2KrPf3iTohn+UgjA4uwVM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=TD1ZIPU0; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="TD1ZIPU0" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-495590dde14so12622695e9.0 for ; Fri, 04 Sep 2026 04:53:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1788522790; x=1789127590; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=SFRs5gGLiDPOnHZoeYS5F95xIoLCLe/yvxqAbvUutf4=; b=TD1ZIPU0MASnCIHWRZ+4eZCpTY4C2SC5YN8b4Kgp25597c1CI8tnwiVJ668/2vdXzA 5B9klTHOzzmH80aEzqS6KiQxFFFz/gjXgmYgAgfYD9hEbir3B/MRpukPaK056b7+967s OGMrNTrqgFAkusPD+CgG/I8O82dzPyypZkMCtDDLdb37STMWCbHpiGVfOCRYJnB12Y/I Kqfau2+oGs3isvsGJzOqh+xfwVYW2iXbUvgEMGfJhp4ET7tCrw/FY/OCiXoqiUVhVkUQ QGDtMQv+Dq8XxIPKM3nuL/36HfB7quHwh465V6QJydKMUYNde22sZDEBdCwYi/E5+Qx2 pfgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788522790; x=1789127590; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=SFRs5gGLiDPOnHZoeYS5F95xIoLCLe/yvxqAbvUutf4=; b=rzILxChuasxeqkR2BmfvvVvzQ1n+n9Mp3IdxN5R77uMLZroIJfj1o2Aiep7VTAdcq6 zAkF9iVBhii4AgPh3CP7XbngAwkC675awKkXf2Xau7YbM3qCqe6uqDlEkqnP/JeMBfD3 76aSX2rKE/bWvqU8EA2cAPSEpriaZgwDFsgO84hGgrr7osgAw76UZ/Hw32JfnfoRfkYC WZ2UD02b6hJ0+/c7RlbTyR6quM4eXdUgMyFryxZSL47lNWjmuRknSBmA4W82CWNCJD9o PBGPHCImnKTT2yap+4hi8p7WxRM2/j/9PrxK9QIn0Suiy1PVDtY6RqS51LolqTrUnjdp aRqA== X-Forwarded-Encrypted: i=1; AKwUvBzhEeNzrgp8yRcZ/zBEJw3f5nPbUvoTE17nauT/d819itM3nMXSsWbkH9WNksBHKzaCW1seoIIg5STMmvo=@vger.kernel.org X-Gm-Message-State: AFuF++l3tZ9hsvzIAaCoX08ThzsycHr5lHYqjc7BfnRDnAFsMQbgy4Fa Io/K/NNJbrO0rMJAupBmvJen1WxBurqMvTH7SPtQgAZfeqKa5QP2lS/d3euwnMxOEAM= X-Gm-Gg: AYBFou2iR/iSiylvRkycrfRJUVgaPD2H8haWu8MY3VNBMVcgr/meniV/UYXO81JRS7r 1TRDHRKzXOT4zcFc9p3AnM4aOYoXqENCdKwoefqTgD/ey2OAOo5vuogPlNXt9mLyLleWYyTvVSb Le0y5hewtgb2vzhV8iEW62VGNsFPBMeo49a9ZeuH6kgIHOLweqlo73u0evX6LwsqD5NtOKJK1pw 976LKmzXg9BRNJTZew+WAYFpFNL8tfq0x5jda9wDQN+Eu/owYNjSOyPfl/vsWH32++TcPsFN5Vo YYkAKJvN86xacGq2iAqv1Syoq1jExZjU9kqkP5mjDfRt3ZNPEmV1EfiIONIhI3p+FOz/5D3EymV J1L13VgVudeWJ5bUjxkskfDgt+tsdT6mVnDR7T0v29H5doiy7Xzim21xoi1IzCKu9QIx+aVLfNC iudvDCmQn26Cq4HE1OWaLw33xBCQGurpbYBTzMbZpHkD5FZb7wAzXBJAu1qriy03UKF8IGumqV X-Received: by 2002:a05:600c:138c:b0:49b:8c63:dfdf with SMTP id 5b1f17b1804b1-49cf825bd7amr84725675e9.15.1788522789911; Fri, 04 Sep 2026 04:53:09 -0700 (PDT) Received: from [192.168.0.35] ([109.76.237.179]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-485885c5bbdsm5474207f8f.36.2026.09.04.04.53.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Sep 2026 04:53:09 -0700 (PDT) From: Bryan O'Donoghue Date: Fri, 04 Sep 2026 12:53:01 +0100 Subject: [PATCH v15 4/4] media: qcom: camss: Add support for PHY API devices Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-4-68b7916e7a3f@linaro.org> References: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> In-Reply-To: <20260904-b4-linux-next-25-03-13-dtsi-x1e80100-camss-v15-0-68b7916e7a3f@linaro.org> To: Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Robert Foss , Todor Tomov , Mauro Carvalho Chehab , Konrad Dybcio , Vladimir Zapolskiy , Bryan O'Donoghue , Loic Poulain , Vinod Koul , Neil Armstrong , Greg Kroah-Hartman , Kishon Vijay Abraham I , Felipe Balbi Cc: linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-phy@lists.infradead.org, Bryan O'Donoghue , Krzysztof Kozlowski , Nihal Kumar Gupta , Dmitry Baryshkov X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=17246; i=bryan.odonoghue@linaro.org; h=from:subject:message-id; bh=YIJJdG8F7qvkpKCTmBVhA8FGxfejNI1V+jwzJ32M+4o=; b=owEBbQKS/ZANAwAKASJxO7Ohjcg6AcsmYgBqmrEd/Vfy80Imxf3WvOf4ctI3KPtce9SNmYKlM hhxxYU6JMqJAjMEAAEKAB0WIQTmk/sqq6Nt4Rerb7QicTuzoY3IOgUCapqxHQAKCRAicTuzoY3I Oke2D/wM54phxKL22zuZ3zsmt0cFt7sOZ5kQZn8zsdSYIzo89FzR0ugct2L1ZM9c8gP2acHEF6r qqZHvJoDYCcT1hCOMbQLI8V+8XVu+vuvr4PFiN01LIhch5zRyPACgQwyQ3ybpQnEw9IHEce8JzD 1sWpQ4aehljnyvuopSrnAAairbp0w4XeBLCTH2bDcdELZezz0F2TH0C60Su3iVEUvP6jZXsA7tz /VCgq5TJiya66Is/Kiz+CnCm3AAgi+MK4hSEYsaIP/2u7R3jtsVhC+mbXB8E/3u7+bXp5GAvlL5 lNSMobgLYajMqrU5wccIOFvAdIx1DJqDsrp/nQPebj9UAei9l0u8gvAP9ZrU2DEYDhCKu2UEFPp GXafPe2I6Mq0964NktEAGUX4nbSKitxUHNQ4/kl7oXv/wTdgmTZ8e5oK+aBezzt8cDcIhKhuv3E YCZznK9wIWhPwQuThK0i8f6l02TWtwrNJGi0Q8o4EhQo/w8z59m0yOhwZnBBtDGp1+Vp2N0Mgtu RZ5XrpRUTZGFXyHFcpq5V8Netsi7VtMXhIOoDw5A7gCtfm+eZXrDvyIbCqfZk+z5UtPm3aZ7qw7 PHFbiz7UMle7goHQk+eZ5AQgx/hF+Jd2gfKYHryHSlYi16b+q8Lje5h7nIV0y2eQOeOkSwEBRX1 Ju08Pa1XhAfi4BQ== X-Developer-Key: i=bryan.odonoghue@linaro.org; a=openpgp; fpr=E693FB2AABA36DE117AB6FB422713BB3A18DC83A Add the ability to use a PHY pointer which interacts with the standard PHY API. In the first instance the code will try to use the new PHY interface. If no PHYs are present in the DT then the legacy method will be attempted. Signed-off-by: Nihal Kumar Gupta Reviewed-by: Loic Poulain Reviewed-by: Dmitry Baryshkov Signed-off-by: Bryan O'Donoghue --- drivers/media/platform/qcom/camss/Kconfig | 1 + drivers/media/platform/qcom/camss/camss-csiphy.c | 177 +++++++++++++++++++= ++-- drivers/media/platform/qcom/camss/camss-csiphy.h | 11 +- drivers/media/platform/qcom/camss/camss.c | 104 +++++++++++-- drivers/media/platform/qcom/camss/camss.h | 1 + 5 files changed, 263 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/plat= form/qcom/camss/Kconfig index 4eda48cb1adf0..1edc5e5a1829e 100644 --- a/drivers/media/platform/qcom/camss/Kconfig +++ b/drivers/media/platform/qcom/camss/Kconfig @@ -7,3 +7,4 @@ config VIDEO_QCOM_CAMSS select VIDEO_V4L2_SUBDEV_API select VIDEOBUF2_DMA_SG select V4L2_FWNODE + select PHY_QCOM_MIPI_CSI2 diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/med= ia/platform/qcom/camss/camss-csiphy.c index 539ac4888b608..e00748dd83b02 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -131,10 +133,10 @@ static u8 csiphy_get_bpp(const struct csiphy_format_i= nfo *formats, } =20 /* - * csiphy_set_clock_rates - Calculate and set clock rates on CSIPHY module + * csiphy_set_clock_rates_legacy - Calculate and set clock rates on CSIPHY= module * @csiphy: CSIPHY device */ -static int csiphy_set_clock_rates(struct csiphy_device *csiphy) +static int csiphy_set_clock_rates_legacy(struct csiphy_device *csiphy) { struct device *dev =3D csiphy->camss->dev; s64 link_freq; @@ -200,7 +202,7 @@ static int csiphy_set_clock_rates(struct csiphy_device = *csiphy) * * Return 0 on success or a negative error code otherwise */ -static int csiphy_set_power(struct v4l2_subdev *sd, int on) +static int csiphy_set_power_legacy(struct v4l2_subdev *sd, int on) { struct csiphy_device *csiphy =3D v4l2_get_subdevdata(sd); struct device *dev =3D csiphy->camss->dev; @@ -219,7 +221,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int= on) return ret; } =20 - ret =3D csiphy_set_clock_rates(csiphy); + ret =3D csiphy_set_clock_rates_legacy(csiphy); if (ret < 0) { regulator_bulk_disable(csiphy->num_supplies, csiphy->supplies); @@ -254,7 +256,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int= on) } =20 /* - * csiphy_stream_on - Enable streaming on CSIPHY module + * csiphy_stream_on_legacy - Enable streaming on CSIPHY module * @csiphy: CSIPHY device * * Helper function to enable streaming on CSIPHY module. @@ -262,7 +264,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int= on) * * Return 0 on success or a negative error code otherwise */ -static int csiphy_stream_on(struct csiphy_device *csiphy) +static int csiphy_stream_on_legacy(struct csiphy_device *csiphy) { struct csiphy_config *cfg =3D &csiphy->cfg; s64 link_freq; @@ -306,11 +308,88 @@ static int csiphy_stream_on(struct csiphy_device *csi= phy) * * Helper function to disable streaming on CSIPHY module */ -static void csiphy_stream_off(struct csiphy_device *csiphy) +static void csiphy_stream_off_legacy(struct csiphy_device *csiphy) { csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg); } =20 +/* + * csiphy_stream_on - Enable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to enable streaming on CSIPHY module. + * Main configuration of CSIPHY module is also done here. + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_stream_on(struct csiphy_device *csiphy) +{ + u8 bpp =3D csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->for= mats->nformats, + csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); + struct csiphy_lanes_cfg *lncfg =3D &csiphy->cfg.csi2->lane_cfg; + struct phy_configure_opts_mipi_dphy *dphy_cfg; + union phy_configure_opts dphy_opts =3D { 0 }; + struct device *dev =3D csiphy->camss->dev; + u8 num_lanes =3D lncfg->num_data; + s64 link_freq; + int ret; + + dphy_cfg =3D &dphy_opts.mipi_dphy; + + link_freq =3D camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); + + if (link_freq < 0) { + dev_err(dev, + "Cannot get CSI2 transmitter's link frequency\n"); + return -EINVAL; + } + + phy_mipi_dphy_get_default_config_for_hsclk(link_freq, num_lanes, dphy_cfg= ); + + phy_set_mode(csiphy->phy, PHY_MODE_MIPI_DPHY); + + ret =3D phy_configure(csiphy->phy, &dphy_opts); + if (ret) { + dev_err(dev, "failed to configure MIPI D-PHY\n"); + goto error; + } + + return phy_power_on(csiphy->phy); + +error: + return ret; +} + +/* + * csiphy_stream_off - Disable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to disable streaming on CSIPHY module + */ +static void csiphy_stream_off(struct csiphy_device *csiphy) +{ + phy_power_off(csiphy->phy); +} + +/* + * csiphy_set_stream - Enable/disable streaming on CSIPHY module + * @sd: CSIPHY V4L2 subdevice + * @enable: Requested streaming state + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_set_stream_legacy(struct v4l2_subdev *sd, int enable) +{ + struct csiphy_device *csiphy =3D v4l2_get_subdevdata(sd); + int ret =3D 0; + + if (enable) + ret =3D csiphy_stream_on_legacy(csiphy); + else + csiphy_stream_off_legacy(csiphy); + + return ret; +} =20 /* * csiphy_set_stream - Enable/disable streaming on CSIPHY module @@ -572,16 +651,16 @@ csiphy_match_clock_name(const char *clock_name, const= char *format, ...) } =20 /* - * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resourc= es + * msm_csiphy_subdev_init_legacy - Initialize CSIPHY device structure and = resources * @csiphy: CSIPHY device * @res: CSIPHY module resources table * @id: CSIPHY module id * * Return 0 on success or a negative error code otherwise */ -int msm_csiphy_subdev_init(struct camss *camss, - struct csiphy_device *csiphy, - const struct camss_subdev_resources *res, u8 id) +int msm_csiphy_subdev_init_legacy(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id) { struct device *dev =3D camss->dev; struct platform_device *pdev =3D to_platform_device(dev); @@ -709,6 +788,56 @@ int msm_csiphy_subdev_init(struct camss *camss, return ret; } =20 +/* + * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resourc= es + * @camss: CAMSS structure + * @port: DT port index + * + * Return 0 on success or absence of link, negative error code otherwise + */ +int msm_csiphy_subdev_init(struct camss *camss, u8 port) +{ + const struct camss_subdev_resources *res =3D &camss->res->csiphy_res[port= ]; + struct csiphy_device *csiphy =3D &camss->csiphy[port]; + struct device *dev =3D camss->dev; + struct device_node *ep, *remote; + int ret; + + ep =3D of_graph_get_endpoint_by_regs(dev->of_node, port, -1); + if (!ep) + return 0; + + remote =3D of_graph_get_remote_port_parent(ep); + of_node_put(ep); + if (!remote) + return 0; + + if (!of_device_is_available(remote)) { + of_node_put(remote); + return 0; + } + + csiphy->phy =3D devm_phy_get_by_of_node(dev, remote); + of_node_put(remote); + if (IS_ERR(csiphy->phy)) { + ret =3D PTR_ERR(csiphy->phy); + goto done; + } + + csiphy->camss =3D camss; + csiphy->id =3D res->csiphy.id; + csiphy->res =3D &res->csiphy; + + snprintf(csiphy->name, ARRAY_SIZE(csiphy->name), "csi%d", csiphy->id); + + ret =3D phy_init(csiphy->phy); + if (ret) + dev_err(dev, "%s init fail %d\n", csiphy->name, ret); + +done: + return ret; +} + /* * csiphy_link_setup - Setup CSIPHY connections * @entity: Pointer to media entity structure @@ -743,8 +872,12 @@ static int csiphy_link_setup(struct media_entity *enti= ty, return 0; } =20 -static const struct v4l2_subdev_core_ops csiphy_core_ops =3D { - .s_power =3D csiphy_set_power, +static const struct v4l2_subdev_core_ops csiphy_core_ops_legacy =3D { + .s_power =3D csiphy_set_power_legacy, +}; + +static const struct v4l2_subdev_video_ops csiphy_video_ops_legacy =3D { + .s_stream =3D csiphy_set_stream_legacy, }; =20 static const struct v4l2_subdev_video_ops csiphy_video_ops =3D { @@ -758,8 +891,13 @@ static const struct v4l2_subdev_pad_ops csiphy_pad_ops= =3D { .set_fmt =3D csiphy_set_format, }; =20 +static const struct v4l2_subdev_ops csiphy_v4l2_ops_legacy =3D { + .core =3D &csiphy_core_ops_legacy, + .video =3D &csiphy_video_ops_legacy, + .pad =3D &csiphy_pad_ops, +}; + static const struct v4l2_subdev_ops csiphy_v4l2_ops =3D { - .core =3D &csiphy_core_ops, .video =3D &csiphy_video_ops, .pad =3D &csiphy_pad_ops, }; @@ -785,10 +923,15 @@ int msm_csiphy_register_entity(struct csiphy_device *= csiphy, { struct v4l2_subdev *sd =3D &csiphy->subdev; struct media_pad *pads =3D csiphy->pads; - struct device *dev =3D csiphy->camss->dev; + struct camss *camss =3D csiphy->camss; + struct device *dev =3D camss->dev; int ret; =20 - v4l2_subdev_init(sd, &csiphy_v4l2_ops); + if (camss->legacy_phy) + v4l2_subdev_init(sd, &csiphy_v4l2_ops_legacy); + else + v4l2_subdev_init(sd, &csiphy_v4l2_ops); + sd->internal_ops =3D &csiphy_v4l2_internal_ops; sd->flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", @@ -828,6 +971,8 @@ int msm_csiphy_register_entity(struct csiphy_device *cs= iphy, */ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy) { + if (!IS_ERR(csiphy->phy)) + phy_exit(csiphy->phy); v4l2_device_unregister_subdev(&csiphy->subdev); media_entity_cleanup(&csiphy->subdev.entity); } diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/med= ia/platform/qcom/camss/camss-csiphy.h index 9d9657b82f748..7a357044b9fdb 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -12,6 +12,7 @@ =20 #include #include +#include #include #include #include @@ -97,6 +98,7 @@ struct csiphy_device_regs { =20 struct csiphy_device { struct camss *camss; + struct phy *phy; u8 id; struct v4l2_subdev subdev; struct media_pad pads[MSM_CSIPHY_PADS_NUM]; @@ -104,6 +106,7 @@ struct csiphy_device { void __iomem *base_clk_mux; u32 irq; char irq_name[30]; + char name[16]; struct camss_clock *clock; bool *rate_set; int nclocks; @@ -118,9 +121,11 @@ struct csiphy_device { =20 struct camss_subdev_resources; =20 -int msm_csiphy_subdev_init(struct camss *camss, - struct csiphy_device *csiphy, - const struct camss_subdev_resources *res, u8 id); +int msm_csiphy_subdev_init_legacy(struct camss *camss, + struct csiphy_device *csiphy, + const struct camss_subdev_resources *res, u8 id); + +int msm_csiphy_subdev_init(struct camss *camss, u8 port); =20 int msm_csiphy_register_entity(struct csiphy_device *csiphy, struct v4l2_device *v4l2_dev); diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/plat= form/qcom/camss/camss.c index 2123f6388e3d7..84097d82d99c9 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4799,8 +4799,43 @@ static int camss_parse_ports(struct camss *camss) fwnode_graph_for_each_endpoint(fwnode, ep) { struct camss_async_subdev *csd; =20 - csd =3D v4l2_async_nf_add_fwnode_remote(&camss->notifier, ep, - typeof(*csd)); + if (!fwnode_device_is_available(ep)) + continue; + + if (camss->legacy_phy) { + csd =3D v4l2_async_nf_add_fwnode_remote(&camss->notifier, ep, + typeof(*csd)); + } else { + struct fwnode_handle *phy_out, *phy_node, *phy_in, *sensor_ep; + + phy_out =3D fwnode_graph_get_remote_endpoint(ep); + if (!phy_out) + continue; + + phy_node =3D fwnode_graph_get_port_parent(phy_out); + fwnode_handle_put(phy_out); + if (!phy_node) + continue; + + phy_in =3D fwnode_graph_get_endpoint_by_id(phy_node, 0, 0, 0); + fwnode_handle_put(phy_node); + if (!phy_in) + continue; + + sensor_ep =3D fwnode_graph_get_remote_endpoint(phy_in); + fwnode_handle_put(phy_in); + if (!sensor_ep) + continue; + + csd =3D v4l2_async_nf_add_fwnode(&camss->notifier, sensor_ep, + struct camss_async_subdev); + fwnode_handle_put(sensor_ep); + if (IS_ERR(csd)) { + ret =3D PTR_ERR(csd); + goto err_cleanup; + } + } + if (IS_ERR(csd)) { ret =3D PTR_ERR(csd); goto err_cleanup; @@ -4819,6 +4854,29 @@ static int camss_parse_ports(struct camss *camss) return ret; } =20 +static void camss_detect_legacy_phy(struct camss *camss) +{ + struct device_node *remote; + struct device_node *ep; + + camss->legacy_phy =3D true; + + /* Find first remote-endpoint and determine if its a PHY */ + for_each_endpoint_of_node(camss->dev->of_node, ep) { + remote =3D of_graph_get_remote_port_parent(ep); + if (!remote) + continue; + + camss->legacy_phy =3D !of_node_name_eq(remote, "phy"); + of_node_put(remote); + of_node_put(ep); + break; + } + + dev_dbg(camss->dev, "legacy phy mode %s\n", + camss->legacy_phy ? "true" : "false"); +} + /* * camss_init_subdevices - Initialize subdev structures and resources * @camss: CAMSS device @@ -4832,14 +4890,21 @@ static int camss_init_subdevices(struct camss *cams= s) unsigned int i; int ret; =20 + camss_detect_legacy_phy(camss); + for (i =3D 0; i < camss->res->csiphy_num; i++) { - ret =3D msm_csiphy_subdev_init(camss, &camss->csiphy[i], - &res->csiphy_res[i], - res->csiphy_res[i].csiphy.id); + if (!camss->legacy_phy) { + ret =3D msm_csiphy_subdev_init(camss, i); + } else { + ret =3D msm_csiphy_subdev_init_legacy(camss, + &camss->csiphy[i], + &res->csiphy_res[i], + res->csiphy_res[i].csiphy.id); + } + if (ret < 0) { - dev_err(camss->dev, - "Failed to init csiphy%d sub-device: %d\n", - i, ret); + dev_err(camss->dev, "csiphy %d init fail\n", + res->csiphy_res[i].csiphy.id); return ret; } } @@ -4917,6 +4982,11 @@ inline void camss_link_err(struct camss *camss, ret); } =20 +static inline bool csiphy_enabled(struct camss *camss, struct csiphy_devic= e *c) +{ + return camss->legacy_phy || c->phy; +} + /* * camss_link_entities - Register subdev nodes and create links * @camss: CAMSS device @@ -4930,6 +5000,9 @@ static int camss_link_entities(struct camss *camss) =20 for (i =3D 0; i < camss->res->csiphy_num; i++) { for (j =3D 0; j < camss->res->csid_num; j++) { + if (!csiphy_enabled(camss, &camss->csiphy[i])) + continue; + ret =3D media_create_pad_link(&camss->csiphy[i].subdev.entity, MSM_CSIPHY_PAD_SRC, &camss->csid[j].subdev.entity, @@ -5056,6 +5129,9 @@ static int camss_register_entities(struct camss *cams= s) int ret; =20 for (i =3D 0; i < camss->res->csiphy_num; i++) { + if (!csiphy_enabled(camss, &camss->csiphy[i])) + continue; + ret =3D msm_csiphy_register_entity(&camss->csiphy[i], &camss->v4l2_dev); if (ret < 0) { @@ -5131,8 +5207,10 @@ static int camss_register_entities(struct camss *cam= ss) =20 i =3D camss->res->csiphy_num; err_reg_csiphy: - for (i--; i >=3D 0; i--) - msm_csiphy_unregister_entity(&camss->csiphy[i]); + for (i--; i >=3D 0; i--) { + if (csiphy_enabled(camss, &camss->csiphy[i])) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + } =20 return ret; } @@ -5147,8 +5225,10 @@ static void camss_unregister_entities(struct camss *= camss) { unsigned int i; =20 - for (i =3D 0; i < camss->res->csiphy_num; i++) - msm_csiphy_unregister_entity(&camss->csiphy[i]); + for (i =3D 0; i < camss->res->csiphy_num; i++) { + if (csiphy_enabled(camss, &camss->csiphy[i])) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + } =20 if (camss->tpg) { for (i =3D 0; i < camss->res->tpg_num; i++) diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/plat= form/qcom/camss/camss.h index 93d691c8ac63b..ba3d51d9c0bf8 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -138,6 +138,7 @@ struct camss { struct device_link *genpd_link; struct icc_path *icc_path[ICC_SM8250_COUNT]; const struct camss_resources *res; + bool legacy_phy; }; =20 struct camss_camera_interface { --=20 2.55.0