summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r--arch/arm/mach-omap2/pm.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index a6c441842cc..6bd5f3b9c7a 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -18,6 +18,11 @@
#include <linux/suspend.h>
#include <linux/cpu.h>
#include <linux/of_platform.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/wakeup_reason.h>
+#include <linux/printk.h>
#include <asm/system_misc.h>
@@ -239,14 +244,80 @@ static void omap_pm_finish(void)
omap_prcm_irq_complete();
}
+bool olio_suspend_again(void);
static const struct platform_suspend_ops omap_pm_ops = {
.begin = omap_pm_begin,
.end = omap_pm_end,
.enter = omap_pm_enter,
.finish = omap_pm_finish,
.valid = suspend_valid_only_mem,
+ .suspend_again = olio_suspend_again
};
+
+
+DECLARE_WAIT_QUEUE_HEAD(wq_susp_again);
+DEFINE_MUTEX(susp_again_decision_mutex);
+#define NO_DECISION 3
+static int accel_should_suspend = NO_DECISION;
+
+
+void susp_again_post_decision(bool should_suspend)
+{
+ int res = mutex_trylock(&susp_again_decision_mutex);
+ if(res) {
+ accel_should_suspend = should_suspend;
+ wake_up(&wq_susp_again);
+ mutex_unlock(&susp_again_decision_mutex);
+ }
+ else
+ pr_err("Unable to post decision, didn't get lock");
+}
+
+//Return True if going back to sleep
+bool olio_suspend_again(void) {
+ int res;
+ bool should_suspend = false;
+ int irqno_6d = 143; // FIXME query 143 from somewhere
+ int wake_was_6d = last_wakeup_reason_test(irqno_6d);
+ if (!wake_was_6d) {
+ // Someone else woke us, so don't go back to suspend
+ return false;
+ }
+
+ /// gpio_set_value (163, 1); // FIXME: Raise UART3 ttyS2 CTS gpio163
+
+ /*Right now we don't need to thaw any threads, but this might be required
+ * if extending functionality to other drivers */
+#ifdef SUSPEND_AGAIN_THAW_KTHREADS
+ thaw_kernel_threads();
+#endif
+
+ // Wait for a decision of 6D driver
+ // We expect the driver to finish in 10ms, so 15 is safe.
+#define MAX_WAIT_TIME_SUSP_AGAIN msecs_to_jiffies(15)
+ res = wait_event_timeout(wq_susp_again, accel_should_suspend != NO_DECISION, MAX_WAIT_TIME_SUSP_AGAIN);
+ if(!res)
+ pr_warn("Suspend again was not acknowledged by driver\n");
+
+#ifdef SUSPEND_AGAIN_THAW_KTHREADS
+ freeze_kernel_threads();
+#endif
+
+ if (accel_should_suspend != NO_DECISION) {
+ pr_info("Suspend again decision: %i", accel_should_suspend);
+ should_suspend = accel_should_suspend;
+ }
+ //clear flags for next time
+ res = mutex_trylock(&susp_again_decision_mutex);
+ if(res) {
+ pr_info("susp again: clearing flag");
+ accel_should_suspend = NO_DECISION; // Not true or false
+ mutex_unlock(&susp_again_decision_mutex);
+ }
+ return should_suspend;
+}
+
#endif /* CONFIG_SUSPEND */
static void __init omap3_init_voltages(void)
@@ -290,6 +361,7 @@ static int __init omap2_common_pm_init(void)
/* if (!of_have_populated_dt()) OLIO TEST */
omap2_init_processor_devices();
+
omap_pm_if_init();
return 0;