Skip to content

Commit

Permalink
i8254: Convert PITCommonState to QOM realizefn
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
afaerber committed Apr 22, 2013
1 parent 9d09d6c commit f9bd9c8
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 23 deletions.
38 changes: 27 additions & 11 deletions hw/i386/kvm/i8254.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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:
Expand All @@ -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);
Expand All @@ -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[] = {
Expand All @@ -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;
Expand All @@ -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)
Expand Down
20 changes: 17 additions & 3 deletions hw/timer/i8254.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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];
Expand All @@ -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[] = {
Expand All @@ -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;
Expand All @@ -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)
Expand Down
8 changes: 0 additions & 8 deletions hw/timer/i8254_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 0 additions & 1 deletion include/hw/timer/i8254_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit f9bd9c8

Please sign in to comment.