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>
This commit is contained in:
Bernhard Beschow
2026-07-02 20:40:35 +02:00
committed by Philippe Mathieu-Daudé
parent 2afca7a592
commit a12368aec4
3 changed files with 69 additions and 17 deletions

View File

@@ -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);

View File

@@ -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 flexcan3_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->desc = "i.MX FlexCAN 3 Controller";
}
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,
},
};
static void can_register_types(void)
{
type_register_static(&flexcan_info);
}
type_init(can_register_types)
DEFINE_TYPES(flexcan_types)

View File

@@ -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