aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThara Gopinath <thara.gopinath@linaro.org>2021-03-26 15:05:25 -0400
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2022-06-09 10:15:58 +0100
commit09c49793cf10713adcda4be592b84a71fdfca3bc (patch)
tree86c1adeb0f858d4549d2b62800ca1a9f8087930a
parent090854301b471d60d4de4402c9c80bf46950f39a (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.c59
-rw-r--r--drivers/firmware/qcom_scm.h5
-rw-r--r--include/linux/qcom_scm.h7
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