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

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

Merge "mhi: core: Enable both time synchronization methods to co-exist"

parents db155d43 798e407b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -346,6 +346,9 @@ void mhi_destroy_sysfs(struct mhi_controller *mhi_cntrl)
		}
		spin_unlock(&mhi_tsync->lock);

		if (mhi_tsync->db_response_pending)
			complete(&mhi_tsync->db_completion);

		kfree(mhi_cntrl->mhi_tsync);
		mhi_cntrl->mhi_tsync = NULL;
		mutex_unlock(&mhi_cntrl->tsync_mutex);
+2 −0
Original line number Diff line number Diff line
@@ -727,8 +727,10 @@ struct mhi_timesync {
	void __iomem *time_reg;
	u32 int_sequence;
	u64 local_time;
	u64 remote_time;
	bool db_support;
	bool db_response_pending;
	struct completion db_completion;
	spinlock_t lock; /* list protection */
	struct list_head head;
};
+49 −21
Original line number Diff line number Diff line
@@ -1402,6 +1402,10 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl,
	if (unlikely(mhi_tsync->int_sequence != sequence)) {
		MHI_ASSERT(1, "Unexpected response:0x%llx Expected:0x%llx\n",
			   sequence, mhi_tsync->int_sequence);

		mhi_device_put(mhi_cntrl->mhi_dev,
			       MHI_VOTE_DEVICE | MHI_VOTE_BUS);

		mutex_unlock(&mhi_cntrl->tsync_mutex);
		goto exit_tsync_process;
	}
@@ -1427,6 +1431,11 @@ int mhi_process_tsync_ev_ring(struct mhi_controller *mhi_cntrl,
	} while (true);

	mhi_tsync->db_response_pending = false;
	mhi_tsync->remote_time = remote_time;
	complete(&mhi_tsync->db_completion);

	mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS);

	mutex_unlock(&mhi_cntrl->tsync_mutex);

exit_tsync_process:
@@ -1484,13 +1493,10 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
	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);
	if (ret)
		goto exit_bw_scale_process;
	}

	mutex_lock(&mhi_cntrl->pm_mutex);

@@ -1508,7 +1514,6 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
	read_unlock_bh(&mhi_cntrl->pm_lock);

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

@@ -2502,13 +2507,37 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
{
	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
	struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync;
	u64 local_time;
	int ret;

	mutex_lock(&mhi_cntrl->tsync_mutex);
	/* not all devices support time features */
	if (!mhi_tsync) {
		ret = -EIO;
		goto error_unlock;
	if (!mhi_tsync)
		return -EINVAL;

	if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) {
		MHI_ERR("MHI is not in active state, pm_state:%s\n",
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
		return -EIO;
	}

	mutex_lock(&mhi_cntrl->tsync_mutex);

	/* return times from last async request completion */
	if (mhi_tsync->db_response_pending) {
		local_time = mhi_tsync->local_time;
		mutex_unlock(&mhi_cntrl->tsync_mutex);

		ret = wait_for_completion_timeout(&mhi_tsync->db_completion,
				       msecs_to_jiffies(mhi_cntrl->timeout_ms));
		if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || !ret) {
			MHI_ERR("Pending DB request did not complete, abort\n");
			return -EAGAIN;
		}

		*t_host = local_time;
		*t_dev = mhi_tsync->remote_time;

		return 0;
	}

	/* bring to M0 state */
@@ -2581,14 +2610,13 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev,
	int ret = 0;

	/* not all devices support all time features */
	if (!mhi_tsync || !mhi_tsync->db_support)
		return -EINVAL;

	mutex_lock(&mhi_cntrl->tsync_mutex);
	if (!mhi_tsync || !mhi_tsync->db_support) {
		ret = -EIO;
		goto error_unlock;
	}

	/* tsync db can only be rung in M0 state */
	ret = __mhi_device_get_sync(mhi_cntrl);
	ret = mhi_device_get_sync(mhi_cntrl->mhi_dev,
				  MHI_VOTE_DEVICE | MHI_VOTE_BUS);
	if (ret)
		goto error_unlock;

@@ -2656,21 +2684,21 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev,
	MHI_VERB("time DB request with seq:0x%llx\n", mhi_tsync->int_sequence);

	mhi_tsync->db_response_pending = true;
	init_completion(&mhi_tsync->db_completion);

skip_tsync_db:
	spin_lock(&mhi_tsync->lock);
	list_add_tail(&tsync_node->node, &mhi_tsync->head);
	spin_unlock(&mhi_tsync->lock);

	ret = 0;
	mutex_unlock(&mhi_cntrl->tsync_mutex);

	return 0;

error_invalid_state:
	if (ret)
	kfree(tsync_node);
error_no_mem:
	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);
	mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS);
error_unlock:
	mutex_unlock(&mhi_cntrl->tsync_mutex);
	return ret;
+5 −2
Original line number Diff line number Diff line
@@ -1241,6 +1241,7 @@ int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_client)
	int ret;
	enum MHI_PM_STATE new_state;
	struct mhi_chan *itr, *tmp;
	struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;

	read_lock_bh(&mhi_cntrl->pm_lock);
	if (mhi_cntrl->pm_state == MHI_PM_DISABLE) {
@@ -1255,7 +1256,8 @@ int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_client)
	read_unlock_bh(&mhi_cntrl->pm_lock);

	/* do a quick check to see if any pending votes to keep us busy */
	if (atomic_read(&mhi_cntrl->pending_pkts)) {
	if (atomic_read(&mhi_cntrl->pending_pkts) ||
	    atomic_read(&mhi_dev->bus_vote)) {
		MHI_VERB("Busy, aborting M3\n");
		return -EBUSY;
	}
@@ -1274,7 +1276,8 @@ int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_client)
	 * Check the votes once more to see if we should abort
	 * suspend.
	 */
	if (atomic_read(&mhi_cntrl->pending_pkts)) {
	if (atomic_read(&mhi_cntrl->pending_pkts) ||
	    atomic_read(&mhi_dev->bus_vote)) {
		MHI_VERB("Busy, aborting M3\n");
		ret = -EBUSY;
		goto error_suspend;