:p
atchew
Login
This series corrects the DesignWare I3C controller's advertised CMD/data FIFO depths and cleans up the misleading field names that made the bug easy to overlook. The Linux DW-I3C master driver reads QUEUE_STATUS_LEVEL and DATA_BUFFER_STATUS_LEVEL at probe to learn the controller's queue depths, then rejects any transfer larger than what was advertised with -EOPNOTSUPP. QEMU was resetting these registers to 0x02 / 0x10 instead of the real 0x10 / 0x40, so the guest believed the controller could only do 64-byte transfers and failed any I3C transfer with a payload larger than 64 B. The backing FIFOs were already allocated at the correct size; only the advertised reset values were wrong. Patch 1 fixes the reset values. Patch 2 is a no-functional-change cleanup renaming the queue-capacity struct fields and device properties from _bytes to _words, since the values are word counts passed to fifo32_create() -- the old names were what made the depth bug slow to spot. Jithu Joseph (2): hw/i3c: fix CMD/data FIFO depth reset values to match real silicon hw/i3c: rename DW-I3C queue capacity fields from _bytes to _words include/hw/i3c/dw-i3c.h | 6 +++--- hw/i3c/dw-i3c.c | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) base-commit: 2db91528542672cf0db78b3f2cc0e22b36302b38 -- 2.43.0
The Linux DW-I3C master driver infers controller queue depths at probe by reading two status registers that report free queue slots, which at probe (queues empty) equals the full depth. It then uses those values to gate every I3C transfer -- any batch whose word count exceeds the advertised depth is rejected with -EOPNOTSUPP. QUEUE_STATUS_LEVEL (0x4c) [7:0] -> cmdfifodepth (cmd slots) DATA_BUFFER_STATUS_LEVEL (0x50) [7:0] -> datafifodepth (32-bit words) Per the AST2600 datasheet the reset values are 0x10 and 0x40 (16 cmd slots, 64 words = 256 B). QEMU was advertising 0x02 and 0x10, making the kernel believe the controller can only do 64-byte transfers. The visible symptom was -EOPNOTSUPP on any I3C transfer whose payload exceeded 64 B (datafifodepth = 0x10 = 16 words = 64 B). The underlying FIFOs in QEMU were already allocated at the right size (fifo32_create takes word counts; the existing defaults give 16 cmd slots and 64 data words). Only the advertised reset values were wrong. With this fix the guest sees datafifodepth=64 words and accepts transfers up to 256 B. Fixes: e974c6957576 ("hw/i3c/dw-i3c: Add more reset values") Signed-off-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com> --- hw/i3c/dw-i3c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i3c/dw-i3c.c +++ b/hw/i3c/dw-i3c.c @@ -XXX,XX +XXX,XX @@ static const uint32_t dw_i3c_resets[DW_I3C_NR_REGS] = { [R_QUEUE_THLD_CTRL] = 0x01000101, [R_DATA_BUFFER_THLD_CTRL] = 0x01010100, [R_SLV_EVENT_CTRL] = 0x0000000b, - [R_QUEUE_STATUS_LEVEL] = 0x00000002, - [R_DATA_BUFFER_STATUS_LEVEL] = 0x00000010, + [R_QUEUE_STATUS_LEVEL] = 0x00000010, + [R_DATA_BUFFER_STATUS_LEVEL] = 0x00000040, [R_PRESENT_STATE] = 0x00000003, [R_I3C_VER_ID] = 0x3130302a, [R_I3C_VER_TYPE] = 0x6c633033, -- 2.43.0
The cmd/resp, tx/rx, and IBI queue capacity values are passed straight to fifo32_create(), which interprets its capacity argument as a 32-bit word count. The fields and device properties were therefore misnamed. Rename the three struct fields and matching device-property strings: cmd_resp_queue_capacity_bytes -> cmd_resp_queue_capacity_words tx_rx_queue_capacity_bytes -> tx_rx_queue_capacity_words ibi_queue_capacity_bytes -> ibi_queue_capacity_words Defaults are unchanged (0x10 / 0x40 / 0x10) -- they were being interpreted correctly by fifo32_create all along, just under a misleading label. No behavioral change. aspeed_i3c.c only sets "device-id" on its child DWI3C objects and nothing else references these properties in the tree, so no external callers need updating. vmstate_dw_i3c migrates only the regs[] array, not cfg.*, so there are no migration-compat concerns either. Signed-off-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com> --- include/hw/i3c/dw-i3c.h | 6 +++--- hw/i3c/dw-i3c.c | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/hw/i3c/dw-i3c.h b/include/hw/i3c/dw-i3c.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/i3c/dw-i3c.h +++ b/include/hw/i3c/dw-i3c.h @@ -XXX,XX +XXX,XX @@ struct DWI3C { struct { uint8_t id; - uint8_t cmd_resp_queue_capacity_bytes; - uint16_t tx_rx_queue_capacity_bytes; - uint8_t ibi_queue_capacity_bytes; + uint8_t cmd_resp_queue_capacity_words; + uint16_t tx_rx_queue_capacity_words; + uint8_t ibi_queue_capacity_words; uint8_t num_addressable_devices; uint16_t dev_addr_table_pointer; uint16_t dev_addr_table_depth; diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i3c/dw-i3c.c +++ b/hw/i3c/dw-i3c.c @@ -XXX,XX +XXX,XX @@ static void dw_i3c_realize(DeviceState *dev, Error **errp) DW_I3C_NR_REGS << 2); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr); - fifo32_create(&s->cmd_queue, s->cfg.cmd_resp_queue_capacity_bytes); - fifo32_create(&s->resp_queue, s->cfg.cmd_resp_queue_capacity_bytes); - fifo32_create(&s->tx_queue, s->cfg.tx_rx_queue_capacity_bytes); - fifo32_create(&s->rx_queue, s->cfg.tx_rx_queue_capacity_bytes); - fifo32_create(&s->ibi_queue, s->cfg.ibi_queue_capacity_bytes); + fifo32_create(&s->cmd_queue, s->cfg.cmd_resp_queue_capacity_words); + fifo32_create(&s->resp_queue, s->cfg.cmd_resp_queue_capacity_words); + fifo32_create(&s->tx_queue, s->cfg.tx_rx_queue_capacity_words); + fifo32_create(&s->rx_queue, s->cfg.tx_rx_queue_capacity_words); + fifo32_create(&s->ibi_queue, s->cfg.ibi_queue_capacity_words); /* Arbitrarily large enough to not be an issue. */ fifo8_create(&s->ibi_data.ibi_intermediate_queue, - s->cfg.ibi_queue_capacity_bytes * 8); + s->cfg.ibi_queue_capacity_words * 8); s->bus = i3c_init_bus(DEVICE(s), name); I3CBusClass *bc = I3C_BUS_GET_CLASS(s->bus); @@ -XXX,XX +XXX,XX @@ static void dw_i3c_realize(DeviceState *dev, Error **errp) static const Property dw_i3c_properties[] = { DEFINE_PROP_UINT8("device-id", DWI3C, cfg.id, 0), - DEFINE_PROP_UINT8("command-response-queue-capacity-bytes", DWI3C, - cfg.cmd_resp_queue_capacity_bytes, 0x10), - DEFINE_PROP_UINT16("tx-rx-queue-capacity-bytes", DWI3C, - cfg.tx_rx_queue_capacity_bytes, 0x40), - DEFINE_PROP_UINT8("ibi-queue-capacity-bytes", DWI3C, - cfg.ibi_queue_capacity_bytes, 0x10), + DEFINE_PROP_UINT8("command-response-queue-capacity-words", DWI3C, + cfg.cmd_resp_queue_capacity_words, 0x10), + DEFINE_PROP_UINT16("tx-rx-queue-capacity-words", DWI3C, + cfg.tx_rx_queue_capacity_words, 0x40), + DEFINE_PROP_UINT8("ibi-queue-capacity-words", DWI3C, + cfg.ibi_queue_capacity_words, 0x10), DEFINE_PROP_UINT8("num-addressable-devices", DWI3C, cfg.num_addressable_devices, 8), DEFINE_PROP_UINT16("dev-addr-table-pointer", DWI3C, -- 2.43.0
This series corrects the DesignWare I3C controller's advertised CMD/data FIFO depths and cleans up the misleading queue-capacity field names that made the bug easy to overlook. The Linux DW-I3C master driver reads QUEUE_STATUS_LEVEL and DATA_BUFFER_STATUS_LEVEL at probe to learn the controller's queue depths, then rejects any transfer larger than what was advertised with -EOPNOTSUPP. QEMU was resetting these registers to 0x02 / 0x10 instead of the real 0x10 / 0x40, so the guest believed the controller could only do 64-byte transfers and failed any I3C transfer with a payload larger than 64 B. The backing FIFOs were already allocated at the correct size; only the advertised reset values were wrong. Patch 1 fixes the reset values, and additionally drives the advertised depths from the queue-capacity configs in the reset handlers (per Philippe's review) so a configured override is no longer silently ignored. Patch 2 is a no-functional-change cleanup renaming the queue-capacity struct fields and device properties from _bytes to _words, since the values are word counts passed to fifo32_create() -- the old names were what made the depth bug slow to spot. Patch 3 keeps the old _bytes property names working as aliases, since they are user-visible and shipped in v11.0.0. Patch 1 is the actual bug fix and is tagged Cc: qemu-stable; it is kept self-contained (using the _bytes field names that exist in released branches) so it cherry-picks cleanly. Patches 2 and 3 are master-only cleanup. Note on the IBI queue capacity: unlike the cmd/resp and tx/rx capacities, it is not advertised to the guest through any status register (the hardware exposes only IBI occupancy via IBI_BUF_BLR / IBI_STATUS_CNT, not a depth), so it sizes only the internal fifo32 backing store and has no entry in dw_i3c_resets[]. Changes since v1: - Patch 1: drive QUEUE_STATUS_LEVEL / DATA_BUFFER_STATUS_LEVEL from the queue-capacity configs in the reset handlers, in addition to correcting the reset-array values (Philippe Mathieu-Daude). - New patch 3: keep the renamed _bytes properties working as aliases so existing command lines do not break (Philippe Mathieu-Daude). - v1: https://lore.kernel.org/qemu-devel/20260529014034.864722-1-jithu.joseph@oss.qualcomm.com/ Jithu Joseph (3): hw/i3c: fix CMD/data FIFO depth reset values to match real silicon hw/i3c: rename DW-I3C queue capacity fields from _bytes to _words hw/i3c: keep _bytes aliases for renamed queue-capacity properties include/hw/i3c/dw-i3c.h | 6 ++--- hw/i3c/dw-i3c.c | 58 +++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 17 deletions(-) base-commit: 2db91528542672cf0db78b3f2cc0e22b36302b38 -- 2.43.0
The Linux DW-I3C master driver infers controller queue depths at probe by reading two status registers that report free queue slots, which at probe (queues empty) equals the full depth. It then uses those values to gate every I3C transfer -- any batch whose word count exceeds the advertised depth is rejected with -EOPNOTSUPP. QUEUE_STATUS_LEVEL (0x4c) [7:0] -> cmdfifodepth (cmd slots) DATA_BUFFER_STATUS_LEVEL (0x50) [7:0] -> datafifodepth (32-bit words) Per the AST2600 datasheet the reset values are 0x10 and 0x40 (16 cmd slots, 64 words = 256 B). QEMU was advertising 0x02 and 0x10, making the kernel believe the controller can only do 64-byte transfers. The visible symptom was -EOPNOTSUPP on any I3C transfer whose payload exceeded 64 B (datafifodepth = 0x10 = 16 words = 64 B). The underlying FIFOs in QEMU were already allocated at the right size (fifo32_create takes word counts; the existing defaults give 16 cmd slots and 64 data words). Only the advertised reset values were wrong. Correct the reset values in dw_i3c_resets[], and additionally drive the advertised depths from the queue-capacity configs in the reset handlers (as is already done for the device/char table pointers), so a configured override is reflected in what the guest reads instead of being silently ignored. The advertised fields are 8-bit, so the depth saturates at 255 regardless of the wider capacity configs. With this fix the guest sees datafifodepth=64 words and accepts transfers up to 256 B. Fixes: e974c6957576 ("hw/i3c/dw-i3c: Add more reset values") Cc: qemu-stable@nongnu.org Signed-off-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com> --- hw/i3c/dw-i3c.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i3c/dw-i3c.c +++ b/hw/i3c/dw-i3c.c @@ -XXX,XX +XXX,XX @@ static const uint32_t dw_i3c_resets[DW_I3C_NR_REGS] = { [R_QUEUE_THLD_CTRL] = 0x01000101, [R_DATA_BUFFER_THLD_CTRL] = 0x01010100, [R_SLV_EVENT_CTRL] = 0x0000000b, - [R_QUEUE_STATUS_LEVEL] = 0x00000002, - [R_DATA_BUFFER_STATUS_LEVEL] = 0x00000010, + [R_QUEUE_STATUS_LEVEL] = 0x00000010, + [R_DATA_BUFFER_STATUS_LEVEL] = 0x00000040, [R_PRESENT_STATE] = 0x00000003, [R_I3C_VER_ID] = 0x3130302a, [R_I3C_VER_TYPE] = 0x6c633033, @@ -XXX,XX +XXX,XX @@ static void dw_i3c_reset(DeviceState *dev) s->cfg.dev_char_table_pointer); ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER, DEV_CHAR_TABLE_DEPTH, s->cfg.dev_char_table_depth); + ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC, + s->cfg.cmd_resp_queue_capacity_bytes); + ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC, + s->cfg.tx_rx_queue_capacity_bytes); dw_i3c_cmd_queue_reset(s); dw_i3c_resp_queue_reset(s); @@ -XXX,XX +XXX,XX @@ static void dw_i3c_reset_enter(Object *obj, ResetType type) s->cfg.dev_char_table_pointer); ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER, DEV_CHAR_TABLE_DEPTH, s->cfg.dev_char_table_depth); + ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC, + s->cfg.cmd_resp_queue_capacity_bytes); + ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC, + s->cfg.tx_rx_queue_capacity_bytes); } static void dw_i3c_realize(DeviceState *dev, Error **errp) -- 2.43.0
The cmd/resp, tx/rx, and IBI queue capacity values are passed straight to fifo32_create(), which interprets its capacity argument as a 32-bit word count. The fields and device properties were therefore misnamed: setting e.g. tx-rx-queue-capacity-bytes=N sized the backing FIFO to N words, not N bytes. Rename the three struct fields and matching device-property strings: cmd_resp_queue_capacity_bytes -> cmd_resp_queue_capacity_words tx_rx_queue_capacity_bytes -> tx_rx_queue_capacity_words ibi_queue_capacity_bytes -> ibi_queue_capacity_words Defaults are unchanged (0x10 / 0x40 / 0x10) -- they were being interpreted as word counts by fifo32_create() all along, just under a misleading label. No behavioral change. Signed-off-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com> --- include/hw/i3c/dw-i3c.h | 6 +++--- hw/i3c/dw-i3c.c | 32 ++++++++++++++++---------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/hw/i3c/dw-i3c.h b/include/hw/i3c/dw-i3c.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/i3c/dw-i3c.h +++ b/include/hw/i3c/dw-i3c.h @@ -XXX,XX +XXX,XX @@ struct DWI3C { struct { uint8_t id; - uint8_t cmd_resp_queue_capacity_bytes; - uint16_t tx_rx_queue_capacity_bytes; - uint8_t ibi_queue_capacity_bytes; + uint8_t cmd_resp_queue_capacity_words; + uint16_t tx_rx_queue_capacity_words; + uint8_t ibi_queue_capacity_words; uint8_t num_addressable_devices; uint16_t dev_addr_table_pointer; uint16_t dev_addr_table_depth; diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i3c/dw-i3c.c +++ b/hw/i3c/dw-i3c.c @@ -XXX,XX +XXX,XX @@ static void dw_i3c_reset(DeviceState *dev) ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER, DEV_CHAR_TABLE_DEPTH, s->cfg.dev_char_table_depth); ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC, - s->cfg.cmd_resp_queue_capacity_bytes); + s->cfg.cmd_resp_queue_capacity_words); ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC, - s->cfg.tx_rx_queue_capacity_bytes); + s->cfg.tx_rx_queue_capacity_words); dw_i3c_cmd_queue_reset(s); dw_i3c_resp_queue_reset(s); @@ -XXX,XX +XXX,XX @@ static void dw_i3c_reset_enter(Object *obj, ResetType type) ARRAY_FIELD_DP32(s->regs, DEV_CHAR_TABLE_POINTER, DEV_CHAR_TABLE_DEPTH, s->cfg.dev_char_table_depth); ARRAY_FIELD_DP32(s->regs, QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC, - s->cfg.cmd_resp_queue_capacity_bytes); + s->cfg.cmd_resp_queue_capacity_words); ARRAY_FIELD_DP32(s->regs, DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC, - s->cfg.tx_rx_queue_capacity_bytes); + s->cfg.tx_rx_queue_capacity_words); } static void dw_i3c_realize(DeviceState *dev, Error **errp) @@ -XXX,XX +XXX,XX @@ static void dw_i3c_realize(DeviceState *dev, Error **errp) DW_I3C_NR_REGS << 2); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr); - fifo32_create(&s->cmd_queue, s->cfg.cmd_resp_queue_capacity_bytes); - fifo32_create(&s->resp_queue, s->cfg.cmd_resp_queue_capacity_bytes); - fifo32_create(&s->tx_queue, s->cfg.tx_rx_queue_capacity_bytes); - fifo32_create(&s->rx_queue, s->cfg.tx_rx_queue_capacity_bytes); - fifo32_create(&s->ibi_queue, s->cfg.ibi_queue_capacity_bytes); + fifo32_create(&s->cmd_queue, s->cfg.cmd_resp_queue_capacity_words); + fifo32_create(&s->resp_queue, s->cfg.cmd_resp_queue_capacity_words); + fifo32_create(&s->tx_queue, s->cfg.tx_rx_queue_capacity_words); + fifo32_create(&s->rx_queue, s->cfg.tx_rx_queue_capacity_words); + fifo32_create(&s->ibi_queue, s->cfg.ibi_queue_capacity_words); /* Arbitrarily large enough to not be an issue. */ fifo8_create(&s->ibi_data.ibi_intermediate_queue, - s->cfg.ibi_queue_capacity_bytes * 8); + s->cfg.ibi_queue_capacity_words * 8); s->bus = i3c_init_bus(DEVICE(s), name); I3CBusClass *bc = I3C_BUS_GET_CLASS(s->bus); @@ -XXX,XX +XXX,XX @@ static void dw_i3c_realize(DeviceState *dev, Error **errp) static const Property dw_i3c_properties[] = { DEFINE_PROP_UINT8("device-id", DWI3C, cfg.id, 0), - DEFINE_PROP_UINT8("command-response-queue-capacity-bytes", DWI3C, - cfg.cmd_resp_queue_capacity_bytes, 0x10), - DEFINE_PROP_UINT16("tx-rx-queue-capacity-bytes", DWI3C, - cfg.tx_rx_queue_capacity_bytes, 0x40), - DEFINE_PROP_UINT8("ibi-queue-capacity-bytes", DWI3C, - cfg.ibi_queue_capacity_bytes, 0x10), + DEFINE_PROP_UINT8("command-response-queue-capacity-words", DWI3C, + cfg.cmd_resp_queue_capacity_words, 0x10), + DEFINE_PROP_UINT16("tx-rx-queue-capacity-words", DWI3C, + cfg.tx_rx_queue_capacity_words, 0x40), + DEFINE_PROP_UINT8("ibi-queue-capacity-words", DWI3C, + cfg.ibi_queue_capacity_words, 0x10), DEFINE_PROP_UINT8("num-addressable-devices", DWI3C, cfg.num_addressable_devices, 8), DEFINE_PROP_UINT16("dev-addr-table-pointer", DWI3C, -- 2.43.0
The command-response/tx-rx/ibi queue-capacity properties were renamed from "-bytes" to "-words". The "-bytes" names are user-visible and shipped in v11.0.0 (reachable via e.g. -global driver=dw.i3c,property=tx-rx-queue-capacity-bytes,...), so register them as aliases of the new names to keep existing command lines working. object_property_add_alias() forwards both reads and writes to the target property, so the old names behave exactly as before; introspection and qom-get/qom-set continue to work under either name. Signed-off-by: Jithu Joseph <jithu.joseph@oss.qualcomm.com> --- hw/i3c/dw-i3c.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i3c/dw-i3c.c +++ b/hw/i3c/dw-i3c.c @@ -XXX,XX +XXX,XX @@ static void dw_i3c_realize(DeviceState *dev, Error **errp) bc->ibi_finish = dw_i3c_ibi_finish; } +/* + * The *-queue-capacity-bytes properties shipped in v11.0.0 under names that + * implied a byte count, but the values are 32-bit word counts (they are passed + * straight to fifo32_create()). They were renamed to *-queue-capacity-words; + * keep the old names working as aliases so existing command lines using e.g. + * -global driver=dw.i3c,property=tx-rx-queue-capacity-bytes,... don't break. + */ +static void dw_i3c_init(Object *obj) +{ + static const char *const alias[][2] = { + { "command-response-queue-capacity-bytes", + "command-response-queue-capacity-words" }, + { "tx-rx-queue-capacity-bytes", "tx-rx-queue-capacity-words" }, + { "ibi-queue-capacity-bytes", "ibi-queue-capacity-words" }, + }; + + for (int i = 0; i < ARRAY_SIZE(alias); i++) { + object_property_add_alias(obj, alias[i][0], obj, alias[i][1]); + } +} + static const Property dw_i3c_properties[] = { DEFINE_PROP_UINT8("device-id", DWI3C, cfg.id, 0), DEFINE_PROP_UINT8("command-response-queue-capacity-words", DWI3C, @@ -XXX,XX +XXX,XX @@ static const TypeInfo dw_i3c_types[] = { .name = TYPE_DW_I3C, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(DWI3C), + .instance_init = dw_i3c_init, .class_init = dw_i3c_class_init, }, }; -- 2.43.0