• Frank Li's avatar
    i3c: master: svc: fix invalidate IBI type and miss call client IBI handler · 38baed9b
    Frank Li authored
    In an In-Band Interrupt (IBI) handle, the code logic is as follows:
    
    1: writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI | SVC_I3C_MCTRL_IBIRESP_AUTO,
    	  master->regs + SVC_I3C_MCTRL);
    
    2: ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val,
                                        SVC_I3C_MSTATUS_IBIWON(val), 0, 1000);
    	...
    3: ibitype = SVC_I3C_MSTATUS_IBITYPE(status);
       ibiaddr = SVC_I3C_MSTATUS_IBIADDR(status);
    
    SVC_I3C_MSTATUS_IBIWON may be set before step 1. Thus, step 2 will return
    immediately, and the I3C controller has not sent out the 9th SCL yet.
    Consequently, ibitype and ibiaddr are 0, resulting in an unknown IBI type
    occurrence and missing call I3C client driver's IBI handler.
    
    A typical case is that SVC_I3C_MSTATUS_IBIWON is set when an IBI occurs
    during the controller send start frame in svc_i3c_master_xfer().
    
    Clear SVC_I3C_MSTATUS_IBIWON before issue SVC_I3C_MCTRL_REQUEST_AUTO_IBI
    to fix this issue.
    
    Cc: stable@vger.kernel.org
    Fixes: 5e5e3c92 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
    Signed-off-by: default avatarFrank Li <Frank.Li@nxp.com>
    Reviewed-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
    Link: https://lore.kernel.org/r/20240506164009.21375-3-Frank.Li@nxp.comSigned-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
    38baed9b
svc-i3c-master.c 47.8 KB