OSDN Git Service

Merge tag 'optee-fixes-for-v5.17' of git://git.linaro.org/people/jens.wiklander/linux...
[uclinux-h8/linux.git] / drivers / tee / optee / smc_abi.c
index dc40ae8..1a55339 100644 (file)
@@ -612,6 +612,7 @@ static void handle_rpc_func_cmd_shm_free(struct tee_context *ctx,
 }
 
 static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+                                         struct optee *optee,
                                          struct optee_msg_arg *arg,
                                          struct optee_call_ctx *call_ctx)
 {
@@ -641,7 +642,8 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
                shm = optee_rpc_cmd_alloc_suppl(ctx, sz);
                break;
        case OPTEE_RPC_SHM_TYPE_KERNEL:
-               shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
+               shm = tee_shm_alloc(optee->ctx, sz,
+                                   TEE_SHM_MAPPED | TEE_SHM_PRIV);
                break;
        default:
                arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -737,7 +739,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
        switch (arg->cmd) {
        case OPTEE_RPC_CMD_SHM_ALLOC:
                free_pages_list(call_ctx);
-               handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
+               handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx);
                break;
        case OPTEE_RPC_CMD_SHM_FREE:
                handle_rpc_func_cmd_shm_free(ctx, arg);
@@ -766,7 +768,7 @@ static void optee_handle_rpc(struct tee_context *ctx,
 
        switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
        case OPTEE_SMC_RPC_FUNC_ALLOC:
-               shm = tee_shm_alloc(ctx, param->a1,
+               shm = tee_shm_alloc(optee->ctx, param->a1,
                                    TEE_SHM_MAPPED | TEE_SHM_PRIV);
                if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
                        reg_pair_from_64(&param->a1, &param->a2, pa);
@@ -944,57 +946,34 @@ static irqreturn_t notif_irq_thread_fn(int irq, void *dev_id)
 {
        struct optee *optee = dev_id;
 
-       optee_smc_do_bottom_half(optee->notif.ctx);
+       optee_smc_do_bottom_half(optee->ctx);
 
        return IRQ_HANDLED;
 }
 
 static int optee_smc_notif_init_irq(struct optee *optee, u_int irq)
 {
-       struct tee_context *ctx;
        int rc;
 
-       ctx = teedev_open(optee->teedev);
-       if (IS_ERR(ctx))
-               return PTR_ERR(ctx);
-
-       optee->notif.ctx = ctx;
        rc = request_threaded_irq(irq, notif_irq_handler,
                                  notif_irq_thread_fn,
                                  0, "optee_notification", optee);
        if (rc)
-               goto err_close_ctx;
+               return rc;
 
        optee->smc.notif_irq = irq;
 
        return 0;
-
-err_close_ctx:
-       teedev_close_context(optee->notif.ctx);
-       optee->notif.ctx = NULL;
-
-       return rc;
 }
 
 static void optee_smc_notif_uninit_irq(struct optee *optee)
 {
-       if (optee->notif.ctx) {
-               optee_smc_stop_async_notif(optee->notif.ctx);
+       if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_ASYNC_NOTIF) {
+               optee_smc_stop_async_notif(optee->ctx);
                if (optee->smc.notif_irq) {
                        free_irq(optee->smc.notif_irq, optee);
                        irq_dispose_mapping(optee->smc.notif_irq);
                }
-
-               /*
-                * The thread normally working with optee->notif.ctx was
-                * stopped with free_irq() above.
-                *
-                * Note we're not using teedev_close_context() or
-                * tee_client_close_context() since we have already called
-                * tee_device_put() while initializing to avoid a circular
-                * reference counting.
-                */
-               teedev_close_context(optee->notif.ctx);
        }
 }
 
@@ -1356,6 +1335,7 @@ static int optee_probe(struct platform_device *pdev)
        struct optee *optee = NULL;
        void *memremaped_shm = NULL;
        struct tee_device *teedev;
+       struct tee_context *ctx;
        u32 max_notif_value;
        u32 sec_caps;
        int rc;
@@ -1436,9 +1416,13 @@ static int optee_probe(struct platform_device *pdev)
        optee->pool = pool;
 
        platform_set_drvdata(pdev, optee);
+       ctx = teedev_open(optee->teedev);
+       if (IS_ERR(ctx))
+               goto err_supp_uninit;
+       optee->ctx = ctx;
        rc = optee_notif_init(optee, max_notif_value);
        if (rc)
-               goto err_supp_uninit;
+               goto err_close_ctx;
 
        if (sec_caps & OPTEE_SMC_SEC_CAP_ASYNC_NOTIF) {
                unsigned int irq;
@@ -1486,6 +1470,8 @@ err_disable_shm_cache:
        optee_unregister_devices();
 err_notif_uninit:
        optee_notif_uninit(optee);
+err_close_ctx:
+       teedev_close_context(ctx);
 err_supp_uninit:
        optee_supp_uninit(&optee->supp);
        mutex_destroy(&optee->call_queue.mutex);