diff options
author | Thara Gopinath <thara.gopinath@linaro.org> | 2021-03-26 15:05:25 -0400 |
---|---|---|
committer | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2022-06-09 10:15:58 +0100 |
commit | 09c49793cf10713adcda4be592b84a71fdfca3bc (patch) | |
tree | 86c1adeb0f858d4549d2b62800ca1a9f8087930a | |
parent | 090854301b471d60d4de4402c9c80bf46950f39a (diff) |
DON'T UPSTREAM: firmware: qcom_scm: Add invoke and callback commands for smc invoke
Signed-off-by: Thara Gopinath <thara.gopinath@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-rw-r--r-- | drivers/firmware/qcom_scm.c | 59 | ||||
-rw-r--r-- | drivers/firmware/qcom_scm.h | 5 | ||||
-rw-r--r-- | include/linux/qcom_scm.h | 7 |
3 files changed, 71 insertions, 0 deletions
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2b5214d5c0da..c881f2fb2ff7 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -1056,6 +1056,65 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, } EXPORT_SYMBOL(qcom_scm_ice_set_key); +int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, + size_t out_buf_size, int *result, u64 *response_type, unsigned int *data) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_SMCINVOKE, + .cmd = QCOM_SCM_SMCINVOKE_INVOKE, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL), + .args[0] = in_buf, + .args[1] = in_buf_size, + .args[2] = out_buf, + .args[3] = out_buf_size, + .owner = ARM_SMCCC_OWNER_TRUSTED_OS, + }; + struct qcom_scm_res res; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + if (ret) + return ret; + + if (response_type) + *response_type = res.result[0]; + + if (result) + *result = res.result[1]; + + return ret; +} +EXPORT_SYMBOL(qcom_scm_invoke_smc); + +int qcom_scm_invoke_callback_response(phys_addr_t out_buf, size_t out_buf_size, int *result, + u64 *response_type, unsigned int *data) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_SMCINVOKE, + .cmd = QCOM_SCM_SMCINVOKE_CB_RSP, + .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL), + .args[0] = out_buf, + .args[1] = out_buf_size, + .owner = ARM_SMCCC_OWNER_TRUSTED_OS, + }; + struct qcom_scm_res res; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + if (ret) + return ret; + + if (response_type) + *response_type = res.result[0]; + if (result) + *result = res.result[1]; + if (data) + *data = res.result[2]; + + return ret; +} +EXPORT_SYMBOL(qcom_scm_invoke_callback_response); + /** * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. * diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index d92156ceb3ac..89cee14f132c 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -122,6 +122,11 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 +/* Trusted OS service and function IDs */ +#define QCOM_SCM_SVC_SMCINVOKE 0x06 +#define QCOM_SCM_SMCINVOKE_INVOKE 0x00 +#define QCOM_SCM_SMCINVOKE_CB_RSP 0x01 + extern void __qcom_scm_init(void); /* common error codes */ diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 81cad9e1e412..4981bf44a3fa 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -114,4 +114,11 @@ extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, extern int qcom_scm_lmh_profile_change(u32 profile_id); extern bool qcom_scm_lmh_dcvsh_available(void); +extern int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, + size_t out_buf_size, int *result, u64 *response_type, + unsigned int *data); + +extern int qcom_scm_invoke_callback_response(phys_addr_t out_buf, size_t out_buf_size, + int *result, u64 *response_type, + unsigned int *data); #endif |