Stellaris qdev conversion

Signed-off-by: Paul Brook <paul@codesourcery.com>
diff --git a/hw/armv7m.c b/hw/armv7m.c
index e3d00ff..9657ed1 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -117,18 +117,35 @@
    bitband_writel
 };
 
+typedef struct {
+    SysBusDevice busdev;
+    uint32_t base;
+} BitBandState;
+
+static void bitband_init(SysBusDevice *dev)
+{
+    BitBandState *s = FROM_SYSBUS(BitBandState, dev);
+    int iomemtype;
+
+    s->base = qdev_get_prop_int(&dev->qdev, "base", 0);
+    iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,
+                                       &s->base);
+    sysbus_init_mmio(dev, 0x02000000, iomemtype);
+}
+
 static void armv7m_bitband_init(void)
 {
-    int iomemtype;
-    static uint32_t bitband1_offset = 0x20000000;
-    static uint32_t bitband2_offset = 0x40000000;
+    DeviceState *dev;
 
-    iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,
-                                       &bitband1_offset);
-    cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype);
-    iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,
-                                       &bitband2_offset);
-    cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype);
+    dev = qdev_create(NULL, "ARM,bitband-memory");
+    qdev_set_prop_int(dev, "base", 0x20000000);
+    qdev_init(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000);
+
+    dev = qdev_create(NULL, "ARM,bitband-memory");
+    qdev_set_prop_int(dev, "base", 0x40000000);
+    qdev_init(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000);
 }
 
 /* Board init.  */
@@ -220,3 +237,11 @@
 
     return pic;
 }
+
+static void armv7m_register_devices(void)
+{
+    sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState),
+                        bitband_init);
+}
+
+device_init(armv7m_register_devices)
diff --git a/hw/pl061.c b/hw/pl061.c
index 1263992..aa0a322 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -8,8 +8,7 @@
  * This code is licenced under the GPL.
  */
 
-#include "hw.h"
-#include "primecell.h"
+#include "sysbus.h"
 
 //#define DEBUG_PL061 1
 
@@ -28,6 +27,7 @@
   { 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
 
 typedef struct {
+    SysBusDevice busdev;
     int locked;
     uint8_t data;
     uint8_t old_data;
@@ -291,21 +291,25 @@
     return 0;
 }
 
-/* Returns an array of inputs.  */
-qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out)
+static void pl061_init(SysBusDevice *dev)
 {
     int iomemtype;
-    pl061_state *s;
+    pl061_state *s = FROM_SYSBUS(pl061_state, dev);
 
-    s = (pl061_state *)qemu_mallocz(sizeof(pl061_state));
     iomemtype = cpu_register_io_memory(0, pl061_readfn,
                                        pl061_writefn, s);
-    cpu_register_physical_memory(base, 0x00001000, iomemtype);
-    s->irq = irq;
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
+    sysbus_init_irq(dev, &s->irq);
+    qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8);
+    qdev_init_gpio_out(&dev->qdev, s->out, 8);
     pl061_reset(s);
-    if (out)
-        *out = s->out;
-
     register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
-    return qemu_allocate_irqs(pl061_set_irq, s, 8);
 }
+
+static void pl061_register_devices(void)
+{
+    sysbus_register_dev("pl061", sizeof(pl061_state),
+                        pl061_init);
+}
+
+device_init(pl061_register_devices)
diff --git a/hw/primecell.h b/hw/primecell.h
index 3e24eb1..490ef8c 100644
--- a/hw/primecell.h
+++ b/hw/primecell.h
@@ -5,10 +5,6 @@
 /* Also includes some devices that are currently only used by the
    ARM boards.  */
 
-/* pl061.c */
-void pl061_float_high(void *opaque, uint8_t mask);
-qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out);
-
 /* pl080.c */
 void *pl080_init(uint32_t base, qemu_irq irq, int nchannels);
 
diff --git a/hw/stellaris.c b/hw/stellaris.c
index d0918de..38b9830 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -10,7 +10,6 @@
 #include "sysbus.h"
 #include "ssi.h"
 #include "arm-misc.h"
-#include "primecell.h"
 #include "devices.h"
 #include "qemu-timer.h"
 #include "i2c.h"
