int slim_do_transfer()

in messaging.c [110:176]


int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
{
	DECLARE_COMPLETION_ONSTACK(done);
	bool need_tid = false, clk_pause_msg = false;
	int ret, timeout;

	/*
	 * do not vote for runtime-PM if the transactions are part of clock
	 * pause sequence
	 */
	if (ctrl->sched.clk_state == SLIM_CLK_ENTERING_PAUSE &&
		(txn->mt == SLIM_MSG_MT_CORE &&
		 txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
		 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
		clk_pause_msg = true;

	if (!clk_pause_msg) {
		ret = pm_runtime_get_sync(ctrl->dev);
		if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
			dev_err(ctrl->dev, "ctrl wrong state:%d, ret:%d\n",
				ctrl->sched.clk_state, ret);
			goto slim_xfer_err;
		}
	}
	/* Initialize tid to invalid value */
	txn->tid = 0;
	need_tid = slim_tid_txn(txn->mt, txn->mc);

	if (need_tid) {
		ret = slim_alloc_txn_tid(ctrl, txn);
		if (ret)
			return ret;

		if (!txn->msg->comp)
			txn->comp = &done;
		else
			txn->comp = txn->comp;
	}

	ret = ctrl->xfer_msg(ctrl, txn);

	if (!ret && need_tid && !txn->msg->comp) {
		unsigned long ms = txn->rl + HZ;

		timeout = wait_for_completion_timeout(txn->comp,
						      msecs_to_jiffies(ms));
		if (!timeout) {
			ret = -ETIMEDOUT;
			slim_free_txn_tid(ctrl, txn);
		}
	}

	if (ret)
		dev_err(ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
			txn->mt, txn->mc, txn->la, ret);

slim_xfer_err:
	if (!clk_pause_msg && (txn->tid == 0  || ret == -ETIMEDOUT)) {
		/*
		 * remove runtime-pm vote if this was TX only, or
		 * if there was error during this transaction
		 */
		pm_runtime_mark_last_busy(ctrl->dev);
		pm_runtime_put_autosuspend(ctrl->dev);
	}
	return ret;
}