[PATCH v2 3/5] i3c: master: Move bus_init error suppression

Jorge Marques posted 5 patches 3 weeks, 4 days ago
There is a newer version of this series
[PATCH v2 3/5] i3c: master: Move bus_init error suppression
Posted by Jorge Marques 3 weeks, 4 days ago
Prepares to fix improper Mx positive error propagation in later commits
by handling Mx error codes where the i3c_ccc_cmd command is allocated.
The CCC DISEC to broadcast address is invoked with
i3c_master_enec_disec_locked() and yields error I3C_ERROR_M2 if there
are no devices active on the bus. This is expected at the bus
initialization stage, where it is not known yet that there are no active
devices on the bus. Add bool suppress_m2 argument to
i3c_master_enec_disec_locked() and update the call site at
i3c_master_bus_init() with the exact corner case to not require
propagating positive Mx error codes. Other call site should not suppress
the error code, for example, if a driver requests to peripheral to
disable events and the transfer is not acknowledged, this is an error
and should not proceed.

Signed-off-by: Jorge Marques <jorge.marques@analog.com>
---
 drivers/i3c/master.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index d4f9e7df4adc5..bc1189afaed81 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1059,7 +1059,8 @@ int i3c_master_entdaa_locked(struct i3c_master_controller *master)
 EXPORT_SYMBOL_GPL(i3c_master_entdaa_locked);
 
 static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
-					u8 addr, bool enable, u8 evts)
+					u8 addr, bool enable, u8 evts,
+					bool suppress_m2)
 {
 	struct i3c_ccc_events *events;
 	struct i3c_ccc_cmd_dest dest;
@@ -1079,6 +1080,9 @@ static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
 	ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
 	i3c_ccc_cmd_dest_cleanup(&dest);
 
+	if (suppress_m2 && ret && cmd.err == I3C_ERROR_M2)
+		ret = 0;
+
 	return ret;
 }
 
@@ -1099,7 +1103,7 @@ static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
 int i3c_master_disec_locked(struct i3c_master_controller *master, u8 addr,
 			    u8 evts)
 {
-	return i3c_master_enec_disec_locked(master, addr, false, evts);
+	return i3c_master_enec_disec_locked(master, addr, false, evts, false);
 }
 EXPORT_SYMBOL_GPL(i3c_master_disec_locked);
 
@@ -1120,7 +1124,7 @@ EXPORT_SYMBOL_GPL(i3c_master_disec_locked);
 int i3c_master_enec_locked(struct i3c_master_controller *master, u8 addr,
 			   u8 evts)
 {
-	return i3c_master_enec_disec_locked(master, addr, true, evts);
+	return i3c_master_enec_disec_locked(master, addr, true, evts, false);
 }
 EXPORT_SYMBOL_GPL(i3c_master_enec_locked);
 
@@ -2108,11 +2112,14 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
 			goto err_bus_cleanup;
 	}
 
