diff --git a/hw/sharpsl.h b/hw/sharpsl.h
index c5ccf79..0b3a774 100644
--- a/hw/sharpsl.h
+++ b/hw/sharpsl.h
@@ -10,13 +10,6 @@
     fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
 
 /* zaurus.c */
-typedef struct ScoopInfo ScoopInfo;
-ScoopInfo *scoop_init(PXA2xxState *cpu,
-                int instance, target_phys_addr_t target_base);
-void scoop_gpio_set(void *opaque, int line, int level);
-qemu_irq *scoop_gpio_in_get(ScoopInfo *s);
-void scoop_gpio_out_set(ScoopInfo *s, int line,
-                qemu_irq handler);
 
 #define SL_PXA_PARAM_BASE	0xa0000a00
 void sl_bootparam_write(target_phys_addr_t ptr);
diff --git a/hw/spitz.c b/hw/spitz.c
index 092bb64..3667618 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -23,6 +23,7 @@
 #include "audio/audio.h"
 #include "boards.h"
 #include "blockdev.h"
+#include "sysbus.h"
 
 #undef REG_FMT
 #define REG_FMT			"0x%02lx"
@@ -851,21 +852,21 @@ static void spitz_out_switch(void *opaque, int line, int level)
 #define SPITZ_SCP2_MIC_BIAS		9
 
 static void spitz_scoop_gpio_setup(PXA2xxState *cpu,
-                ScoopInfo *scp0, ScoopInfo *scp1)
+                DeviceState *scp0, DeviceState *scp1)
 {
     qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8);
 
-    scoop_gpio_out_set(scp0, SPITZ_SCP_CHRG_ON, outsignals[0]);
-    scoop_gpio_out_set(scp0, SPITZ_SCP_JK_B, outsignals[1]);
-    scoop_gpio_out_set(scp0, SPITZ_SCP_LED_GREEN, outsignals[2]);
-    scoop_gpio_out_set(scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]);
+    qdev_connect_gpio_out(scp0, SPITZ_SCP_CHRG_ON, outsignals[0]);
+    qdev_connect_gpio_out(scp0, SPITZ_SCP_JK_B, outsignals[1]);
+    qdev_connect_gpio_out(scp0, SPITZ_SCP_LED_GREEN, outsignals[2]);
+    qdev_connect_gpio_out(scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]);
 
     if (scp1) {
-        scoop_gpio_out_set(scp1, SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]);
-        scoop_gpio_out_set(scp1, SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]);
+        qdev_connect_gpio_out(scp1, SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]);
+        qdev_connect_gpio_out(scp1, SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]);
     }
 
-    scoop_gpio_out_set(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
+    qdev_connect_gpio_out(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
 }
 
 #define SPITZ_GPIO_HSYNC		22
@@ -952,7 +953,7 @@ static void spitz_common_init(ram_addr_t ram_size,
                 const char *cpu_model, enum spitz_model_e model, int arm_id)
 {
     PXA2xxState *cpu;
-    ScoopInfo *scp0, *scp1 = NULL;
+    DeviceState *scp0, *scp1 = NULL;
 
     if (!cpu_model)
         cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
@@ -970,9 +971,9 @@ static void spitz_common_init(ram_addr_t ram_size,
 
     spitz_ssp_attach(cpu);
 
-    scp0 = scoop_init(cpu, 0, 0x10800000);
+    scp0 = sysbus_create_simple("scoop", 0x10800000, NULL);
     if (model != akita) {
-	    scp1 = scoop_init(cpu, 1, 0x08800040);
+	    scp1 = sysbus_create_simple("scoop", 0x08800040, NULL);
     }
 
     spitz_scoop_gpio_setup(cpu, scp0, scp1);
diff --git a/hw/tosa.c b/hw/tosa.c
index cc8ce6d..18e3be5 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -20,6 +20,7 @@
 #include "i2c.h"
 #include "ssi.h"
 #include "blockdev.h"
+#include "sysbus.h"
 
 #define TOSA_RAM    0x04000000
 #define TOSA_ROM	0x00800000
@@ -86,14 +87,14 @@ static void tosa_out_switch(void *opaque, int line, int level)
 
 
 static void tosa_gpio_setup(PXA2xxState *cpu,
-                ScoopInfo *scp0,
-                ScoopInfo *scp1,
+                DeviceState *scp0,
+                DeviceState *scp1,
                 TC6393xbState *tmio)
 {
     qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4);
     /* MMC/SD host */
     pxa2xx_mmci_handlers(cpu->mmc,
-                    scoop_gpio_in_get(scp0)[TOSA_GPIO_SD_WP],
+                    qdev_get_gpio_in(scp0, TOSA_GPIO_SD_WP),
                     qemu_irq_invert(pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_nSD_DETECT]));
 
     /* Handle reset */
@@ -108,12 +109,12 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
                         pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_JC_CF_IRQ],
                         NULL);
 
