diff --git a/hw/lm832x.c b/hw/lm832x.c
index f0ba52f..f7369dd 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -414,76 +414,9 @@ static int lm_i2c_tx(i2c_slave *i2c, uint8_t data)
     return 0;
 }

-static void lm_kbd_save(QEMUFile *f, void *opaque)
+static int lm_kbd_post_load(void *opaque)
 {
-    LM823KbdState *s = (LM823KbdState *) opaque;
-    int i;
-
-    i2c_slave_save(f, &s->i2c);
-    qemu_put_byte(f, s->i2c_dir);
-    qemu_put_byte(f, s->i2c_cycle);
-    qemu_put_byte(f, (uint8_t) s->reg);
-
-    qemu_put_8s(f, &s->config);
-    qemu_put_8s(f, &s->status);
-    qemu_put_8s(f, &s->acttime);
-    qemu_put_8s(f, &s->error);
-    qemu_put_8s(f, &s->clock);
-
-    qemu_put_be16s(f, &s->gpio.pull);
-    qemu_put_be16s(f, &s->gpio.mask);
-    qemu_put_be16s(f, &s->gpio.dir);
-    qemu_put_be16s(f, &s->gpio.level);
-
-    qemu_put_byte(f, s->kbd.dbnctime);
-    qemu_put_byte(f, s->kbd.size);
-    qemu_put_byte(f, s->kbd.start);
-    qemu_put_byte(f, s->kbd.len);
-    qemu_put_buffer(f, s->kbd.fifo, sizeof(s->kbd.fifo));
-
-    for (i = 0; i < sizeof(s->pwm.file); i ++)
-        qemu_put_be16s(f, &s->pwm.file[i]);
-    qemu_put_8s(f, &s->pwm.faddr);
-    qemu_put_buffer(f, s->pwm.addr, sizeof(s->pwm.addr));
-    qemu_put_timer(f, s->pwm.tm[0]);
-    qemu_put_timer(f, s->pwm.tm[1]);
-    qemu_put_timer(f, s->pwm.tm[2]);
-}
-
-static int lm_kbd_load(QEMUFile *f, void *opaque, int version_id)
-{
-    LM823KbdState *s = (LM823KbdState *) opaque;
-    int i;
-
-    i2c_slave_load(f, &s->i2c);
-    s->i2c_dir = qemu_get_byte(f);
-    s->i2c_cycle = qemu_get_byte(f);
-    s->reg = (int8_t) qemu_get_byte(f);
-
-    qemu_get_8s(f, &s->config);
-    qemu_get_8s(f, &s->status);
-    qemu_get_8s(f, &s->acttime);
-    qemu_get_8s(f, &s->error);
-    qemu_get_8s(f, &s->clock);
-
-    qemu_get_be16s(f, &s->gpio.pull);
-    qemu_get_be16s(f, &s->gpio.mask);
-    qemu_get_be16s(f, &s->gpio.dir);
-    qemu_get_be16s(f, &s->gpio.level);
-
-    s->kbd.dbnctime = qemu_get_byte(f);
-    s->kbd.size = qemu_get_byte(f);
-    s->kbd.start = qemu_get_byte(f);
-    s->kbd.len = qemu_get_byte(f);
-    qemu_get_buffer(f, s->kbd.fifo, sizeof(s->kbd.fifo));
-
-    for (i = 0; i < sizeof(s->pwm.file); i ++)
-        qemu_get_be16s(f, &s->pwm.file[i]);
-    qemu_get_8s(f, &s->pwm.faddr);
-    qemu_get_buffer(f, s->pwm.addr, sizeof(s->pwm.addr));
-    qemu_get_timer(f, s->pwm.tm[0]);
-    qemu_get_timer(f, s->pwm.tm[1]);
-    qemu_get_timer(f, s->pwm.tm[2]);
+    LM823KbdState *s = opaque;

     lm_kbd_irq_update(s);
     lm_kbd_gpio_update(s);
@@ -491,6 +424,40 @@ static int lm_kbd_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }

+static const VMStateDescription vmstate_lm_kbd = {
+    .name = "LM8323",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = lm_kbd_post_load,
+    .fields      = (VMStateField []) {
+        VMSTATE_I2C_SLAVE(i2c, LM823KbdState),
+        VMSTATE_UINT8(i2c_dir, LM823KbdState),
+        VMSTATE_UINT8(i2c_cycle, LM823KbdState),
+        VMSTATE_UINT8(reg, LM823KbdState),
+        VMSTATE_UINT8(config, LM823KbdState),
+        VMSTATE_UINT8(status, LM823KbdState),
+        VMSTATE_UINT8(acttime, LM823KbdState),
+        VMSTATE_UINT8(error, LM823KbdState),
+        VMSTATE_UINT8(clock, LM823KbdState),
+        VMSTATE_UINT16(gpio.pull, LM823KbdState),
+        VMSTATE_UINT16(gpio.mask, LM823KbdState),
+        VMSTATE_UINT16(gpio.dir, LM823KbdState),
+        VMSTATE_UINT16(gpio.level, LM823KbdState),
+        VMSTATE_UINT8(kbd.dbnctime, LM823KbdState),
+        VMSTATE_UINT8(kbd.size, LM823KbdState),
+        VMSTATE_UINT8(kbd.start, LM823KbdState),
+        VMSTATE_UINT8(kbd.len, LM823KbdState),
+        VMSTATE_BUFFER(kbd.fifo, LM823KbdState),
+        VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256),
+        VMSTATE_UINT8(pwm.faddr, LM823KbdState),
+        VMSTATE_BUFFER(pwm.addr, LM823KbdState),
+        VMSTATE_TIMER_ARRAY(pwm.tm, LM823KbdState, 3),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+
 static int lm8323_init(i2c_slave *i2c)
 {
     LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
@@ -504,7 +471,7 @@ static int lm8323_init(i2c_slave *i2c)
     lm_kbd_reset(s);

     qemu_register_reset((void *) lm_kbd_reset, s);
-    register_savevm("LM8323", -1, 0, lm_kbd_save, lm_kbd_load, s);
+    vmstate_register(-1, &vmstate_lm_kbd, s);
     return 0;
 }