-	/* Disable all slave events before starting DAA. */
-	ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
-				      I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
-				      I3C_CCC_EVENT_HJ);
-	if (ret && ret != I3C_ERROR_M2)
+	/*
+	 * Disable all slave events before starting DAA. When no active device
+	 * is on the bus, returns Mx error code M2, this error is ignored.
+	 */
+	ret = i3c_master_enec_disec_locked(master, I3C_BROADCAST_ADDR, false,
+					   I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
+					   I3C_CCC_EVENT_HJ, true);
+	if (ret)
 		goto err_bus_cleanup;
 
 	/*

-- 
2.51.1
Re: [PATCH v2 3/5] i3c: master: Move bus_init error suppression
Posted by Frank Li 2 weeks, 6 days ago
On Thu, Mar 12, 2026 at 05:38:06PM +0100, Jorge Marques wrote:
> Prepares to fix improper Mx positive error propagation in later commits
> by handling Mx error codes where the i3c_ccc_cmd command is allocated.
> The CCC DISEC to broadcast address is invoked with
> i3c_master_enec_disec_locked() and yields error I3C_ERROR_M2 if there
> are no devices active on the bus. This is expected at the bus
> initialization stage, where it is not known yet that there are no active
> devices on the bus. Add bool suppress_m2 argument to
> i3c_master_enec_disec_locked() and update the call site at
> i3c_master_bus_init() with the exact corner case to not require
> propagating positive Mx error codes. Other call site should not suppress
> the error code, for example, if a driver requests to peripheral to
> disable events and the transfer is not acknowledged, this is an error
> and should not proceed.
>
> Signed-off-by: Jorge Marques <jorge.marques@analog.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
>  drivers/i3c/master.c | 23 +++++++++++++++--------
>  1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index d4f9e7df4adc5..bc1189afaed81 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1059,7 +1059,8 @@ int i3c_master_entdaa_locked(struct i3c_master_controller *master)
>  EXPORT_SYMBOL_GPL(i3c_master_entdaa_locked);
>
>  static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
> -					u8 addr, bool enable, u8 evts)
> +					u8 addr, bool enable, u8 evts,
> +					bool suppress_m2)
>  {
>  	struct i3c_ccc_events *events;
>  	struct i3c_ccc_cmd_dest dest;
> @@ -1079,6 +1080,9 @@ static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
>  	ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
>  	i3c_ccc_cmd_dest_cleanup(&dest);
>
> +	if (suppress_m2 && ret && cmd.err == I3C_ERROR_M2)
> +		ret = 0;
> +
>  	return ret;
>  }
>
> @@ -1099,7 +1103,7 @@ static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
>  int i3c_master_disec_locked(struct i3c_master_controller *master, u8 addr,
>  			    u8 evts)
>  {
> -	return i3c_master_enec_disec_locked(master, addr, false, evts);
> +	return i3c_master_enec_disec_locked(master, addr, false, evts, false);
>  }
>  EXPORT_SYMBOL_GPL(i3c_master_disec_locked);
>
> @@ -1120,7 +1124,7 @@ EXPORT_SYMBOL_GPL(i3c_master_disec_locked);
>  int i3c_master_enec_locked(struct i3c_master_controller *master, u8 addr,
>  			   u8 evts)
>  {
> -	return i3c_master_enec_disec_locked(master, addr, true, evts);
> +	return i3c_master_enec_disec_locked(master, addr, true, evts, false);
>  }
>  EXPORT_SYMBOL_GPL(i3c_master_enec_locked);
>
> @@ -2108,11 +2112,14 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
>  			goto err_bus_cleanup;
>  	}
>
> -	/* Disable all slave events before starting DAA. */
> -	ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
> -				      I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
> -				      I3C_CCC_EVENT_HJ);
> -	if (ret && ret != I3C_ERROR_M2)
> +	/*
> +	 * Disable all slave events before starting DAA. When no active device
> +	 * is on the bus, returns Mx error code M2, this error is ignored.
> +	 */
> +	ret = i3c_master_enec_disec_locked(master, I3C_BROADCAST_ADDR, false,
> +					   I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
> +					   I3C_CCC_EVENT_HJ, true);
> +	if (ret)
>  		goto err_bus_cleanup;
>
>  	/*
>
> --
> 2.51.1
>
Re: [PATCH v2 3/5] i3c: master: Move bus_init error suppression
Posted by Adrian Hunter 3 weeks, 3 days ago
On 12/03/2026 18:38, Jorge Marques wrote:
> Prepares to fix improper Mx positive error propagation in later commits

Prepares -> Prepare

> by handling Mx error codes where the i3c_ccc_cmd command is allocated.
> The CCC DISEC to broadcast address is invoked with
> i3c_master_enec_disec_locked() and yields error I3C_ERROR_M2 if there
> are no devices active on the bus. This is expected at the bus
> initialization stage, where it is not known yet that there are no active
> devices on the bus. Add bool suppress_m2 argument to
> i3c_master_enec_disec_locked() and update the call site at
> i3c_master_bus_init() with the exact corner case to not require
> propagating positive Mx error codes. Other call site should not suppress
> the error code, for example, if a driver requests to peripheral to
> disable events and the transfer is not acknowledged, this is an error
> and should not proceed.
> 
> Signed-off-by: Jorge Marques <jorge.marques@analog.com>

Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/i3c/master.c | 23 +++++++++++++++--------
>  1 file changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index d4f9e7df4adc5..bc1189afaed81 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -1059,7 +1059,8 @@ int i3c_master_entdaa_locked(struct i3c_master_controller *master)
>  EXPORT_SYMBOL_GPL(i3c_master_entdaa_locked);
>  
>  static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
> -					u8 addr, bool enable, u8 evts)
> +					u8 addr, bool enable, u8 evts,
> +					bool suppress_m2)
>  {
>  	struct i3c_ccc_events *events;
>  	struct i3c_ccc_cmd_dest dest;
> @@ -1079,6 +1080,9 @@ static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
>  	ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
>  	i3c_ccc_cmd_dest_cleanup(&dest);
>  
> +	if (suppress_m2 && ret && cmd.err == I3C_ERROR_M2)
> +		ret = 0;
> +
>  	return ret;
>  }
>  
> @@ -1099,7 +1103,7 @@ static int i3c_master_enec_disec_locked(struct i3c_master_controller *master,
>  int i3c_master_disec_locked(struct i3c_master_controller *master, u8 addr,
>  			    u8 evts)
>  {
> -	return i3c_master_enec_disec_locked(master, addr, false, evts);
> +	return i3c_master_enec_disec_locked(master, addr, false, evts, false);
>  }
>  EXPORT_SYMBOL_GPL(i3c_master_disec_locked);
>  
> @@ -1120,7 +1124,7 @@ EXPORT_SYMBOL_GPL(i3c_master_disec_locked);
>  int i3c_master_enec_locked(struct i3c_master_controller *master, u8 addr,
>  			   u8 evts)
>  {
> -	return i3c_master_enec_disec_locked(master, addr, true, evts);
> +	return i3c_master_enec_disec_locked(master, addr, true, evts, false);
>  }
>  EXPORT_SYMBOL_GPL(i3c_master_enec_locked);
>  
> @@ -2108,11 +2112,14 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
>  			goto err_bus_cleanup;
>  	}
>  
> -	/* Disable all slave events before starting DAA. */
> -	ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
> -				      I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
> -				      I3C_CCC_EVENT_HJ);
> -	if (ret && ret != I3C_ERROR_M2)
> +	/*
> +	 * Disable all slave events before starting DAA. When no active device
> +	 * is on the bus, returns Mx error code M2, this error is ignored.
> +	 */
> +	ret = i3c_master_enec_disec_locked(master, I3C_BROADCAST_ADDR, false,
> +					   I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
> +					   I3C_CCC_EVENT_HJ, true);
> +	if (ret)
>  		goto err_bus_cleanup;
>  
>  	/*
>