msm: smem: split out shared memory functionality

For historical reasons, the low level shared memory functionality exists in
a combined driver with the higher level communication protocols.  Move the
low level shared memory functionality out into its own driver to improve
clarity and ease maintenance.

Change-Id: Ie55ecda7ef923c1f19a277ba8a47660f7a14e7b5
Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 321040e..400f859 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -75,7 +75,7 @@
 $(obj)/smd_rpc_sym.c: $(src)/smd_rpc_sym $(src)/mkrpcsym.pl
 	$(call if_changed,mkrpcsym)
 
-obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o
+obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o smem.o
 obj-$(CONFIG_MSM_SMP2P) += smp2p.o smp2p_debug.o smp2p_gpio.o
 obj-$(CONFIG_MSM_SMP2P_TEST) += smp2p_loopback.o smp2p_test.o smp2p_gpio_test.o smp2p_spinlock_test.o
 obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index d2be1f9..8d99ad1 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,10 +19,10 @@
 
 #include <mach/scm-io.h>
 #include <mach/msm_iomap.h>
+#include <mach/msm_smem.h>
 
 #include "clock.h"
 #include "clock-pll.h"
-#include "smd_private.h"
 
 #ifdef CONFIG_MSM_SECURE_IO
 #undef readl_relaxed
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index d155c6f..2cc7b10 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -19,7 +19,9 @@
 #define __ASM_ARCH_MSM_SMD_H
 
 #include <linux/io.h>
-#include <mach/msm_smsm.h>
+#include <linux/notifier.h>
+
+#include <mach/msm_smem.h>
 
 typedef struct smd_channel smd_channel_t;
 
@@ -40,13 +42,13 @@
  * SMD, the entry will only exist in this enum.
  */
 enum {
-	SMD_APPS = SMSM_APPS,
-	SMD_MODEM = SMSM_MODEM,
-	SMD_Q6 = SMSM_Q6,
-	SMD_WCNSS = SMSM_WCNSS,
-	SMD_DSPS = SMSM_DSPS,
-	SMD_MODEM_Q6_FW,
-	SMD_RPM,
+	SMD_APPS = SMEM_APPS,
+	SMD_MODEM = SMEM_MODEM,
+	SMD_Q6 = SMEM_Q6,
+	SMD_DSPS = SMEM_DSPS,
+	SMD_WCNSS = SMEM_WCNSS,
+	SMD_MODEM_Q6_FW = SMEM_MODEM_Q6_FW,
+	SMD_RPM = SMEM_RPM,
 	NUM_SMD_SUBSYSTEMS,
 };
 
diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h
new file mode 100644
index 0000000..57f22cc
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_smem.h
@@ -0,0 +1,180 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_SMEM_H_
+#define _ARCH_ARM_MACH_MSM_SMEM_H_
+
+#include <linux/types.h>
+
+enum {
+	SMEM_APPS,
+	SMEM_MODEM,
+	SMEM_Q6,
+	SMEM_DSPS,
+	SMEM_WCNSS,
+	SMEM_MODEM_Q6_FW,
+	SMEM_RPM,
+	NUM_SMEM_SUBSYSTEMS,
+};
+
+#define SMEM_NUM_SMD_STREAM_CHANNELS        64
+#define SMEM_NUM_SMD_BLOCK_CHANNELS         64
+
+enum {
+	/* fixed items */
+	SMEM_PROC_COMM = 0,
+	SMEM_HEAP_INFO,
+	SMEM_ALLOCATION_TABLE,
+	SMEM_VERSION_INFO,
+	SMEM_HW_RESET_DETECT,
+	SMEM_AARM_WARM_BOOT,
+	SMEM_DIAG_ERR_MESSAGE,
+	SMEM_SPINLOCK_ARRAY,
+	SMEM_MEMORY_BARRIER_LOCATION,
+	SMEM_FIXED_ITEM_LAST = SMEM_MEMORY_BARRIER_LOCATION,
+
+	/* dynamic items */
+	SMEM_AARM_PARTITION_TABLE,
+	SMEM_AARM_BAD_BLOCK_TABLE,
+	SMEM_RESERVE_BAD_BLOCKS,
+	SMEM_WM_UUID,
+	SMEM_CHANNEL_ALLOC_TBL,
+	SMEM_SMD_BASE_ID,
+	SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_STREAM_CHANNELS,
+	SMEM_SMEM_LOG_EVENTS,
+	SMEM_SMEM_STATIC_LOG_IDX,
+	SMEM_SMEM_STATIC_LOG_EVENTS,
+	SMEM_SMEM_SLOW_CLOCK_SYNC,
+	SMEM_SMEM_SLOW_CLOCK_VALUE,
+	SMEM_BIO_LED_BUF,
+	SMEM_SMSM_SHARED_STATE,
+	SMEM_SMSM_INT_INFO,
+	SMEM_SMSM_SLEEP_DELAY,
+	SMEM_SMSM_LIMIT_SLEEP,
+	SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
+	SMEM_KEYPAD_KEYS_PRESSED,
+	SMEM_KEYPAD_STATE_UPDATED,
+	SMEM_KEYPAD_STATE_IDX,
+	SMEM_GPIO_INT,
+	SMEM_MDDI_LCD_IDX,
+	SMEM_MDDI_HOST_DRIVER_STATE,
+	SMEM_MDDI_LCD_DISP_STATE,
+	SMEM_LCD_CUR_PANEL,
+	SMEM_MARM_BOOT_SEGMENT_INFO,
+	SMEM_AARM_BOOT_SEGMENT_INFO,
+	SMEM_SLEEP_STATIC,
+	SMEM_SCORPION_FREQUENCY,
+	SMEM_SMD_PROFILES,
+	SMEM_TSSC_BUSY,
+	SMEM_HS_SUSPEND_FILTER_INFO,
+	SMEM_BATT_INFO,
+	SMEM_APPS_BOOT_MODE,
+	SMEM_VERSION_FIRST,
+	SMEM_VERSION_SMD = SMEM_VERSION_FIRST,
+	SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
+	SMEM_OSS_RRCASN1_BUF1,
+	SMEM_OSS_RRCASN1_BUF2,
+	SMEM_ID_VENDOR0,
+	SMEM_ID_VENDOR1,
+	SMEM_ID_VENDOR2,
+	SMEM_HW_SW_BUILD_ID,
+	SMEM_SMD_BLOCK_PORT_BASE_ID,
+	SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID +
+						SMEM_NUM_SMD_BLOCK_CHANNELS,
+	SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP +
+						SMEM_NUM_SMD_BLOCK_CHANNELS,
+	SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP +
+						SMEM_NUM_SMD_BLOCK_CHANNELS,
+	SMEM_SCLK_CONVERSION,
+	SMEM_SMD_SMSM_INTR_MUX,
+	SMEM_SMSM_CPU_INTR_MASK,
+	SMEM_APPS_DEM_SLAVE_DATA,
+	SMEM_QDSP6_DEM_SLAVE_DATA,
+	SMEM_CLKREGIM_BSP,
+	SMEM_CLKREGIM_SOURCES,
+	SMEM_SMD_FIFO_BASE_ID,
+	SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID +
+						SMEM_NUM_SMD_STREAM_CHANNELS,
+	SMEM_POWER_ON_STATUS_INFO,
+	SMEM_DAL_AREA,
+	SMEM_SMEM_LOG_POWER_IDX,
+	SMEM_SMEM_LOG_POWER_WRAP,
+	SMEM_SMEM_LOG_POWER_EVENTS,
+	SMEM_ERR_CRASH_LOG,
+	SMEM_ERR_F3_TRACE_LOG,
+	SMEM_SMD_BRIDGE_ALLOC_TABLE,
+	SMEM_SMDLITE_TABLE,
+	SMEM_SD_IMG_UPGRADE_STATUS,
+	SMEM_SEFS_INFO,
+	SMEM_RESET_LOG,
+	SMEM_RESET_LOG_SYMBOLS,
+	SMEM_MODEM_SW_BUILD_ID,
+	SMEM_SMEM_LOG_MPROC_WRAP,
+	SMEM_BOOT_INFO_FOR_APPS,
+	SMEM_SMSM_SIZE_INFO,
+	SMEM_SMD_LOOPBACK_REGISTER,
+	SMEM_SSR_REASON_MSS0,
+	SMEM_SSR_REASON_WCNSS0,
+	SMEM_SSR_REASON_LPASS0,
+	SMEM_SSR_REASON_DSPS0,
+	SMEM_SSR_REASON_VCODEC0,
+	SMEM_SMP2P_APPS_BASE = 427,
+	SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8,    /* 435 */
+	SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8,   /* 443 */
+	SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */
+	SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */
+	SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8,  /* 467 */
+	SMEM_BAM_PIPE_MEMORY,     /* 468 */
+	SMEM_IMAGE_VERSION_TABLE, /* 469 */
+	SMEM_LC_DEBUGGER, /* 470 */
+	SMEM_NUM_ITEMS,
+};
+
+#ifdef CONFIG_MSM_SMD
+void *smem_alloc(unsigned id, unsigned size);
+void *smem_alloc2(unsigned id, unsigned size_in);
+void *smem_get_entry(unsigned id, unsigned *size);
+void *smem_find(unsigned id, unsigned size);
+/**
+ * smem_virt_to_phys() - Convert SMEM address to physical address.
+ *
+ * @smem_address: Virtual address returned by smem_alloc()/smem_alloc2()
+ * @returns: Physical address (or NULL if there is a failure)
+ *
+ * This function should only be used if an SMEM item needs to be handed
+ * off to a DMA engine.
+ */
+phys_addr_t smem_virt_to_phys(void *smem_address);
+
+#else
+static inline void *smem_alloc(unsigned id, unsigned size)
+{
+	return NULL;
+}
+static inline void *smem_alloc2(unsigned id, unsigned size_in)
+{
+	return NULL;
+}
+static inline void *smem_get_entry(unsigned id, unsigned *size)
+{
+	return NULL;
+}
+static inline void *smem_find(unsigned id, unsigned size)
+{
+	return NULL;
+}
+static inline phys_addr_t smem_virt_to_phys(void *smem_address)
+{
+	return (phys_addr_t) NULL;
+}
+#endif /* CONFIG_MSM_SMD  */
+#endif /* _ARCH_ARM_MACH_MSM_SMEM_H_ */
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 5173c12..733f5a9 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -14,6 +14,9 @@
 #define _ARCH_ARM_MACH_MSM_SMSM_H_
 
 #include <linux/notifier.h>
