Commit a12368aec4 for qemu.org

commit a12368aec4b49b73f090dfbc3eb3653f1b54afa8
Author: Bernhard Beschow <shentey@gmail.com>
Date:   Thu Jul 2 20:40:35 2026 +0200

    hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN

    Subclass TYPE_CAN_FLEXCAN, yielding TYPE_CAN_FLEXCAN2 and
    TYPE_CAN_FLEXCAN3.
    Since TYPE_CAN_FLEXCAN is now abstract, TYPE_FSL_IMX6 needs to use
    TYPE_CAN_FLEXCAN2. TYPE_CAN_FLEXCAN3 will be used in TYPE_FSL_IMX8MP.

    Signed-off-by: Bernhard Beschow <shentey@gmail.com>
    Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
    Acked-by: Pavel Pisa <pisa@fel.cvut.cz>
    Tested-by: Pavel Pisa <pisa@fel.cvut.cz>
    Message-ID: <20260702184038.178196-3-shentey@gmail.com>
    Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 585c935b89..eec9673c6f 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -92,7 +92,7 @@ static void fsl_imx6_init(Object *obj)
     }
     for (i = 0; i < FSL_IMX6_NUM_CANS; i++) {
         snprintf(name, NAME_SIZE, "flexcan%d", i + 1);
-        object_initialize_child(obj, name, &s->flexcan[i], TYPE_CAN_FLEXCAN);
+        object_initialize_child(obj, name, &s->flexcan[i], TYPE_CAN_FLEXCAN2);
     }
     for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) {
         snprintf(name, NAME_SIZE, "wdt%d", i);
diff --git a/hw/net/can/flexcan.c b/hw/net/can/flexcan.c
index 8f3f066ef5..da36d10bd3 100644
--- a/hw/net/can/flexcan.c
+++ b/hw/net/can/flexcan.c
@@ -1290,7 +1290,7 @@ static bool flexcan_mem_accepts(void *opaque, hwaddr addr,
     return true;
 }

-static const struct MemoryRegionOps flexcan_ops = {
+static const struct MemoryRegionOps flexcan2_ops = {
     .read = flexcan_mem_read,
     .write = flexcan_mem_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
@@ -1307,6 +1307,23 @@ static const struct MemoryRegionOps flexcan_ops = {
     },
 };

+static const struct MemoryRegionOps flexcan3_ops = {
+    .read = flexcan_mem_read,
+    .write = flexcan_mem_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+        .unaligned = true,
+        .accepts = flexcan_mem_accepts
+    },
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+        .unaligned = false
+    },
+};
+
 static CanBusClientInfo flexcan_bus_client_info = {
     .can_receive = flexcan_can_receive,
     .receive = flexcan_receive,
@@ -1322,16 +1339,26 @@ static int flexcan_connect_to_bus(FlexcanState *s, CanBusState *bus)
     return 0;
 }

-static void flexcan_init(Object *obj)
+static void flexcan2_init(Object *obj)
 {
     FlexcanState *s = CAN_FLEXCAN(obj);

     memory_region_init_io(
-        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN,
+        &s->iomem, obj, &flexcan2_ops, s, TYPE_CAN_FLEXCAN2,
         offsetof(FlexcanRegs, _reserved6)
     );
 }

+static void flexcan3_init(Object *obj)
+{
+    FlexcanState *s = CAN_FLEXCAN(obj);
+
+    memory_region_init_io(
+        &s->iomem, obj, &flexcan3_ops, s, TYPE_CAN_FLEXCAN3,
+        sizeof(FlexcanRegs)
+    );
+}
+
 static void flexcan_realize(DeviceState *dev, Error **errp)
 {
     FlexcanState *s = CAN_FLEXCAN(dev);
@@ -1384,19 +1411,42 @@ static void flexcan_class_init(ObjectClass *klass, const void *data)
     dc->realize = flexcan_realize;
     device_class_set_props(dc, flexcan_properties);
     dc->vmsd = &vmstate_can;
-    dc->desc = "i.MX FLEXCAN Controller";
 }

-static const TypeInfo flexcan_info = {
-    .name          = TYPE_CAN_FLEXCAN,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(FlexcanState),
-    .class_init    = flexcan_class_init,
-    .instance_init = flexcan_init,
-};
+static void flexcan2_class_init(ObjectClass *klass, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->desc = "i.MX FlexCAN 2 Controller";
+}

-static void can_register_types(void)
+static void flexcan3_class_init(ObjectClass *klass, const void *data)
 {
-    type_register_static(&flexcan_info);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->desc = "i.MX FlexCAN 3 Controller";
 }
-type_init(can_register_types)
+
+static const TypeInfo flexcan_types[] = {
+    {
+        .name          = TYPE_CAN_FLEXCAN,
+        .parent        = TYPE_SYS_BUS_DEVICE,
+        .instance_size = sizeof(FlexcanState),
+        .class_init    = flexcan_class_init,
+        .abstract      = true,
+    },
+    {
+        .name          = TYPE_CAN_FLEXCAN2,
+        .parent        = TYPE_CAN_FLEXCAN,
+        .class_init    = flexcan2_class_init,
+        .instance_init = flexcan2_init,
+    },
+    {
+        .name          = TYPE_CAN_FLEXCAN3,
+        .parent        = TYPE_CAN_FLEXCAN,
+        .class_init    = flexcan3_class_init,
+        .instance_init = flexcan3_init,
+    },
+};
+
+DEFINE_TYPES(flexcan_types)
diff --git a/include/hw/net/flexcan.h b/include/hw/net/flexcan.h
index 153afc1e03..32de7b904a 100644
--- a/include/hw/net/flexcan.h
+++ b/include/hw/net/flexcan.h
@@ -139,7 +139,9 @@ typedef struct FlexcanState {
 } FlexcanState;

 #define TYPE_CAN_FLEXCAN "flexcan"
-
 OBJECT_DECLARE_SIMPLE_TYPE(FlexcanState, CAN_FLEXCAN);

+#define TYPE_CAN_FLEXCAN2 "flexcan2"
+#define TYPE_CAN_FLEXCAN3 "flexcan3"
+
 #endif