summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMattias Nilsson <mattias.i.nilsson@stericsson.com>2012-02-27 16:08:24 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 10:59:33 +0200
commit6fdae26dd1ed7dc56d6d231a48f88e59aee98d8c (patch)
tree2e837b3e40ee0317149a0b5ff1b6765862f748d3 /drivers/mfd
parent4eb4e784ac67d4339cb56842aa411ef07fab1313 (diff)
mfd: db8500-prcmu: add function to read reset status
This patch adds a function that returns the value of the reset status register at startup. It also changes the read of the (software) reset code, so that the saved value is only read at startup. ST Ericsson ID: 366664 ST Ericsson FOSS-OUT ID: trivial Signed-off-by: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/db8500-prcmu.c33
-rw-r--r--drivers/mfd/dbx500-prcmu-regs.h14
2 files changed, 45 insertions, 2 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 536566a890d..186206daab7 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -426,6 +426,13 @@ static DEFINE_SPINLOCK(clkout_lock);
/* Global var to runtime determine TCDM base for v2 or v1 */
static __iomem void *tcdm_base;
+/*
+ * Copies of the startup values of the reset status register and the SW reset
+ * code.
+ */
+static u32 reset_status_copy;
+static u16 reset_code_copy;
+
struct clk_mgt {
void __iomem *reg;
u32 pllsw;
@@ -2404,7 +2411,17 @@ void db8500_prcmu_system_reset(u16 reset_code)
*/
u16 db8500_prcmu_get_reset_code(void)
{
- return readw(tcdm_base + PRCM_SW_RST_REASON);
+ return reset_code_copy;
+}
+
+/**
+ * db8500_prcmu_get_reset_status - Retrieve reset status
+ *
+ * Retrieves the value of the reset status register as read at startup.
+ */
+u32 db8500_prcmu_get_reset_status(void)
+{
+ return reset_status_copy;
}
/**
@@ -2689,6 +2706,7 @@ void __init db8500_prcmu_early_init(void)
{
unsigned int i;
void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
+ void __iomem *sec_base;
if (tcpm_base != NULL) {
u32 version;
@@ -2707,6 +2725,19 @@ void __init db8500_prcmu_early_init(void)
tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
+ /*
+ * Copy the value of the reset status register and if needed also
+ * the software reset code.
+ */
+ sec_base = ioremap_nocache(U8500_PRCMU_SEC_BASE, SZ_4K);
+ if (sec_base != NULL) {
+ reset_status_copy = readl(sec_base +
+ DB8500_SEC_PRCM_RESET_STATUS);
+ iounmap(sec_base);
+ }
+ if (reset_status_copy & DB8500_SEC_PRCM_RESET_STATUS_APE_SOFTWARE_RESET)
+ reset_code_copy = readw(tcdm_base + PRCM_SW_RST_REASON);
+
spin_lock_init(&mb0_transfer.lock);
spin_lock_init(&mb0_transfer.dbb_irqs_lock);
mutex_init(&mb0_transfer.ac_wake_lock);
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h
index 48b84061db0..0835a57dac1 100644
--- a/drivers/mfd/dbx500-prcmu-regs.h
+++ b/drivers/mfd/dbx500-prcmu-regs.h
@@ -127,7 +127,6 @@
#define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168)
#define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484)
#define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488)
-#define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018)
/* System reset register */
#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228)
@@ -250,4 +249,17 @@
/* System reset register */
#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228)
+/* Secure read-only registers */
+#define DB8500_SEC_PRCM_RESET_STATUS 0x03C
+#define DB8500_SEC_PRCM_RESET_STATUS_A9_CPU0_WATCHDOG_RESET BIT(0)
+#define DB8500_SEC_PRCM_RESET_STATUS_A9_CPU1_WATCHDOG_RESET BIT(1)
+#define DB8500_SEC_PRCM_RESET_STATUS_APE_SOFTWARE_RESET BIT(2)
+#define DB8500_SEC_PRCM_RESET_STATUS_APE_RESET BIT(3)
+#define DB8500_SEC_PRCM_RESET_STATUS_SECURE_WATCHDOG BIT(4)
+#define DB8500_SEC_PRCM_RESET_STATUS_POWER_ON_RESET BIT(5)
+#define DB8500_SEC_PRCM_RESET_STATUS_A9_RESTART BIT(6)
+#define DB8500_SEC_PRCM_RESET_STATUS_APE_RESTART BIT(7)
+#define DB8500_SEC_PRCM_RESET_STATUS_MODEM_SOFTWARE_RESET BIT(8)
+#define DB8500_SEC_PRCM_RESET_STATUS_BOOT_ENGI BIT(16)
+
#endif /* __DB8500_PRCMU_REGS_H */