Lines Matching +full:smc +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-only
14 #include <linux/arm-smccc.h>
15 #include <linux/dma-mapping.h>
21 * @args: The array of values used in registers in smc instruction
33 #define SCM_SMC_FIRST_EXT_IDX (SCM_SMC_N_REG_ARGS - 1)
34 #define SCM_SMC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1)
36 #define SCM_SMC_LAST_REG_IDX (SCM_SMC_FIRST_REG_IDX + SCM_SMC_N_REG_ARGS - 1)
38 static void __scm_smc_do_quirk(const struct arm_smccc_args *smc, in __scm_smc_do_quirk() argument
41 unsigned long a0 = smc->args[0]; in __scm_smc_do_quirk()
42 struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 }; in __scm_smc_do_quirk()
47 arm_smccc_smc_quirk(a0, smc->args[1], smc->args[2], in __scm_smc_do_quirk()
48 smc->args[3], smc->args[4], smc->args[5], in __scm_smc_do_quirk()
49 quirk.state.a6, smc->args[7], res, &quirk); in __scm_smc_do_quirk()
51 if (res->a0 == QCOM_SCM_INTERRUPTED) in __scm_smc_do_quirk()
52 a0 = res->a0; in __scm_smc_do_quirk()
54 } while (res->a0 == QCOM_SCM_INTERRUPTED); in __scm_smc_do_quirk()
59 memset(resume->args, 0, sizeof(resume->args[0]) * ARRAY_SIZE(resume->args)); in fill_wq_resume_args()
61 resume->args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, in fill_wq_resume_args()
65 resume->args[1] = QCOM_SCM_ARGS(1); in fill_wq_resume_args()
67 resume->args[2] = smc_call_ctx; in fill_wq_resume_args()
99 struct arm_smccc_args *smc = waitq; in __scm_smc_do_quirk_handle_waitq() local
102 __scm_smc_do_quirk(smc, res); in __scm_smc_do_quirk_handle_waitq()
104 if (res->a0 == QCOM_SCM_WAITQ_SLEEP) { in __scm_smc_do_quirk_handle_waitq()
105 wq_ctx = res->a1; in __scm_smc_do_quirk_handle_waitq()
106 smc_call_ctx = res->a2; in __scm_smc_do_quirk_handle_waitq()
113 smc = &resume; in __scm_smc_do_quirk_handle_waitq()
115 } while (res->a0 == QCOM_SCM_WAITQ_SLEEP); in __scm_smc_do_quirk_handle_waitq()
120 static int __scm_smc_do(struct device *dev, struct arm_smccc_args *smc, in __scm_smc_do() argument
126 __scm_smc_do_quirk(smc, res); in __scm_smc_do()
133 ret = __scm_smc_do_quirk_handle_waitq(dev, smc, res); in __scm_smc_do()
140 if (res->a0 == QCOM_SCM_V2_EBUSY) { in __scm_smc_do()
145 } while (res->a0 == QCOM_SCM_V2_EBUSY); in __scm_smc_do()
155 int arglen = desc->arginfo & 0xf; in __scm_smc_call()
163 struct arm_smccc_args smc = {0}; in __scm_smc_call() local
165 smc.args[0] = ARM_SMCCC_CALL_VAL( in __scm_smc_call()
168 desc->owner, in __scm_smc_call()
169 SCM_SMC_FNID(desc->svc, desc->cmd)); in __scm_smc_call()
170 smc.args[1] = desc->arginfo; in __scm_smc_call()
172 smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i]; in __scm_smc_call()
178 return -EINVAL; in __scm_smc_call()
184 return -ENOMEM; in __scm_smc_call()
190 args[i] = cpu_to_le32(desc->args[i + in __scm_smc_call()
196 args[i] = cpu_to_le64(desc->args[i + in __scm_smc_call()
200 smc.args[SCM_SMC_LAST_REG_IDX] = qcom_tzmem_to_phys(args_virt); in __scm_smc_call()
203 ret = __scm_smc_do(dev, &smc, &smc_res, atomic); in __scm_smc_call()
208 res->result[0] = smc_res.a1; in __scm_smc_call()
209 res->result[1] = smc_res.a2; in __scm_smc_call()
210 res->result[2] = smc_res.a3; in __scm_smc_call()