-    scoop_gpio_out_set(scp1, TOSA_GPIO_BT_LED, outsignals[0]);
-    scoop_gpio_out_set(scp1, TOSA_GPIO_NOTE_LED, outsignals[1]);
-    scoop_gpio_out_set(scp1, TOSA_GPIO_CHRG_ERR_LED, outsignals[2]);
-    scoop_gpio_out_set(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]);
+    qdev_connect_gpio_out(scp1, TOSA_GPIO_BT_LED, outsignals[0]);
+    qdev_connect_gpio_out(scp1, TOSA_GPIO_NOTE_LED, outsignals[1]);
+    qdev_connect_gpio_out(scp1, TOSA_GPIO_CHRG_ERR_LED, outsignals[2]);
+    qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]);
 
-    scoop_gpio_out_set(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
+    qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
 }
 
 static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
@@ -208,7 +209,7 @@ static void tosa_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     TC6393xbState *tmio;
-    ScoopInfo *scp0, *scp1;
+    DeviceState *scp0, *scp1;
 
     if (!cpu_model)
         cpu_model = "pxa255";
@@ -221,8 +222,8 @@ static void tosa_init(ram_addr_t ram_size,
     tmio = tc6393xb_init(0x10000000,
             pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_TC6393XB_INT]);
 
-    scp0 = scoop_init(cpu, 0, 0x08800000);
-    scp1 = scoop_init(cpu, 1, 0x14800040);
+    scp0 = sysbus_create_simple("scoop", 0x08800000, NULL);
+    scp1 = sysbus_create_simple("scoop", 0x14800040, NULL);
 
     tosa_gpio_setup(cpu, scp0, scp1, tmio);
 
diff --git a/hw/zaurus.c b/hw/zaurus.c
index 36be94a..fca11a5 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -18,15 +18,17 @@
 #include "hw.h"
 #include "pxa.h"
 #include "sharpsl.h"
+#include "sysbus.h"
 
 #undef REG_FMT
 #define REG_FMT			"0x%02lx"
 
 /* SCOOP devices */
 
