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

Commit d8f08466 authored by Isaac J. Manjarres's avatar Isaac J. Manjarres
Browse files

soc: qcom: pil: Allow timeouts for graceful subsystem shutdown



Currently, if a subsystem does not send a response through QMI
confirming that it has properly gone through its shutdown
sequence within a certain time, it is assumed that something
went wrong, and the subsystem could not shutdown gracefully.
However, for some subsystems, part of their shutdown sequence
may involve disabling the QMI service prior to sending the
response, and continuing the rest of the shutdown sequence
without any problems. The real indicator of an issue is not
receiving either an SMP2P interrupt or an QMI indication that
the subsystem has shutdown. Allow for timeouts to be
an acceptable cause of a graceful shutdown sequence, and wait
for either an SMP2P interrupt or QMI indication that indicate
whether the device has shutdown or not.

Change-Id: Id870f948f5e99a999965cf83ca225788e01eaf2e
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent 0274d931
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -814,7 +814,7 @@ int wait_for_shutdown_ack(struct subsys_desc *desc)
	int ret;
	struct subsys_device *dev;

	if (!desc || !desc->shutdown_ack_irq)
	if (!desc)
		return 0;

	dev = find_subsys_device(desc->name);
+14 −22
Original line number Diff line number Diff line
@@ -71,7 +71,6 @@ struct sysmon_qmi_data {
	struct notifier_block notifier;
	void *notif_handle;
	bool legacy_version;
	struct completion ind_recv;
	struct sockaddr_qrtr ssctl;
	struct list_head list;
};
@@ -99,8 +98,13 @@ static void sysmon_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
	struct sysmon_qmi_data *qmi_data = container_of(qmi,
					struct sysmon_qmi_data, clnt_handle);

	struct subsys_device *subsys_dev = find_subsys_device(qmi_data->name);
	pr_info("%s: Indication received from subsystem\n", qmi_data->name);
	complete(&qmi_data->ind_recv);
	if (subsys_dev)
		complete_shutdown_ack(subsys_dev);
	else
		pr_err("Failed to find subsystem: %s for indication\n",
		       qmi_data->name);
}

static struct qmi_msg_handler qmi_indication_handler[] = {
@@ -400,8 +404,6 @@ int sysmon_send_shutdown(struct subsys_desc *dest_desc)
	if (!data->connected)
		return -EAGAIN;

	reinit_completion(&data->ind_recv);

	ret = qmi_txn_init(&data->clnt_handle, &txn,
			qmi_ssctl_shutdown_resp_msg_ei,
			&resp);
@@ -428,11 +430,11 @@ int sysmon_send_shutdown(struct subsys_desc *dest_desc)
	if (ret < 0) {
		pr_err("SYSMON QMI txn wait failed to dest %s, ret - %d\n",
			dest_ss, ret);
		goto out;
	}

	/* Check the response */
	if (QMI_RESP_BIT_SHIFT(resp.resp.result) != QMI_RESULT_SUCCESS_V01) {
	if (ret != -ETIMEDOUT && QMI_RESP_BIT_SHIFT(resp.resp.result) !=
	    QMI_RESULT_SUCCESS_V01) {
		pr_err("SYSMON QMI request failed 0x%x\n",
					QMI_RESP_BIT_SHIFT(resp.resp.error));
		ret = -EREMOTEIO;
@@ -440,21 +442,13 @@ int sysmon_send_shutdown(struct subsys_desc *dest_desc)
	}

	shutdown_ack_ret = wait_for_shutdown_ack(dest_desc);
	if (shutdown_ack_ret < 0) {
		pr_err("shutdown_ack SMP2P bit for %s not set\n", data->name);
		if (!data->ind_recv.done) {
			pr_err("QMI shutdown indication not received\n");
			ret = shutdown_ack_ret;
		}
	if (shutdown_ack_ret > 0) {
		ret = 0;
		goto out;
	} else if (shutdown_ack_ret > 0)
		goto out;

	if (!wait_for_completion_timeout(&data->ind_recv,
					msecs_to_jiffies(SHUTDOWN_TIMEOUT))) {
		pr_err("Timed out waiting for shutdown indication from %s\n",
	} else if (shutdown_ack_ret < 0) {
		pr_err("shutdown acknowledgment not received for %s\n",
		       data->name);
		ret = -ETIMEDOUT;
		ret = shutdown_ack_ret;
	}
out:
	return ret;
@@ -651,8 +645,6 @@ int sysmon_notifier_register(struct subsys_desc *desc)
		goto add_list;
	}

	init_completion(&data->ind_recv);

	rc = qmi_handle_init(&data->clnt_handle,
			QMI_SSCTL_RESP_MSG_LENGTH, &ssctl_ops,
			qmi_indication_handler);