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");