Skip to content

Commit a7869b0

Browse files
stanleychuysalexandrebelloni
authored andcommitted
i3c: master: svc: Use manual response for IBI events
Driver wants to nack the IBI request when the target is not in the known address list. In below code, svc_i3c_master_nack_ibi() will cause undefined behavior when using AUTOIBI with auto response rule, because hw always auto ack the IBI request. switch (ibitype) { case SVC_I3C_MSTATUS_IBITYPE_IBI: dev = svc_i3c_master_dev_from_addr(master, ibiaddr); if (!dev || !is_events_enabled(master, SVC_I3C_EVENT_IBI)) svc_i3c_master_nack_ibi(master); ... break; AutoIBI has another issue that the controller doesn't quit AutoIBI state after IBIWON polling timeout when there is a SDA glitch(high->low->high). 1. SDA high->low: raising an interrupt to execute IBI ISR 2. SDA low->high 3. Driver writes an AutoIBI request 4. AutoIBI process does not start because SDA is not low 5. IBIWON polling times out 6. Controller reamins in AutoIBI state and doesn't accept EmitStop request Emitting broadcast address with IBIRESP_MANUAL avoids both issues. Fixes: dd3c528 ("i3c: master: svc: Add Silvaco I3C master driver") Signed-off-by: Stanley Chu <yschu@nuvoton.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://lore.kernel.org/r/20250829012309.3562585-2-yschu@nuvoton.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent a79ac2c commit a7869b0

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -517,9 +517,24 @@ static void svc_i3c_master_ibi_isr(struct svc_i3c_master *master)
517517
*/
518518
writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
519519

520-
/* Acknowledge the incoming interrupt with the AUTOIBI mechanism */
521-
writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI |
522-
SVC_I3C_MCTRL_IBIRESP_AUTO,
520+
/*
521+
* Write REQUEST_START_ADDR request to emit broadcast address for arbitration,
522+
* instend of using AUTO_IBI.
523+
*
524+
* Using AutoIBI request may cause controller to remain in AutoIBI state when
525+
* there is a glitch on SDA line (high->low->high).
526+
* 1. SDA high->low, raising an interrupt to execute IBI isr.
527+
* 2. SDA low->high.
528+
* 3. IBI isr writes an AutoIBI request.
529+
* 4. The controller will not start AutoIBI process because SDA is not low.
530+
* 5. IBIWON polling times out.
531+
* 6. Controller reamins in AutoIBI state and doesn't accept EmitStop request.
532+
*/
533+
writel(SVC_I3C_MCTRL_REQUEST_START_ADDR |
534+
SVC_I3C_MCTRL_TYPE_I3C |
535+
SVC_I3C_MCTRL_IBIRESP_MANUAL |
536+
SVC_I3C_MCTRL_DIR(SVC_I3C_MCTRL_DIR_WRITE) |
537+
SVC_I3C_MCTRL_ADDR(I3C_BROADCAST_ADDR),
523538
master->regs + SVC_I3C_MCTRL);
524539

525540
/* Wait for IBIWON, should take approximately 100us */
@@ -539,10 +554,15 @@ static void svc_i3c_master_ibi_isr(struct svc_i3c_master *master)
539554
switch (ibitype) {
540555
case SVC_I3C_MSTATUS_IBITYPE_IBI:
541556
dev = svc_i3c_master_dev_from_addr(master, ibiaddr);
542-
if (!dev || !is_events_enabled(master, SVC_I3C_EVENT_IBI))
557+
if (!dev || !is_events_enabled(master, SVC_I3C_EVENT_IBI)) {
543558
svc_i3c_master_nack_ibi(master);
544-
else
559+
} else {
560+
if (dev->info.bcr & I3C_BCR_IBI_PAYLOAD)
561+
svc_i3c_master_ack_ibi(master, true);
562+
else
563+
svc_i3c_master_ack_ibi(master, false);
545564
svc_i3c_master_handle_ibi(master, dev);
565+
}
546566
break;
547567
case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN:
548568
if (is_events_enabled(master, SVC_I3C_EVENT_HOTJOIN))

0 commit comments

Comments
 (0)