]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
i3c: master: svc: manually emit NACK/ACK for hotjoin
authorFrank Li <Frank.Li@nxp.com>
Wed, 2 Oct 2024 14:50:34 +0000 (10:50 -0400)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Thu, 31 Oct 2024 22:53:39 +0000 (23:53 +0100)
When the address is arbitrated at send address, the hardware can auto-send
NACK if it is an IBI. However, manual emission of NACK/ACK is needed for
hot join or controller request events.

Add help function svc_i3c_master_handle_ibi_won() to check event type and
send out NACK if the event is not an IBI.

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20241002-svc-i3c-hj-v6-2-7e6e1d3569ae@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/i3c/master/svc-i3c-master.c

index 7cd3ce2643f1a8c0ed2758b9fd2dbc2406697b65..c35a228f0c2f47ebacc0cd9c0923b011a6ac88ba 100644 (file)
@@ -409,6 +409,24 @@ static void svc_i3c_master_nack_ibi(struct svc_i3c_master *master)
               master->regs + SVC_I3C_MCTRL);
 }
 
+static int svc_i3c_master_handle_ibi_won(struct svc_i3c_master *master, u32 mstatus)
+{
+       u32 ibitype;
+
+       ibitype = SVC_I3C_MSTATUS_IBITYPE(mstatus);
+
+       writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
+
+       /* Hardware can't auto emit NACK for hot join and master request */
+       switch (ibitype) {
+       case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN:
+       case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST:
+               svc_i3c_master_nack_ibi(master);
+       }
+
+       return 0;
+}
+
 static void svc_i3c_master_ibi_work(struct work_struct *work)
 {
        struct svc_i3c_master *master = container_of(work, struct svc_i3c_master, ibi_work);
@@ -1177,7 +1195,7 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
                 * start.
                 */
                if (SVC_I3C_MSTATUS_IBIWON(reg)) {
-                       writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
+                       svc_i3c_master_handle_ibi_won(master, reg);
                        continue;
                }