diff --git a/gdbstub.c b/gdbstub.c
index ecea8c4..2fe71ca 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1745,7 +1745,7 @@ int gdbserver_start(const char *device)
             sigaction(SIGINT, &act, NULL);
         }
 #endif
-        chr = qemu_chr_new_noreplay("gdb", device, NULL);
+        chr = qemu_chr_new_noreplay("gdb", device);
         if (!chr)
             return -1;
 
diff --git a/hmp.c b/hmp.c
index 80f7f1f..3d60259 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2002,7 +2002,7 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict)
     if (opts == NULL) {
         error_setg(&err, "Parsing chardev args failed");
     } else {
-        qemu_chr_new_from_opts(opts, NULL, &err);
+        qemu_chr_new_from_opts(opts, &err);
         qemu_opts_del(opts);
     }
     hmp_handle_error(mon, &err);
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index b4e358d..7bb7be7 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -125,7 +125,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
             if (!chr) {
                 char label[20];
                 snprintf(label, sizeof(label), "imx31.uart%d", i);
-                chr = qemu_chr_new(label, "null", NULL);
+                chr = qemu_chr_new(label, "null");
             }
 
             qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index fe204ac..f23672b 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -114,7 +114,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
             if (!chr) {
                 char label[20];
                 snprintf(label, sizeof(label), "imx31.uart%d", i);
-                chr = qemu_chr_new(label, "null", NULL);
+                chr = qemu_chr_new(label, "null");
             }
 
             qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 6a1bf26..e93532f 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -193,7 +193,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
 
             if (!chr) {
                 char *label = g_strdup_printf("imx6.uart%d", i + 1);
-                chr = qemu_chr_new(label, "null", NULL);
+                chr = qemu_chr_new(label, "null");
                 g_free(label);
                 serial_hds[i] = chr;
             }
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 7e11c65..0b2a355 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -798,7 +798,7 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
     s->irq = irq;
     omap_sti_reset(s);
 
-    s->chr = chr ?: qemu_chr_new("null", "null", NULL);
+    s->chr = chr ?: qemu_chr_new("null", "null");
 
     memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti",
                           omap_l4_region_size(ta, 0));
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 1107578..66e6304 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -606,7 +606,7 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
         chr = serial_hds[channel];
         if (!chr) {
             snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, channel);
-            chr = qemu_chr_new(label, "null", NULL);
+            chr = qemu_chr_new(label, "null");
             if (!(chr)) {
                 error_report("Can't assign serial port to UART%d", channel);
                 exit(1);
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
index 415bec5..893ab10 100644
--- a/hw/char/omap_uart.c
+++ b/hw/char/omap_uart.c
@@ -63,7 +63,7 @@ struct omap_uart_s *omap_uart_init(hwaddr base,
     s->irq = irq;
     s->serial = serial_mm_init(get_system_memory(), base, 2, irq,
                                omap_clk_getrate(fclk)/16,
-                               chr ?: qemu_chr_new(label, "null", NULL),
+                               chr ?: qemu_chr_new(label, "null"),
                                DEVICE_NATIVE_ENDIAN);
     return s;
 }
@@ -183,6 +183,6 @@ void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
     /* TODO: Should reuse or destroy current s->serial */
     s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
                                omap_clk_getrate(s->fclk) / 16,
-                               chr ?: qemu_chr_new("null", "null", NULL),
+                               chr ?: qemu_chr_new("null", "null"),
                                DEVICE_NATIVE_ENDIAN);
 }
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 83108b0..11bf6a4 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -199,7 +199,7 @@ static int con_init(struct XenDevice *xendev)
         con->chr = serial_hds[con->xendev.dev];
     } else {
         snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
-        con->chr = qemu_chr_new(label, output, NULL);
+        con->chr = qemu_chr_new(label, output);
     }
 
     xenstore_store_pv_console_info(con->xendev.dev, con->chr);
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index c3ebf3e..b1c1a0a 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -283,7 +283,7 @@ static void pc87312_realize(DeviceState *dev, Error **errp)
         /* FIXME use a qdev chardev prop instead of parallel_hds[] */
         chr = parallel_hds[0];
         if (chr == NULL) {
-            chr = qemu_chr_new("par0", "null", NULL);
+            chr = qemu_chr_new("par0", "null");
         }
         isa = isa_create(bus, "isa-parallel");
         d = DEVICE(isa);
