summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacky Cheung <jackyc@google.com>2014-05-23 17:09:09 -0700
committerSocrates Guerrero <sguerrero@google.com>2014-05-24 20:23:51 +0000
commite6e1b713e4b161bb1e44191ae846fe07bb93c299 (patch)
tree75a5d35427d103193fa91bb264d6a0bf049f12c3
parent977177cfc920f1f7f9fb09abcf7502eef26db9cc (diff)
downloadomap-glass-omap-xrv67.tar.gz
Add reboot reason on suspend/resume timeout.glass-omap-xrv67glass-omap-xrv60b
This is needed to debug suspend/resume timeout issues. On reboot, the bootloader will pick up this written reason and take actions. For example, pass it along to Linux for tracking purpose. Change-Id: I432a7bf17870f6c75372a8de9f83de237448e2ef (cherry picked from commit f17d040a48b6c45f6fb624348cf276427724d04e)
-rw-r--r--arch/arm/mach-omap2/omap-reboot-reason.c43
-rw-r--r--drivers/base/power/main.c13
2 files changed, 45 insertions, 11 deletions
diff --git a/arch/arm/mach-omap2/omap-reboot-reason.c b/arch/arm/mach-omap2/omap-reboot-reason.c
index c0c7e6e51db2..12264a428f41 100644
--- a/arch/arm/mach-omap2/omap-reboot-reason.c
+++ b/arch/arm/mach-omap2/omap-reboot-reason.c
@@ -20,23 +20,18 @@
#include "common.h"
#include "omap4-sar-layout.h"
-static int omap_reboot_notifier_call(struct notifier_block *this,
- unsigned long code, void *cmd)
+static int _omap_write_reboot_reason(const char* reason)
{
char __iomem *sar_base;
- char *reason = "normal";
int offset = 0;
+ size_t size;
sar_base = omap4_get_sar_ram_base();
if (!sar_base)
- return notifier_from_errno(-ENOMEM);
+ return -ENOMEM;
/* Save reboot mode in scratch memory */
- if (code == SYS_RESTART && cmd != NULL && *(char *)cmd)
- reason = cmd;
- else if (code == SYS_POWER_OFF)
- reason = "off";
if (cpu_is_omap44xx())
offset = OMAP4_REBOOT_REASON_OFFSET;
@@ -45,17 +40,43 @@ static int omap_reboot_notifier_call(struct notifier_block *this,
else
WARN("undefined chip, %s", __func__);
- strncpy(sar_base + offset, reason, OMAP_REBOOT_REASON_SIZE-1);
+ size = (strlen(reason) > OMAP_REBOOT_REASON_SIZE-1)?
+ (OMAP_REBOOT_REASON_SIZE-1) : strlen(reason);
+
+ strncpy(sar_base + offset, reason, size);
/* always end with terminal symbol */
- *(sar_base + offset + OMAP_REBOOT_REASON_SIZE - 1) = '\0';
- return NOTIFY_DONE;
+ *(sar_base + offset + size) = '\0';
+
+ return 0;
+}
+
+static int omap_reboot_notifier_call(struct notifier_block *this,
+ unsigned long code, void *cmd)
+{
+ char *reason = "normal";
+ int err;
+
+ /* Save reboot mode in scratch memory */
+ if (code == SYS_RESTART && cmd != NULL && *(char *)cmd)
+ reason = cmd;
+ else if (code == SYS_POWER_OFF)
+ reason = "off";
+
+ err = _omap_write_reboot_reason(reason);
+
+ return (err)? notifier_from_errno(err) : NOTIFY_DONE;
}
static struct notifier_block omap_reboot_notifier = {
.notifier_call = omap_reboot_notifier_call,
};
+int omap_write_reboot_reason(const char* reason)
+{
+ return _omap_write_reboot_reason(reason);
+}
+
static int __init omap_reboot_reason_init(void)
{
char __iomem *sar_base;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 293864ed8a47..0ce18a74353d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -33,6 +33,11 @@
#include "../base.h"
#include "power.h"
+#ifdef CONFIG_MACH_NOTLE
+#include <linux/reboot.h>
+extern int omap_write_reboot_reason(const char* reason);
+#endif
+
typedef int (*pm_callback_t)(struct device *);
/*
@@ -694,6 +699,14 @@ static void dpm_drv_timeout(unsigned long data)
struct device *dev = wd_data->dev;
struct task_struct *tsk = wd_data->tsk;
+#ifdef CONFIG_MACH_NOTLE
+ /* Record the timed-out device */
+ char buf[16];
+ scnprintf(buf,15,"srto:%s", dev_name(dev));
+ buf[15] = '\0';
+ omap_write_reboot_reason(buf);
+#endif
+
printk(KERN_EMERG "**** DPM device timeout: %s (%s)\n", dev_name(dev),
(dev->driver ? dev->driver->name : "no driver"));