static int qcom_slim_ngd_power_up()

in qcom-ngd-ctrl.c [1098:1153]


static int qcom_slim_ngd_power_up(struct qcom_slim_ngd_ctrl *ctrl)
{
	enum qcom_slim_ngd_state cur_state = ctrl->state;
	struct qcom_slim_ngd *ngd = ctrl->ngd;
	u32 laddr, rx_msgq;
	int timeout, ret = 0;

	if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN) {
		timeout = wait_for_completion_timeout(&ctrl->qmi.qmi_comp, HZ);
		if (!timeout)
			return -EREMOTEIO;
	}

	if (ctrl->state == QCOM_SLIM_NGD_CTRL_ASLEEP ||
		ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN) {
		ret = qcom_slim_qmi_power_request(ctrl, true);
		if (ret) {
			dev_err(ctrl->dev, "SLIM QMI power request failed:%d\n",
					ret);
			return ret;
		}
	}

	ctrl->ver = readl_relaxed(ctrl->base);
	/* Version info in 16 MSbits */
	ctrl->ver >>= 16;

	laddr = readl_relaxed(ngd->base + NGD_STATUS);
	if (laddr & NGD_LADDR) {
		/*
		 * external MDM restart case where ADSP itself was active framer
		 * For example, modem restarted when playback was active
		 */
		if (cur_state == QCOM_SLIM_NGD_CTRL_AWAKE) {
			dev_info(ctrl->dev, "Subsys restart: ADSP active framer\n");
			return 0;
		}
		qcom_slim_ngd_setup(ctrl);
		return 0;
	}

	writel_relaxed(DEF_NGD_INT_MASK, ngd->base + NGD_INT_EN);
	rx_msgq = readl_relaxed(ngd->base + NGD_RX_MSGQ_CFG);

	writel_relaxed(rx_msgq|SLIM_RX_MSGQ_TIMEOUT_VAL,
				ngd->base + NGD_RX_MSGQ_CFG);
	qcom_slim_ngd_setup(ctrl);

	timeout = wait_for_completion_timeout(&ctrl->reconf, HZ);
	if (!timeout) {
		dev_err(ctrl->dev, "capability exchange timed-out\n");
		return -ETIMEDOUT;
	}

	return 0;
}