@@ -303,7 +303,7 @@ static void pc87312_realize(DeviceState *dev, Error **errp)
             chr = serial_hds[i];
             if (chr == NULL) {
                 snprintf(name, sizeof(name), "ser%d", i);
-                chr = qemu_chr_new(name, "null", NULL);
+                chr = qemu_chr_new(name, "null");
             }
             isa = isa_create(bus, "isa-serial");
             d = DEVICE(isa);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 3aec6d8..ed0850c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -566,7 +566,7 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
     memory_region_add_subregion(address_space, base, &s->iomem_lo);
     memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
 
-    s->display = qemu_chr_new("fpga", "vc:320x200", NULL);
+    s->display = qemu_chr_new("fpga", "vc:320x200");
     qemu_chr_add_handlers(s->display, NULL, NULL,
                           malta_fgpa_display_event, s);
 
@@ -1033,7 +1033,7 @@ void mips_malta_init(MachineState *machine)
         if (!serial_hds[i]) {
             char label[32];
             snprintf(label, sizeof(label), "serial%d", i);
-            serial_hds[i] = qemu_chr_new(label, "null", NULL);
+            serial_hds[i] = qemu_chr_new(label, "null");
         }
     }
 
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 966ad84..61452b5 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -547,7 +547,7 @@ static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
     filename++;
 
     snprintf(label, sizeof(label), "usbserial%d", index++);
-    cdrv = qemu_chr_new(label, filename, NULL);
+    cdrv = qemu_chr_new(label, filename);
     if (!cdrv)
         return NULL;
 
@@ -565,7 +565,7 @@ static USBDevice *usb_braille_init(USBBus *bus, const char *unused)
     USBDevice *dev;
     CharDriverState *cdrv;
 
-    cdrv = qemu_chr_new("braille", "braille", NULL);
+    cdrv = qemu_chr_new("braille", "braille");
     if (!cdrv)
         return NULL;
 
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index ac75949..dc6fdcc 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -265,7 +265,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
     }
 
     if (!serial_hds[0]) {
-        serial_hds[0] = qemu_chr_new("serial0", "null", NULL);
+        serial_hds[0] = qemu_chr_new("serial0", "null");
     }
 
     serial_mm_init(system_io, 0x0d050020, 2, xtensa_get_extint(env, 0),
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index d0ffdbd..eba77e0 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -75,7 +75,6 @@ typedef enum {
 
 struct CharDriverState {
     QemuMutex chr_write_lock;
-    void (*init)(struct CharDriverState *s);
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
     int (*chr_sync_read)(struct CharDriverState *s,
                          const uint8_t *buf, int len);
@@ -130,13 +129,11 @@ CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp);
  * Create a new character backend from a QemuOpts list.
  *
  * @opts see qemu-config.c for a list of valid options
- * @init not sure..
  *
  * Returns: a new character backend
  */
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
-                                    void (*init)(struct CharDriverState *s),
-                                    Error **errp);
+                                        Error **errp);
 
 /**
  * @qemu_chr_parse_common:
@@ -155,12 +152,10 @@ void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend);
  *
  * @label the name of the backend
  * @filename the URI
- * @init not sure..
  *
  * Returns: a new character backend
  */
-CharDriverState *qemu_chr_new(const char *label, const char *filename,
-                              void (*init)(struct CharDriverState *s));
+CharDriverState *qemu_chr_new(const char *label, const char *filename);
 /**
  * @qemu_chr_disconnect:
  *
@@ -191,12 +186,10 @@ int qemu_chr_wait_connected(CharDriverState *chr, Error **errp);
  *
  * @label the name of the backend
  * @filename the URI
- * @init not sure..
  *
  * Returns: a new character backend
  */
-CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
-                                       void (*init)(struct CharDriverState *s));
+CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename);
 
 /**
  * @qemu_chr_delete:
diff --git a/net/slirp.c b/net/slirp.c
index b60893f..f9fdff5 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -747,7 +747,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
         }
     } else {
         fwd = g_new(struct GuestFwd, 1);
-        fwd->hd = qemu_chr_new(buf, p, NULL);
+        fwd->hd = qemu_chr_new(buf, p);
         if (!fwd->hd) {
             error_report("could not open guest forwarding device '%s'", buf);
             g_free(fwd);
diff --git a/qemu-char.c b/qemu-char.c
index 650943d..22504cc 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3909,8 +3909,7 @@ void register_char_driver(const char *name, ChardevBackendKind kind,
 }
 
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
-                                    void (*init)(struct CharDriverState *s),
-                                    Error **errp)
+                                        Error **errp)
 {
     Error *local_err = NULL;
     CharDriver *cd;
@@ -4007,8 +4006,7 @@ err:
     return NULL;
 }
 
-CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
-                                       void (*init)(struct CharDriverState *s))
+CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename)
 {
     const char *p;
     CharDriverState *chr;
@@ -4023,7 +4021,7 @@ CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
     if (!opts)
         return NULL;
 
-    chr = qemu_chr_new_from_opts(opts, init, &err);
+    chr = qemu_chr_new_from_opts(opts, &err);
     if (err) {
         error_report_err(err);
     }
@@ -4035,10 +4033,10 @@ CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
     return chr;
 }
 
-CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
+CharDriverState *qemu_chr_new(const char *label, const char *filename)
 {
     CharDriverState *chr;
-    chr = qemu_chr_new_noreplay(label, filename, init);
+    chr = qemu_chr_new_noreplay(label, filename);
     if (chr) {
         chr->replay = replay_mode != REPLAY_MODE_NONE;
         if (chr->replay && chr->chr_ioctl) {
diff --git a/qtest.c b/qtest.c
index b53b39c..2d9a021 100644
--- a/qtest.c
+++ b/qtest.c
@@ -670,7 +670,7 @@ void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
 {
     CharDriverState *chr;
 
-    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
+    chr = qemu_chr_new("qtest", qtest_chrdev);
 
     if (chr == NULL) {
         error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index d7c48c5..edf30ac 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -455,7 +455,7 @@ static void test_server_create_chr(TestServer *server, const gchar *opt)
     gchar *chr_path;
 
     chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
-    server->chr = qemu_chr_new(server->chr_name, chr_path, NULL);
+    server->chr = qemu_chr_new(server->chr_name, chr_path);
     g_free(chr_path);
 
     qemu_chr_add_handlers(server->chr, chr_can_read, chr_read,
diff --git a/ui/console.c b/ui/console.c
index fa3e658..19adac7 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -2033,8 +2033,6 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
     }
 
     qemu_chr_be_generic_open(chr);
-    if (chr->init)
-        chr->init(chr);
 }
 
 static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
diff --git a/ui/gtk.c b/ui/gtk.c
index 58d20ee..83984f6 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1789,9 +1789,6 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
                              gtk_label_new(vc->label));
 
     qemu_chr_be_generic_open(vc->vte.chr);
-    if (vc->vte.chr->init) {
-        vc->vte.chr->init(vc->vte.chr);
-    }
 
     return group;
 }
diff --git a/vl.c b/vl.c
index 2e152ac..e4c534c 100644
--- a/vl.c
+++ b/vl.c
@@ -2369,7 +2369,7 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
 {
     Error *local_err = NULL;
 
-    qemu_chr_new_from_opts(opts, NULL, &local_err);
+    qemu_chr_new_from_opts(opts, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return -1;
@@ -2514,7 +2514,7 @@ static int serial_parse(const char *devname)
         exit(1);
     }
     snprintf(label, sizeof(label), "serial%d", index);
-    serial_hds[index] = qemu_chr_new(label, devname, NULL);
+    serial_hds[index] = qemu_chr_new(label, devname);
     if (!serial_hds[index]) {
         error_report("could not connect serial device"
                      " to character backend '%s'", devname);
@@ -2536,7 +2536,7 @@ static int parallel_parse(const char *devname)
         exit(1);
     }
     snprintf(label, sizeof(label), "parallel%d", index);
-    parallel_hds[index] = qemu_chr_new(label, devname, NULL);
+    parallel_hds[index] = qemu_chr_new(label, devname);
     if (!parallel_hds[index]) {
         error_report("could not connect parallel device"
                      " to character backend '%s'", devname);
@@ -2567,7 +2567,7 @@ static int virtcon_parse(const char *devname)
     qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort);
 
     snprintf(label, sizeof(label), "virtcon%d", index);
-    virtcon_hds[index] = qemu_chr_new(label, devname, NULL);
+    virtcon_hds[index] = qemu_chr_new(label, devname);
     if (!virtcon_hds[index]) {
         error_report("could not connect virtio console"
                      " to character backend '%s'", devname);
@@ -2600,7 +2600,7 @@ static int sclp_parse(const char *devname)
     qemu_opt_set(dev_opts, "driver", "sclpconsole", &error_abort);
 
     snprintf(label, sizeof(label), "sclpcon%d", index);
-    sclp_hds[index] = qemu_chr_new(label, devname, NULL);
+    sclp_hds[index] = qemu_chr_new(label, devname);
     if (!sclp_hds[index]) {
         error_report("could not connect sclp console"
                      " to character backend '%s'", devname);
@@ -2616,7 +2616,7 @@ static int debugcon_parse(const char *devname)
 {
     QemuOpts *opts;
 
-    if (!qemu_chr_new("debugcon", devname, NULL)) {
+    if (!qemu_chr_new("debugcon", devname)) {
         exit(1);
     }
     opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
