static irqreturn_t imx_mu_isr()

in imx-mailbox.c [285:338]


static irqreturn_t imx_mu_isr(int irq, void *p)
{
	struct mbox_chan *chan = p;
	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
	struct imx_mu_con_priv *cp = chan->con_priv;
	u32 val, ctrl;

	switch (cp->type) {
	case IMX_MU_TYPE_TX:
		ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_TCR]);
		val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_TSR]);
		val &= IMX_MU_xSR_TEn(priv->dcfg->type, cp->idx) &
			(ctrl & IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));
		break;
	case IMX_MU_TYPE_RX:
		ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_RCR]);
		val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_RSR]);
		val &= IMX_MU_xSR_RFn(priv->dcfg->type, cp->idx) &
			(ctrl & IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx));
		break;
	case IMX_MU_TYPE_RXDB:
		ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_GIER]);
		val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_GSR]);
		val &= IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx) &
			(ctrl & IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx));
		break;
	default:
		dev_warn_ratelimited(priv->dev, "Unhandled channel type %d\n",
				     cp->type);
		return IRQ_NONE;
	}

	if (!val)
		return IRQ_NONE;

	if ((val == IMX_MU_xSR_TEn(priv->dcfg->type, cp->idx)) &&
	    (cp->type == IMX_MU_TYPE_TX)) {
		imx_mu_xcr_rmw(priv, IMX_MU_TCR, 0, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));
		mbox_chan_txdone(chan, 0);
	} else if ((val == IMX_MU_xSR_RFn(priv->dcfg->type, cp->idx)) &&
		   (cp->type == IMX_MU_TYPE_RX)) {
		priv->dcfg->rx(priv, cp);
	} else if ((val == IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx)) &&
		   (cp->type == IMX_MU_TYPE_RXDB)) {
		imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),
			     priv->dcfg->xSR[IMX_MU_GSR]);
		mbox_chan_received_data(chan, NULL);
	} else {
		dev_warn_ratelimited(priv->dev, "Not handled interrupt\n");
		return IRQ_NONE;
	}

	return IRQ_HANDLED;
}