diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0df25c331ffcdabc22a0a818a8cadb9ab4eb1004..36a8f0d098e2df26e76abadde9df6ac1aa79b9c5 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -53,3 +53,11 @@ config DM_CROS_EC
 	  but otherwise makes few changes. Since cros_ec also supports
 	  LPC (which doesn't support driver model yet), a full
 	  conversion is not yet possible.
+
+config CONFIG_FSL_SEC_MON
+	bool "Enable FSL SEC_MON Driver"
+	help
+	  Freescale Security Monitor block is responsible for monitoring
+	  system states.
+	  Security Monitor can be transitioned on any security failures,
+	  like software violations or hardware security violations.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a34972df4ee14e5db82b68b82a32d8a9653b2266..6028cd43fb15c596ba6c63950615ff7b996da624 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
 obj-$(CONFIG_STATUS_LED) += status_led.o
 obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
+obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
diff --git a/drivers/misc/fsl_sec_mon.c b/drivers/misc/fsl_sec_mon.c
new file mode 100644
index 0000000000000000000000000000000000000000..d482a7db9ca1cfd54adfea18cd86374867836ad5
--- /dev/null
+++ b/drivers/misc/fsl_sec_mon.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_sec_mon.h>
+
+int change_sec_mon_state(u32 initial_state, u32 final_state)
+{
+	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
+						(CONFIG_SYS_SEC_MON_ADDR);
+	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
+	int timeout = 10;
+
+	if ((sts & HPSR_SSM_ST_MASK) != initial_state)
+		return -1;
+
+	if (initial_state == HPSR_SSM_ST_TRUST) {
+		switch (final_state) {
+		case HPSR_SSM_ST_NON_SECURE:
+			printf("SEC_MON state transitioning to Soft Fail.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
+
+			/*
+			 * poll till SEC_MON is in
+			 * Soft Fail state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_SOFT_FAIL)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_SOFT_FAIL)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+
+			timeout = 10;
+
+			printf("SEC_MON state transitioning to Non Secure.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
+
+			/*
+			 * poll till SEC_MON is in
+			 * Non Secure state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_NON_SECURE)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_NON_SECURE)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+			break;
+		case HPSR_SSM_ST_SOFT_FAIL:
+			printf("SEC_MON state transitioning to Soft Fail.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
+
+			/*
+			 * polling loop till SEC_MON is in
+			 * Soft Fail state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_SOFT_FAIL)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_SOFT_FAIL)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+			break;
+		default:
+			return -1;
+		}
+	} else if (initial_state == HPSR_SSM_ST_NON_SECURE) {
+		switch (final_state) {
+		case HPSR_SSM_ST_SOFT_FAIL:
+			printf("SEC_MON state transitioning to Soft Fail.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
+
+			/*
+			 * polling loop till SEC_MON is in
+			 * Soft Fail state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_SOFT_FAIL)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_SOFT_FAIL)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+			break;
+		default:
+			return -1;
+		}
+	}
+
+	return 0;
+}
diff --git a/include/fsl_sec_mon.h b/include/fsl_sec_mon.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6794cefcc53b78df3a3df65542aa284ae0971c1
--- /dev/null
+++ b/include/fsl_sec_mon.h
@@ -0,0 +1,58 @@
+/*
+ * Common internal memory map for some Freescale SoCs
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __FSL_SEC_MON_H
+#define __FSL_SEC_MON_H
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SYS_FSL_SEC_MON_LE
+#define sec_mon_in32(a)       in_le32(a)
+#define sec_mon_out32(a, v)   out_le32(a, v)
+#define sec_mon_in16(a)       in_le16(a)
+#define sec_mon_clrbits32     clrbits_le32
+#define sec_mon_setbits32     setbits_le32
+#elif defined(CONFIG_SYS_FSL_SEC_MON_BE)
+#define sec_mon_in32(a)       in_be32(a)
+#define sec_mon_out32(a, v)   out_be32(a, v)
+#define sec_mon_in16(a)       in_be16(a)
+#define sec_mon_clrbits32     clrbits_be32
+#define sec_mon_setbits32     setbits_be32
+#else
+#error Neither CONFIG_SYS_FSL_SEC_MON_LE nor CONFIG_SYS_FSL_SEC_MON_BE defined
+#endif
+
+struct ccsr_sec_mon_regs {
+	u8 reserved0[0x04];
+	u32 hp_com;	/* 0x04 SEC_MON_HP Command Register */
+	u8 reserved2[0x0c];
+	u32 hp_stat;	/* 0x08 SEC_MON_HP Status Register */
+};
+
+#define HPCOMR_SW_SV 0x100		/* Security Violation bit */
+#define HPCOMR_SW_FSV 0x200		/* Fatal Security Violation bit */
+#define HPCOMR_SSM_ST 0x1		/* SSM_ST field in SEC_MON command */
+#define HPSR_SSM_ST_CHECK	0x900	/* SEC_MON is in check state */
+#define HPSR_SSM_ST_NON_SECURE	0xb00	/* SEC_MON is in non secure state */
+#define HPSR_SSM_ST_TRUST	0xd00	/* SEC_MON is in trusted state */
+#define HPSR_SSM_ST_SOFT_FAIL	0x300	/* SEC_MON is in soft fail state */
+#define HPSR_SSM_ST_MASK	0xf00	/* Mask for SSM_ST field */
+
+/*
+ * SEC_MON read. This specifies the possible reads
+ * from the SEC_MON
+ */
+enum {
+	SEC_MON_SSM_ST,
+	SEC_MON_SW_FSV,
+	SEC_MON_SW_SV,
+};
+
+int change_sec_mon_state(uint32_t initial_state, uint32_t final_state);
+
+#endif /* __FSL_SEC_MON_H */