diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 27cce454c86a..3d736c74a60d 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015,2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015,2020-2021 The Linux Foundation. All rights reserved. */ #include @@ -2020,6 +2020,38 @@ int __qcom_scm_request_encrypted_log(struct device *dev, phys_addr_t buf, return ret ? : desc.res[0]; } +int __qcom_scm_invoke_smc_legacy(struct device *dev, phys_addr_t in_buf, + size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, + int32_t *result, u64 *response_type, unsigned int *data) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_SMCINVOKE, + .cmd = QCOM_SCM_SMCINVOKE_INVOKE_LEGACY, + .owner = ARM_SMCCC_OWNER_TRUSTED_OS + }; + + desc.args[0] = in_buf; + desc.args[1] = in_buf_size; + desc.args[2] = out_buf; + desc.args[3] = out_buf_size; + desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, + QCOM_SCM_VAL); + + ret = qcom_scm_call(dev, &desc); + + if (result) + *result = desc.res[1]; + + if (response_type) + *response_type = desc.res[0]; + + if (data) + *data = desc.res[2]; + + return ret; +} + int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *response_type, unsigned int *data) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 0b20d4af4c09..33b3c188bb81 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -980,6 +980,15 @@ int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len, } EXPORT_SYMBOL(qcom_scm_request_encrypted_log); +int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size, + phys_addr_t out_buf, size_t out_buf_size, int32_t *result, + u64 *response_type, unsigned int *data) +{ + return __qcom_scm_invoke_smc_legacy(__scm->dev, in_buf, in_buf_size, out_buf, + out_buf_size, result, response_type, data); +} +EXPORT_SYMBOL(qcom_scm_invoke_smc_legacy); + 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, int32_t *result, u64 *response_type, unsigned int *data) diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 60ba9b8a67a9..9406a82f23bc 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2010-2015,2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2015,2020-2021 The Linux Foundation. All rights reserved. */ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H @@ -260,8 +260,12 @@ extern int __qcom_scm_request_encrypted_log(struct device *dev, phys_addr_t buf, extern int __qcom_scm_ice_restore_cfg(struct device *dev); #define QCOM_SCM_SVC_SMCINVOKE 0x06 +#define QCOM_SCM_SMCINVOKE_INVOKE_LEGACY 0x00 #define QCOM_SCM_SMCINVOKE_INVOKE 0x02 #define QCOM_SCM_SMCINVOKE_CB_RSP 0x01 +extern int __qcom_scm_invoke_smc_legacy(struct device *dev, phys_addr_t in_buf, + size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, + int32_t *result, u64 *response_type, unsigned int *data); extern int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *response_type, unsigned int *data); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 2f73d491dc71..cb799791f626 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -192,6 +192,9 @@ extern int qcom_scm_register_qsee_log_buf(phys_addr_t buf, size_t len); extern int qcom_scm_query_encrypted_log_feature(u64 *enabled); extern int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len, uint32_t log_id); +extern int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size, + phys_addr_t out_buf, size_t out_buf_size, int32_t *result, + u64 *response_type, unsigned int *data); 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, int32_t *result, u64 *response_type, unsigned int *data); @@ -365,6 +368,9 @@ static inline int qcom_scm_query_encrypted_log_feature(u64 *enabled) static inline int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len, uint32_t log_id) { return -ENODEV; } +static inline int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size, + phys_addr_t out_buf, size_t out_buf_size, int32_t *result, + u64 *request_type, unsigned int *data) { return -ENODEV; } static inline 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, int32_t *result, u64 *request_type, unsigned int *data) { return -ENODEV; }