static int imx_mu_specific_tx()

in imx-mailbox.c [180:235]


static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)
{
	u32 *arg = data;
	int i, ret;
	u32 xsr;
	u32 size, max_size, num_tr;

	if (priv->dcfg->type & IMX_MU_V2_S4) {
		size = ((struct imx_s4_rpc_msg_max *)data)->hdr.size;
		max_size = sizeof(struct imx_s4_rpc_msg_max);
		num_tr = 8;
	} else {
		size = ((struct imx_sc_rpc_msg_max *)data)->hdr.size;
		max_size = sizeof(struct imx_sc_rpc_msg_max);
		num_tr = 4;
	}

	switch (cp->type) {
	case IMX_MU_TYPE_TX:
		/*
		 * msg->hdr.size specifies the number of u32 words while
		 * sizeof yields bytes.
		 */

		if (size > max_size / 4) {
			/*
			 * The real message size can be different to
			 * struct imx_sc_rpc_msg_max/imx_s4_rpc_msg_max size
			 */
			dev_err(priv->dev, "Maximal message size (%u bytes) exceeded on TX; got: %i bytes\n", max_size, size << 2);
			return -EINVAL;
		}

		for (i = 0; i < num_tr && i < size; i++)
			imx_mu_write(priv, *arg++, priv->dcfg->xTR + (i % num_tr) * 4);
		for (; i < size; i++) {
			ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_TSR],
						 xsr,
						 xsr & IMX_MU_xSR_TEn(priv->dcfg->type, i % num_tr),
						 0, 100);
			if (ret) {
				dev_err(priv->dev, "Send data index: %d timeout\n", i);
				return ret;
			}
			imx_mu_write(priv, *arg++, priv->dcfg->xTR + (i % num_tr) * 4);
		}

		imx_mu_xcr_rmw(priv, IMX_MU_TCR, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx), 0);
		break;
	default:
		dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
		return -EINVAL;
	}

	return 0;
}