diff options
| author | Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> | 2026-07-24 15:19:39 +0530 |
|---|---|---|
| committer | Bjorn Andersson <andersson@kernel.org> | 2026-07-30 16:31:34 -0500 |
| commit | 9941fe8a04f3d258e07eb5899db3027252a4190f (patch) | |
| tree | 87b29647f22e3c57f6a788b4bc500a9da8acaa24 /drivers | |
| parent | b697b20cea4374d27e2134da4bb7b0ea39f36c8b (diff) | |
| download | linux-9941fe8a04f3d258e07eb5899db3027252a4190f.tar.gz linux-9941fe8a04f3d258e07eb5899db3027252a4190f.zip | |
firmware: qcom: scm: Fix tzmem state on probe retry
qcom_tzmem_enable() returns -EBUSY if called a second time, but this
causes probe retries to fail permanently if a later step in
qcom_scm_probe() defers after qcom_tzmem_enable() has already succeeded.
Use DO_ONCE() to ensure qcom_tzmem_init() runs exactly once across all
calls in a thread-safe manner. qcom_tzmem_dev is set on every call since
probe retries use the same device pointer. The result of the first
initialisation is cached and returned to every subsequent caller.
Fixes: 40289e35ca52 ("firmware: qcom: scm: enable the TZ mem allocator")
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260724094939.613844-4-mukesh.ojha@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/firmware/qcom/qcom_tzmem.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c index 0635cbeacfc8..0fd9581275f1 100644 --- a/drivers/firmware/qcom/qcom_tzmem.c +++ b/drivers/firmware/qcom/qcom_tzmem.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/mm.h> +#include <linux/once.h> #include <linux/radix-tree.h> #include <linux/slab.h> #include <linux/spinlock.h> @@ -507,14 +508,18 @@ phys_addr_t qcom_tzmem_to_phys(void *vaddr) } EXPORT_SYMBOL_GPL(qcom_tzmem_to_phys); +static void qcom_tzmem_do_init(int *result) +{ + *result = qcom_tzmem_init(); +} + int qcom_tzmem_enable(struct device *dev) { - if (qcom_tzmem_dev) - return -EBUSY; + static int result; qcom_tzmem_dev = dev; - - return qcom_tzmem_init(); + DO_ONCE(qcom_tzmem_do_init, &result); + return result; } EXPORT_SYMBOL_GPL(qcom_tzmem_enable); |
