[PATCH 08/11] bus: mhi: MHI CB support for Channel error notification

Sivareddy Surasani posted 11 patches 2 months ago
[PATCH 08/11] bus: mhi: MHI CB support for Channel error notification
Posted by Sivareddy Surasani 2 months ago
From: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com>

If a device reports an error on any channel, it sends a
CH_ERROR_EVENT over the control event ring. Update the host to
parse the entire channel list, check the channel context ring
for CH_STATE_ERROR, and notify the client. This enables the
client driver to take appropriate action as needed.

Signed-off-by: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com>
Signed-off-by: Sivareddy Surasani <sivareddy.surasani@oss.qualcomm.com>
---
 drivers/bus/mhi/common.h    |  1 +
 drivers/bus/mhi/host/main.c | 24 ++++++++++++++++++++++++
 include/linux/mhi.h         |  2 ++
 3 files changed, 27 insertions(+)

diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h
index 31ff4d2e6eba..3b3ecbc6169f 100644
--- a/drivers/bus/mhi/common.h
+++ b/drivers/bus/mhi/common.h
@@ -230,6 +230,7 @@ enum mhi_pkt_type {
 	MHI_PKT_TYPE_TX_EVENT = 0x22,
 	MHI_PKT_TYPE_RSC_TX_EVENT = 0x28,
 	MHI_PKT_TYPE_EE_EVENT = 0x40,
+	MHI_PKT_TYPE_CH_ERROR_EVENT = 0x41,
 	MHI_PKT_TYPE_TSYNC_EVENT = 0x48,
 	MHI_PKT_TYPE_BW_REQ_EVENT = 0x50,
 	MHI_PKT_TYPE_STALE_EVENT, /* internal event */
diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c
index 53bb93da4017..9772fb13400c 100644
--- a/drivers/bus/mhi/host/main.c
+++ b/drivers/bus/mhi/host/main.c
@@ -798,6 +798,27 @@ static int parse_rsc_event(struct mhi_controller *mhi_cntrl,
 	return 0;
 }
 
+static void mhi_process_channel_error(struct mhi_controller *mhi_cntrl)
+{
+	struct mhi_chan *mhi_chan;
+	struct mhi_chan_ctxt *chan_ctxt;
+	struct mhi_device *mhi_dev;
+	int i;
+
+	mhi_chan = mhi_cntrl->mhi_chan;
+	for (i = 0; i < mhi_cntrl->max_chan; i++, mhi_chan++) {
+		chan_ctxt = &mhi_cntrl->mhi_ctxt->chan_ctxt[mhi_chan->chan];
+
+		if ((chan_ctxt->chcfg & CHAN_CTX_CHSTATE_MASK) == MHI_CH_STATE_ERROR) {
+			dev_err(&mhi_cntrl->mhi_dev->dev,
+				"ch_id:%d is moved to error state by device", mhi_chan->chan);
+				mhi_dev = mhi_chan->mhi_dev;
+			if (mhi_dev)
+				mhi_notify(mhi_dev, MHI_CB_CHANNEL_ERROR);
+		}
+	}
+}
+
 static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
 				       struct mhi_ring_element *tre)
 {
@@ -961,6 +982,9 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
 
 			break;
 		}
+		case MHI_PKT_TYPE_CH_ERROR_EVENT:
+			mhi_process_channel_error(mhi_cntrl);
+			break;
 		case MHI_PKT_TYPE_TX_EVENT:
 			chan = MHI_TRE_GET_EV_CHID(local_rp);
 
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index 926a20835467..66fd83bed306 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -34,6 +34,7 @@ struct mhi_buf_info;
  * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
  * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
  * @MHI_CB_BW_REQ: Received a bandwidth switch request from device