@@ -45,6 +44,7 @@
 /* General purpose timer module.  */
 
 typedef struct gptm_state {
+    SysBusDevice busdev;
     uint32_t config;
     uint32_t mode[2];
     uint32_t control;
@@ -112,8 +112,7 @@
         s->state |= 1;
         if ((s->control & 0x20)) {
             /* Output trigger.  */
-	    qemu_irq_raise(s->trigger);
-	    qemu_irq_lower(s->trigger);
+	    qemu_irq_pulse(s->trigger);
         }
         if (s->mode[0] & 1) {
             /* One-shot.  */
@@ -340,19 +339,19 @@
     return 0;
 }
 
-static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger)
+static void stellaris_gptm_init(SysBusDevice *dev)
 {
     int iomemtype;
-    gptm_state *s;
+    gptm_state *s = FROM_SYSBUS(gptm_state, dev);
 
-    s = (gptm_state *)qemu_mallocz(sizeof(gptm_state));
-    s->irq = irq;
-    s->trigger = trigger;
-    s->opaque[0] = s->opaque[1] = s;
+    sysbus_init_irq(dev, &s->irq);
+    qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
 
     iomemtype = cpu_register_io_memory(0, gptm_readfn,
                                        gptm_writefn, s);
-    cpu_register_physical_memory(base, 0x00001000, iomemtype);
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
+
+    s->opaque[0] = s->opaque[1] = s;
     s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
     s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
     register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
@@ -906,6 +905,7 @@
 
 typedef struct
 {
+    SysBusDevice busdev;
     uint32_t actss;
     uint32_t ris;
     uint32_t im;
@@ -1178,26 +1178,23 @@
     return 0;
 }
 
-static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq *irq)
+static void stellaris_adc_init(SysBusDevice *dev)
 {
-    stellaris_adc_state *s;
+    stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
     int iomemtype;
-    qemu_irq *qi;
     int n;
 
-    s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
     for (n = 0; n < 4; n++) {
-        s->irq[n] = irq[n];
+        sysbus_init_irq(dev, &s->irq[n]);
     }
 
     iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
                                        stellaris_adc_writefn, s);
-    cpu_register_physical_memory(base, 0x00001000, iomemtype);
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
     stellaris_adc_reset(s);
-    qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1);
+    qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
     register_savevm("stellaris_adc", -1, 1,
                     stellaris_adc_save, stellaris_adc_load, s);
-    return qi[0];
 }
 
 /* Some boards have both an OLED controller and SD card connected to
@@ -1294,27 +1291,36 @@
     static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
 
     qemu_irq *pic;
-    qemu_irq *gpio_in[7];
-    qemu_irq *gpio_out[7];
+    DeviceState *gpio_dev[7];
+    qemu_irq gpio_in[7][8];
+    qemu_irq gpio_out[7][8];
     qemu_irq adc;
     int sram_size;
     int flash_size;
     i2c_bus *i2c;
+    DeviceState *dev;
     int i;
+    int j;
 
     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
     sram_size = (board->dc0 >> 18) + 1;
     pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
-        adc = stellaris_adc_init(0x40038000, pic + 14);
+        dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
+                                    pic[14], pic[15], pic[16], pic[17], NULL);
+        adc = qdev_get_gpio_in(dev, 0);
     } else {
         adc = NULL;
     }
     for (i = 0; i < 4; i++) {
         if (board->dc2 & (0x10000 << i)) {
-            stellaris_gptm_init(0x40030000 + i * 0x1000,
-                                pic[timer_irq[i]], adc);
+            dev = sysbus_create_simple("stellaris-gptm",
+                                       0x40030000 + i * 0x1000,
+                                       pic[timer_irq[i]]);
+            /* TODO: This is incorrect, but we get away with it because
+               the ADC output is only ever pulsed.  */
+            qdev_connect_gpio_out(dev, 0, adc);
         }
     }
 
@@ -1322,13 +1328,16 @@
 
     for (i = 0; i < 7; i++) {
         if (board->dc4 & (1 << i)) {
-            gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]],
-                                    &gpio_out[i]);
+            gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i],
+                                               pic[gpio_irq[i]]);
+            for (j = 0; j < 8; j++) {
+                gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
+                gpio_out[i][j] = NULL;
+            }
         }
     }
 
     if (board->dc2 & (1 << 12)) {
-        DeviceState *dev;
         dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
         i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
         if (board->peripherals & BP_OLED_I2C) {
@@ -1343,7 +1352,6 @@
         }
     }
     if (board->dc2 & (1 << 4)) {
-        DeviceState *dev;
         dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
         if (board->peripherals & BP_OLED_SSI) {
             DeviceState *mux;
@@ -1387,6 +1395,15 @@
 
         stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
     }
+    for (i = 0; i < 7; i++) {
+        if (board->dc4 & (1 << i)) {
+            for (j = 0; j < 8; j++) {
+                if (gpio_out[i][j]) {
+                    qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
+                }
+            }
+        }
+    }
 }
 
 /* FIXME: Figure out how to generate these from stellaris_boards.  */
@@ -1435,6 +1452,10 @@
 {
     sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
                         stellaris_i2c_init);
+    sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
+                        stellaris_gptm_init);
+    sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
+                        stellaris_adc_init);
     ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state),
                        &stellaris_ssi_bus_info);
 }