[PATCH v2 4/4] firmware: arm_scmi: optee: Rework transport probe sequence
Cristian Marussi
cristian.marussi at arm.com
Sun May 10 09:05:27 PDT 2026
Use the new per-instance transport handles helpers to synchronize and
optionally defer the core SCMI driver probe up until the transport driver
has completely been initialized and it is fully operational as a supplier.
Introduce proper module init/exit routines while removing the ugly trick of
registering a driver from within the probe sequence of another one, just to
avoid to have to deal with probe deferrals.
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v1 -> v2
- fixed __MUTEX_INITILIAZER() usage
- use common generic supplier definitions
- get rid of init/cleanup wrappers
- use proper barrier on scmi_optee_agent
---
drivers/firmware/arm_scmi/transports/optee.c | 46 +++++++++++++++-----
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/firmware/arm_scmi/transports/optee.c b/drivers/firmware/arm_scmi/transports/optee.c
index 07ae18d5279d..dbe32e141748 100644
--- a/drivers/firmware/arm_scmi/transports/optee.c
+++ b/drivers/firmware/arm_scmi/transports/optee.c
@@ -154,6 +154,8 @@ static struct scmi_transport_core_operations *core;
/* There can be only 1 SCMI service in OP-TEE we connect to */
static struct scmi_optee_agent *scmi_optee_private;
+static DEFINE_SCMI_TRANSPORT_SUPPLIER(scmi_optee_supplier);
+
/* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
static int open_session(struct scmi_optee_agent *agent, u32 *tee_session)
{
@@ -522,7 +524,7 @@ static struct scmi_desc scmi_optee_desc = {
};
static const struct of_device_id scmi_of_match[] = {
- { .compatible = "linaro,scmi-optee" },
+ { .compatible = "linaro,scmi-optee", .data = &scmi_optee_supplier.th},
{ /* Sentinel */ },
};
@@ -561,18 +563,20 @@ static int scmi_optee_service_probe(struct tee_client_device *scmi_pta)
if (ret)
goto err;
- /* Ensure agent resources are all visible before scmi_optee_private is */
+ /* Ensure initialized scmi_optee_private is visible */
smp_mb();
scmi_optee_private = agent;
- ret = platform_driver_register(&scmi_optee_driver);
- if (ret) {
- scmi_optee_private = NULL;
- goto err;
- }
+ ret = scmi_transport_supplier_put(&scmi_optee_supplier.th, agent->dev);
+ if (ret)
+ goto err_put;
return 0;
+err_put:
+ /* Ensure cleared reference is visible before resources are released */
+ smp_store_mb(scmi_optee_private, NULL);
+
err:
tee_client_close_context(tee_ctx);
@@ -586,13 +590,12 @@ static void scmi_optee_service_remove(struct tee_client_device *scmi_pta)
if (!scmi_optee_private)
return;
- platform_driver_unregister(&scmi_optee_driver);
-
if (!list_empty(&scmi_optee_private->channel_list))
return;
/* Ensure cleared reference is visible before resources are released */
smp_store_mb(scmi_optee_private, NULL);
+ scmi_transport_supplier_put(&scmi_optee_supplier.th, agent->dev);
tee_client_close_context(agent->tee_ctx);
}
@@ -616,7 +619,30 @@ static struct tee_client_driver scmi_optee_service_driver = {
},
};
-module_tee_client_driver(scmi_optee_service_driver);
+static int __init scmi_transport_optee_init(void)
+{
+ int ret;
+
+ ret = tee_client_driver_register(&scmi_optee_service_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&scmi_optee_driver);
+ if (ret) {
+ tee_client_driver_unregister(&scmi_optee_service_driver);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(scmi_transport_optee_init);
+
+static void __exit scmi_transport_optee_exit(void)
+{
+ platform_driver_unregister(&scmi_optee_driver);
+ tee_client_driver_unregister(&scmi_optee_service_driver);
+}
+module_exit(scmi_transport_optee_exit);
MODULE_AUTHOR("Etienne Carriere <etienne.carriere at foss.st.com>");
MODULE_DESCRIPTION("SCMI OPTEE Transport driver");
--
2.53.0
More information about the linux-arm-kernel
mailing list