+ * @MHI_CB_CHANNEL_ERROR: MHI channel entered error state from device
  */
 enum mhi_callback {
 	MHI_CB_IDLE,
@@ -45,6 +46,7 @@ enum mhi_callback {
 	MHI_CB_SYS_ERROR,
 	MHI_CB_FATAL_ERROR,
 	MHI_CB_BW_REQ,
+	MHI_CB_CHANNEL_ERROR,
 };
 
 /**

-- 
2.34.1
Re: [PATCH 08/11] bus: mhi: MHI CB support for Channel error notification
Posted by Manivannan Sadhasivam 4 weeks ago
On Thu, Dec 11, 2025 at 01:37:40PM +0530, Sivareddy Surasani wrote:
> From: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com>
> 
> If a device reports an error on any channel, it sends a
> CH_ERROR_EVENT over the control event ring. Update the host to
> parse the entire channel list, check the channel context ring
> for CH_STATE_ERROR, and notify the client. This enables the
> client driver to take appropriate action as needed.
> 

What scenarios could lead to the device sending this channel error event?

> Signed-off-by: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com>
> Signed-off-by: Sivareddy Surasani <sivareddy.surasani@oss.qualcomm.com>
> ---
>  drivers/bus/mhi/common.h    |  1 +
>  drivers/bus/mhi/host/main.c | 24 ++++++++++++++++++++++++
>  include/linux/mhi.h         |  2 ++
>  3 files changed, 27 insertions(+)
> 
> diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h
> index 31ff4d2e6eba..3b3ecbc6169f 100644
> --- a/drivers/bus/mhi/common.h
> +++ b/drivers/bus/mhi/common.h
> @@ -230,6 +230,7 @@ enum mhi_pkt_type {
>  	MHI_PKT_TYPE_TX_EVENT = 0x22,
>  	MHI_PKT_TYPE_RSC_TX_EVENT = 0x28,
>  	MHI_PKT_TYPE_EE_EVENT = 0x40,
> +	MHI_PKT_TYPE_CH_ERROR_EVENT = 0x41,
>  	MHI_PKT_TYPE_TSYNC_EVENT = 0x48,
>  	MHI_PKT_TYPE_BW_REQ_EVENT = 0x50,
>  	MHI_PKT_TYPE_STALE_EVENT, /* internal event */
> diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c
> index 53bb93da4017..9772fb13400c 100644
> --- a/drivers/bus/mhi/host/main.c
> +++ b/drivers/bus/mhi/host/main.c
> @@ -798,6 +798,27 @@ static int parse_rsc_event(struct mhi_controller *mhi_cntrl,
>  	return 0;
>  }
>  
> +static void mhi_process_channel_error(struct mhi_controller *mhi_cntrl)
> +{
> +	struct mhi_chan *mhi_chan;
> +	struct mhi_chan_ctxt *chan_ctxt;
> +	struct mhi_device *mhi_dev;
> +	int i;
> +
> +	mhi_chan = mhi_cntrl->mhi_chan;
> +	for (i = 0; i < mhi_cntrl->max_chan; i++, mhi_chan++) {
> +		chan_ctxt = &mhi_cntrl->mhi_ctxt->chan_ctxt[mhi_chan->chan];
> +
> +		if ((chan_ctxt->chcfg & CHAN_CTX_CHSTATE_MASK) == MHI_CH_STATE_ERROR) {
> +			dev_err(&mhi_cntrl->mhi_dev->dev,

You should use the channel mhi_dev.

> +				"ch_id:%d is moved to error state by device", mhi_chan->chan);

"Channel entered error state"

- Mani

> +				mhi_dev = mhi_chan->mhi_dev;
> +			if (mhi_dev)
> +				mhi_notify(mhi_dev, MHI_CB_CHANNEL_ERROR);
> +		}
> +	}
> +}
> +
>  static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl,
>  				       struct mhi_ring_element *tre)
>  {
> @@ -961,6 +982,9 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
>  
>  			break;
>  		}
> +		case MHI_PKT_TYPE_CH_ERROR_EVENT:
> +			mhi_process_channel_error(mhi_cntrl);
> +			break;
>  		case MHI_PKT_TYPE_TX_EVENT:
>  			chan = MHI_TRE_GET_EV_CHID(local_rp);
>  
> diff --git a/include/linux/mhi.h b/include/linux/mhi.h
> index 926a20835467..66fd83bed306 100644
> --- a/include/linux/mhi.h
> +++ b/include/linux/mhi.h
> @@ -34,6 +34,7 @@ struct mhi_buf_info;
>   * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
>   * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
>   * @MHI_CB_BW_REQ: Received a bandwidth switch request from device
> + * @MHI_CB_CHANNEL_ERROR: MHI channel entered error state from device
>   */
>  enum mhi_callback {
>  	MHI_CB_IDLE,
> @@ -45,6 +46,7 @@ enum mhi_callback {
>  	MHI_CB_SYS_ERROR,
>  	MHI_CB_FATAL_ERROR,
>  	MHI_CB_BW_REQ,
> +	MHI_CB_CHANNEL_ERROR,
>  };
>  
>  /**
> 
> -- 
> 2.34.1
> 

-- 
மணிவண்ணன் சதாசிவம்