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