Merge "platform: msm_shared: Fix for spmi lock up issue"
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index b2ae7a9..6b9efb5 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -174,6 +174,9 @@
 #define SCM_SVC_ES                      0x10
 #define SCM_SAVE_PARTITION_HASH_ID      0x01
 
+#define SCM_SVC_PWR                     0x9
+#define SCM_IO_DISABLE_PMIC_ARBITER     0x1
+
 enum ap_ce_channel_type {
 AP_CE_REGISTER_USE = 0,
 AP_CE_ADM_USE = 1
@@ -187,6 +190,8 @@
 
 void set_tamper_fuse_cmd();
 
+int scm_halt_pmic_arbiter();
+
 /**
  * struct scm_command - one SCM command buffer
  * @len: total available memory for command and response
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 8adc0d2..5592f20 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -29,6 +29,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <err.h>
+#include <asm.h>
+#include <bits.h>
 #include <arch/ops.h>
 #include "scm.h"
 
@@ -41,6 +43,14 @@
 #  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 #endif
 
+#define SCM_CLASS_REGISTER         (0x2 << 8)
+#define SCM_MASK_IRQS              BIT(5)
+#define SCM_ATOMIC(svc, cmd, n)    ((((((svc) & 0x3f) << 10)|((cmd) & 0x3ff)) << 12) | \
+                                   SCM_CLASS_REGISTER | \
+                                   SCM_MASK_IRQS | \
+                                   ((n) & 0xf))
+
+
 /**
  * alloc_scm_command() - Allocate an SCM command
  * @cmd_size: size of the command buffer
@@ -122,6 +132,32 @@
 }
 
 /**
+* scm_call_automic: Make scm call with one or no argument
+* @svc: service id
+* @cmd: command id
+* @ arg1: argument
+*/
+
+static int scm_call_atomic(uint32_t svc, uint32_t cmd, uint32_t arg1)
+{
+	uint32_t context_id;
+	register uint32_t r0 __asm__("r0") = SCM_ATOMIC(svc, cmd, 1);
+	register uint32_t r1 __asm__("r1") = &context_id;
+	register uint32_t r2 __asm__("r2") = arg1;
+
+	__asm__ volatile(
+		__asmeq("%0", "r0")
+		__asmeq("%1", "r0")
+		__asmeq("%2", "r1")
+		__asmeq("%3", "r2")
+		"smc    #0  @ switch to secure world\n"
+		: "=r" (r0)
+		: "r" (r0), "r" (r1), "r" (r2)
+		: "r3");
+	return r0;
+}
+
+/**
  * scm_call() - Send an SCM command
  * @svc_id: service identifier
  * @cmd_id: command identifier
@@ -561,3 +597,11 @@
 	return resp_buf;
 }
 
+int scm_halt_pmic_arbiter()
+{
+	int ret = 0;
+
+	ret = scm_call_atomic(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER, 0);
+
+	return ret;
+}