diff mbox series

[01/11] hw/sd/omap_mmc: Do a minimal conversion to QDev

Message ID 20250128104519.3981448-2-peter.maydell@linaro.org
State New
Headers show
Series hw/sd: QOMify omap-mmc, remove legacy APIs | expand

Commit Message

Peter Maydell Jan. 28, 2025, 10:45 a.m. UTC
Do a minimal conversion of the omap_mmc device model to QDev.

In this commit we do the bare minimum to produce a working device:
 * add the SysBusDevice parent_obj and the usual type boilerplate
 * omap_mmc_init() now returns a DeviceState*
 * reset is handled by sysbus reset, so the SoC reset function
   doesn't need to call omap_mmc_reset() any more
 * code that should obviously be in init/realize is moved there
   from omap_mmc_init()

We leave various pieces of cleanup to later commits:
 * rationalizing 'struct omap_mmc_s *' to 'OMAPMMCState *'
 * using gpio lines rather than having omap_mmc_init() directly
   set s->irq, s->dma
 * switching away from the legacy SD API and instead having
   the SD card plugged into a bus

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/omap.h | 15 ++++----
 hw/arm/omap1.c        |  1 -
 hw/sd/omap_mmc.c      | 83 +++++++++++++++++++++++++++++++++++--------
 3 files changed, 76 insertions(+), 23 deletions(-)

Comments

Richard Henderson Jan. 28, 2025, 6:50 p.m. UTC | #1
On 1/28/25 02:45, Peter Maydell wrote:
> +static const TypeInfo omap_mmc_info = {
> +    .name = TYPE_OMAP_MMC,
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(OMAPMMCState),
> +    .instance_init = omap_mmc_initfn,
> +    .class_init = omap_mmc_class_init,
> +};
> +
> +static void omap_mmc_register_types(void)
> +{
> +    type_register_static(&omap_mmc_info);
> +}
> +
> +type_init(omap_mmc_register_types)

Phil seems to be moving everything to DEFINE_TYPES now.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
Peter Maydell Jan. 28, 2025, 8:13 p.m. UTC | #2
On Tue, 28 Jan 2025 at 18:51, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 1/28/25 02:45, Peter Maydell wrote:
> > +static const TypeInfo omap_mmc_info = {
> > +    .name = TYPE_OMAP_MMC,
> > +    .parent = TYPE_SYS_BUS_DEVICE,
> > +    .instance_size = sizeof(OMAPMMCState),
> > +    .instance_init = omap_mmc_initfn,
> > +    .class_init = omap_mmc_class_init,
> > +};
> > +
> > +static void omap_mmc_register_types(void)
> > +{
> > +    type_register_static(&omap_mmc_info);
> > +}
> > +
> > +type_init(omap_mmc_register_types)
>
> Phil seems to be moving everything to DEFINE_TYPES now.

I looked at that, but it wants an array of TypeInfo,
and this is just one. So I did it this way instead.

-- PMM
diff mbox series

Patch

diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index 420ed1d5735..6339c5a581e 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -529,12 +529,13 @@  struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
                                         omap_clk clk);
 
 /* omap_mmc.c */
-struct omap_mmc_s;
-struct omap_mmc_s *omap_mmc_init(hwaddr base,
-                MemoryRegion *sysmem,
-                BlockBackend *blk,
-                qemu_irq irq, qemu_irq dma[], omap_clk clk);
-void omap_mmc_reset(struct omap_mmc_s *s);
+#define TYPE_OMAP_MMC "omap-mmc"
+OBJECT_DECLARE_SIMPLE_TYPE(omap_mmc_s, OMAP_MMC)
+
+DeviceState *omap_mmc_init(hwaddr base,
+                           MemoryRegion *sysmem,
+                           BlockBackend *blk,
+                           qemu_irq irq, qemu_irq dma[], omap_clk clk);
 
 /* omap_i2c.c */
 I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
