Patchwork [RFC,31/34] i8254: Convert PITCommonState to QOM realizefn

login
register
mail settings
Submitter Andreas Färber
Date Nov. 26, 2012, 12:12 a.m.
Message ID <1353888766-6951-32-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/201594/
State New
Headers show

Comments

Andreas Färber - Nov. 26, 2012, 12:12 a.m.
Instead of having the parent provide PITCommonClass::init,
let the children override DeviceClass::realize themselves.
This pushes the responsibility for saving and calling the parent's
realizefn to the children.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Cc: Anthony Liguori <anthony@codemonkey.ws>
---
 hw/i8254.c          |   20 +++++++++++++++++---
 hw/i8254_common.c   |    8 --------
 hw/i8254_internal.h |    1 -
 hw/kvm/i8254.c      |   38 +++++++++++++++++++++++++++-----------
 4 Dateien geändert, 44 Zeilen hinzugefügt(+), 23 Zeilen entfernt(-)

Patch

diff --git a/hw/i8254.c b/hw/i8254.c
index 2a01217..6fa4825 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -35,6 +35,15 @@ 
 #define RW_STATE_WORD0 3
 #define RW_STATE_WORD1 4
 
+#define PIT_CLASS(class) OBJECT_CLASS_CHECK(PITClass, (class), TYPE_I8254)
+#define PIT_GET_CLASS(obj) OBJECT_GET_CLASS(PITClass, (obj), TYPE_I8254)
+
+typedef struct PITClass {
+    PITCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} PITClass;
+
 static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
 
 static int pit_get_count(PITChannelState *s)
@@ -313,8 +322,10 @@  static void pit_post_load(PITCommonState *s)
     }
 }
 
