[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 12/18] xen/arm: Suspend/resume timer interrupt generation



Timer interrupts have to be disabled while the system is in suspend.
Otherwise, a timer interrupt would fire and wake-up the system.
Suspending the timer interrupts consists of disabling physical EL1
and EL2 timers. The resume consists only of raising timer softirq,
which will trigger the generic timer code to reprogram the EL2 timer
as needed. Enabling of EL1 physical timer will be triggered by an
entity which uses it.

Signed-off-by: Mirela Simonovic <mirela.simonovic@xxxxxxxxxx>
Signed-off-by: Saeed Nowshadi <saeed.nowshadi@xxxxxxxxxx>
---
 xen/arch/arm/suspend.c     |  4 ++++
 xen/arch/arm/time.c        | 22 ++++++++++++++++++++++
 xen/include/asm-arm/time.h |  3 +++
 3 files changed, 29 insertions(+)

diff --git a/xen/arch/arm/suspend.c b/xen/arch/arm/suspend.c
index b7940fe03f..d1b48c339a 100644
--- a/xen/arch/arm/suspend.c
+++ b/xen/arch/arm/suspend.c
@@ -131,6 +131,8 @@ static long system_suspend(void *data)
         goto resume_nonboot_cpus;
     }
 
+    time_suspend();
+
     local_irq_save(flags);
     status = gic_suspend();
     if ( status )
@@ -146,6 +148,8 @@ static long system_suspend(void *data)
 resume_irqs:
     local_irq_restore(flags);
 
+    time_resume();
+
 resume_nonboot_cpus:
     rcu_barrier();
     enable_nonboot_cpus();
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index bbccee742e..aaefcb6441 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -357,6 +357,28 @@ void domain_set_time_offset(struct domain *d, int64_t 
time_offset_seconds)
     /* XXX update guest visible wallclock time */
 }
 
+void time_suspend(void)
+{
+    /* Disable physical EL1 timer */
+    WRITE_SYSREG32(0, CNTP_CTL_EL0);
+
+    /* Disable hypervisor's timer */
+    WRITE_SYSREG32(0, CNTHP_CTL_EL2);
+    isb();
+}
+
+void time_resume(void)
+{
+    /*
+     * Raising timer softirq will trigger generic timer code to reprogram_timer
+     * with the correct timeout value (which is not known here). There is no
+     * need to do anything else in order to recover the time keeping from power
+     * down, because the system counter is not affected by the power down (it
+     * resides out of the ARM's cluster in an always-on part of the SoC).
+     */
+    raise_softirq(TIMER_SOFTIRQ);
+}
+
 static int cpu_time_callback(struct notifier_block *nfb,
                              unsigned long action,
                              void *hcpu)
diff --git a/xen/include/asm-arm/time.h b/xen/include/asm-arm/time.h
index 19a4515e72..9275b39a4a 100644
--- a/xen/include/asm-arm/time.h
+++ b/xen/include/asm-arm/time.h
@@ -42,6 +42,9 @@ extern uint64_t ns_to_ticks(s_time_t ns);
 
 void preinit_xen_time(void);
 
+void time_suspend(void);
+void time_resume(void);
+
 #endif /* __ARM_TIME_H__ */
 /*
  * Local variables:
-- 
2.13.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.