Skip to content

Commit 3c6684a

Browse files
nxpfranklialexandrebelloni
authored andcommitted
i3c: master: svc: use repeat start when IBI WIN happens
There is a possibility of an IBI WIN occurring when addressing issues, even when sending CCC commands. Most of the time, returning -EAGAIN is acceptable, but the case below becomes highly complex. When a Hotjoin event occurs: - i3c_master_do_daa() - i3c_master_add_i3c_dev_locked() - A dynamic address (e.g., 0x9) is already set during DAA. - i3c_master_getpid_locked() - Another device issues HJ or IBI here. Returning -EAGAIN causes failure in adding the new device. However, the dynamic address(0x9) has already been assigned to this device. If another device issues HJ, it will get this address 0x9 again, causing two devices on the bus to use the same dynamic address 0x9. - Attempting to send RSTDAA when the first device fails at i3c_master_getpid_locked() could also fail when sending RSTDAA for the same reason. According to the I3C spec, address arbitration only happens at START, never at REPEAT start. Using repeat start when an IBI WIN occurs simplifies this case, as i3c_master_getpid_locked() will not return an error when another device tries to send HJ or IBI. Acked-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 851bd21 commit 3c6684a

File tree

1 file changed

+18
-18
lines changed

1 file changed

+18
-18
lines changed

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

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,24 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
11631163
if (ret)
11641164
goto emit_stop;
11651165

1166+
/*
1167+
* According to I3C spec ver 1.1.1, 5.1.2.2.3 Consequence of Controller Starting a
1168+
* Frame with I3C Target Address.
1169+
*
1170+
* The I3C Controller normally should start a Frame, the Address may be arbitrated,
1171+
* and so the Controller shall monitor to see whether an In-Band Interrupt request,
1172+
* a Controller Role Request (i.e., Secondary Controller requests to become the
1173+
* Active Controller), or a Hot-Join Request has been made.
1174+
*
1175+
* If missed IBIWON check, the wrong data will be return. When IBIWON happen, issue
1176+
* repeat start. Address arbitrate only happen at START, never happen at REPEAT
1177+
* start.
1178+
*/
1179+
if (SVC_I3C_MSTATUS_IBIWON(reg)) {
1180+
writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
1181+
continue;
1182+
}
1183+
11661184
if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) {
11671185
/*
11681186
* According to I3C Spec 1.1.1, 11-Jun-2021, section: 5.1.2.2.3.
@@ -1196,24 +1214,6 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
11961214
}
11971215
}
11981216

1199-
/*
1200-
* According to I3C spec ver 1.1.1, 5.1.2.2.3 Consequence of Controller Starting a Frame
1201-
* with I3C Target Address.
1202-
*
1203-
* The I3C Controller normally should start a Frame, the Address may be arbitrated, and so
1204-
* the Controller shall monitor to see whether an In-Band Interrupt request, a Controller
1205-
* Role Request (i.e., Secondary Controller requests to become the Active Controller), or
1206-
* a Hot-Join Request has been made.
1207-
*
1208-
* If missed IBIWON check, the wrong data will be return. When IBIWON happen, return failure
1209-
* and yield the above events handler.
1210-
*/
1211-
if (SVC_I3C_MSTATUS_IBIWON(reg)) {
1212-
ret = -EAGAIN;
1213-
*actual_len = 0;
1214-
goto emit_stop;
1215-
}
1216-
12171217
if (rnw)
12181218
ret = svc_i3c_master_read(master, in, xfer_len);
12191219
else

0 commit comments

Comments
 (0)