diff options
author | Jacky Cheung <jackyc@google.com> | 2014-05-23 17:09:09 -0700 |
---|---|---|
committer | Socrates Guerrero <sguerrero@google.com> | 2014-05-24 20:23:51 +0000 |
commit | e6e1b713e4b161bb1e44191ae846fe07bb93c299 (patch) | |
tree | 75a5d35427d103193fa91bb264d6a0bf049f12c3 | |
parent | 977177cfc920f1f7f9fb09abcf7502eef26db9cc (diff) | |
download | omap-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.c | 43 | ||||
-rw-r--r-- | drivers/base/power/main.c | 13 |
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")); |