mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
Merge "firmware: qcom_scm-32: Create common legacy atomic call"
This commit is contained in:
commit
ec7edb6fa6
1 changed files with 67 additions and 44 deletions
|
|
@ -260,6 +260,8 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define LEGACY_ATOMIC_N_REG_ARGS 5
|
||||
#define LEGACY_ATOMIC_FIRST_REG_IDX 2
|
||||
#define LEGACY_CLASS_REGISTER (0x2 << 8)
|
||||
#define LEGACY_MASK_IRQS BIT(5)
|
||||
#define LEGACY_ATOMIC_ID(svc, cmd, n) \
|
||||
|
|
@ -269,51 +271,33 @@ out:
|
|||
(n & 0xf))
|
||||
|
||||
/**
|
||||
* qcom_scm_call_atomic1() - Send an atomic SCM command with one argument
|
||||
* @svc_id: service identifier
|
||||
* @cmd_id: command identifier
|
||||
* @arg1: first argument
|
||||
* qcom_scm_call_atomic() - Send an atomic SCM command with up to 5 arguments
|
||||
* and 3 return values
|
||||
*
|
||||
* This shall only be used with commands that are guaranteed to be
|
||||
* uninterruptable, atomic and SMP safe.
|
||||
*/
|
||||
static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
|
||||
static int qcom_scm_call_atomic(struct qcom_scm_desc *desc)
|
||||
{
|
||||
int context_id;
|
||||
struct arm_smccc_args smc = {0};
|
||||
struct arm_smccc_args smc = {{0}};
|
||||
struct arm_smccc_res res;
|
||||
size_t i, arglen = desc->arginfo & 0xf;
|
||||
|
||||
smc.a[0] = LEGACY_ATOMIC_ID(svc, cmd, 1);
|
||||
BUG_ON(arglen > LEGACY_ATOMIC_N_REG_ARGS);
|
||||
|
||||
smc.a[0] = LEGACY_ATOMIC(desc->svc, desc->cmd, arglen);
|
||||
smc.a[1] = (unsigned long)&context_id;
|
||||
smc.a[2] = arg1;
|
||||
|
||||
for (i = 0; i < arglen; i++)
|
||||
smc.a[i + LEGACY_ATOMIC_FIRST_REG_IDX] = desc->args[i];
|
||||
|
||||
arm_smccc_smc(smc.a[0], smc.a[1], smc.a[2], smc.a[3],
|
||||
smc.a[4], smc.a[5], smc.a[6], smc.a[7], &res);
|
||||
|
||||
return res.a0;
|
||||
}
|
||||
|
||||
/**
|
||||
* qcom_scm_call_atomic2() - Send an atomic SCM command with two arguments
|
||||
* @svc_id: service identifier
|
||||
* @cmd_id: command identifier
|
||||
* @arg1: first argument
|
||||
* @arg2: second argument
|
||||
*
|
||||
* This shall only be used with commands that are guaranteed to be
|
||||
* uninterruptable, atomic and SMP safe.
|
||||
*/
|
||||
static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
|
||||
{
|
||||
int context_id;
|
||||
struct arm_smccc_args smc = {0};
|
||||
struct arm_smccc_res res;
|
||||
|
||||
smc.a[0] = LEGACY_ATOMIC_ID(svc, cmd, 2);
|
||||
smc.a[1] = (unsigned long)&context_id;
|
||||
smc.a[2] = arg1;
|
||||
smc.a[3] = arg2;
|
||||
arm_smccc_smc(smc.a[0], smc.a[1], smc.a[2], smc.a[3],
|
||||
smc.a[4], smc.a[5], smc.a[6], smc.a[7], &res);
|
||||
desc->res[0] = res.a1;
|
||||
desc->res[1] = res.a2;
|
||||
desc->res[2] = res.a3;
|
||||
|
||||
return res.a0;
|
||||
}
|
||||
|
|
@ -336,6 +320,11 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
|
|||
QCOM_SCM_FLAG_COLDBOOT_CPU2,
|
||||
QCOM_SCM_FLAG_COLDBOOT_CPU3,
|
||||
};
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_BOOT,
|
||||
.cmd = QCOM_SCM_BOOT_SET_ADDR,
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
if (!cpus || (cpus && cpumask_empty(cpus)))
|
||||
return -EINVAL;
|
||||
|
|
@ -347,8 +336,11 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
|
|||
set_cpu_present(cpu, false);
|
||||
}
|
||||
|
||||
return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_ADDR,
|
||||
flags, virt_to_phys(entry));
|
||||
desc.args[0] = flags;
|
||||
desc.args[1] = virt_to_phys(entry);
|
||||
desc.arginfo = QCOM_SCM_ARGS(2);
|
||||
|
||||
return qcom_scm_call_atomic(&desc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -406,8 +398,15 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
|
|||
*/
|
||||
void __qcom_scm_cpu_power_down(u32 flags)
|
||||
{
|
||||
qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_TERMINATE_PC,
|
||||
flags & QCOM_SCM_FLUSH_FLAG_MASK);
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_BOOT,
|
||||
.cmd = QCOM_SCM_BOOT_TERMINATE_PC,
|
||||
.args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK,
|
||||
.arginfo = QCOM_SCM_ARGS(1),
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
qcom_scm_call_atomic(&desc);
|
||||
}
|
||||
|
||||
int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
|
||||
|
|
@ -430,10 +429,17 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
|
|||
|
||||
int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
|
||||
{
|
||||
return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT,
|
||||
QCOM_SCM_BOOT_SET_DLOAD_MODE,
|
||||
enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0,
|
||||
0);
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_BOOT,
|
||||
.cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE,
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE;
|
||||
desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0;
|
||||
desc.arginfo = QCOM_SCM_ARGS(2);
|
||||
|
||||
return qcom_scm_call_atomic(&desc);
|
||||
}
|
||||
|
||||
bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral)
|
||||
|
|
@ -545,18 +551,35 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr,
|
|||
unsigned int *val)
|
||||
{
|
||||
int ret;
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_IO,
|
||||
.cmd = QCOM_SCM_IO_READ,
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
ret = qcom_scm_call_atomic1(QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, addr);
|
||||
desc.args[0] = addr;
|
||||
desc.arginfo = QCOM_SCM_ARGS(1);
|
||||
|
||||
ret = qcom_scm_call_atomic(&desc);
|
||||
if (ret >= 0)
|
||||
*val = ret;
|
||||
*val = desc.res[0];
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
|
||||
{
|
||||
return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
|
||||
addr, val);
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_IO,
|
||||
.cmd = QCOM_SCM_IO_WRITE,
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
desc.args[0] = addr;
|
||||
desc.args[1] = val;
|
||||
desc.arginfo = QCOM_SCM_ARGS(2);
|
||||
|
||||
return qcom_scm_call_atomic(&desc);
|
||||
}
|
||||
|
||||
int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
|
||||
|
|
|
|||
Loading…
Reference in a new issue