Skip to content

Commit c85e209

Browse files
nxpfranklialexandrebelloni
authored andcommitted
i3c: master: svc: fix ibi may not return mandatory data byte
MSTATUS[RXPEND] is only updated after the data transfer cycle started. This creates an issue when the I3C clock is slow, and the CPU is running fast enough that MSTATUS[RXPEND] may not be updated when the code reaches checking point. As a result, mandatory data can be missed. Add a wait for MSTATUS[COMPLETE] to ensure that all mandatory data is already in FIFO. It also works without mandatory data. Fixes: dd3c528 ("i3c: master: svc: Add Silvaco I3C master driver") Cc: <[email protected]> Reviewed-by: Miquel Raynal <[email protected]> Signed-off-by: Frank Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 5e5e3c9 commit c85e209

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

drivers/i3c/master/svc-i3c-master.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master,
333333
struct i3c_ibi_slot *slot;
334334
unsigned int count;
335335
u32 mdatactrl;
336+
int ret, val;
336337
u8 *buf;
337338

338339
slot = i3c_generic_ibi_get_free_slot(data->ibi_pool);
@@ -342,6 +343,13 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master,
342343
slot->len = 0;
343344
buf = slot->data;
344345

346+
ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val,
347+
SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000);
348+
if (ret) {
349+
dev_err(master->dev, "Timeout when polling for COMPLETE\n");
350+
return ret;
351+
}
352+
345353
while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) &&
346354
slot->len < SVC_I3C_FIFO_SIZE) {
347355
mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL);

0 commit comments

Comments
 (0)