diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a709707..b324d73 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -39,6 +39,7 @@ COBJS-$(CONFIG_PMIC_FSL) += pmic_fsl.o
 COBJS-$(CONFIG_PMIC_I2C) += pmic_i2c.o
 COBJS-$(CONFIG_PMIC_SPI) += pmic_spi.o
 COBJS-$(CONFIG_PMIC_MAX8998) += pmic_max8998.o
+COBJS-$(CONFIG_MSM_PCOMM) += msm_proc_comm.o

 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/misc/msm_proc_comm.c b/drivers/misc/msm_proc_comm.c
new file mode 100644
index 0000000..f1db917
--- /dev/null
+++ b/drivers/misc/msm_proc_comm.c
@@ -0,0 +1,303 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#define ACPU_CLK       0  /* Applications processor clock */
+#define ADM_CLK                1  /* Applications data mover clock */
+#define ADSP_CLK       2  /* ADSP clock */
+#define EBI1_CLK       3  /* External bus interface 1 clock */
+#define EBI2_CLK       4  /* External bus interface 2 clock */
+#define ECODEC_CLK     5  /* External CODEC clock */
+#define EMDH_CLK       6  /* External MDDI host clock */
+#define GP_CLK         7  /* General purpose clock */
+#define GRP_CLK                8  /* Graphics clock */
+#define I2C_CLK                9  /* I2C clock */
+#define ICODEC_RX_CLK  10  /* Internal CODEX RX clock */
+#define ICODEC_TX_CLK  11  /* Internal CODEX TX clock */
+#define IMEM_CLK       12  /* Internal graphics memory clock */
+#define MDC_CLK                13  /* MDDI client clock */
+#define MDP_CLK                14  /* Mobile display processor clock */
+#define PBUS_CLK       15  /* Peripheral bus clock */
+#define PCM_CLK                16  /* PCM clock */
+#define PMDH_CLK       17  /* Primary MDDI host clock */
+#define SDAC_CLK       18  /* Stereo DAC clock */
+#define SDC1_CLK       19  /* Secure Digital Card clocks */
+#define SDC1_PCLK      20
+#define SDC2_CLK       21
+#define SDC2_PCLK      22
+#define SDC3_CLK       23
+#define SDC3_PCLK      24
+#define SDC4_CLK       25
+#define SDC4_PCLK      26
+#define TSIF_CLK       27  /* Transport Stream Interface clocks */
+#define TSIF_REF_CLK   28
+#define TV_DAC_CLK     29  /* TV clocks */
+#define TV_ENC_CLK     30
+#define UART1_CLK      31  /* UART clocks */
+#define UART2_CLK      32
+#define UART3_CLK      33
+#define UART1DM_CLK    34
+#define UART2DM_CLK    35
+#define USB_HS_CLK     36  /* High speed USB core clock */
+#define USB_HS_PCLK    37  /* High speed USB pbus clock */
+#define USB_OTG_CLK    38  /* Full speed USB clock */
+#define VDC_CLK                39  /* Video controller clock */
+#define VFE_CLK                40  /* Camera / Video Front End clock */
+#define VFE_MDC_CLK    41  /* VFE MDDI client clock */
+
+/* qsd8k adds... */
+#define MDP_LCDC_PCLK_CLK      42
+#define MDP_LCDC_PAD_PCLK_CLK  43
+#define MDP_VSYNC_CLK          44
+
+#define P_USB_HS_CORE_CLK      53  /* High speed USB 1 core clock */
+/* msm7x30 adds... */
+#define PMDH_P_CLK             82
+#define MDP_P_CLK              86
+
+enum {
+       PCOM_CMD_IDLE = 0x0,
+       PCOM_CMD_DONE,
+       PCOM_RESET_APPS,
+       PCOM_RESET_CHIP,
+       PCOM_CONFIG_NAND_MPU,
+       PCOM_CONFIG_USB_CLKS,
+       PCOM_GET_POWER_ON_STATUS,
+       PCOM_GET_WAKE_UP_STATUS,
+       PCOM_GET_BATT_LEVEL,
+       PCOM_CHG_IS_CHARGING,
+       PCOM_POWER_DOWN,
+       PCOM_USB_PIN_CONFIG,
+       PCOM_USB_PIN_SEL,
+       PCOM_SET_RTC_ALARM,
+       PCOM_NV_READ,
+       PCOM_NV_WRITE,
+       PCOM_GET_UUID_HIGH,
+       PCOM_GET_UUID_LOW,
+       PCOM_GET_HW_ENTROPY,
+       PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
+       PCOM_CLKCTL_RPC_ENABLE,
+       PCOM_CLKCTL_RPC_DISABLE,
+       PCOM_CLKCTL_RPC_RESET,
+       PCOM_CLKCTL_RPC_SET_FLAGS,
+       PCOM_CLKCTL_RPC_SET_RATE,
+       PCOM_CLKCTL_RPC_MIN_RATE,
+       PCOM_CLKCTL_RPC_MAX_RATE,
+       PCOM_CLKCTL_RPC_RATE,
+       PCOM_CLKCTL_RPC_PLL_REQUEST,
+       PCOM_CLKCTL_RPC_ENABLED,
+       PCOM_VREG_SWITCH,
+       PCOM_VREG_SET_LEVEL,
+       PCOM_GPIO_TLMM_CONFIG_GROUP,
+       PCOM_GPIO_TLMM_UNCONFIG_GROUP,
+       PCOM_NV_READ_HIGH_BITS,
+       PCOM_NV_WRITE_HIGH_BITS,
+       PCOM_RPC_GPIO_TLMM_CONFIG_EX = 0x25,
+       PCOM_NUM_CMDS,
+};
+
+enum {
+        PCOM_INVALID_STATUS = 0x0,
+        PCOM_READY,
+        PCOM_CMD_RUNNING,
+        PCOM_CMD_SUCCESS,
+        PCOM_CMD_FAIL,
+};
+
+#ifndef PLATFORM_MSM7X30
+#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+#endif
+static inline void notify_other_proc_comm(void)
+{
+#ifndef PLATFORM_MSM7X30
+       writel(1, MSM_A2M_INT(6));
+#else
+       writel(1<<6, (MSM_GCC_BASE + 0x8));
+#endif
+}
+
+#define APP_COMMAND    (MSM_SHARED_BASE + 0x00)
+#define APP_STATUS     (MSM_SHARED_BASE + 0x04)
+#define APP_DATA1      (MSM_SHARED_BASE + 0x08)
+#define APP_DATA2      (MSM_SHARED_BASE + 0x0C)
+
+#define MDM_COMMAND    (MSM_SHARED_BASE + 0x10)
+#define MDM_STATUS     (MSM_SHARED_BASE + 0x14)
+#define MDM_DATA1      (MSM_SHARED_BASE + 0x18)
+#define MDM_DATA2      (MSM_SHARED_BASE + 0x1C)
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
+{
+       int ret = -1;
+       unsigned status;
+
+       while (readl(MDM_STATUS) != PCOM_READY)
+               /* XXX check for A9 reset */
+               ;
+       writel(cmd, APP_COMMAND);
+       if (data1)
+               writel(*data1, APP_DATA1);
+       if (data2)
+               writel(*data2, APP_DATA2);
+
+       notify_other_proc_comm();
+       while (readl(APP_COMMAND) != PCOM_CMD_DONE)
+               /* XXX check for A9 reset */
+               ;
+       status = readl(APP_STATUS);
+
+       if (status != PCOM_CMD_FAIL) {
+               if (data1)
+                       *data1 = readl(APP_DATA1);
+               if (data2)
+                       *data2 = readl(APP_DATA2);
+               ret = 0;
+       }
+       return ret;
+}
+
+static int clock_enable(unsigned id)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0);
+}
+
+static int clock_disable(unsigned id)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0);
+}
+
+static int clock_set_rate(unsigned id, unsigned rate)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+}
+
+static int clock_get_rate(unsigned id)
+{
+       if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0))
+               return -1;
+       else
+               return (int) id;
+
+}
+
+void usb_clock_init(void)
+{
+       clock_enable(USB_HS_PCLK);
+       clock_enable(USB_HS_CLK);
+       clock_enable(P_USB_HS_CORE_CLK);
+}
+
+void lcdc_clock_init(unsigned rate)
+{
+       clock_set_rate(MDP_LCDC_PCLK_CLK, rate);
+       clock_enable(MDP_LCDC_PCLK_CLK);
+       clock_enable(MDP_LCDC_PAD_PCLK_CLK);
+}
+
+void mdp_clock_init(unsigned rate)
+{
+       clock_set_rate(MDP_CLK, rate);
+       clock_enable(MDP_CLK);
+       clock_enable(MDP_P_CLK);
+}
+
+void uart3_clock_init(void)
+{
+       clock_enable(UART3_CLK);
+       clock_set_rate(UART3_CLK, 19200000 / 4);
+}
+
+void uart2_clock_init(void)
+{
+       clock_enable(UART2_CLK);
+       clock_set_rate(UART2_CLK, 19200000);
+}
+
+void uart1_clock_init(void)
+{
+       clock_enable(UART1_CLK);
+       clock_set_rate(UART1_CLK, 19200000 / 4);
+}
+
+void mddi_clock_init(unsigned num, unsigned rate)
+{
+       unsigned clock_id;
+
+       if (num == 0)
+               clock_id = PMDH_CLK;
+       else
+               clock_id = EMDH_CLK;
+
+       clock_enable(clock_id);
+       clock_set_rate(clock_id, rate);
+#ifdef PLATFORM_MSM7X30
+       clock_enable(PMDH_P_CLK);
+#endif
+}
+
+void reboot(unsigned reboot_reason)
+{
+       msm_proc_comm(PCOM_RESET_CHIP, &reboot_reason, 0);
+       for (;;)
+               ;
+}
+
+int mmc_clock_enable_disable(unsigned id, unsigned enable)
+{
+       if (enable)
+               return clock_enable(id); /*Enable mmc clock rate*/
+       else
+               return clock_disable(id); /*Disable mmc clock rate*/
+}
+
+int mmc_clock_set_rate(unsigned id, unsigned rate)
+{
+       return clock_set_rate(id, rate); /*Set mmc clock rate*/
+}
+
+int mmc_clock_get_rate(unsigned id)
+{
+       return clock_get_rate(id); /*Get mmc clock rate*/
+}
+
+int gpio_tlmm_config(unsigned config, unsigned disable)
+{
+       return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
+}
+
+int vreg_set_level(unsigned id, unsigned mv)
+{
+       return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+}
+
+int vreg_enable(unsigned id)
+{
+       unsigned enable = 1;
+       return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+}
+
+int vreg_disable(unsigned id)
+{
+       unsigned enable = 0;
+       return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
