int mhi_prepare_for_power_up()

in mhi/core/init.c [1066:1138]


int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl)
{
	struct device *dev = &mhi_cntrl->mhi_dev->dev;
	u32 bhi_off, bhie_off;
	int ret;

	mutex_lock(&mhi_cntrl->pm_mutex);

	ret = mhi_init_dev_ctxt(mhi_cntrl);
	if (ret)
		goto error_dev_ctxt;

	ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs, BHIOFF, &bhi_off);
	if (ret) {
		dev_err(dev, "Error getting BHI offset\n");
		goto error_reg_offset;
	}

	if (bhi_off >= mhi_cntrl->reg_len) {
		dev_err(dev, "BHI offset: 0x%x is out of range: 0x%zx\n",
			bhi_off, mhi_cntrl->reg_len);
		ret = -EINVAL;
		goto error_reg_offset;
	}
	mhi_cntrl->bhi = mhi_cntrl->regs + bhi_off;

	if (mhi_cntrl->fbc_download || mhi_cntrl->rddm_size) {
		ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs, BHIEOFF,
				   &bhie_off);
		if (ret) {
			dev_err(dev, "Error getting BHIE offset\n");
			goto error_reg_offset;
		}

		if (bhie_off >= mhi_cntrl->reg_len) {
			dev_err(dev,
				"BHIe offset: 0x%x is out of range: 0x%zx\n",
				bhie_off, mhi_cntrl->reg_len);
			ret = -EINVAL;
			goto error_reg_offset;
		}
		mhi_cntrl->bhie = mhi_cntrl->regs + bhie_off;
	}

	if (mhi_cntrl->rddm_size) {
		/*
		 * This controller supports RDDM, so we need to manually clear
		 * BHIE RX registers since POR values are undefined.
		 */
		memset_io(mhi_cntrl->bhie + BHIE_RXVECADDR_LOW_OFFS,
			  0, BHIE_RXVECSTATUS_OFFS - BHIE_RXVECADDR_LOW_OFFS +
			  4);
		/*
		 * Allocate RDDM table for debugging purpose if specified
		 */
		mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image,
				     mhi_cntrl->rddm_size);
		if (mhi_cntrl->rddm_image)
			mhi_rddm_prepare(mhi_cntrl, mhi_cntrl->rddm_image);
	}

	mutex_unlock(&mhi_cntrl->pm_mutex);

	return 0;

error_reg_offset:
	mhi_deinit_dev_ctxt(mhi_cntrl);

error_dev_ctxt:
	mutex_unlock(&mhi_cntrl->pm_mutex);

	return ret;
}