From nobody Thu Apr 9 14:58:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 84B8127B343; Sun, 8 Mar 2026 06:27:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772951267; cv=none; b=Lg8SdMei+REdZ/iB6iC2xwBnrYWbgSHkuleZhvPqKH0oU1TGhatrI3TVk+ljdyJMd4dQ/RyRBvI6xIx/pdhp17mfPWDJze3hbmvkgc/Xu5L6kzruoDXFo+oWluUtjp4GNC5NQvPXYRe5ihq1WrD+1lufaLx3Yu9RMyDLfXWzib0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772951267; c=relaxed/simple; bh=idcDeAlJQXfXyS4G3nzM1x69kvurnmzd3DZy9RI8eyE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=p8UDACVbbJq6yw9cbwYkgAuHoXHhbc/0RONM/vKbRKpwFCKyoiGNNLbm13OzQjLDE2DRVQuItx8gw1s05DiYGKKgCQf+eDej/DMNcAgMwEoAbOKqspi3Rs7zY4RztJt1QF42XksWmlMw4ynVoSnlr4gbiOZQ3De/UdsVpJsb0Pg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qX/ZsgpO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qX/ZsgpO" Received: by smtp.kernel.org (Postfix) with ESMTPS id 2BAB9C2BC86; Sun, 8 Mar 2026 06:27:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772951267; bh=idcDeAlJQXfXyS4G3nzM1x69kvurnmzd3DZy9RI8eyE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=qX/ZsgpOHtpc7HTc1bPQbb2V66jhj0nMDCGPiWEGW3gH9zzqp745AjQ6Dapz6kFug BiMYKVkhWqx9khLUoxC3GH8Y+8YR5HJOi/gRY/x8GIqo5tlz3lXKbf1URW51mVRlvF VbtqGAoTXRc5hq7BRG+t4wtdtphf+Ypzcj7b7qKphM83xUTphDHIQUKoDUiUMm2fkU CPRA/Sqr9QUtjUCVJrDvDCSFITNnJ8zQlasniqYVnliTxUpMsZQnV6I595W9ZOtHNR 69zpfeNM0g5MrPEJEv+vx/oluWPHd2DkPLEXQ7C1rkC9Q91dkecI7xKwtgLJsZexAQ GJvosoHonmhrA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13613F5512F; Sun, 8 Mar 2026 06:27:47 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Sun, 08 Mar 2026 11:57:27 +0530 Subject: [PATCH v5 1/5] soc: qcom: ice: Fix race between qcom_ice_probe() and of_qcom_ice_get() 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: <20260308-qcom-ice-fix-v5-1-e47e8a44b6c4@oss.qualcomm.com> References: <20260308-qcom-ice-fix-v5-0-e47e8a44b6c4@oss.qualcomm.com> In-Reply-To: <20260308-qcom-ice-fix-v5-0-e47e8a44b6c4@oss.qualcomm.com> To: Bjorn Andersson , Konrad Dybcio , Adrian Hunter , Ulf Hansson , Manivannan Sadhasivam , "James E.J. Bottomley" , "Martin K. Petersen" , Abel Vesa , Abel Vesa Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, Sumit Garg , mani@kernel.org, Neeraj Soni , Manivannan Sadhasivam , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4898; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=2PuOSvq7nnlpuETEJ0CuJEYnb+PMzyX987WVqcITQEY=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBprRbgN42Q1bJ36wY0Z+wzx33nXWRl1JS3i5Cc/ WYi0GuSPP+JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaa0W4AAKCRBVnxHm/pHO 9Q17CACpB7yHxnQYQwOxBVaBRncoamYSOyVYZ9oASA+7vlAPonPKzSJXB6oJYHByUMj6Pzc0ofN 4stdbJlXSC+m8W9eZmJfnyzcoAxcQMrLcOOAqBQXApkrLBeqJFXnH1pA+MPvtToZ723bNCaop1H nMpXFYj4eDAQGGgr737ds4OTUirkggNeOfLLTikat7/I3G+/dtJ3ej7Jx0MnzadezOOa3C0iXiP z8hC0xemduki4128S17Mjun8itYC1JDPpi3l1JzC1+n0tGn5j3eS6BLYqy6+yDpytaGmrC7Jmyf pyiSuHSPELE1IMaKDyvXb06xBC6Y+AqZyBxv/zMEk6XF4K8r X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam The current platform driver design causes probe ordering races with consumers (UFS, eMMC) due to ICE's dependency on SCM firmware calls. If ICE probe fails (missing ICE SCM or DT registers), devm_of_qcom_ice_get() loops with -EPROBE_DEFER, leaving consumers non-functional even when ICE should be gracefully disabled. devm_of_qcom_ice_get() doesn't know if the ICE driver probe has failed due to above reasons or it is waiting for the SCM driver. Moreover, there is no devlink dependency between ICE and consumer drivers as 'qcom,ice' is not considered as a DT 'supplier'. So the consumer drivers have no idea of when the ICE driver is going to probe. To address these issues, store the error pointer in a global xarray with ice node phandle as a key during probe in addition to the valid ice pointer and synchronize both qcom_ice_probe() and of_qcom_ice_get() using a mutex. If the xarray entry is NULL, then it implies that the driver is not probed yet, so return -EPROBE_DEFER. If it has any error pointer, return that error pointer directly. Otherwise, add the devlink as usual and return the valid pointer to the consumer. Xarray is used instead of platform drvdata, since driver core frees the drvdata during probe failure. So it cannot be used to pass the error pointer to the consumers. Note that this change only fixes the standalone ICE DT node bindings and not the ones with 'ice' range embedded in the consumer nodes, where there is no issue. Cc: # 6.4 Fixes: 2afbf43a4aec ("soc: qcom: Make the Qualcomm UFS/SDCC ICE a dedicated= driver") Reported-by: Sumit Garg Signed-off-by: Manivannan Sadhasivam --- drivers/soc/qcom/ice.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index b203bc685cad..50da5a3e8073 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -16,6 +16,7 @@ #include #include #include +#include =20 #include =20 @@ -113,6 +114,9 @@ struct qcom_ice { u8 hwkm_version; }; =20 +DEFINE_XARRAY(ice_handles); +static DEFINE_MUTEX(ice_mutex); + static bool qcom_ice_check_supported(struct qcom_ice *ice) { u32 regval =3D qcom_ice_readl(ice, QCOM_ICE_REG_VERSION); @@ -631,6 +635,8 @@ static struct qcom_ice *of_qcom_ice_get(struct device *= dev) return qcom_ice_create(&pdev->dev, base); } =20 + guard(mutex)(&ice_mutex); + /* * If the consumer node does not provider an 'ice' reg range * (legacy DT binding), then it must at least provide a phandle @@ -647,12 +653,13 @@ static struct qcom_ice *of_qcom_ice_get(struct device= *dev) return ERR_PTR(-EPROBE_DEFER); } =20 - ice =3D platform_get_drvdata(pdev); - if (!ice) { - dev_err(dev, "Cannot get ice instance from %s\n", - dev_name(&pdev->dev)); + ice =3D xa_load(&ice_handles, pdev->dev.of_node->phandle); + if (IS_ERR_OR_NULL(ice)) { platform_device_put(pdev); - return ERR_PTR(-EPROBE_DEFER); + if (!ice) + return ERR_PTR(-EPROBE_DEFER); + else + return ice; } =20 link =3D device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER); @@ -716,24 +723,40 @@ EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get); =20 static int qcom_ice_probe(struct platform_device *pdev) { + unsigned long phandle =3D pdev->dev.of_node->phandle; struct qcom_ice *engine; void __iomem *base; =20 + guard(mutex)(&ice_mutex); + base =3D devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { dev_warn(&pdev->dev, "ICE registers not found\n"); + /* Store the error pointer for devm_of_qcom_ice_get() */ + xa_store(&ice_handles, phandle, base, GFP_KERNEL); return PTR_ERR(base); } =20 engine =3D qcom_ice_create(&pdev->dev, base); - if (IS_ERR(engine)) + if (IS_ERR(engine)) { + /* Store the error pointer for devm_of_qcom_ice_get() */ + xa_store(&ice_handles, phandle, engine, GFP_KERNEL); return PTR_ERR(engine); + } =20 - platform_set_drvdata(pdev, engine); + xa_store(&ice_handles, phandle, engine, GFP_KERNEL); =20 return 0; } =20 +static void qcom_ice_remove(struct platform_device *pdev) +{ + unsigned long phandle =3D pdev->dev.of_node->phandle; + + guard(mutex)(&ice_mutex); + xa_store(&ice_handles, phandle, NULL, GFP_KERNEL); +} + static const struct of_device_id qcom_ice_of_match_table[] =3D { { .compatible =3D "qcom,inline-crypto-engine" }, { }, @@ -742,6 +765,7 @@ MODULE_DEVICE_TABLE(of, qcom_ice_of_match_table); =20 static struct platform_driver qcom_ice_driver =3D { .probe =3D qcom_ice_probe, + .remove =3D qcom_ice_remove, .driver =3D { .name =3D "qcom-ice", .of_match_table =3D qcom_ice_of_match_table, --=20 2.51.0