+typedef struct ScoopInfo ScoopInfo;
 struct ScoopInfo {
+    SysBusDevice busdev;
     qemu_irq handler[16];
-    qemu_irq *in;
     uint16_t status;
     uint16_t power;
     uint32_t gpio_level;
@@ -153,7 +155,7 @@ static CPUWriteMemoryFunc * const scoop_writefn[] = {
     scoop_writeb,
 };
 
-void scoop_gpio_set(void *opaque, int line, int level)
+static void scoop_gpio_set(void *opaque, int line, int level)
 {
     ScoopInfo *s = (ScoopInfo *) opaque;
 
@@ -163,77 +165,66 @@ void scoop_gpio_set(void *opaque, int line, int level)
         s->gpio_level &= ~(1 << line);
 }
 
-qemu_irq *scoop_gpio_in_get(ScoopInfo *s)
+static int scoop_init(SysBusDevice *dev)
 {
-    return s->in;
-}
+    ScoopInfo *s = FROM_SYSBUS(ScoopInfo, dev);
+    int iomemtype;
 
-void scoop_gpio_out_set(ScoopInfo *s, int line,
-                qemu_irq handler) {
-    if (line >= 16) {
-        fprintf(stderr, "No GPIO pin %i\n", line);
-        exit(-1);
-    }
+    s->status = 0x02;
+    qdev_init_gpio_out(&s->busdev.qdev, s->handler, 16);
+    qdev_init_gpio_in(&s->busdev.qdev, scoop_gpio_set, 16);
+    iomemtype = cpu_register_io_memory(scoop_readfn,
+                    scoop_writefn, s, DEVICE_NATIVE_ENDIAN);
 
-    s->handler[line] = handler;
-}
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
 
-static void scoop_save(QEMUFile *f, void *opaque)
-{
-    ScoopInfo *s = (ScoopInfo *) opaque;
-    qemu_put_be16s(f, &s->status);
-    qemu_put_be16s(f, &s->power);
-    qemu_put_be32s(f, &s->gpio_level);
-    qemu_put_be32s(f, &s->gpio_dir);
-    qemu_put_be32s(f, &s->prev_level);
-    qemu_put_be16s(f, &s->mcr);
-    qemu_put_be16s(f, &s->cdr);
-    qemu_put_be16s(f, &s->ccr);
-    qemu_put_be16s(f, &s->irr);
-    qemu_put_be16s(f, &s->imr);
-    qemu_put_be16s(f, &s->isr);
+    return 0;
 }
 
-static int scoop_load(QEMUFile *f, void *opaque, int version_id)
+static bool is_version_0 (void *opaque, int version_id)
 {
-    uint16_t dummy;
-    ScoopInfo *s = (ScoopInfo *) opaque;
-    qemu_get_be16s(f, &s->status);
-    qemu_get_be16s(f, &s->power);
-    qemu_get_be32s(f, &s->gpio_level);
-    qemu_get_be32s(f, &s->gpio_dir);
-    qemu_get_be32s(f, &s->prev_level);
-    qemu_get_be16s(f, &s->mcr);
-    qemu_get_be16s(f, &s->cdr);
-    qemu_get_be16s(f, &s->ccr);
-    qemu_get_be16s(f, &s->irr);
-    qemu_get_be16s(f, &s->imr);
-    qemu_get_be16s(f, &s->isr);
-    if (version_id < 1)
-	    qemu_get_be16s(f, &dummy);
-
-    return 0;
+    return version_id == 0;
 }
 
-ScoopInfo *scoop_init(PXA2xxState *cpu,
-		int instance,
-		target_phys_addr_t target_base) {
-    int iomemtype;
-    ScoopInfo *s;
 
-    s = (ScoopInfo *)
-            qemu_mallocz(sizeof(ScoopInfo));
-    memset(s, 0, sizeof(ScoopInfo));
+static const VMStateDescription vmstate_scoop_regs = {
+    .name = "scoop",
+    .version_id = 1,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields = (VMStateField []) {
+        VMSTATE_UINT16(status, ScoopInfo),
+        VMSTATE_UINT16(power, ScoopInfo),
+        VMSTATE_UINT32(gpio_level, ScoopInfo),
+        VMSTATE_UINT32(gpio_dir, ScoopInfo),
+        VMSTATE_UINT32(prev_level, ScoopInfo),
+        VMSTATE_UINT16(mcr, ScoopInfo),
+        VMSTATE_UINT16(cdr, ScoopInfo),
+        VMSTATE_UINT16(ccr, ScoopInfo),
+        VMSTATE_UINT16(irr, ScoopInfo),
+        VMSTATE_UINT16(imr, ScoopInfo),
+        VMSTATE_UINT16(isr, ScoopInfo),
+        VMSTATE_UNUSED_TEST(is_version_0, 2),
+        VMSTATE_END_OF_LIST(),
+    },
+};
 
-    s->status = 0x02;
-    s->in = qemu_allocate_irqs(scoop_gpio_set, s, 16);
-    iomemtype = cpu_register_io_memory(scoop_readfn,
-                    scoop_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(target_base, 0x1000, iomemtype);
-    register_savevm(NULL, "scoop", instance, 1, scoop_save, scoop_load, s);
+static SysBusDeviceInfo scoop_sysbus_info = {
+    .init           = scoop_init,
+    .qdev.name      = "scoop",
+    .qdev.desc      = "Scoop2 Sharp custom ASIC",
+    .qdev.size      = sizeof(ScoopInfo),
+    .qdev.vmsd      = &vmstate_scoop_regs,
+    .qdev.props     = (Property[]) {
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
 
-    return s;
+static void scoop_register(void)
+{
+    sysbus_register_withprop(&scoop_sysbus_info);
 }
+device_init(scoop_register);
 
 /* Write the bootloader parameters memory area.  */
 
