[ARM] msm: Add item argument to smsm_change_state and smsm_get_state

The new protocol require writing to two state fields, and reading
several fields.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index f731dde..e33fd02 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -49,16 +49,13 @@
 struct shared_info
 {
 	int ready;
-	unsigned state_apps;
-	unsigned state_modem;
+	unsigned state;
 };
 
-static unsigned dummy_state_apps;
-static unsigned dummy_state_modem;
+static unsigned dummy_state[SMSM_STATE_COUNT];
 
 static struct shared_info smd_info = {
-	.state_apps = (unsigned) &dummy_state_apps,
-	.state_modem = (unsigned) &dummy_state_modem,
+	.state = (unsigned) &dummy_state,
 };
 
 module_param_named(debug_mask, msm_smd_debug_mask,
@@ -115,9 +112,14 @@
 
 extern int (*msm_check_for_modem_crash)(void);
 
+uint32_t raw_smsm_get_state(enum smsm_state_item item)
+{
+	return readl(smd_info.state + item * 4);
+}
+
 static int check_for_modem_crash(void)
 {
-	if (readl(smd_info.state_modem) & SMSM_RESET) {
+	if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
 		handle_modem_crash();
 		return -1;
 	}
@@ -978,8 +980,8 @@
 
 	spin_lock_irqsave(&smem_lock, flags);
 
-	apps = readl(smd_info.state_apps);
-	modm = readl(smd_info.state_modem);
+	apps = raw_smsm_get_state(SMSM_STATE_APPS);
+	modm = raw_smsm_get_state(SMSM_STATE_MODEM);
 
 	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
 		pr_info("<SM %08x %08x>\n", apps, modm);
@@ -992,24 +994,26 @@
 	return IRQ_HANDLED;
 }
 
-int smsm_change_state(uint32_t clear_mask, uint32_t set_mask)
+int smsm_change_state(enum smsm_state_item item,
+		      uint32_t clear_mask, uint32_t set_mask)
 {
 	unsigned long flags;
 	unsigned state;
+	unsigned addr = smd_info.state + item * 4;
 
 	if (!smd_info.ready)
 		return -EIO;
 
 	spin_lock_irqsave(&smem_lock, flags);
 
-	if (readl(smd_info.state_modem) & SMSM_RESET)
+	if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
 		handle_modem_crash();
 
-	state = (readl(smd_info.state_apps) & ~clear_mask) | set_mask;
-	writel(state, smd_info.state_apps);
+	state = (readl(addr) & ~clear_mask) | set_mask;
+	writel(state, addr);
 
 	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
-		pr_info("smsm_change_state %x\n", state);
+		pr_info("smsm_change_state %d %x\n", item, state);
 	notify_other_smsm();
 
 	spin_unlock_irqrestore(&smem_lock, flags);
@@ -1017,16 +1021,16 @@
 	return 0;
 }
 
-uint32_t smsm_get_state(void)
+uint32_t smsm_get_state(enum smsm_state_item item)
 {
 	unsigned long flags;
 	uint32_t rv;
 
 	spin_lock_irqsave(&smem_lock, flags);
 
-	rv = readl(smd_info.state_modem);
+	rv = readl(smd_info.state + item * 4);
 
-	if (rv & SMSM_RESET)
+	if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
 		handle_modem_crash();
 
 	spin_unlock_irqrestore(&smem_lock, flags);
@@ -1145,14 +1149,8 @@
 		unsigned size;
 		void *state;
 		state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
-		if (size == SMSM_V1_SIZE) {
-			smd_info.state_apps = state + SMSM_V1_STATE_APPS;
-			smd_info.state_modem = state + SMSM_V1_STATE_MODEM;
-			break;
-		}
-		if (size == SMSM_V2_SIZE) {
-			smd_info.state_apps = state + SMSM_V2_STATE_APPS;
-			smd_info.state_modem = state + SMSM_V2_STATE_MODEM;
+		if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
+			smd_info.state = (unsigned)state;
 			break;
 		}
 	}
@@ -1181,8 +1179,8 @@
 	do_smd_probe();
 
 	/* indicate that we're up and running */
-	writel(SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT, smd_info.state_apps);
-	notify_other_smsm();
+	smsm_change_state(SMSM_STATE_APPS,
+			  ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT);
 
 	pr_info("smd_core_init() done\n");
 
@@ -1227,13 +1225,13 @@
 
 	msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
 
-	if (readl(smd_info.state_modem) & SMSM_RESET)
+	if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
 		i += scnprintf(buf + i, max - i,
 			       "smsm: ARM9 HAS CRASHED\n");
 
 	i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
-		       readl(smd_info.state_modem),
-		       readl(smd_info.state_apps));
+		       raw_smsm_get_state(SMSM_STATE_MODEM),
+		       raw_smsm_get_state(SMSM_STATE_APPS));
 
 	if (msg) {
 		msg[SZ_DIAG_ERR_MSG - 1] = 0;
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index 732147c..35e0835 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -59,13 +59,7 @@
 };
 
 #define SMSM_V1_SIZE		(sizeof(unsigned) * 8)
-#define SMSM_V1_STATE_APPS	0x0000
-#define SMSM_V1_STATE_MODEM	0x0004
-#define SMSM_V1_STATE_DSP	0x0008
-
 #define SMSM_V2_SIZE		(sizeof(unsigned) * 4)
-#define SMSM_V2_STATE_APPS	0x0004
-#define SMSM_V2_STATE_MODEM	0x000C
 
 struct smsm_interrupt_info
 {
@@ -113,9 +107,29 @@
 #define SMSM_WKUP_REASON_ALARM	0x00000010
 #define SMSM_WKUP_REASON_RESET	0x00000020
 
+#ifndef CONFIG_ARCH_MSM_SCORPION
+enum smsm_state_item {
+	SMSM_STATE_APPS = 1,
+	SMSM_STATE_MODEM = 3,
+	SMSM_STATE_COUNT,
+};
+#else
+enum smsm_state_item {
+	SMSM_STATE_APPS,
+	SMSM_STATE_MODEM,
+	SMSM_STATE_HEXAGON,
+	SMSM_STATE_APPS_DEM,
+	SMSM_STATE_MODEM_DEM,
+	SMSM_STATE_QDSP6_DEM,
+	SMSM_STATE_POWER_MASTER_DEM,
+	SMSM_STATE_TIME_MASTER_DEM,
+	SMSM_STATE_COUNT,
+};
+#endif
+
 void *smem_alloc(unsigned id, unsigned size);
-int smsm_change_state(uint32_t clear_mask, uint32_t set_mask);
-uint32_t smsm_get_state(void);
+int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask);
+uint32_t smsm_get_state(enum smsm_state_item item);
 int smsm_set_sleep_duration(uint32_t delay);
 int smsm_set_interrupt_info(struct smsm_interrupt_info *info);
 void smsm_print_sleep_info(void);