]> Git Repo - qemu.git/blobdiff - hw/char/etraxfs_ser.c
qdev: set properties with device_class_set_props()
[qemu.git] / hw / char / etraxfs_ser.c
index 11820f5864b24c387e43cff18ac1f481be6dd312..947bdb649a5257fcfb6a03f49699f30fd583b1e5 100644 (file)
  * THE SOFTWARE.
  */
 
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
 #include "hw/sysbus.h"
-#include "sysemu/char.h"
+#include "chardev/char-fe.h"
 #include "qemu/log.h"
+#include "qemu/module.h"
 
 #define D(x)
 
 #define STAT_TR_IDLE 22
 #define STAT_TR_RDY  24
 
-struct etrax_serial
-{
-    SysBusDevice busdev;
+#define TYPE_ETRAX_FS_SERIAL "etraxfs,serial"
+#define ETRAX_SERIAL(obj) \
+    OBJECT_CHECK(ETRAXSerial, (obj), TYPE_ETRAX_FS_SERIAL)
+
+typedef struct ETRAXSerial {
+    SysBusDevice parent_obj;
+
     MemoryRegion mmio;
-    CharDriverState *chr;
+    CharBackend chr;
     qemu_irq irq;
 
     int pending_tx;
@@ -59,9 +67,9 @@ struct etrax_serial
 
     /* Control registers.  */
     uint32_t regs[R_MAX];
-};
+} ETRAXSerial;
 
-static void ser_update_irq(struct etrax_serial *s)
+static void ser_update_irq(ETRAXSerial *s)
 {
 
     if (s->rx_fifo_len) {
@@ -77,7 +85,7 @@ static void ser_update_irq(struct etrax_serial *s)
 static uint64_t
 ser_read(void *opaque, hwaddr addr, unsigned int size)
 {
-    struct etrax_serial *s = opaque;
+    ETRAXSerial *s = opaque;
     uint32_t r = 0;
 
     addr >>= 2;
@@ -112,7 +120,7 @@ static void
 ser_write(void *opaque, hwaddr addr,
           uint64_t val64, unsigned int size)
 {
-    struct etrax_serial *s = opaque;
+    ETRAXSerial *s = opaque;
     uint32_t value = val64;
     unsigned char ch = val64;
 
@@ -121,7 +129,9 @@ ser_write(void *opaque, hwaddr addr,
     switch (addr)
     {
         case RW_DOUT:
-            qemu_chr_fe_write(s->chr, &ch, 1);
+            /* XXX this blocks entire thread. Rewrite to use
+             * qemu_chr_fe_write and background I/O callbacks */
+            qemu_chr_fe_write_all(&s->chr, &ch, 1);
             s->regs[R_INTR] |= 3;
             s->pending_tx = 1;
             s->regs[addr] = value;
@@ -154,14 +164,19 @@ static const MemoryRegionOps ser_ops = {
     }
 };
 
+static Property etraxfs_ser_properties[] = {
+    DEFINE_PROP_CHR("chardev", ETRAXSerial, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void serial_receive(void *opaque, const uint8_t *buf, int size)
 {
-    struct etrax_serial *s = opaque;
+    ETRAXSerial *s = opaque;
     int i;
 
     /* Got a byte.  */
     if (s->rx_fifo_len >= 16) {
-        qemu_log("WARNING: UART dropped char.\n");
+        D(qemu_log("WARNING: UART dropped char.\n"));
         return;
     }
 
@@ -177,26 +192,24 @@ static void serial_receive(void *opaque, const uint8_t *buf, int size)
 
 static int serial_can_receive(void *opaque)
 {
-    struct etrax_serial *s = opaque;
-    int r;
+    ETRAXSerial *s = opaque;
 
     /* Is the receiver enabled?  */
     if (!(s->regs[RW_REC_CTRL] & (1 << 3))) {
         return 0;
     }
 
-    r = sizeof(s->rx_fifo) - s->rx_fifo_len;
-    return r;
+    return sizeof(s->rx_fifo) - s->rx_fifo_len;
 }
 
-static void serial_event(void *opaque, int event)
+static void serial_event(void *opaque, QEMUChrEvent event)
 {
 
 }
 
 static void etraxfs_ser_reset(DeviceState *d)
 {
-    struct etrax_serial *s = container_of(d, typeof(*s), busdev.qdev);
+    ETRAXSerial *s = ETRAX_SERIAL(d);
 
     /* transmitter begins ready and idle.  */
     s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY);
@@ -206,35 +219,40 @@ static void etraxfs_ser_reset(DeviceState *d)
 
 }
 
-static int etraxfs_ser_init(SysBusDevice *dev)
+static void etraxfs_ser_init(Object *obj)
 {
-    struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
+    ETRAXSerial *s = ETRAX_SERIAL(obj);
+    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
 
     sysbus_init_irq(dev, &s->irq);
-    memory_region_init_io(&s->mmio, &ser_ops, s, "etraxfs-serial", R_MAX * 4);
+    memory_region_init_io(&s->mmio, obj, &ser_ops, s,
+                          "etraxfs-serial", R_MAX * 4);
     sysbus_init_mmio(dev, &s->mmio);
+}
+
+static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
+{
+    ETRAXSerial *s = ETRAX_SERIAL(dev);
 
-    s->chr = qemu_char_get_next_serial();
-    if (s->chr)
-        qemu_chr_add_handlers(s->chr,
-                      serial_can_receive, serial_receive,
-                      serial_event, s);
-    return 0;
+    qemu_chr_fe_set_handlers(&s->chr,
+                             serial_can_receive, serial_receive,
+                             serial_event, NULL, s, NULL, true);
 }
 
 static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = etraxfs_ser_init;
     dc->reset = etraxfs_ser_reset;
+    device_class_set_props(dc, etraxfs_ser_properties);
+    dc->realize = etraxfs_ser_realize;
 }
 
 static const TypeInfo etraxfs_ser_info = {
-    .name          = "etraxfs,serial",
+    .name          = TYPE_ETRAX_FS_SERIAL,
     .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(struct etrax_serial),
+    .instance_size = sizeof(ETRAXSerial),
+    .instance_init = etraxfs_ser_init,
     .class_init    = etraxfs_ser_class_init,
 };
 
This page took 0.028336 seconds and 4 git commands to generate.