Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4a46395 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mhi: core: improve bandwidth switch events processing"

parents a0f82a4c 649971df
Loading
Loading
Loading
Loading
+25 −32
Original line number Diff line number Diff line
@@ -1437,29 +1437,12 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
	struct mhi_link_info link_info, *cur_info = &mhi_cntrl->mhi_link_info;
	int result, ret = 0;

	if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) {
		MHI_LOG("No EV access, PM_STATE:%s\n",
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
		ret = -EIO;
		goto exit_no_lock;
	}

	ret = __mhi_device_get_sync(mhi_cntrl);
	if (ret)
		goto exit_no_lock;

	mutex_lock(&mhi_cntrl->pm_mutex);

	spin_lock_bh(&mhi_event->lock);
	dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);

	if (ev_ring->rp == dev_rp) {
		spin_unlock_bh(&mhi_event->lock);
		read_lock_bh(&mhi_cntrl->pm_lock);
		mhi_cntrl->wake_put(mhi_cntrl, false);
		read_unlock_bh(&mhi_cntrl->pm_lock);
		MHI_VERB("no pending event found\n");
		goto exit_bw_process;
		goto exit_bw_scale_process;
	}

	/* if rp points to base, we need to wrap it around */
@@ -1467,6 +1450,13 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
		dev_rp = ev_ring->base + ev_ring->len;
	dev_rp--;

	/* fast forward to currently processed element and recycle er */
	ev_ring->rp = dev_rp;
	ev_ring->wp = dev_rp - 1;
	if (ev_ring->wp < ev_ring->base)
		ev_ring->wp = ev_ring->base + ev_ring->len - ev_ring->el_size;
	mhi_recycle_fwd_ev_ring_element(mhi_cntrl, ev_ring);

	MHI_ASSERT(MHI_TRE_GET_EV_TYPE(dev_rp) != MHI_PKT_TYPE_BW_REQ_EVENT,
		   "!BW SCALE REQ event");

@@ -1479,19 +1469,22 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
		 link_info.target_link_speed,
		 link_info.target_link_width);

	/* fast forward to currently processed element and recycle er */
	ev_ring->rp = dev_rp;
	ev_ring->wp = dev_rp - 1;
	if (ev_ring->wp < ev_ring->base)
		ev_ring->wp = ev_ring->base + ev_ring->len - ev_ring->el_size;
	mhi_recycle_fwd_ev_ring_element(mhi_cntrl, ev_ring);

	read_lock_bh(&mhi_cntrl->pm_lock);
	if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl)))
		mhi_ring_er_db(mhi_event);
	read_unlock_bh(&mhi_cntrl->pm_lock);
	spin_unlock_bh(&mhi_event->lock);

	atomic_inc(&mhi_cntrl->pending_pkts);
	ret = mhi_device_get_sync(mhi_cntrl->mhi_dev,
				  MHI_VOTE_DEVICE | MHI_VOTE_BUS);
	if (ret) {
		atomic_dec(&mhi_cntrl->pending_pkts);
		goto exit_bw_scale_process;
	}

	mutex_lock(&mhi_cntrl->pm_mutex);

	ret = mhi_cntrl->bw_scale(mhi_cntrl, &link_info);
	if (!ret)
		*cur_info = link_info;
@@ -1503,15 +1496,15 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
		mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bw_scale_db, 0,
				     MHI_BW_SCALE_RESULT(result,
				     link_info.sequence_num));

	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

exit_bw_process:
	mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS);
	atomic_dec(&mhi_cntrl->pending_pkts);

	mutex_unlock(&mhi_cntrl->pm_mutex);

exit_no_lock:
	MHI_VERB("exit er_index:%u\n", mhi_event->er_index);
exit_bw_scale_process:
	MHI_VERB("exit er_index:%u ret:%d\n", mhi_event->er_index, ret);

	return ret;
}