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;
}