+
+#include <mach/msm_smem.h>
+
 #if defined(CONFIG_MSM_N_WAY_SMSM)
 enum {
 	SMSM_APPS_STATE,
@@ -37,11 +40,11 @@
 #endif
 
 enum {
-	SMSM_APPS,
-	SMSM_MODEM,
-	SMSM_Q6,
-	SMSM_WCNSS,
-	SMSM_DSPS,
+	SMSM_APPS = SMEM_APPS,
+	SMSM_MODEM = SMEM_MODEM,
+	SMSM_Q6 = SMEM_Q6,
+	SMSM_DSPS = SMEM_DSPS,
+	SMSM_WCNSS = SMEM_WCNSS,
 };
 extern uint32_t SMSM_NUM_HOSTS;
 
@@ -97,119 +100,6 @@
 #define SMSM_SUBSYS2AP_STATUS         0x00008000
 
 
-#define SMEM_NUM_SMD_STREAM_CHANNELS        64
-#define SMEM_NUM_SMD_BLOCK_CHANNELS         64
-
-enum {
-	/* fixed items */
-	SMEM_PROC_COMM = 0,
-	SMEM_HEAP_INFO,
-	SMEM_ALLOCATION_TABLE,
-	SMEM_VERSION_INFO,
-	SMEM_HW_RESET_DETECT,
-	SMEM_AARM_WARM_BOOT,
-	SMEM_DIAG_ERR_MESSAGE,
-	SMEM_SPINLOCK_ARRAY,
-	SMEM_MEMORY_BARRIER_LOCATION,
-	SMEM_FIXED_ITEM_LAST = SMEM_MEMORY_BARRIER_LOCATION,
-
-	/* dynamic items */
-	SMEM_AARM_PARTITION_TABLE,
-	SMEM_AARM_BAD_BLOCK_TABLE,
-	SMEM_RESERVE_BAD_BLOCKS,
-	SMEM_WM_UUID,
-	SMEM_CHANNEL_ALLOC_TBL,
-	SMEM_SMD_BASE_ID,
-	SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_STREAM_CHANNELS,
-	SMEM_SMEM_LOG_EVENTS,
-	SMEM_SMEM_STATIC_LOG_IDX,
-	SMEM_SMEM_STATIC_LOG_EVENTS,
-	SMEM_SMEM_SLOW_CLOCK_SYNC,
-	SMEM_SMEM_SLOW_CLOCK_VALUE,
-	SMEM_BIO_LED_BUF,
-	SMEM_SMSM_SHARED_STATE,
-	SMEM_SMSM_INT_INFO,
-	SMEM_SMSM_SLEEP_DELAY,
-	SMEM_SMSM_LIMIT_SLEEP,
-	SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
-	SMEM_KEYPAD_KEYS_PRESSED,
-	SMEM_KEYPAD_STATE_UPDATED,
-	SMEM_KEYPAD_STATE_IDX,
-	SMEM_GPIO_INT,
-	SMEM_MDDI_LCD_IDX,
-	SMEM_MDDI_HOST_DRIVER_STATE,
-	SMEM_MDDI_LCD_DISP_STATE,
-	SMEM_LCD_CUR_PANEL,
-	SMEM_MARM_BOOT_SEGMENT_INFO,
-	SMEM_AARM_BOOT_SEGMENT_INFO,
-	SMEM_SLEEP_STATIC,
-	SMEM_SCORPION_FREQUENCY,
-	SMEM_SMD_PROFILES,
-	SMEM_TSSC_BUSY,
-	SMEM_HS_SUSPEND_FILTER_INFO,
-	SMEM_BATT_INFO,
-	SMEM_APPS_BOOT_MODE,
-	SMEM_VERSION_FIRST,
-	SMEM_VERSION_SMD = SMEM_VERSION_FIRST,
-	SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
-	SMEM_OSS_RRCASN1_BUF1,
-	SMEM_OSS_RRCASN1_BUF2,
-	SMEM_ID_VENDOR0,
-	SMEM_ID_VENDOR1,
-	SMEM_ID_VENDOR2,
-	SMEM_HW_SW_BUILD_ID,
-	SMEM_SMD_BLOCK_PORT_BASE_ID,
-	SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID +
-						SMEM_NUM_SMD_BLOCK_CHANNELS,
-	SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP +
-						SMEM_NUM_SMD_BLOCK_CHANNELS,
-	SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP +
-						SMEM_NUM_SMD_BLOCK_CHANNELS,
-	SMEM_SCLK_CONVERSION,
-	SMEM_SMD_SMSM_INTR_MUX,
-	SMEM_SMSM_CPU_INTR_MASK,
-	SMEM_APPS_DEM_SLAVE_DATA,
-	SMEM_QDSP6_DEM_SLAVE_DATA,
-	SMEM_CLKREGIM_BSP,
-	SMEM_CLKREGIM_SOURCES,
-	SMEM_SMD_FIFO_BASE_ID,
-	SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID +
-						SMEM_NUM_SMD_STREAM_CHANNELS,
-	SMEM_POWER_ON_STATUS_INFO,
-	SMEM_DAL_AREA,
-	SMEM_SMEM_LOG_POWER_IDX,
-	SMEM_SMEM_LOG_POWER_WRAP,
-	SMEM_SMEM_LOG_POWER_EVENTS,
-	SMEM_ERR_CRASH_LOG,
-	SMEM_ERR_F3_TRACE_LOG,
-	SMEM_SMD_BRIDGE_ALLOC_TABLE,
-	SMEM_SMDLITE_TABLE,
-	SMEM_SD_IMG_UPGRADE_STATUS,
-	SMEM_SEFS_INFO,
-	SMEM_RESET_LOG,
-	SMEM_RESET_LOG_SYMBOLS,
-	SMEM_MODEM_SW_BUILD_ID,
-	SMEM_SMEM_LOG_MPROC_WRAP,
-	SMEM_BOOT_INFO_FOR_APPS,
-	SMEM_SMSM_SIZE_INFO,
-	SMEM_SMD_LOOPBACK_REGISTER,
-	SMEM_SSR_REASON_MSS0,
-	SMEM_SSR_REASON_WCNSS0,
-	SMEM_SSR_REASON_LPASS0,
-	SMEM_SSR_REASON_DSPS0,
-	SMEM_SSR_REASON_VCODEC0,
-	SMEM_SMP2P_APPS_BASE = 427,
-	SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8,    /* 435 */
-	SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8,   /* 443 */
-	SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */
-	SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */
-	SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8,  /* 467 */
-	SMEM_BAM_PIPE_MEMORY,     /* 468 */
-	SMEM_IMAGE_VERSION_TABLE, /* 469 */
-	SMEM_LC_DEBUGGER, /* 470 */
-	SMEM_NUM_ITEMS,
-};
-
 enum {
 	SMEM_APPS_Q6_SMSM = 3,
 	SMEM_Q6_APPS_SMSM = 5,
@@ -217,9 +107,6 @@
 };
 
 #ifdef CONFIG_MSM_SMD
-void *smem_alloc(unsigned id, unsigned size);
-void *smem_alloc2(unsigned id, unsigned size_in);
-void *smem_get_entry(unsigned id, unsigned *size);
 int smsm_change_state(uint32_t smsm_entry,
 		      uint32_t clear_mask, uint32_t set_mask);
 
@@ -254,36 +141,8 @@
 
 
 int smsm_check_for_modem_crash(void);
-void *smem_find(unsigned id, unsigned size);
-void *smem_get_entry(unsigned id, unsigned *size);
-
-/**
- * smem_virt_to_phys() - Convert SMEM address to physical address.
- *
- * @smem_address: Virtual address returned by smem_alloc()/smem_alloc2()
- * @returns: Physical address (or NULL if there is a failure)
- *
- * This function should only be used if an SMEM item needs to be handed
- * off to a DMA engine.
- */
-phys_addr_t smem_virt_to_phys(void *smem_address);
 
 #else
-static inline void *smem_alloc(unsigned id, unsigned size)
-{
-	return NULL;
-}
-
-static inline void *smem_alloc2(unsigned id, unsigned size_in)
-{
-	return NULL;
-}
-
-static inline void *smem_get_entry(unsigned id, unsigned *size)
-{
-	return NULL;
-}
-
 static inline int smsm_change_state(uint32_t smsm_entry,
 		      uint32_t clear_mask, uint32_t set_mask)
 {
@@ -347,13 +206,5 @@
 {
 	return -ENODEV;
 }
-static inline void *smem_find(unsigned id, unsigned size)
-{
-	return NULL;
-}
-static inline phys_addr_t smem_virt_to_phys(void *smem_address)
-{
-	return (phys_addr_t) NULL;
-}
 #endif
 #endif
diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c
index 781cd69..97195e3 100644
--- a/arch/arm/mach-msm/memory_topology.c
+++ b/arch/arm/mach-msm/memory_topology.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
 #include <linux/memory.h>
 #include <mach/msm_memtypes.h>
 #include <mach/socinfo.h>
+#include <mach/msm_smem.h>
 #include "smd_private.h"
 
 #if defined(CONFIG_ARCH_MSM8960)
diff --git a/arch/arm/mach-msm/msm_smem_iface.h b/arch/arm/mach-msm/msm_smem_iface.h
index bc3e73b..c9c56d9 100644
--- a/arch/arm/mach-msm/msm_smem_iface.h
+++ b/arch/arm/mach-msm/msm_smem_iface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,7 @@
 #define __ARCH_ARM_MACH_MSM_SMEM_IFACE_H
 
 #include <mach/msm_smsm.h>
+#include <mach/msm_smem.h>
 
 #define MAX_KEY_EVENTS 10
 #define MAX_SEC_KEY_PAYLOAD 32
diff --git a/arch/arm/mach-msm/nand_partitions.c b/arch/arm/mach-msm/nand_partitions.c
index ea5fb9c..ad2a10e 100644
--- a/arch/arm/mach-msm/nand_partitions.c
+++ b/arch/arm/mach-msm/nand_partitions.c
@@ -4,7 +4,7 @@
  * bootloader.
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009,2011 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2009,2011,2013 The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -34,7 +34,7 @@
 
 #include <mach/board.h>
 #ifdef CONFIG_MSM_SMD
-#include "smd_private.h"
+#include <mach/msm_smem.h>
 #endif
 
 /* configuration tags specific to msm */
diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c
index df5ea35..73b58ab 100644
--- a/arch/arm/mach-msm/pil-dsps.c
+++ b/arch/arm/mach-msm/pil-dsps.c
@@ -22,6 +22,7 @@
 #include <mach/subsystem_restart.h>
 #include <mach/msm_smsm.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index 65f86bc..840c90f 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -30,6 +30,7 @@
 #include <mach/msm_bus.h>
 #include <mach/subsystem_restart.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index b186a4d..30168b8 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -30,6 +30,7 @@
 #include <mach/subsystem_restart.h>
 #include <mach/msm_smsm.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
diff --git a/arch/arm/mach-msm/pil-q6v4-lpass.c b/arch/arm/mach-msm/pil-q6v4-lpass.c
index f05bcdb..7acb599 100644
--- a/arch/arm/mach-msm/pil-q6v4-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v4-lpass.c
@@ -25,6 +25,7 @@
 #include <mach/subsystem_restart.h>
 #include <mach/subsystem_notif.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "smd_private.h"
 #include "sysmon.h"
diff --git a/arch/arm/mach-msm/pil-q6v4-mss.c b/arch/arm/mach-msm/pil-q6v4-mss.c
index 1821ab1..c4b6038 100644
--- a/arch/arm/mach-msm/pil-q6v4-mss.c
+++ b/arch/arm/mach-msm/pil-q6v4-mss.c
@@ -23,6 +23,7 @@
 #include <mach/subsystem_restart.h>
 #include <mach/msm_smsm.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "smd_private.h"
 #include "peripheral-loader.h"
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 6e8e79e..9a5883f 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -29,6 +29,7 @@
 #include <mach/subsystem_notif.h>
 #include <mach/scm.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "peripheral-loader.h"
 #include "pil-q6v5.h"
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 979458e..5ef6638 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -31,6 +31,7 @@
 #include <mach/clk.h>
 #include <mach/msm_smsm.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "peripheral-loader.h"
 #include "pil-q6v5.h"
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index d72b848..5419bf0 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -24,6 +24,7 @@
 
 #include <mach/subsystem_restart.h>
 #include <mach/ramdump.h>
+#include <mach/msm_smem.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index a2da8b0..9f97a59 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -3,7 +3,7 @@
  * MSM Power Management Routines
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2013 The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -44,9 +44,10 @@
 #endif
 #include <mach/socinfo.h>
 #include <mach/proc_comm.h>
+#include <mach/msm_smem.h>
+#include <mach/msm_smsm.h>
 #include <asm/smp_scu.h>
 
-#include "smd_private.h"
 #include "smd_rpcrouter.h"
 #include "acpuclock.h"
 #include "clock.h"
diff --git a/arch/arm/mach-msm/remote_spinlock.c b/arch/arm/mach-msm/remote_spinlock.c
index 62e3e05..a9ebd7c 100644
--- a/arch/arm/mach-msm/remote_spinlock.c
+++ b/arch/arm/mach-msm/remote_spinlock.c
@@ -25,6 +25,7 @@
 #include <mach/msm_iomap.h>
 #include <mach/remote_spinlock.h>
 #include <mach/dal.h>
+#include <mach/msm_smem.h>
 #include "smd_private.h"
 
 
diff --git a/arch/arm/mach-msm/rmt_storage_client.c b/arch/arm/mach-msm/rmt_storage_client.c
index a4562e9..550624c 100644
--- a/arch/arm/mach-msm/rmt_storage_client.c
+++ b/arch/arm/mach-msm/rmt_storage_client.c
@@ -35,7 +35,7 @@
 #ifdef CONFIG_MSM_SDIO_SMEM
 #include <mach/sdio_smem.h>
 #endif
-#include "smd_private.h"
+#include <mach/msm_smem.h>
 
 enum {
 	RMT_STORAGE_EVNT_OPEN = 0,
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 3590e6b..1945651 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -47,11 +47,13 @@
 #include <mach/msm_ipc_logging.h>
 #include <mach/ramdump.h>
 #include <mach/board.h>
+#include <mach/msm_smem.h>
 
 #include <asm/cacheflush.h>
 
 #include "smd_private.h"
 #include "modem_notifier.h"
+#include "smem_private.h"
 
 #if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM8X60) \
 	|| defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_FSM9XXX) \
@@ -175,16 +177,6 @@
 	},
 };
 
