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

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

Merge "rpmsg: glink: wait for intent request completion"

parents 26bd2a4e 7d97944f
Loading
Loading
Loading
Loading
+47 −15
Original line number Diff line number Diff line
@@ -198,8 +198,10 @@ enum {
 * @open_req:	completed once open-request has been received
 * @intent_req_lock: Synchronises multiple intent requests
 * @intent_req_result: Result of intent request
 * @intent_req_comp: Status of intent request completion
 * @intent_req_event: Waitqueue for @intent_req_comp
 * @intent_req_acked: Status of intent request acknowledgment
 * @intent_req_completed: Status of intent request completion
 * @intent_req_ack: Waitqueue for @intent_req_acked
 * @intent_req_comp: Waitqueue for @intent_req_completed
 * @lsigs:	local side signals
 * @rsigs:	remote side signals
 */
@@ -233,8 +235,10 @@ struct glink_channel {
	struct mutex intent_req_lock;
	bool intent_req_result;
	bool channel_ready;
	atomic_t intent_req_comp;
	wait_queue_head_t intent_req_event;
	atomic_t intent_req_acked;
	atomic_t intent_req_completed;
	wait_queue_head_t intent_req_ack;
	wait_queue_head_t intent_req_comp;

	unsigned int lsigs;
	unsigned int rsigs;
@@ -288,8 +292,10 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,

	init_completion(&channel->open_req);
	init_completion(&channel->open_ack);
	atomic_set(&channel->intent_req_comp, 0);
	init_waitqueue_head(&channel->intent_req_event);
	atomic_set(&channel->intent_req_acked, 0);
	atomic_set(&channel->intent_req_completed, 0);
	init_waitqueue_head(&channel->intent_req_ack);
	init_waitqueue_head(&channel->intent_req_comp);

	INIT_LIST_HEAD(&channel->done_intents);
	kthread_init_work(&channel->intent_work, qcom_glink_rx_done_work);
@@ -312,8 +318,10 @@ static void qcom_glink_channel_release(struct kref *ref)

	CH_INFO(channel, "\n");
	channel->intent_req_result = false;
	atomic_inc(&channel->intent_req_comp);
	wake_up(&channel->intent_req_event);
	atomic_inc(&channel->intent_req_acked);
	wake_up(&channel->intent_req_ack);
	atomic_inc(&channel->intent_req_completed);
	wake_up(&channel->intent_req_comp);

	/* cancel pending rx_done work */
	kthread_cancel_work_sync(&channel->intent_work);
@@ -504,8 +512,8 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
	}

	channel->intent_req_result = granted;
	atomic_inc(&channel->intent_req_comp);
	wake_up(&channel->intent_req_event);
	atomic_inc(&channel->intent_req_acked);
	wake_up(&channel->intent_req_ack);
	CH_INFO(channel, "\n");
}

@@ -1144,6 +1152,9 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
			dev_err(glink->dev, "failed to store remote intent\n");
	}

	atomic_inc(&channel->intent_req_completed);
	wake_up(&channel->intent_req_comp);

	kfree(msg);
	qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
}
@@ -1537,7 +1548,8 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,

	mutex_lock(&channel->intent_req_lock);

	atomic_set(&channel->intent_req_comp, 0);
	atomic_set(&channel->intent_req_acked, 0);
	atomic_set(&channel->intent_req_completed, 0);

	cmd.id = RPM_CMD_RX_INTENT_REQ;
	cmd.cid = channel->lcid;
@@ -1549,11 +1561,11 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
	if (ret)
		goto unlock;

	ret = wait_event_timeout(channel->intent_req_event,
				 atomic_read(&channel->intent_req_comp) ||
	ret = wait_event_timeout(channel->intent_req_ack,
				 atomic_read(&channel->intent_req_acked) ||
				 atomic_read(&glink->in_reset), 10 * HZ);
	if (!ret) {
		dev_err(glink->dev, "intent request timed out\n");
		dev_err(glink->dev, "intent request ack timed out\n");
		ret = -ETIMEDOUT;
	} else if (atomic_read(&glink->in_reset)) {
		CH_INFO(channel, "ssr detected\n");
@@ -1614,6 +1626,25 @@ static int __qcom_glink_send(struct glink_channel *channel,
			ret = qcom_glink_request_intent(glink, channel, len);
			if (ret < 0)
				return ret;

			/*Wait for intents to arrive*/
			ret = wait_event_timeout(channel->intent_req_comp,
				atomic_read(&channel->intent_req_completed) ||
				atomic_read(&glink->in_reset), 10 * HZ);

			if (!ret) {
				dev_err(glink->dev,
				    "intent request completion timed out\n");
				ret = -ETIMEDOUT;
			} else if (atomic_read(&glink->in_reset)) {
				CH_INFO(channel, "ssr detected\n");
				ret = -ECONNRESET;
			} else {
				ret = channel->intent_req_result ? 0 : -ECANCELED;
			}

			if (ret < 0)
				return ret;
		}

		iid = intent->id;
@@ -2041,7 +2072,8 @@ static void qcom_glink_notif_reset(void *data)

	spin_lock_irqsave(&glink->idr_lock, flags);
	idr_for_each_entry(&glink->lcids, channel, cid) {
		wake_up(&channel->intent_req_event);
		wake_up(&channel->intent_req_ack);
		wake_up(&channel->intent_req_comp);
	}
	spin_unlock_irqrestore(&glink->idr_lock, flags);
}