[PATCH v40 4/7] firmware: imx: device context dedicated to priv

Frank Li Frank.li at oss.nxp.com
Fri Aug 21 08:56:05 PDT 2026


On Sat, Aug 22, 2026 at 12:06:11AM +0530, pankaj.gupta at oss.nxp.com wrote:
> From: Pankaj Gupta <pankaj.gupta at nxp.com>
>
> Add priv_dev_ctx to prepare enabling misc-device context based send-receive
> path, to communicate with FW.
>
> No functionality change.
>
> Signed-off-by: Pankaj Gupta <pankaj.gupta at nxp.com>
> Reviewed-by: Frank Li <Frank.Li at nxp.com>
> Signed-off-by: Frank Li <Frank.Li at nxp.com>
> ---
>  drivers/firmware/imx/ele_base_msg.c | 15 +++++-----
>  drivers/firmware/imx/ele_common.c   | 55 +++++++++++++++++++++----------------
>  drivers/firmware/imx/ele_common.h   |  8 +++---
>  drivers/firmware/imx/se_ctrl.c      | 41 +++++++++++++++++++++++++++
>  drivers/firmware/imx/se_ctrl.h      |  9 ++++++
>  5 files changed, 94 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
> index 724f6e913ce7..b70e3ef88a16 100644
> --- a/drivers/firmware/imx/ele_base_msg.c
> +++ b/drivers/firmware/imx/ele_base_msg.c
> @@ -71,8 +71,9 @@ int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info)
>  	tx_msg->data[0] = upper_32_bits(get_info_addr);
>  	tx_msg->data[1] = lower_32_bits(get_info_addr);
>  	tx_msg->data[2] = sizeof(*s_info);
> -	ret = ele_msg_send_rcv(priv, tx_msg, ELE_GET_INFO_REQ_MSG_SZ, rx_msg,
> -			       ELE_GET_INFO_RSP_MSG_SZ);
> +
> +	ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_GET_INFO_REQ_MSG_SZ,
> +			       rx_msg, ELE_GET_INFO_RSP_MSG_SZ);
>  	if (ret < 0) {
>  		ele_get_info_cleanup(priv, get_info_data, get_info_addr, get_info_len);
>  		return ret;
> @@ -117,8 +118,8 @@ int ele_ping(struct se_if_priv *priv)
>  	se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
>  			    ELE_PING_REQ, ELE_PING_REQ_SZ, true);
>
> -	ret = ele_msg_send_rcv(priv, tx_msg, ELE_PING_REQ_SZ, rx_msg,
> -			       ELE_PING_RSP_SZ);
> +	ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_PING_REQ_SZ,
> +			       rx_msg, ELE_PING_RSP_SZ);
>  	if (ret < 0)
>  		return ret;
>
> @@ -165,7 +166,7 @@ int ele_service_swap(struct se_if_priv *priv,
>  	if (ret)
>  		return -EINVAL;
>
> -	ret = ele_msg_send_rcv(priv, tx_msg, ELE_SERVICE_SWAP_REQ_MSG_SZ,
> +	ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_SERVICE_SWAP_REQ_MSG_SZ,
>  			       rx_msg, ELE_SERVICE_SWAP_RSP_MSG_SZ);
>  	if (ret < 0)
>  		return ret;
> @@ -213,7 +214,7 @@ int ele_fw_authenticate(struct se_if_priv *priv, dma_addr_t contnr_addr,
>  	tx_msg->data[1] = 0;
>  	tx_msg->data[2] = lower_32_bits(img_addr);
>
> -	ret = ele_msg_send_rcv(priv, tx_msg, ELE_FW_AUTH_REQ_SZ, rx_msg,
> +	ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_FW_AUTH_REQ_SZ, rx_msg,
>  			       ELE_FW_AUTH_RSP_MSG_SZ);
>  	if (ret < 0)
>  		return ret;
> @@ -251,7 +252,7 @@ int ele_debug_dump(struct se_if_priv *priv)
>  	do {
>  		memset(rx_msg, 0x0, ELE_DEBUG_DUMP_RSP_SZ);
>
> -		ret = ele_msg_send_rcv(priv, tx_msg, ELE_DEBUG_DUMP_REQ_SZ,
> +		ret = ele_msg_send_rcv(priv->priv_dev_ctx, tx_msg, ELE_DEBUG_DUMP_REQ_SZ,
>  				       rx_msg, ELE_DEBUG_DUMP_RSP_SZ);
>  		if (ret < 0)
>  			return ret;
> diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
> index 04ee5112d346..b662063c3b1c 100644
> --- a/drivers/firmware/imx/ele_common.c
> +++ b/drivers/firmware/imx/ele_common.c
> @@ -46,8 +46,9 @@ int se_update_msg_chksum(u32 *msg, u32 msg_len)
>  	return 0;
>  }
>
> -int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl)
> +int ele_msg_rcv(struct se_if_device_ctx *dev_ctx, struct se_clbk_handle *se_clbk_hdl)
>  {
> +	struct se_if_priv *priv = dev_ctx->priv;
>  	bool is_rsp_wait_with_timeout = false;
>  	bool wait_uninterruptible = false;
>  	unsigned long remaining_jiffies;
> @@ -134,7 +135,7 @@ int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl)
>  	return ret;
>  }
>
> -int ele_msg_send(struct se_if_priv *priv,
> +int ele_msg_send(struct se_if_device_ctx *dev_ctx,
>  		 void *tx_msg,
>  		 int tx_msg_sz)
>  {
> @@ -146,9 +147,9 @@ int ele_msg_send(struct se_if_priv *priv,
>  	 * carried in the message.
>  	 */
>  	if (header->size << 2 != tx_msg_sz) {
> -		dev_err(priv->dev,
> -			"User buf hdr: 0x%x, sz mismatced with input-sz (%d != %d).",
> -			*(u32 *)header, header->size << 2, tx_msg_sz);
> +		dev_err(dev_ctx->priv->dev,
> +			"%s: User buf hdr: 0x%x, sz mismatched with input-sz (%d != %d).",
> +			dev_ctx->devname, *(u32 *)header, header->size << 2, tx_msg_sz);
>  		return -EINVAL;
>  	}
>
> @@ -158,9 +159,10 @@ int ele_msg_send(struct se_if_priv *priv,
>  	 * caller-provided tx_msg pointer after mbox_send_message() returns, so
>  	 * the caller-owned buffer may be released after a successful send.
>  	 */
> -	err = mbox_send_message(priv->tx_chan, tx_msg);
> +	err = mbox_send_message(dev_ctx->priv->tx_chan, tx_msg);
>  	if (err < 0) {
> -		dev_err(priv->dev, "Error: mbox_send_message failure.\n");
> +		dev_err(dev_ctx->priv->dev,
> +			"%s: Error: mbox_send_message failure.", dev_ctx->devname);
>  		return err;
>  	}
>
> @@ -172,38 +174,41 @@ static void ele_msg_send_rcv_cleanup(struct se_if_priv *priv)
>  	unsigned long flags;
>
>  	spin_lock_irqsave(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags);
> +	priv->waiting_rsp_clbk_hdl.dev_ctx = NULL;
>  	priv->waiting_rsp_clbk_hdl.rx_msg = NULL;
>  	priv->waiting_rsp_clbk_hdl.rx_msg_sz = 0;
>  	spin_unlock_irqrestore(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags);
>  }
>
> -/* API used for send/receive blocking call. */
> -int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
> -		     void *rx_msg, int exp_rx_msg_sz)
> +/* API used for send/receive blocking calls. */
> +int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg,
> +		     int tx_msg_sz, void *rx_msg, int exp_rx_msg_sz)
>  {
> +	struct se_if_priv *priv = dev_ctx->priv;
>  	unsigned long flags;
>  	int err;
>
>  	guard(mutex)(&priv->se_if_cmd_lock);
>
>  	if (atomic_read(&priv->fw_busy)) {
> -		dev_dbg(priv->dev, "ELE became unresponsive.\n");
> +		dev_dbg(priv->dev, "%s: ELE became unresponsive.\n", dev_ctx->devname);
>  		return -EBUSY;
>  	}
>  	reinit_completion(&priv->waiting_rsp_clbk_hdl.done);
>  	/* Publish rx_msg/rx_msg_sz under the lock read by se_if_rx_callback(). */
>  	spin_lock_irqsave(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags);
> +	priv->waiting_rsp_clbk_hdl.dev_ctx = dev_ctx;
>  	priv->waiting_rsp_clbk_hdl.rx_msg_sz = exp_rx_msg_sz;
>  	priv->waiting_rsp_clbk_hdl.rx_msg = rx_msg;
>  	spin_unlock_irqrestore(&priv->waiting_rsp_clbk_hdl.clbk_rx_lock, flags);
>
> -	err = ele_msg_send(priv, tx_msg, tx_msg_sz);
> +	err = ele_msg_send(dev_ctx, tx_msg, tx_msg_sz);
>  	if (err < 0) {
>  		ele_msg_send_rcv_cleanup(priv);
>  		return err;
>  	}
>
> -	err = ele_msg_rcv(priv, &priv->waiting_rsp_clbk_hdl);
> +	err = ele_msg_rcv(dev_ctx, &priv->waiting_rsp_clbk_hdl);
>
>  	if (priv->waiting_rsp_clbk_hdl.signal_rcvd) {
>  		/*
> @@ -214,7 +219,8 @@ int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
>  		if (err > 0)
>  			err = -ERESTARTSYS;
>  		priv->waiting_rsp_clbk_hdl.signal_rcvd = false;
> -		dev_dbg(priv->dev, "Err[0x%x]:Interrupted by signal.", err);
> +		dev_dbg(priv->dev, "%s: Err[0x%x]:Interrupted by signal.",
> +			dev_ctx->devname, err);
>  	}
>
>  	ele_msg_send_rcv_cleanup(priv);
> @@ -243,6 +249,7 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
>  {
>  	struct se_clbk_handle *se_clbk_hdl;
>  	struct device *dev = mbox_cl->dev;
> +	const char *devname = NULL;
>  	struct se_msg_hdr *header;
>  	bool sz_mismatch = false;
>  	struct se_if_priv *priv;
> @@ -266,7 +273,7 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
>  	if (header->tag == priv->if_defs->cmd_tag) {
>  		se_clbk_hdl = &priv->cmd_receiver_clbk_hdl;
>  		spin_lock_irqsave(&se_clbk_hdl->clbk_rx_lock, flags);
> -		if (!se_clbk_hdl->rx_msg) {
> +		if (!se_clbk_hdl->dev_ctx || !se_clbk_hdl->rx_msg) {
>  			spin_unlock_irqrestore(&se_clbk_hdl->clbk_rx_lock, flags);
>  			dev_warn(dev, "No command receiver registered for message: %.8x\n",
>  				 *((u32 *)header));
> @@ -280,8 +287,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
>  		 * SE_IOCTL_ENABLE_CMD_RCV and is not subject to the timeout/circuit-
>  		 * breaker handling used for rsp_tag messages.
>  		 */
> -		dev_dbg(dev, "Selecting cmd receiver: for mesg header:0x%x.",
> -			*(u32 *)header);
> +		dev_dbg(dev, "Selecting cmd receiver:%s for mesg header:0x%x.",
> +			se_clbk_hdl->dev_ctx->devname,  *(u32 *)header);
>
>  		/*
>  		 * Pre-allocated buffer of MAX_NVM_MSG_LEN
> @@ -296,13 +303,14 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
>  		 * Clamp the copy length to the pre-allocated receiver buffer (MAX_NVM_MSG_LEN).
>  		 */
>  		se_clbk_hdl->rx_msg_sz = min_t(u32, rx_msg_sz, MAX_NVM_MSG_LEN);
> +		devname = se_clbk_hdl->dev_ctx->devname;
>  		memcpy(se_clbk_hdl->rx_msg, msg, se_clbk_hdl->rx_msg_sz);
>  		complete(&se_clbk_hdl->done);
>  		spin_unlock_irqrestore(&se_clbk_hdl->clbk_rx_lock, flags);
>  		if (sz_mismatch)
>  			dev_err(dev,
> -				"CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n",
> -				*(u32 *)header,
> +				"%s: CMD-RCVER NVM: hdr(0x%x) with different sz(%d != %d).\n",
> +				devname, *(u32 *)header,
>  				(header->size << 2), rx_msg_sz);
>  	} else if (header->tag == priv->if_defs->rsp_tag) {
>  		bool exception_for_sz_mismatch = check_hdr_exception_for_sz(priv, header);
> @@ -324,8 +332,8 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
>  			return;
>  		}
>  		exp_rx_msg_sz = se_clbk_hdl->rx_msg_sz;
> -		dev_dbg(dev, "Selecting resp waiter: for mesg header:0x%x.",
> -			*(u32 *)header);
> +		dev_dbg(dev, "Selecting resp waiter:%s for mesg header:0x%x.",
> +			se_clbk_hdl->dev_ctx->devname, *(u32 *)header);
>
>  		/*
>  		 * For rsp_tag traffic, the sender provides the expected response
> @@ -337,14 +345,15 @@ void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg)
>  			sz_mismatch = true;
>
>  		se_clbk_hdl->rx_msg_sz = min(rx_msg_sz, exp_rx_msg_sz);
> +		devname = se_clbk_hdl->dev_ctx->devname;
>  		memcpy(se_clbk_hdl->rx_msg, msg, se_clbk_hdl->rx_msg_sz);
>  		complete(&se_clbk_hdl->done);
>  		spin_unlock_irqrestore(&se_clbk_hdl->clbk_rx_lock, flags);
>
>  		if (sz_mismatch)
>  			dev_err(dev,
> -				"Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n",
> -				*(u32 *)header,
> +				"%s: Rsp to CMD: hdr(0x%x) with different sz(%d != %d).\n",
> +				devname, *(u32 *)header,
>  				(header->size << 2), exp_rx_msg_sz);
>  	} else {
>  		dev_err(dev, "Failed to select a device for message: %.8x\n",
> diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
> index 7bf2febefc45..07e6b6a1bafa 100644
> --- a/drivers/firmware/imx/ele_common.h
> +++ b/drivers/firmware/imx/ele_common.h
> @@ -16,12 +16,12 @@
>
>  int se_update_msg_chksum(u32 *msg, u32 msg_len);
>
> -int ele_msg_rcv(struct se_if_priv *priv, struct se_clbk_handle *se_clbk_hdl);
> +int ele_msg_rcv(struct se_if_device_ctx *dev_ctx, struct se_clbk_handle *se_clbk_hdl);
>
> -int ele_msg_send(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz);
> +int ele_msg_send(struct se_if_device_ctx *dev_ctx, void *tx_msg, int tx_msg_sz);
>
> -int ele_msg_send_rcv(struct se_if_priv *priv, void *tx_msg, int tx_msg_sz,
> -		     void *rx_msg, int exp_rx_msg_sz);
> +int ele_msg_send_rcv(struct se_if_device_ctx *dev_ctx, void *tx_msg,
> +		     int tx_msg_sz, void *rx_msg, int exp_rx_msg_sz);
>
>  void se_if_rx_callback(struct mbox_client *mbox_cl, void *msg);
>
> diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
> index df3d1da28a75..2ee0f70c38cd 100644
> --- a/drivers/firmware/imx/se_ctrl.c
> +++ b/drivers/firmware/imx/se_ctrl.c
> @@ -284,6 +284,36 @@ static int get_se_soc_info(struct se_if_priv *priv, const struct se_soc_info *se
>  	return 0;
>  }
>
> +static int init_misc_device_context(struct se_if_priv *priv, int ch_id,
> +				    struct se_if_device_ctx **new_dev_ctx)
> +{
> +	const char *err_str = "Failed to allocate memory";
> +	struct se_if_device_ctx *dev_ctx;
> +	int ret = -ENOMEM;
> +
> +	dev_ctx = kzalloc_obj(*dev_ctx, GFP_KERNEL);
> +
> +	if (!dev_ctx)
> +		return ret;

		return -ENOMEM;

> +
> +	dev_ctx->devname = kasprintf(GFP_KERNEL, "%s0_ch%d",
> +				     get_se_if_name(priv->if_defs->se_if_type),
> +				     ch_id);
> +	if (!dev_ctx->devname)
> +		goto exit;
> +
> +	dev_ctx->priv = priv;
> +	*new_dev_ctx = dev_ctx;
> +
> +	return 0;
> +exit:
> +	*new_dev_ctx = NULL;
> +
> +	kfree(dev_ctx->devname);
> +	kfree(dev_ctx);
> +	return dev_err_probe(priv->dev, ret, "%s", err_str);

Needn't var err_str and generally, needn't print msg for -ENOMEM

	return -ENOMEM;


> +}
> +
>  static int se_if_request_channel(struct device *dev, struct mbox_chan **chan,
>  				 struct mbox_client *cl, const char *name)
>  {
> @@ -328,6 +358,11 @@ static void se_if_probe_cleanup(void *plat_dev)
>
>  	dev_set_drvdata(dev, NULL);
>
> +	if (priv->priv_dev_ctx) {
> +		kfree(priv->priv_dev_ctx->devname);
> +		kfree(priv->priv_dev_ctx);
> +	}
> +
>  	kfree(priv);
>  }
>
> @@ -425,6 +460,12 @@ static int se_if_probe(struct platform_device *pdev)
>  		load_fw->imem_mgmt = true;
>  	}
>
> +	ret = init_misc_device_context(priv, 0, &priv->priv_dev_ctx);
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "Failed[0x%x] to create device contexts.",
> +				     ret);

Needn't print error code, dev_err_probe() already print for you.

		dev_err_probe(dev, ret, "Failed to ...\n"):

and need "\n" for all error message, please double other.

Frank
> +
>  	if (if_node->if_defs.se_if_type == SE_TYPE_ID_HSM) {
>  		ret = get_se_soc_info(priv, se_info);
>  		if (ret)
> diff --git a/drivers/firmware/imx/se_ctrl.h b/drivers/firmware/imx/se_ctrl.h
> index 54b2a262a2c3..dd4a1ea7e35a 100644
> --- a/drivers/firmware/imx/se_ctrl.h
> +++ b/drivers/firmware/imx/se_ctrl.h
> @@ -20,6 +20,7 @@
>  #define MESSAGING_VERSION_7		0x7
>
>  struct se_clbk_handle {
> +	struct se_if_device_ctx *dev_ctx;
>  	struct completion done;
>  	bool signal_rcvd;
>  	u32 rx_msg_sz;
> @@ -44,6 +45,12 @@ struct se_imem_buf {
>  	u32 state;
>  };
>
> +/* Private struct for each char device instance. */
> +struct se_if_device_ctx {
> +	struct se_if_priv *priv;
> +	const char *devname;
> +};
> +
>  /* Header of the messages exchange with the EdgeLock Enclave */
>  struct se_msg_hdr {
>  	u8 ver;
> @@ -106,6 +113,8 @@ struct se_if_priv {
>  	struct se_fw_load_info load_fw;
>
>  	atomic_t fw_busy;
> +
> +	struct se_if_device_ctx *priv_dev_ctx;
>  };
>
>  char *get_se_if_name(u8 se_if_id);
>
> --
> 2.43.0
>



More information about the linux-arm-kernel mailing list