public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers()
@ 2024-05-06 16:40 Frank Li
  2024-05-06 16:40 ` [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame Frank Li
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Frank Li @ 2024-05-06 16:40 UTC (permalink / raw)
  To: miquel.raynal
  Cc: Frank.Li, alexandre.belloni, conor.culhane, imx, linux-i3c,
	linux-kernel

In accordance with I3C spec ver 1.1.1 09-Jun-2021, section: 5.1.2.2.3, if
a target requests hot join (HJ), In-Band Interrupt (IBI), or controller
role request (CRR) during the emission of an I3C address in
i3c_device_do_priv_xfers(), the target may win bus arbitration. In such
cases, it is imperative to notify the I3C client driver and retry
i3c_device_do_priv_xfers() after some delay.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v1 to v2
    - new patch

 drivers/i3c/device.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/i3c/device.c b/drivers/i3c/device.c
index 1a6a8703dbc3a..b04a55a1337d4 100644
--- a/drivers/i3c/device.c
+++ b/drivers/i3c/device.c
@@ -27,6 +27,10 @@
  * This function can sleep and thus cannot be called in atomic context.
  *
  * Return: 0 in case of success, a negative error core otherwise.
+ *	   -EAGAIN: controller lost address arbitration. Target
+ *		    (IBI, HJ or controller role request) win the bus. Client
+ *		    driver need resend this 'xfers' some time later.
+ *		    See I3C spec ver 1.1.1 09-Jun-2021. Section: 5.1.2.2.3.
  */
 int i3c_device_do_priv_xfers(struct i3c_device *dev,
 			     struct i3c_priv_xfer *xfers,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
  2024-05-06 16:40 [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Frank Li
@ 2024-05-06 16:40 ` Frank Li
  2024-05-07  8:03   ` Miquel Raynal
  2024-05-06 16:40 ` [PATCH v2 3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler Frank Li
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Frank Li @ 2024-05-06 16:40 UTC (permalink / raw)
  To: miquel.raynal
  Cc: Frank.Li, alexandre.belloni, conor.culhane, imx, linux-i3c,
	linux-kernel

svc_i3c_master_xfer() returns error ENXIO if an In-Band Interrupt (IBI)
occurs when the host starts the frame.

Change error code to EAGAIN to inform the client driver that this
situation has occurred and to try again sometime later.

Fixes: 5e5e3c92e748 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    change from v1 to v2
    - none

 drivers/i3c/master/svc-i3c-master.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index fd8de54b13667..94e4954509558 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -1080,7 +1080,7 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
 	 * and yield the above events handler.
 	 */
 	if (SVC_I3C_MSTATUS_IBIWON(reg)) {
-		ret = -ENXIO;
+		ret = -EAGAIN;
 		*actual_len = 0;
 		goto emit_stop;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
  2024-05-06 16:40 [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Frank Li
  2024-05-06 16:40 ` [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame Frank Li
@ 2024-05-06 16:40 ` Frank Li
  2024-05-07  8:04   ` Miquel Raynal
  2024-05-07  8:03 ` [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Miquel Raynal
  2024-05-07 20:27 ` Alexandre Belloni
  3 siblings, 1 reply; 7+ messages in thread
From: Frank Li @ 2024-05-06 16:40 UTC (permalink / raw)
  To: miquel.raynal
  Cc: Frank.Li, alexandre.belloni, conor.culhane, imx, linux-i3c,
	linux-kernel

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: 5e5e3c92e748 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---

Notes:
    Change from v1 to v2
    - improve comments.

 drivers/i3c/master/svc-i3c-master.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index 94e4954509558..032fe032ec433 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -415,6 +415,19 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
 	int ret;
 
 	mutex_lock(&master->lock);
+	/*
+	 * IBIWON may be set before SVC_I3C_MCTRL_REQUEST_AUTO_IBI, causing
+	 * readl_relaxed_poll_timeout() to return immediately. Consequently,
+	 * ibitype will be 0 since it was last updated only after the 8th SCL
+	 * cycle, leading to missed client IBI handlers.
+	 *
+	 * A typical scenario is when IBIWON occurs and bus arbitration is lost
+	 * at svc_i3c_master_priv_xfers().
+	 *
+	 * Clear SVC_I3C_MINT_IBIWON before sending SVC_I3C_MCTRL_REQUEST_AUTO_IBI.
+	 */
+	writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
+
 	/* Acknowledge the incoming interrupt with the AUTOIBI mechanism */
 	writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI |
 	       SVC_I3C_MCTRL_IBIRESP_AUTO,
@@ -429,9 +442,6 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
 		goto reenable_ibis;
 	}
 
-	/* Clear the interrupt status */
-	writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
-
 	status = readl(master->regs + SVC_I3C_MSTATUS);
 	ibitype = SVC_I3C_MSTATUS_IBITYPE(status);
 	ibiaddr = SVC_I3C_MSTATUS_IBIADDR(status);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers()
  2024-05-06 16:40 [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Frank Li
  2024-05-06 16:40 ` [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame Frank Li
  2024-05-06 16:40 ` [PATCH v2 3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler Frank Li
@ 2024-05-07  8:03 ` Miquel Raynal
  2024-05-07 20:27 ` Alexandre Belloni
  3 siblings, 0 replies; 7+ messages in thread
From: Miquel Raynal @ 2024-05-07  8:03 UTC (permalink / raw)
  To: Frank Li; +Cc: alexandre.belloni, conor.culhane, imx, linux-i3c, linux-kernel

Hi Frank,

Frank.Li@nxp.com wrote on Mon,  6 May 2024 12:40:07 -0400:

> In accordance with I3C spec ver 1.1.1 09-Jun-2021, section: 5.1.2.2.3, if
> a target requests hot join (HJ), In-Band Interrupt (IBI), or controller
> role request (CRR) during the emission of an I3C address in
> i3c_device_do_priv_xfers(), the target may win bus arbitration. In such
> cases, it is imperative to notify the I3C client driver and retry
> i3c_device_do_priv_xfers() after some delay.
> 
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> 
> Notes:
>     Change from v1 to v2
>     - new patch
> 
>  drivers/i3c/device.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/i3c/device.c b/drivers/i3c/device.c
> index 1a6a8703dbc3a..b04a55a1337d4 100644
> --- a/drivers/i3c/device.c
> +++ b/drivers/i3c/device.c
> @@ -27,6 +27,10 @@
>   * This function can sleep and thus cannot be called in atomic context.
>   *
>   * Return: 0 in case of success, a negative error core otherwise.
> + *	   -EAGAIN: controller lost address arbitration. Target
> + *		    (IBI, HJ or controller role request) win the bus. Client
> + *		    driver need resend this 'xfers' some time later.

			 needs to resend the 'xfers'

> + *		    See I3C spec ver 1.1.1 09-Jun-2021. Section: 5.1.2.2.3.
>   */
>  int i3c_device_do_priv_xfers(struct i3c_device *dev,
>  			     struct i3c_priv_xfer *xfers,


With this little nit,

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
  2024-05-06 16:40 ` [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame Frank Li
@ 2024-05-07  8:03   ` Miquel Raynal
  0 siblings, 0 replies; 7+ messages in thread
From: Miquel Raynal @ 2024-05-07  8:03 UTC (permalink / raw)
  To: Frank Li; +Cc: alexandre.belloni, conor.culhane, imx, linux-i3c, linux-kernel

Hi Frank,

Frank.Li@nxp.com wrote on Mon,  6 May 2024 12:40:08 -0400:

> svc_i3c_master_xfer() returns error ENXIO if an In-Band Interrupt (IBI)
> occurs when the host starts the frame.
> 
> Change error code to EAGAIN to inform the client driver that this
> situation has occurred and to try again sometime later.
> 
> Fixes: 5e5e3c92e748 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
> Signed-off-by: Frank Li <Frank.Li@nxp.com>

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>


Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
  2024-05-06 16:40 ` [PATCH v2 3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler Frank Li
@ 2024-05-07  8:04   ` Miquel Raynal
  0 siblings, 0 replies; 7+ messages in thread
From: Miquel Raynal @ 2024-05-07  8:04 UTC (permalink / raw)
  To: Frank Li; +Cc: alexandre.belloni, conor.culhane, imx, linux-i3c, linux-kernel

Hi Frank,

Frank.Li@nxp.com wrote on Mon,  6 May 2024 12:40:09 -0400:

> 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: 5e5e3c92e748 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> 
> Notes:
>     Change from v1 to v2
>     - improve comments.
> 
>  drivers/i3c/master/svc-i3c-master.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
> index 94e4954509558..032fe032ec433 100644
> --- a/drivers/i3c/master/svc-i3c-master.c
> +++ b/drivers/i3c/master/svc-i3c-master.c
> @@ -415,6 +415,19 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)
>  	int ret;
>  
>  	mutex_lock(&master->lock);
> +	/*
> +	 * IBIWON may be set before SVC_I3C_MCTRL_REQUEST_AUTO_IBI, causing
> +	 * readl_relaxed_poll_timeout() to return immediately. Consequently,
> +	 * ibitype will be 0 since it was last updated only after the 8th SCL
> +	 * cycle, leading to missed client IBI handlers.
> +	 *
> +	 * A typical scenario is when IBIWON occurs and bus arbitration is lost
> +	 * at svc_i3c_master_priv_xfers().
> +	 *
> +	 * Clear SVC_I3C_MINT_IBIWON before sending SVC_I3C_MCTRL_REQUEST_AUTO_IBI.
> +	 */

Thanks a lot.

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers()
  2024-05-06 16:40 [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Frank Li
                   ` (2 preceding siblings ...)
  2024-05-07  8:03 ` [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Miquel Raynal
@ 2024-05-07 20:27 ` Alexandre Belloni
  3 siblings, 0 replies; 7+ messages in thread
From: Alexandre Belloni @ 2024-05-07 20:27 UTC (permalink / raw)
  To: miquel.raynal, Frank Li; +Cc: conor.culhane, imx, linux-i3c, linux-kernel

On Mon, 06 May 2024 12:40:07 -0400, Frank Li wrote:
> In accordance with I3C spec ver 1.1.1 09-Jun-2021, section: 5.1.2.2.3, if
> a target requests hot join (HJ), In-Band Interrupt (IBI), or controller
> role request (CRR) during the emission of an I3C address in
> i3c_device_do_priv_xfers(), the target may win bus arbitration. In such
> cases, it is imperative to notify the I3C client driver and retry
> i3c_device_do_priv_xfers() after some delay.
> 
> [...]

Applied, thanks!

[1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers()
      https://git.kernel.org/abelloni/c/5e45614ef8ae
[2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
      https://git.kernel.org/abelloni/c/75cb32046b5d
[3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
      https://git.kernel.org/abelloni/c/677a7b0e3ae4

Best regards,

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-05-07 20:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-06 16:40 [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Frank Li
2024-05-06 16:40 ` [PATCH v2 2/3] i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame Frank Li
2024-05-07  8:03   ` Miquel Raynal
2024-05-06 16:40 ` [PATCH v2 3/3] i3c: master: svc: fix invalidate IBI type and miss call client IBI handler Frank Li
2024-05-07  8:04   ` Miquel Raynal
2024-05-07  8:03 ` [PATCH v2 1/3] i3c: Add comment for -EAGAIN in i3c_device_do_priv_xfers() Miquel Raynal
2024-05-07 20:27 ` Alexandre Belloni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox