mirror of
https://github.com/torvalds/linux
synced 2024-10-23 19:57:28 +00:00
firmware: qcom_scm-64: Improve SMC convention detection
Improve the calling convention detection to use __qcom_scm_is_call_available() and not blindly assume 32-bit mode if the checks fails. BUG() if neither 32-bit or 64-bit mode works. Tested-by: Brian Masney <masneyb@onstation.org> # arm32 Tested-by: Stephan Gerhold <stephan@gerhold.net> Signed-off-by: Elliot Berman <eberman@codeaurora.org> Link: https://lore.kernel.org/r/1578431066-19600-9-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
parent
3f951ea627
commit
5dad8deee2
|
@ -336,21 +336,34 @@ int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset,
|
||||||
|
|
||||||
void __qcom_scm_init(void)
|
void __qcom_scm_init(void)
|
||||||
{
|
{
|
||||||
u64 cmd;
|
struct qcom_scm_desc desc = {
|
||||||
struct arm_smccc_res res;
|
.svc = QCOM_SCM_SVC_INFO,
|
||||||
u32 fnid = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL);
|
.cmd = QCOM_SCM_INFO_IS_CALL_AVAIL,
|
||||||
|
.args[0] = SCM_SMC_FNID(QCOM_SCM_SVC_INFO,
|
||||||
|
QCOM_SCM_INFO_IS_CALL_AVAIL) |
|
||||||
|
(ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT),
|
||||||
|
.arginfo = QCOM_SCM_ARGS(1),
|
||||||
|
.owner = ARM_SMCCC_OWNER_SIP,
|
||||||
|
};
|
||||||
|
struct qcom_scm_res res;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* First try a SMC64 call */
|
qcom_smccc_convention = ARM_SMCCC_SMC_64;
|
||||||
cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64,
|
// Device isn't required as there is only one argument - no device
|
||||||
ARM_SMCCC_OWNER_SIP, fnid);
|
// needed to dma_map_single to secure world
|
||||||
|
ret = qcom_scm_call_atomic(NULL, &desc, &res);
|
||||||
|
if (!ret && res.result[0] == 1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
arm_smccc_smc(cmd, QCOM_SCM_ARGS(1), cmd & (~BIT(ARM_SMCCC_TYPE_SHIFT)),
|
qcom_smccc_convention = ARM_SMCCC_SMC_32;
|
||||||
0, 0, 0, 0, 0, &res);
|
ret = qcom_scm_call_atomic(NULL, &desc, &res);
|
||||||
|
if (!ret && res.result[0] == 1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (!res.a0 && res.a1)
|
qcom_smccc_convention = -1;
|
||||||
qcom_smccc_convention = ARM_SMCCC_SMC_64;
|
BUG();
|
||||||
else
|
out:
|
||||||
qcom_smccc_convention = ARM_SMCCC_SMC_32;
|
pr_info("QCOM SCM SMC Convention: %lld\n", qcom_smccc_convention);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral)
|
bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral)
|
||||||
|
|
Loading…
Reference in a new issue