mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
firmware: qcom_scm: Enable legacy convention in qcom_scm-64.c
Enable legacy calling convention in qcom_scm-64. Add enum to represent current calling convention being used. Update is_call_available to use legacy function numbers when using legacy convention. Change-Id: I4aa1364f219d4db68c03023e63009a53326ecca5 Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
parent
298983059d
commit
bdce17645f
1 changed files with 50 additions and 12 deletions
|
|
@ -58,7 +58,14 @@ struct arm_smccc_args {
|
|||
unsigned long a[8];
|
||||
};
|
||||
|
||||
static u64 qcom_smccc_convention = -1;
|
||||
enum qcom_smc_convention {
|
||||
SMC_CONVENTION_UNKNOWN,
|
||||
SMC_CONVENTION_LEGACY,
|
||||
SMC_CONVENTION_ARM_32,
|
||||
SMC_CONVENTION_ARM_64,
|
||||
};
|
||||
|
||||
static enum qcom_smc_convention qcom_smc_convention = SMC_CONVENTION_UNKNOWN;
|
||||
static DEFINE_MUTEX(qcom_scm_lock);
|
||||
|
||||
#define QCOM_SCM_EBUSY_WAIT_MS 30
|
||||
|
|
@ -177,6 +184,9 @@ static int qcom_scm_call_smccc(struct device *dev,
|
|||
size_t alloc_len;
|
||||
gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
|
||||
u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
|
||||
u32 qcom_smccc_convention =
|
||||
(qcom_smc_convention == SMC_CONVENTION_ARM_32) ?
|
||||
ARM_SMCCC_SMC_32 : ARM_SMCCC_SMC_64;
|
||||
struct arm_smccc_res res;
|
||||
struct arm_smccc_args smc = {{0}};
|
||||
|
||||
|
|
@ -196,7 +206,7 @@ static int qcom_scm_call_smccc(struct device *dev,
|
|||
if (!args_virt)
|
||||
return -ENOMEM;
|
||||
|
||||
if (qcom_smccc_convention == ARM_SMCCC_SMC_32) {
|
||||
if (qcom_smc_convention == SMC_CONVENTION_ARM_32) {
|
||||
__le32 *args = args_virt;
|
||||
|
||||
for (i = 0; i < SMCCC_N_EXT_ARGS; i++)
|
||||
|
|
@ -429,7 +439,16 @@ static int qcom_scm_call_atomic_legacy(struct device *dev,
|
|||
static int qcom_scm_call(struct device *dev, struct qcom_scm_desc *desc)
|
||||
{
|
||||
might_sleep();
|
||||
return qcom_scm_call_smccc(dev, desc, false);
|
||||
switch (qcom_smc_convention) {
|
||||
case SMC_CONVENTION_ARM_32:
|
||||
case SMC_CONVENTION_ARM_64:
|
||||
return qcom_scm_call_smccc(dev, desc, false);
|
||||
case SMC_CONVENTION_LEGACY:
|
||||
return qcom_scm_call_legacy(dev, desc);
|
||||
default:
|
||||
pr_err("Unknown current SCM calling convention.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -445,7 +464,16 @@ static int qcom_scm_call(struct device *dev, struct qcom_scm_desc *desc)
|
|||
*/
|
||||
static int qcom_scm_call_atomic(struct device *dev, struct qcom_scm_desc *desc)
|
||||
{
|
||||
return qcom_scm_call_smccc(dev, desc, true);
|
||||
switch (qcom_smc_convention) {
|
||||
case SMC_CONVENTION_ARM_32:
|
||||
case SMC_CONVENTION_ARM_64:
|
||||
return qcom_scm_call_smccc(dev, desc, true);
|
||||
case SMC_CONVENTION_LEGACY:
|
||||
return qcom_scm_call_atomic_legacy(dev, desc);
|
||||
default:
|
||||
pr_err("Unknown current SCM calling convention.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -742,10 +770,21 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
|
|||
};
|
||||
|
||||
desc.arginfo = QCOM_SCM_ARGS(1);
|
||||
desc.args[0] = SMCCC_FUNCNUM(svc_id, cmd_id) |
|
||||
(ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT);
|
||||
switch (qcom_smc_convention) {
|
||||
case SMC_CONVENTION_ARM_32:
|
||||
case SMC_CONVENTION_ARM_64:
|
||||
desc.args[0] = SMCCC_FUNCNUM(svc_id, cmd_id) |
|
||||
(ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT);
|
||||
break;
|
||||
case SMC_CONVENTION_LEGACY:
|
||||
desc.args[0] = LEGACY_FUNCNUM(svc_id, cmd_id);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown SMC convention being used\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = qcom_scm_call(dev, &desc);
|
||||
ret = qcom_scm_call_atomic(dev, &desc);
|
||||
|
||||
return ret ? : desc.res[0];
|
||||
}
|
||||
|
|
@ -902,17 +941,16 @@ void __qcom_scm_init(void)
|
|||
};
|
||||
|
||||
qcom_smcc_convention = ARM_SMCCC_SMC_64;
|
||||
ret = qcom_scm_call_atomic(NULL, &desc);
|
||||
ret = qcom_scm_call_smccc(NULL, &desc, true);
|
||||
if (!ret && desc.res[0] == 1)
|
||||
goto out;
|
||||
|
||||
qcom_smcc_convention = ARM_SMCCC_SMC_32;
|
||||
ret = qcom_scm_call_atomic(NULL, &desc);
|
||||
ret = qcom_scm_call_smccc(NULL, &desc, true);
|
||||
if (!ret && desc.res[0] == 1)
|
||||
goto out;
|
||||
|
||||
qcom_smccc_convention = -1;
|
||||
BUG();
|
||||
qcom_smc_convention = SMC_CONVENTION_LEGACY;
|
||||
out:
|
||||
pr_debug("QCOM SCM SMC Convention: %d\n", qcom_smcc_convention);
|
||||
pr_debug("QCOM SCM SMC Convention: %d\n", qcom_smc_convention);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue