summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/qcom_scm-64.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2017-03-06 10:49:34 +0100
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-03-06 10:49:34 +0100
commit700ea5e0e0dd70420a04e703ff264cc133834cba (patch)
treed217b0d90d014953ea10ab7d88809660d2da8a64 /drivers/firmware/qcom_scm-64.c
parent[media] media: ti-vpe: vpe: allow use of user specified stride (diff)
parentLinux 4.11-rc1 (diff)
downloadlinux-700ea5e0e0dd70420a04e703ff264cc133834cba.tar.xz
linux-700ea5e0e0dd70420a04e703ff264cc133834cba.zip
Merge tag 'v4.11-rc1' into patchwork
Linux 4.11-rc1 * tag 'v4.11-rc1': (10730 commits) Linux 4.11-rc1 strparser: destroy workqueue on module exit Documentation/sphinx: fix primary_domain configuration docs: Fix htmldocs build failure doc/ko_KR/memory-barriers: Update control-dependencies section pcieaer doc: update the link Documentation: Update path to sysrq.txt sfc: fix IPID endianness in TSOv2 sfc: avoid max() in array size rds: remove unnecessary returned value check rxrpc: Fix potential NULL-pointer exception nfp: correct DMA direction in XDP DMA sync nfp: don't tell FW about the reserved buffer space net: ethernet: bgmac: mac address change bug net: ethernet: bgmac: init sequence bug xen-netback: don't vfree() queues under spinlock xen-netback: keep a local pointer for vif in backend_disconnect() netfilter: nf_tables: don't call nfnetlink_set_err() if nfnetlink_send() fails netfilter: nft_set_rbtree: incorrect assumption on lower interval lookups netfilter: nf_conntrack_sip: fix wrong memory initialisation ...
Diffstat (limited to 'drivers/firmware/qcom_scm-64.c')
-rw-r--r--drivers/firmware/qcom_scm-64.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index 4a0f5ead4fb5..c9332590e8c6 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -91,6 +91,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
dma_addr_t args_phys = 0;
void *args_virt = NULL;
size_t alloc_len;
+ struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6};
if (unlikely(arglen > N_REGISTER_ARGS)) {
alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
@@ -131,10 +132,16 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
qcom_smccc_convention,
ARM_SMCCC_OWNER_SIP, fn_id);
+ quirk.state.a6 = 0;
+
do {
- arm_smccc_smc(cmd, desc->arginfo, desc->args[0],
- desc->args[1], desc->args[2], x5, 0, 0,
- res);
+ arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
+ desc->args[1], desc->args[2], x5,
+ quirk.state.a6, 0, res, &quirk);
+
+ if (res->a0 == QCOM_SCM_INTERRUPTED)
+ cmd = res->a0;
+
} while (res->a0 == QCOM_SCM_INTERRUPTED);
mutex_unlock(&qcom_scm_lock);
@@ -358,3 +365,19 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
return ret ? : res.a1;
}
+
+int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
+{
+ struct qcom_scm_desc desc = {0};
+ struct arm_smccc_res res;
+ int ret;
+
+ desc.args[0] = state;
+ desc.args[1] = id;
+ desc.arginfo = QCOM_SCM_ARGS(2);
+
+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
+ &desc, &res);
+
+ return ret ? : res.a1;
+}