Message ID | 20231019222725.3598022-3-Frank.Li@nxp.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | i3c: master: svc: collection of bugs fixes | expand |
Hi Frank, Frank.Li@nxp.com wrote on Thu, 19 Oct 2023 18:27:21 -0400: > ┌─────┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┌───── > SCL: ┘ └─────┛ └──┛ └──┛ └──┛ └──┛ └──┛ └──┛ └──┛ └──┘ > ───┐ ┌─────┐ ┌─────┐ ┌───────────┐ > SDA: └───────────────────────┘ └─────┘ └─────┘ └───── > xxx╱ ╲╱ ╲╱ ╲╱ ╲╱ ╲ > : xxx╲IBI ╱╲ Addr(0x0a) ╱╲ RW ╱╲NACK╱╲ S ╱ > > If an In-Band Interrupt (IBI) occurs and IBI work thread is not immediately > scheduled, When svc_i3c_master_priv_xfers() initiates the I3C transfer and nit: when > attempts to send address 0x7e, the target interprets it as an > IBI handler and returns the target address 0x0a. > > However, svc_i3c_master_priv_xfers() does not handle this case and proceeds > with other transfers, resulting in incorrect data being returned. > > Add IBIWON check in svc_i3c_master_xfer(). In case this situation occurs, > return a failure to the driver. > > Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") > Cc: stable@vger.kernel.org > Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com> > Signed-off-by: Frank Li <Frank.Li@nxp.com> > --- Thanks, Miquèl
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index 8cd708c965085..abebef666b2bb 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -1010,6 +1010,9 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, u32 reg; int ret; + /* clean SVC_I3C_MINT_IBIWON w1c bits */ + writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS); + writel(SVC_I3C_MCTRL_REQUEST_START_ADDR | xfer_type | SVC_I3C_MCTRL_IBIRESP_NACK | @@ -1028,6 +1031,23 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, goto emit_stop; } + /* + * According to I3C spec ver 1.1.1, 5.1.2.2.3 Consequence of Controller Starting a Frame + * with I3C Target Address. + * + * The I3C Controller normally should start a Frame, the Address may be arbitrated, and so + * the Controller shall monitor to see whether an In-Band Interrupt request, a Controller + * Role Request (i.e., Secondary Controller requests to become the Active Controller), or + * a Hot-Join Request has been made. + * + * If missed IBIWON check, the wrong data will be return. When IBIWON happen, return failure + * and yield the above events handler. + */ + if (SVC_I3C_MSTATUS_IBIWON(reg)) { + ret = -ENXIO; + goto emit_stop; + } + if (rnw) ret = svc_i3c_master_read(master, in, xfer_len); else