From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/tee/optee/rpc.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 103 insertions(+), 13 deletions(-) diff --git a/kernel/drivers/tee/optee/rpc.c b/kernel/drivers/tee/optee/rpc.c index b45c73d..f1e0332 100644 --- a/kernel/drivers/tee/optee/rpc.c +++ b/kernel/drivers/tee/optee/rpc.c @@ -1,21 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2016, Linaro Limited - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/delay.h> #include <linux/device.h> +#include <linux/i2c.h> #include <linux/slab.h> #include <linux/tee_drv.h> #include "optee_private.h" @@ -57,6 +49,98 @@ bad: arg->ret = TEEC_ERROR_BAD_PARAMETERS; } + +#if IS_REACHABLE(CONFIG_I2C) +static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx, + struct optee_msg_arg *arg) +{ + struct tee_param *params; + struct i2c_adapter *adapter; + struct i2c_msg msg = { }; + size_t i; + int ret = -EOPNOTSUPP; + u8 attr[] = { + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT, + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT, + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT, + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT, + }; + + if (arg->num_params != ARRAY_SIZE(attr)) { + arg->ret = TEEC_ERROR_BAD_PARAMETERS; + return; + } + + params = kmalloc_array(arg->num_params, sizeof(struct tee_param), + GFP_KERNEL); + if (!params) { + arg->ret = TEEC_ERROR_OUT_OF_MEMORY; + return; + } + + if (optee_from_msg_param(params, arg->num_params, arg->params)) + goto bad; + + for (i = 0; i < arg->num_params; i++) { + if (params[i].attr != attr[i]) + goto bad; + } + + adapter = i2c_get_adapter(params[0].u.value.b); + if (!adapter) + goto bad; + + if (params[1].u.value.a & OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT) { + if (!i2c_check_functionality(adapter, + I2C_FUNC_10BIT_ADDR)) { + i2c_put_adapter(adapter); + goto bad; + } + + msg.flags = I2C_M_TEN; + } + + msg.addr = params[0].u.value.c; + msg.buf = params[2].u.memref.shm->kaddr; + msg.len = params[2].u.memref.size; + + switch (params[0].u.value.a) { + case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD: + msg.flags |= I2C_M_RD; + break; + case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR: + break; + default: + i2c_put_adapter(adapter); + goto bad; + } + + ret = i2c_transfer(adapter, &msg, 1); + + if (ret < 0) { + arg->ret = TEEC_ERROR_COMMUNICATION; + } else { + params[3].u.value.a = msg.len; + if (optee_to_msg_param(arg->params, arg->num_params, params)) + arg->ret = TEEC_ERROR_BAD_PARAMETERS; + else + arg->ret = TEEC_SUCCESS; + } + + i2c_put_adapter(adapter); + kfree(params); + return; +bad: + kfree(params); + arg->ret = TEEC_ERROR_BAD_PARAMETERS; +} +#else +static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx, + struct optee_msg_arg *arg) +{ + arg->ret = TEEC_ERROR_NOT_SUPPORTED; +} +#endif static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key) { @@ -200,6 +284,7 @@ } 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) { @@ -229,7 +314,8 @@ shm = cmd_alloc_suppl(ctx, sz); break; case OPTEE_MSG_RPC_SHM_TYPE_KERNEL: - shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED); + shm = tee_shm_alloc(optee->ctx, sz, + TEE_SHM_MAPPED | TEE_SHM_PRIV); break; default: arg->ret = TEEC_ERROR_BAD_PARAMETERS; @@ -386,10 +472,13 @@ break; case OPTEE_MSG_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_MSG_RPC_CMD_SHM_FREE: handle_rpc_func_cmd_shm_free(ctx, arg); + break; + case OPTEE_MSG_RPC_CMD_I2C_TRANSFER: + handle_rpc_func_cmd_i2c_transfer(ctx, arg); break; default: handle_rpc_supp_cmd(ctx, arg); @@ -414,7 +503,8 @@ switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) { case OPTEE_SMC_RPC_FUNC_ALLOC: - shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED); + 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(¶m->a1, ¶m->a2, pa); reg_pair_from_64(¶m->a4, ¶m->a5, -- Gitblit v1.6.2