@@ -601,7 +602,7 @@  struct omap_mpu_state_s {
     /* MPU public TIPB peripherals */
     struct omap_32khz_timer_s *os_timer;
 
-    struct omap_mmc_s *mmc;
+    DeviceState *mmc;
 
     struct omap_mpuio_s *mpuio;
 
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index f3a0ac40e48..ea07b9aa31e 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -3716,7 +3716,6 @@  static void omap1_mpu_reset(void *opaque)
     omap_uart_reset(mpu->uart[0]);
     omap_uart_reset(mpu->uart[1]);
     omap_uart_reset(mpu->uart[2]);
-    omap_mmc_reset(mpu->mmc);
     omap_mpuio_reset(mpu->mpuio);
     omap_uwire_reset(mpu->microwire);
     omap_pwl_reset(mpu->pwl);
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
index 1d4e30e6b7b..9cba437f74e 100644
--- a/hw/sd/omap_mmc.c
+++ b/hw/sd/omap_mmc.c
@@ -21,11 +21,15 @@ 
 
 #include "qemu/osdep.h"
 #include "qemu/log.h"
+#include "qapi/error.h"
 #include "hw/irq.h"
+#include "hw/sysbus.h"
 #include "hw/arm/omap.h"
 #include "hw/sd/sdcard_legacy.h"
 
-struct omap_mmc_s {
+typedef struct omap_mmc_s {
+    SysBusDevice parent_obj;
+
     qemu_irq irq;
     qemu_irq *dma;
     qemu_irq coverswitch;
@@ -66,7 +70,7 @@  struct omap_mmc_s {
     int cdet_enable;
     int cdet_state;
     qemu_irq cdet;
-};
+} OMAPMMCState;
 
 static void omap_mmc_interrupts_update(struct omap_mmc_s *s)
 {
@@ -297,7 +301,7 @@  static void omap_mmc_pseudo_reset(struct omap_mmc_s *host)
     host->fifo_len = 0;
 }
 
-void omap_mmc_reset(struct omap_mmc_s *host)
+static void omap_mmc_reset(struct omap_mmc_s *host)
 {
     host->last_cmd = 0;
     memset(host->rsp, 0, sizeof(host->rsp));
@@ -328,7 +332,9 @@  void omap_mmc_reset(struct omap_mmc_s *host)
      * into any bus, and we must reset it manually. When omap_mmc is
      * QOMified this must move into the QOM reset function.
      */
-    device_cold_reset(DEVICE(host->card));
+    if (host->card) {
+        device_cold_reset(DEVICE(host->card));
+    }
 }
 
 static uint64_t omap_mmc_read(void *opaque, hwaddr offset, unsigned size)
@@ -583,29 +589,76 @@  static const MemoryRegionOps omap_mmc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-struct omap_mmc_s *omap_mmc_init(hwaddr base,
-                MemoryRegion *sysmem,
-                BlockBackend *blk,
-                qemu_irq irq, qemu_irq dma[], omap_clk clk)
+DeviceState *omap_mmc_init(hwaddr base,
+                           MemoryRegion *sysmem,
+                           BlockBackend *blk,
+                           qemu_irq irq, qemu_irq dma[], omap_clk clk)
 {
-    struct omap_mmc_s *s = g_new0(struct omap_mmc_s, 1);
+    DeviceState *dev;
+    OMAPMMCState *s;
+
+    dev = qdev_new(TYPE_OMAP_MMC);
+    s = OMAP_MMC(dev);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
 
     s->irq = irq;
     s->dma = dma;
     s->clk = clk;
-    s->lines = 1;	/* TODO: needs to be settable per-board */
-    s->rev = 1;
 
-    memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);
-    memory_region_add_subregion(sysmem, base, &s->iomem);
+    memory_region_add_subregion(sysmem, base,
+                                sysbus_mmio_get_region(SYS_BUS_DEVICE(s), 0));
 
     /* Instantiate the storage */
     s->card = sd_init(blk, false);
     if (s->card == NULL) {
         exit(1);
     }
+    return dev;
+}
+
+static void omap_mmc_reset_hold(Object *obj, ResetType type)
+{
+    OMAPMMCState *s = OMAP_MMC(obj);
 
     omap_mmc_reset(s);
-
-    return s;
 }
+
+static void omap_mmc_initfn(Object *obj)
+{
+    OMAPMMCState *s = OMAP_MMC(obj);
+
+    /* In theory these could be settable per-board */
+    s->lines = 1;
+    s->rev = 1;
+
+    memory_region_init_io(&s->iomem, obj, &omap_mmc_ops, s, "omap.mmc", 0x800);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static void omap_mmc_realize(DeviceState *dev, Error **errp)
+{
+}
+
+static void omap_mmc_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    ResettableClass *rc = RESETTABLE_CLASS(oc);
+
+    rc->phases.hold = omap_mmc_reset_hold;
+    dc->realize = omap_mmc_realize;
+}
+
+static const TypeInfo omap_mmc_info = {
+    .name = TYPE_OMAP_MMC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OMAPMMCState),
+    .instance_init = omap_mmc_initfn,
+    .class_init = omap_mmc_class_init,
+};
+
+static void omap_mmc_register_types(void)
+{
+    type_register_static(&omap_mmc_info);
+}
+
+type_init(omap_mmc_register_types)