From: Cristian Marussi Date: Sun, 10 May 2026 16:05:27 +0000 (+0100) Subject: firmware: arm_scmi: optee: Rework transport probe sequence X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=524abd2fa6907ebe2762342be339afcc5b227dc4;p=thirdparty%2Fkernel%2Flinux.git firmware: arm_scmi: optee: Rework transport probe sequence 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 Link: https://patch.msgid.link/20260510160527.3537474-5-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- 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 "); MODULE_DESCRIPTION("SCMI OPTEE Transport driver");