summaryrefslogtreecommitdiff
path: root/arch/arm/mach-ux500/pm/suspend_dbg.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ux500/pm/suspend_dbg.c')
-rw-r--r--arch/arm/mach-ux500/pm/suspend_dbg.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/arch/arm/mach-ux500/pm/suspend_dbg.c b/arch/arm/mach-ux500/pm/suspend_dbg.c
index 1b7d871ba52..68afa96e547 100644
--- a/arch/arm/mach-ux500/pm/suspend_dbg.c
+++ b/arch/arm/mach-ux500/pm/suspend_dbg.c
@@ -14,10 +14,16 @@
#include <linux/suspend.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/wakelock.h>
#include <mach/pm.h>
+#include <mach/pm-timer.h>
+
+/* To reach main_wake_lock */
+#include "../../../../kernel/power/power.h"
#ifdef CONFIG_UX500_SUSPEND_STANDBY
static u32 sleep_enabled = 1;
@@ -100,6 +106,79 @@ int ux500_suspend_dbg_begin(suspend_state_t state)
return 0;
}
+/* The number of failed suspend attempts in a row before giving up */
+#define TEST_FAILS 10
+
+static int suspend_test_count;
+static int suspend_test_current;
+static int suspend_test_fail_count;
+
+void ux500_suspend_dbg_test_set_wakeup(void)
+{
+ if (suspend_test_count == 0)
+ return;
+
+ ux500_rtcrtt_off();
+
+ /* Make sure the rtc writes have been accepted */
+ udelay(120);
+
+ if (cpu_is_u9500())
+ prcmu_enable_wakeups(PRCMU_WAKEUP(ABB) | PRCMU_WAKEUP(RTC) |
+ PRCMU_WAKEUP(HSI0));
+ else
+ prcmu_enable_wakeups(PRCMU_WAKEUP(ABB) | PRCMU_WAKEUP(RTC));
+
+ /* Program RTC to generate an interrupt 1s later */
+ ux500_rtcrtt_next(1000000);
+}
+
+void ux500_suspend_dbg_test_start(int num)
+{
+ suspend_test_count = num;
+ suspend_test_current = deepsleeps_done;
+ suspend_test_fail_count = 0;
+}
+
+bool ux500_suspend_test_success(bool *ongoing)
+{
+ (*ongoing) = ((suspend_test_fail_count < TEST_FAILS) &&
+ (suspend_test_count > 0));
+ return suspend_test_fail_count < TEST_FAILS;
+}
+
+void ux500_suspend_dbg_end(void)
+{
+ static int attempts;
+
+ if (suspend_test_count > 0) {
+ attempts++;
+ pr_info("Suspend test: %d done\n", attempts);
+ suspend_test_count--;
+ wake_lock(&main_wake_lock);
+
+ if (suspend_test_current < deepsleeps_done) {
+ suspend_test_current = deepsleeps_done;
+ suspend_test_fail_count = 0;
+ } else {
+ suspend_test_fail_count++;
+ }
+
+ if (suspend_test_fail_count > TEST_FAILS) {
+ suspend_test_count = 0;
+ pr_err("suspend: Aborting after %d "
+ "failed suspend in a row\n",
+ TEST_FAILS);
+ } else if (suspend_test_count > 0) {
+ msleep(100);
+ wake_unlock(&main_wake_lock);
+ }
+
+ if (suspend_test_count == 0)
+ attempts = 0;
+ }
+}
+
void ux500_suspend_dbg_init(void)
{
struct dentry *suspend_dir;
@@ -145,7 +224,6 @@ void ux500_suspend_dbg_init(void)
if (IS_ERR_OR_NULL(file))
goto error;
-
file = debugfs_create_u32("sleep_failed", S_IRUGO,
suspend_dir,
&sleeps_failed);