-struct smem_area {
-	phys_addr_t phys_addr;
-	resource_size_t size;
-	void __iomem *virt_addr;
-};
-static uint32_t num_smem_areas;
-static struct smem_area *smem_areas;
-static struct ramdump_segment *smem_ramdump_segments;
-static void *smem_ramdump_dev;
-static void *smem_phys_to_virt(phys_addr_t base, unsigned offset);
 static void *smd_dev;
 
 struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
@@ -380,9 +372,6 @@
 
 #define SMD_LOOPBACK_CID 100
 
-#define SMEM_SPINLOCK_SMEM_ALLOC       "S:3"
-static remote_spinlock_t remote_spinlock;
-
 static LIST_HEAD(smd_ch_list_loopback);
 static void smd_fake_irq_handler(unsigned long arg);
 static void smsm_cb_snapshot(uint32_t use_wakelock);
@@ -392,7 +381,6 @@
 static DECLARE_WORK(smsm_cb_work, notify_smsm_cb_clients_worker);
 static DEFINE_MUTEX(smsm_lock);
 static struct smsm_state_info *smsm_states;
-static int spinlocks_initialized;
 
 /**
  * Variables to indicate smd module initialization.
@@ -2408,222 +2396,6 @@
 }
 EXPORT_SYMBOL(smd_is_pkt_avail);
 
-
-/* -------------------------------------------------------------------------- */
-
-/**
- * smem_phys_to_virt() - Convert a physical base and offset to virtual address
- *
- * @base: physical base address to check
- * @offset: offset from the base to get the final address
- * @returns: virtual SMEM address; NULL for failure
- *
- * Takes a physical address and an offset and checks if the resulting physical
- * address would fit into one of the smem regions.  If so, returns the
- * corresponding virtual address.  Otherwise returns NULL.
- */
-static void *smem_phys_to_virt(phys_addr_t base, unsigned offset)
-{
-	int i;
-	phys_addr_t phys_addr;
-	resource_size_t size;
-
-	if (OVERFLOW_ADD_UNSIGNED(phys_addr_t, base, offset))
-		return NULL;
-
-	if (!smem_areas) {
-		/*
-		 * Early boot - no area configuration yet, so default
-		 * to using the main memory region.
-		 *
-		 * To remove the MSM_SHARED_RAM_BASE and the static
-		 * mapping of SMEM in the future, add dump_stack()
-		 * to identify the early callers of smem_get_entry()
-		 * (which calls this function) and replace those calls
-		 * with a new function that knows how to lookup the
-		 * SMEM base address before SMEM has been probed.
-		 */
-		phys_addr = msm_shared_ram_phys;
-		size = MSM_SHARED_RAM_SIZE;
-
-		if (base >= phys_addr && base + offset < phys_addr + size) {
-			if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
-				(uintptr_t)MSM_SHARED_RAM_BASE, offset)) {
-				pr_err("%s: overflow %p %x\n", __func__,
-					MSM_SHARED_RAM_BASE, offset);
-				return NULL;
-			}
-
-			return MSM_SHARED_RAM_BASE + offset;
-		} else {
-			return NULL;
-		}
-	}
-	for (i = 0; i < num_smem_areas; ++i) {
-		phys_addr = smem_areas[i].phys_addr;
-		size = smem_areas[i].size;
-
-		if (base < phys_addr || base + offset >= phys_addr + size)
-			continue;
-
-		if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
-				(uintptr_t)smem_areas[i].virt_addr, offset)) {
-			pr_err("%s: overflow %p %x\n", __func__,
-				smem_areas[i].virt_addr, offset);
-			return NULL;
-		}
-
-		return smem_areas[i].virt_addr + offset;
-	}
-
-	return NULL;
-}
-
-/**
- * smem_virt_to_phys() - Convert SMEM address to physical address.
- *
- * @smem_address: Address of SMEM item (returned by smem_alloc(), etc)
- * @returns: Physical address (or NULL if there is a failure)
- *
- * This function should only be used if an SMEM item needs to be handed
- * off to a DMA engine.
- */
-phys_addr_t smem_virt_to_phys(void *smem_address)
-{
-	phys_addr_t phys_addr = 0;
-	int i;
-	void *vend;
-
-	if (!smem_areas)
-		return phys_addr;
-
-	for (i = 0; i < num_smem_areas; ++i) {
-		vend = (void *)(smem_areas[i].virt_addr + smem_areas[i].size);
-
-		if (smem_address >= smem_areas[i].virt_addr &&
-				smem_address < vend) {
-			phys_addr = smem_address - smem_areas[i].virt_addr;
-			phys_addr +=  smem_areas[i].phys_addr;
-			break;
-		}
-	}
-
-	return phys_addr;
-}
-EXPORT_SYMBOL(smem_virt_to_phys);
-
-/* smem_alloc returns the pointer to smem item if it is already allocated.
- * Otherwise, it returns NULL.
- */
-void *smem_alloc(unsigned id, unsigned size)
-{
-	return smem_find(id, size);
-}
-EXPORT_SYMBOL(smem_alloc);
-
-/* smem_alloc2 returns the pointer to smem item.  If it is not allocated,
- * it allocates it and then returns the pointer to it.
- */
-void *smem_alloc2(unsigned id, unsigned size_in)
-{
-	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
-	struct smem_heap_entry *toc = shared->heap_toc;
-	unsigned long flags;
-	void *ret = NULL;
-
-	if (!shared->heap_info.initialized) {
-		pr_err("%s: smem heap info not initialized\n", __func__);
-		return NULL;
-	}
-
-	if (id >= SMEM_NUM_ITEMS)
-		return NULL;
-
-	size_in = ALIGN(size_in, 8);
-	remote_spin_lock_irqsave(&remote_spinlock, flags);
-	if (toc[id].allocated) {
-		SMD_DBG("%s: %u already allocated\n", __func__, id);
-		if (size_in != toc[id].size)
-			pr_err("%s: wrong size %u (expected %u)\n",
-			       __func__, toc[id].size, size_in);
-		else
-			ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset);
-	} else if (id > SMEM_FIXED_ITEM_LAST) {
-		SMD_DBG("%s: allocating %u\n", __func__, id);
-		if (shared->heap_info.heap_remaining >= size_in) {
-			toc[id].offset = shared->heap_info.free_offset;
-			toc[id].size = size_in;
-			wmb();
-			toc[id].allocated = 1;
-
-			shared->heap_info.free_offset += size_in;
-			shared->heap_info.heap_remaining -= size_in;
-			ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset);
-		} else
-			pr_err("%s: not enough memory %u (required %u)\n",
-			       __func__, shared->heap_info.heap_remaining,
-			       size_in);
-	}
-	wmb();
-	remote_spin_unlock_irqrestore(&remote_spinlock, flags);
-	return ret;
-}
-EXPORT_SYMBOL(smem_alloc2);
-
-void *smem_get_entry(unsigned id, unsigned *size)
-{
-	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
-	struct smem_heap_entry *toc = shared->heap_toc;
-	int use_spinlocks = spinlocks_initialized;
-	void *ret = 0;
-	unsigned long flags = 0;
-
-	if (id >= SMEM_NUM_ITEMS)
-		return ret;
-
-	if (use_spinlocks)
-		remote_spin_lock_irqsave(&remote_spinlock, flags);
-	/* toc is in device memory and cannot be speculatively accessed */
-	if (toc[id].allocated) {
-		phys_addr_t phys_base;
-
-		*size = toc[id].size;
-		barrier();
-
-		phys_base = toc[id].reserved & BASE_ADDR_MASK;
-		if (!phys_base)
-			phys_base = (phys_addr_t)msm_shared_ram_phys;
-		ret = smem_phys_to_virt(phys_base, toc[id].offset);
-	} else {
-		*size = 0;
-	}
-	if (use_spinlocks)
-		remote_spin_unlock_irqrestore(&remote_spinlock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(smem_get_entry);
-
-void *smem_find(unsigned id, unsigned size_in)
-{
-	unsigned size;
-	void *ptr;
-
-	ptr = smem_get_entry(id, &size);
-	if (!ptr)
-		return 0;
-
-	size_in = ALIGN(size_in, 8);
-	if (size_in != size) {
-		pr_err("smem_find(%d, %d): wrong size %d\n",
-		       id, size_in, size);
-		return 0;
-	}
-
-	return ptr;
-}
-EXPORT_SYMBOL(smem_find);
-
 static int smsm_cb_init(void)
 {
 	struct smsm_state_info *state_info;
@@ -3313,17 +3085,6 @@
 }
 EXPORT_SYMBOL(smsm_state_cb_deregister);
 
-/**
- * smem_get_remote_spinlock - Remote spinlock pointer for unit testing.
- *
- * @returns: pointer to SMEM remote spinlock
- */
-remote_spinlock_t *smem_get_remote_spinlock(void)
-{
-	return &remote_spinlock;
-}
-EXPORT_SYMBOL(smem_get_remote_spinlock);
-
 int smd_module_init_notifier_register(struct notifier_block *nb)
 {
 	int ret;
@@ -4126,23 +3887,6 @@
 		remote_spin_release(&remote_spinlock, notifier->processor);
 		remote_spin_release_all(notifier->processor);
 
-		if (smem_ramdump_dev) {
-			int ret;
-
-			SMD_INFO("%s: saving ramdump\n", __func__);
-			/*
-			 * XPU protection does not currently allow the
-			 * auxiliary memory regions to be dumped.  If this
-			 * changes, then num_smem_areas + 1 should be passed
-			 * into do_elf_ramdump() to dump all regions.
-			 */
-			ret = do_elf_ramdump(smem_ramdump_dev,
-					smem_ramdump_segments, 1);
-			if (ret < 0)
-				pr_err("%s: unable to dump smem %d\n", __func__,
-						ret);
-		}
-
 		smd_channel_reset(notifier->processor);
 	}
 
@@ -4155,13 +3899,6 @@
 	void *handle;
 	struct restart_notifier_block *nb;
 
-	smem_ramdump_dev = create_ramdump_device("smem-smd", smd_dev);
-	if (IS_ERR_OR_NULL(smem_ramdump_dev)) {
-		pr_err("%s: Unable to create smem ramdump device.\n",
-			__func__);
-		smem_ramdump_dev = NULL;
-	}
-
 	for (i = 0; i < ARRAY_SIZE(restart_notifiers); i++) {
 		nb = &restart_notifiers[i];
 		handle = subsys_notif_register_notifier(nb->name, &nb->nb);
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index 4dcf72f..b66e258 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -21,8 +21,10 @@
 #include <linux/jiffies.h>
 
 #include <mach/msm_iomap.h>
+#include <mach/msm_smem.h>
 
 #include "smd_private.h"
+#include "smem_private.h"
 
 #if defined(CONFIG_DEBUG_FS)
 
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index 4a6a509..4fe9592 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -34,37 +34,6 @@
 #define VERSION_MODEM     9
 #define VERSION_DSPS      10
 
-#define SMD_HEAP_SIZE 512
-
-struct smem_heap_info {
-	unsigned initialized;
-	unsigned free_offset;
-	unsigned heap_remaining;
-	unsigned reserved;
-};
-
-struct smem_heap_entry {
-	unsigned allocated;
-	unsigned offset;
-	unsigned size;
-	unsigned reserved; /* bits 1:0 reserved, bits 31:2 aux smem base addr */
-};
-#define BASE_ADDR_MASK 0xfffffffc
-
-struct smem_proc_comm {
-	unsigned command;
-	unsigned status;
-	unsigned data1;
-	unsigned data2;
-};
-
-struct smem_shared {
-	struct smem_proc_comm proc_comm[4];
-	unsigned version[32];
-	struct smem_heap_info heap_info;
-	struct smem_heap_entry heap_toc[SMD_HEAP_SIZE];
-};
-
 #if defined(CONFIG_MSM_SMD_PKG4)
 struct smsm_interrupt_info {
 	uint32_t aArm_en_mask;
@@ -313,7 +282,4 @@
 	uint32_t smsm_interrupt_id;
 };
 extern struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS];
-
-/* used for unit testing spinlocks */
-remote_spinlock_t *smem_get_remote_spinlock(void);
 #endif
diff --git a/arch/arm/mach-msm/smem.c b/arch/arm/mach-msm/smem.c
new file mode 100644
index 0000000..c00f96f
--- /dev/null
+++ b/arch/arm/mach-msm/smem.c
@@ -0,0 +1,363 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/printk.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_smem.h>
+#include <mach/ramdump.h>
+#include <mach/subsystem_notif.h>
+
+#include "smem_private.h"
+
+/**
+ * OVERFLOW_ADD_UNSIGNED() - check for unsigned overflow
+ *
+ * @type: type to check for overflow
+ * @a: left value to use
+ * @b: right value to use
+ * @returns: true if a + b will result in overflow; false otherwise
+ */
+#define OVERFLOW_ADD_UNSIGNED(type, a, b) \
+	(((type)~0 - (a)) < (b) ? true : false)
+
+enum {
+	MSM_SMEM_DEBUG = 1U << 0,
+	MSM_SMEM_INFO = 1U << 1,
+};
+
+static int msm_smem_debug_mask;
+module_param_named(debug_mask, msm_smem_debug_mask,
+			int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define SMEM_DBG(x...) do {                               \
+		if (msm_smem_debug_mask & MSM_SMEM_DEBUG) \
+			pr_debug(x);                      \
+	} while (0)
+
+remote_spinlock_t remote_spinlock;
+int spinlocks_initialized;
+uint32_t num_smem_areas;
+struct smem_area *smem_areas;
+struct ramdump_segment *smem_ramdump_segments;
+
+static void *smem_ramdump_dev;
+
+struct restart_notifier_block {
+	unsigned processor;
+	char *name;
+	struct notifier_block nb;
+};
+
+static int restart_notifier_cb(struct notifier_block *this,
+				unsigned long code,
+				void *data);
+
+static struct restart_notifier_block restart_notifiers[] = {
+	{SMEM_MODEM, "modem", .nb.notifier_call = restart_notifier_cb},
+	{SMEM_Q6, "lpass", .nb.notifier_call = restart_notifier_cb},
+	{SMEM_WCNSS, "wcnss", .nb.notifier_call = restart_notifier_cb},
+	{SMEM_DSPS, "dsps", .nb.notifier_call = restart_notifier_cb},
+	{SMEM_MODEM, "gss", .nb.notifier_call = restart_notifier_cb},
+	{SMEM_Q6, "adsp", .nb.notifier_call = restart_notifier_cb},
+};
+
+/**
+ * smem_phys_to_virt() - Convert a physical base and offset to virtual address
+ *
+ * @base: physical base address to check
+ * @offset: offset from the base to get the final address
+ * @returns: virtual SMEM address; NULL for failure
+ *
+ * Takes a physical address and an offset and checks if the resulting physical
+ * address would fit into one of the smem regions.  If so, returns the
+ * corresponding virtual address.  Otherwise returns NULL.
+ */
+static void *smem_phys_to_virt(phys_addr_t base, unsigned offset)
+{
+	int i;
+	phys_addr_t phys_addr;
+	resource_size_t size;
+
+	if (OVERFLOW_ADD_UNSIGNED(phys_addr_t, base, offset))
+		return NULL;
+
+	if (!smem_areas) {
+		/*
+		 * Early boot - no area configuration yet, so default
+		 * to using the main memory region.
+		 *
+		 * To remove the MSM_SHARED_RAM_BASE and the static
+		 * mapping of SMEM in the future, add dump_stack()
+		 * to identify the early callers of smem_get_entry()
+		 * (which calls this function) and replace those calls
+		 * with a new function that knows how to lookup the
+		 * SMEM base address before SMEM has been probed.
+		 */
+		phys_addr = msm_shared_ram_phys;
+		size = MSM_SHARED_RAM_SIZE;
+
+		if (base >= phys_addr && base + offset < phys_addr + size) {
+			if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
+				(uintptr_t)MSM_SHARED_RAM_BASE, offset)) {
+				pr_err("%s: overflow %p %x\n", __func__,
+					MSM_SHARED_RAM_BASE, offset);
+				return NULL;
+			}
+
+			return MSM_SHARED_RAM_BASE + offset;
+		} else {
+			return NULL;
+		}
+	}
+	for (i = 0; i < num_smem_areas; ++i) {
+		phys_addr = smem_areas[i].phys_addr;
+		size = smem_areas[i].size;
+
+		if (base < phys_addr || base + offset >= phys_addr + size)
+			continue;
+
+		if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
+				(uintptr_t)smem_areas[i].virt_addr, offset)) {
+			pr_err("%s: overflow %p %x\n", __func__,
+				smem_areas[i].virt_addr, offset);
+			return NULL;
+		}
+
+		return smem_areas[i].virt_addr + offset;
+	}
+
+	return NULL;
+}
+
+/**
+ * smem_virt_to_phys() - Convert SMEM address to physical address.
+ *
+ * @smem_address: Address of SMEM item (returned by smem_alloc(), etc)
+ * @returns: Physical address (or NULL if there is a failure)
+ *
+ * This function should only be used if an SMEM item needs to be handed
+ * off to a DMA engine.
+ */
+phys_addr_t smem_virt_to_phys(void *smem_address)
+{
+	phys_addr_t phys_addr = 0;
+	int i;
+	void *vend;
+
+	if (!smem_areas)
+		return phys_addr;
+
+	for (i = 0; i < num_smem_areas; ++i) {
+		vend = (void *)(smem_areas[i].virt_addr + smem_areas[i].size);
+
+		if (smem_address >= smem_areas[i].virt_addr &&
+				smem_address < vend) {
+			phys_addr = smem_address - smem_areas[i].virt_addr;
+			phys_addr +=  smem_areas[i].phys_addr;
+			break;
+		}
+	}
+
+	return phys_addr;
+}
+EXPORT_SYMBOL(smem_virt_to_phys);
+
+/* smem_alloc returns the pointer to smem item if it is already allocated.
+ * Otherwise, it returns NULL.
+ */
+void *smem_alloc(unsigned id, unsigned size)
+{
+	return smem_find(id, size);
+}
+EXPORT_SYMBOL(smem_alloc);
+
+void *smem_find(unsigned id, unsigned size_in)
+{
+	unsigned size;
+	void *ptr;
+
+	ptr = smem_get_entry(id, &size);
+	if (!ptr)
+		return 0;
+
+	size_in = ALIGN(size_in, 8);
+	if (size_in != size) {
+		pr_err("smem_find(%d, %d): wrong size %d\n",
+			id, size_in, size);
+		return 0;
+	}
+
+	return ptr;
+}
+EXPORT_SYMBOL(smem_find);
+
+/* smem_alloc2 returns the pointer to smem item.  If it is not allocated,
+ * it allocates it and then returns the pointer to it.
+ */
+void *smem_alloc2(unsigned id, unsigned size_in)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	struct smem_heap_entry *toc = shared->heap_toc;
+	unsigned long flags;
+	void *ret = NULL;
+
+	if (!shared->heap_info.initialized) {
+		pr_err("%s: smem heap info not initialized\n", __func__);
+		return NULL;
+	}
+
+	if (id >= SMEM_NUM_ITEMS)
+		return NULL;
+
+	size_in = ALIGN(size_in, 8);
+	remote_spin_lock_irqsave(&remote_spinlock, flags);
+	if (toc[id].allocated) {
+		SMEM_DBG("%s: %u already allocated\n", __func__, id);
+		if (size_in != toc[id].size)
+			pr_err("%s: wrong size %u (expected %u)\n",
+				__func__, toc[id].size, size_in);
+		else
+			ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset);
+	} else if (id > SMEM_FIXED_ITEM_LAST) {
+		SMEM_DBG("%s: allocating %u\n", __func__, id);
+		if (shared->heap_info.heap_remaining >= size_in) {
+			toc[id].offset = shared->heap_info.free_offset;
+			toc[id].size = size_in;
+			wmb();
+			toc[id].allocated = 1;
+
+			shared->heap_info.free_offset += size_in;
+			shared->heap_info.heap_remaining -= size_in;
+			ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset);
+		} else
+			pr_err("%s: not enough memory %u (required %u)\n",
+				__func__, shared->heap_info.heap_remaining,
+				size_in);
+	}
+	wmb();
+	remote_spin_unlock_irqrestore(&remote_spinlock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(smem_alloc2);
+
+void *smem_get_entry(unsigned id, unsigned *size)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	struct smem_heap_entry *toc = shared->heap_toc;
+	int use_spinlocks = spinlocks_initialized;
+	void *ret = 0;
+	unsigned long flags = 0;
+
+	if (id >= SMEM_NUM_ITEMS)
+		return ret;
+
+	if (use_spinlocks)
+		remote_spin_lock_irqsave(&remote_spinlock, flags);
+	/* toc is in device memory and cannot be speculatively accessed */
+	if (toc[id].allocated) {
+		phys_addr_t phys_base;
+
+		*size = toc[id].size;
+		barrier();
+
+		phys_base = toc[id].reserved & BASE_ADDR_MASK;
+		if (!phys_base)
+			phys_base = (phys_addr_t)msm_shared_ram_phys;
+		ret = smem_phys_to_virt(phys_base, toc[id].offset);
+	} else {
+		*size = 0;
+	}
+	if (use_spinlocks)
+		remote_spin_unlock_irqrestore(&remote_spinlock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(smem_get_entry);
+
+
+/**
+ * smem_get_remote_spinlock - Remote spinlock pointer for unit testing.
+ *
+ * @returns: pointer to SMEM remote spinlock
+ */
+remote_spinlock_t *smem_get_remote_spinlock(void)
+{
+	return &remote_spinlock;
+}
+EXPORT_SYMBOL(smem_get_remote_spinlock);
+
+static int restart_notifier_cb(struct notifier_block *this,
+				unsigned long code,
+				void *data)
+{
+	if (code == SUBSYS_AFTER_SHUTDOWN) {
+		struct restart_notifier_block *notifier;
+
+		notifier = container_of(this,
+					struct restart_notifier_block, nb);
+		SMEM_DBG("%s: ssrestart for processor %d ('%s')\n",
+				__func__, notifier->processor,
+				notifier->name);
+
+		remote_spin_release(&remote_spinlock, notifier->processor);
+		remote_spin_release_all(notifier->processor);
+
+		if (smem_ramdump_dev) {
+			int ret;
+
+			SMEM_DBG("%s: saving ramdump\n", __func__);
+			/*
+			 * XPU protection does not currently allow the
+			 * auxiliary memory regions to be dumped.  If this
+			 * changes, then num_smem_areas + 1 should be passed
+			 * into do_elf_ramdump() to dump all regions.
+			 */
+			ret = do_elf_ramdump(smem_ramdump_dev,
+					smem_ramdump_segments, 1);
+			if (ret < 0)
+				pr_err("%s: unable to dump smem %d\n", __func__,
+						ret);
+		}
+	}
+
+	return NOTIFY_DONE;
+}
+
+static __init int modem_restart_late_init(void)
+{
+	int i;
+	void *handle;
+	struct restart_notifier_block *nb;
+
+	smem_ramdump_dev = create_ramdump_device("smem", NULL);
+	if (IS_ERR_OR_NULL(smem_ramdump_dev)) {
+		pr_err("%s: Unable to create smem ramdump device.\n",
+			__func__);
+		smem_ramdump_dev = NULL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(restart_notifiers); i++) {
+		nb = &restart_notifiers[i];
+		handle = subsys_notif_register_notifier(nb->name, &nb->nb);
+		SMEM_DBG("%s: registering notif for '%s', handle=%p\n",
+				__func__, nb->name, handle);
+	}
+
+	return 0;
+}
+late_initcall(modem_restart_late_init);
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index 361df33..87f141d2 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -32,6 +32,7 @@
 
 #include <mach/msm_iomap.h>
 #include <mach/smem_log.h>
+#include <mach/msm_smem.h>
 
 #include <asm/arch_timer.h>
 
diff --git a/arch/arm/mach-msm/smem_private.h b/arch/arm/mach-msm/smem_private.h
new file mode 100644
index 0000000..89b2b7b
--- /dev/null
+++ b/arch/arm/mach-msm/smem_private.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_
+#define _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_
+
+#include <linux/remote_spinlock.h>
+
+#include <mach/ramdump.h>
+
+#define SMEM_SPINLOCK_SMEM_ALLOC       "S:3"
+extern remote_spinlock_t remote_spinlock;
+extern int spinlocks_initialized;
+
+#define SMD_HEAP_SIZE 512
+
+struct smem_heap_info {
+	unsigned initialized;
+	unsigned free_offset;
+	unsigned heap_remaining;
+	unsigned reserved;
+};
+
+struct smem_heap_entry {
+	unsigned allocated;
+	unsigned offset;
+	unsigned size;
+	unsigned reserved; /* bits 1:0 reserved, bits 31:2 aux smem base addr */
+};
+#define BASE_ADDR_MASK 0xfffffffc
+
+struct smem_proc_comm {
+	unsigned command;
+	unsigned status;
+	unsigned data1;
+	unsigned data2;
+};
+
+struct smem_shared {
+	struct smem_proc_comm proc_comm[4];
+	unsigned version[32];
+	struct smem_heap_info heap_info;
+	struct smem_heap_entry heap_toc[SMD_HEAP_SIZE];
+};
+
+struct smem_area {
+	phys_addr_t phys_addr;
+	resource_size_t size;
+	void __iomem *virt_addr;
+};
+
+extern uint32_t num_smem_areas;
+extern struct smem_area *smem_areas;
+
+extern struct ramdump_segment *smem_ramdump_segments;
+
+/* used for unit testing spinlocks */
+remote_spinlock_t *smem_get_remote_spinlock(void);
+#endif /* _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_ */
diff --git a/arch/arm/mach-msm/smp2p.c b/arch/arm/mach-msm/smp2p.c
index 7bdcce9..ee262b0 100644
--- a/arch/arm/mach-msm/smp2p.c
+++ b/arch/arm/mach-msm/smp2p.c
@@ -19,7 +19,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <mach/msm_smsm.h>
+#include <mach/msm_smem.h>
 #include <mach/msm_ipc_logging.h>
 #include "smp2p_private_api.h"
 #include "smp2p_private.h"
diff --git a/arch/arm/mach-msm/smp2p_loopback.c b/arch/arm/mach-msm/smp2p_loopback.c
index d95c93f..5df3d70 100644
--- a/arch/arm/mach-msm/smp2p_loopback.c
+++ b/arch/arm/mach-msm/smp2p_loopback.c
@@ -21,7 +21,7 @@
 #include <linux/termios.h>
 #include <linux/module.h>
 #include <linux/remote_spinlock.h>
-#include "smd_private.h"
+#include "smem_private.h"
 #include "smp2p_private.h"
 
 /**
diff --git a/arch/arm/mach-msm/smp2p_spinlock_test.c b/arch/arm/mach-msm/smp2p_spinlock_test.c
index 09d7c0d..c14bac0 100644
--- a/arch/arm/mach-msm/smp2p_spinlock_test.c
+++ b/arch/arm/mach-msm/smp2p_spinlock_test.c
@@ -17,8 +17,8 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/remote_spinlock.h>
-#include <mach/msm_smsm.h>
-#include "smd_private.h"
+#include <mach/msm_smem.h>
+#include "smem_private.h"
 #include "smp2p_private.h"
 #include "smp2p_test_common.h"
 
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index abc63ef..0c02b51 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -27,8 +27,8 @@
 #include <asm/mach-types.h>
 
 #include <mach/socinfo.h>
+#include <mach/msm_smem.h>
 
-#include "smd_private.h"
 #include "boot_stats.h"
 
 #define BUILD_ID_LENGTH 32
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 06a4c29..1ea0f2d 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -36,7 +36,8 @@
 #include <mach/socinfo.h>
 
 #if defined(CONFIG_MSM_SMD)
-#include "smd_private.h"
+#include <mach/msm_smem.h>
+#include <mach/msm_smsm.h>
 #endif
 #include "timer.h"