From: Mirela Simonovic <mirela.simono...@aggios.com>

GIC state is saved on system suspend by calling gic_suspend
(this function does not change current state of the GIC but only
saves the values of configuration registers).
The state of GIC has to be restored by calling gic_resume, but only
if the gic_suspend has succeeded. If gic_suspend fails, we'll just
restore interrupts configuration and abort suspend.

Signed-off-by: Mirela Simonovic <mirela.simono...@aggios.com>
Signed-off-by: Saeed Nowshadi <saeed.nowsh...@xilinx.com>
---
 xen/arch/arm/gic.c     |  4 +---
 xen/arch/arm/suspend.c | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index e9feb1fd3b..ef90664929 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -476,9 +476,7 @@ int gic_suspend(void)
     if ( !gic_hw_ops->suspend || !gic_hw_ops->resume )
         return -ENOSYS;
 
-    gic_hw_ops->suspend();
-
-    return 0;
+    return gic_hw_ops->suspend();
 }
 
 void gic_resume(void)
diff --git a/xen/arch/arm/suspend.c b/xen/arch/arm/suspend.c
index 0c16cfc750..b94a6df86d 100644
--- a/xen/arch/arm/suspend.c
+++ b/xen/arch/arm/suspend.c
@@ -137,6 +137,7 @@ void vcpu_resume(struct vcpu *v)
 static long system_suspend(void *data)
 {
     int status;
+    unsigned long flags;
 
     BUG_ON(system_state != SYS_STATE_active);
 
@@ -150,8 +151,21 @@ static long system_suspend(void *data)
         goto resume_nonboot_cpus;
     }
 
+    local_irq_save(flags);
+    status = gic_suspend();
+    if ( status )
+    {
+        system_state = SYS_STATE_resume;
+        goto resume_irqs;
+    }
+
     system_state = SYS_STATE_resume;
 
+    gic_resume();
+
+resume_irqs:
+    local_irq_restore(flags);
+
 resume_nonboot_cpus:
     rcu_barrier();
     enable_nonboot_cpus();
-- 
2.37.1

Reply via email to