-static int pit_initfn(PITCommonState *pit)
+static void pit_realizefn(DeviceState *dev, Error **err)
 {
+    PITCommonState *pit = PIT_COMMON(dev);
+    PITClass *pc = PIT_GET_CLASS(dev);
     PITChannelState *s;
 
     s = &pit->channels[0];
@@ -326,7 +337,7 @@  static int pit_initfn(PITCommonState *pit)
 
     qdev_init_gpio_in(&pit->dev.qdev, pit_irq_control, 1);
 
-    return 0;
+    pc->parent_realize(dev, err);
 }
 
 static Property pit_properties[] = {
@@ -336,10 +347,12 @@  static Property pit_properties[] = {
 
 static void pit_class_initfn(ObjectClass *klass, void *data)
 {
+    PITClass *pc = PIT_CLASS(klass);
     PITCommonClass *k = PIT_COMMON_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = pit_initfn;
+    pc->parent_realize = dc->realize;
+    dc->realize = pit_realizefn;
     k->set_channel_gate = pit_set_channel_gate;
     k->get_channel_info = pit_get_channel_info_common;
     k->post_load = pit_post_load;
@@ -352,6 +365,7 @@  static const TypeInfo pit_info = {
     .parent        = TYPE_PIT_COMMON,
     .instance_size = sizeof(PITCommonState),
     .class_init    = pit_class_initfn,
+    .class_size    = sizeof(PITClass),
 };
 
 static void pit_register_types(void)
diff --git a/hw/i8254_common.c b/hw/i8254_common.c
index 1883405..3beb2cd 100644
--- a/hw/i8254_common.c
+++ b/hw/i8254_common.c
@@ -170,14 +170,6 @@  static void pit_common_realize(DeviceState *dev, Error **err)
 {
     ISADevice *isadev = ISA_DEVICE(dev);
     PITCommonState *pit = PIT_COMMON(dev);
-    PITCommonClass *c = PIT_COMMON_GET_CLASS(pit);
-    int ret;
-
-    ret = c->init(pit);
-    if (ret < 0) {
-        error_setg(err, "PIT init failed.");
-        return;
-    }
 
     isa_register_ioport(isadev, &pit->ioports, pit->iobase);
 
diff --git a/hw/i8254_internal.h b/hw/i8254_internal.h
index 686f0c2..8cd4faa 100644
--- a/hw/i8254_internal.h
+++ b/hw/i8254_internal.h
@@ -68,7 +68,6 @@  typedef struct PITCommonState {
 typedef struct PITCommonClass {
     ISADeviceClass parent_class;
 
-    int (*init)(PITCommonState *s);
     void (*set_channel_gate)(PITCommonState *s, PITChannelState *sc, int val);
     void (*get_channel_info)(PITCommonState *s, PITChannelState *sc,
                              PITChannelInfo *info);
diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c
index 420d5ad..72d84e8 100644
--- a/hw/kvm/i8254.c
+++ b/hw/kvm/i8254.c
@@ -33,6 +33,10 @@ 
 #define CALIBRATION_ROUNDS   3
 
 #define KVM_PIT(obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254)
+#define KVM_PIT_CLASS(class) \
+    OBJECT_CLASS_CHECK(KVMPITClass, (class), TYPE_KVM_I8254)
+#define KVM_PIT_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(KVMPITClass, (obj), TYPE_KVM_I8254)
 
 typedef struct KVMPITState {
     PITCommonState parent_obj;
@@ -42,6 +46,12 @@  typedef struct KVMPITState {
     int64_t kernel_clock_offset;
 } KVMPITState;
 
+typedef struct KVMPITClass {
+    PITCommonClass parent_class;
+
+    DeviceRealize parent_realize;
+} KVMPITClass;
+
 static int64_t abs64(int64_t v)
 {
     return v < 0 ? -v : v;
@@ -237,8 +247,10 @@  static void kvm_pit_vm_state_change(void *opaque, int running,
     }
 }
 
-static int kvm_pit_initfn(PITCommonState *pit)
+static void kvm_pit_realizefn(DeviceState *dev, Error **err)
 {
+    PITCommonState *pit = PIT_COMMON(dev);
+    KVMPITClass *kpc = KVM_PIT_GET_CLASS(dev);
     KVMPITState *s = KVM_PIT(pit);
     struct kvm_pit_config config = {
         .flags = 0,
@@ -251,9 +263,9 @@  static int kvm_pit_initfn(PITCommonState *pit)
         ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
     }
     if (ret < 0) {
-        fprintf(stderr, "Create kernel PIC irqchip failed: %s\n",
-                strerror(ret));
-        return ret;
+        error_setg(err, "Create kernel PIC irqchip failed: %s\n",
+                   strerror(ret));
+        return;
     }
     switch (s->lost_tick_policy) {
     case LOST_TICK_DELAY:
@@ -264,15 +276,16 @@  static int kvm_pit_initfn(PITCommonState *pit)
 
             ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control);
             if (ret < 0) {
-                fprintf(stderr,
-                        "Can't disable in-kernel PIT reinjection: %s\n",
-                        strerror(ret));
-                return ret;
+                error_setg(err,
+                           "Can't disable in-kernel PIT reinjection: %s\n",
+                           strerror(ret));
+                return;
             }
         }
         break;
     default:
-        return -EINVAL;
+        error_setg(err, "Lost tick policy not supported.");
+        return;
     }
 
     memory_region_init_reservation(&pit->ioports, "kvm-pit", 4);
@@ -281,7 +294,7 @@  static int kvm_pit_initfn(PITCommonState *pit)
 
     qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
 
-    return 0;
+    kpc->parent_realize(dev, err);
 }
 
 static Property kvm_pit_properties[] = {
@@ -293,10 +306,12 @@  static Property kvm_pit_properties[] = {
 
 static void kvm_pit_class_init(ObjectClass *klass, void *data)
 {
+    KVMPITClass *kpc = KVM_PIT_CLASS(klass);
     PITCommonClass *k = PIT_COMMON_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = kvm_pit_initfn;
+    kpc->parent_realize = dc->realize;
+    dc->realize = kvm_pit_realizefn;
     k->set_channel_gate = kvm_pit_set_gate;
     k->get_channel_info = kvm_pit_get_channel_info;
     k->pre_save = kvm_pit_get;
@@ -310,6 +325,7 @@  static const TypeInfo kvm_pit_info = {
     .parent        = TYPE_PIT_COMMON,
     .instance_size = sizeof(KVMPITState),
     .class_init = kvm_pit_class_init,
+    .class_size = sizeof(KVMPITClass),
 };
 
 static void kvm_pit_register(void)