Patchwork [v6,10/12] suspend: make rtc alarm wakeup the guest.

login
register
mail settings
Submitter Gerd Hoffmann
Date Feb. 23, 2012, 12:45 p.m.
Message ID <1330001126-20564-11-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/142601/
State New
Headers show

Comments

Gerd Hoffmann - Feb. 23, 2012, 12:45 p.m.
Make the rtc wake up the guest when the alarm fires.
Add acpi windup to property support RTC_EN, so guests
can enable and disable this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/acpi.c        |    7 +++++++
 hw/mc146818rtc.c |    1 +
 sysemu.h         |    1 +
 3 files changed, 9 insertions(+), 0 deletions(-)

Patch

diff --git a/hw/acpi.c b/hw/acpi.c
index 7b16716..c05dde6 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -254,6 +254,10 @@  static void acpi_notify_wakeup(Notifier *notifier, void *data)
     WakeupReason *reason = data;
 
     switch (*reason) {
+    case QEMU_WAKEUP_REASON_RTC:
+        ar->pm1.evt.sts |=
+            (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS);
+        break;
     case QEMU_WAKEUP_REASON_OTHER:
     default:
         /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
@@ -287,6 +291,8 @@  void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
 void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
 {
     ar->pm1.evt.en = val;
+    qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
+                              val & ACPI_BITMASK_RT_CLOCK_ENABLE);
 }
 
 void acpi_pm1_evt_power_down(ACPIREGS *ar)
@@ -301,6 +307,7 @@  void acpi_pm1_evt_reset(ACPIREGS *ar)
 {
     ar->pm1.evt.sts = 0;
     ar->pm1.evt.en = 0;
+    qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, 0);
 }
 
 /* ACPI PM_TMR */
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index ee7a02f..a46fdfc 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -437,6 +437,7 @@  static void rtc_update_second2(void *opaque)
 
         s->cmos_data[RTC_REG_C] |= REG_C_AF;
         if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
+            qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
             qemu_irq_raise(s->irq);
             s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
         }
diff --git a/sysemu.h b/sysemu.h
index af73813..781bdaf 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -40,6 +40,7 @@  void vm_stop_force_state(RunState state);
 
 typedef enum WakeupReason {
     QEMU_WAKEUP_REASON_OTHER = 0,
+    QEMU_WAKEUP_REASON_RTC,
 } WakeupReason;
 
 void qemu_system_reset_request(void);