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(-)
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)
--
2.34.1
On 28/1/25 11:45, Peter Maydell wrote: > 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(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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~
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
© 2016 - 2025 Red Hat, Inc.