All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/3] dt-bindings: remoteproc: qcom: Introduce shutdown-ack irq for Q6V5
@ 2019-01-08 10:23 Sibi Sankar
  2019-01-08 10:23 ` [PATCH v3 2/3] remoteproc: qcom: Add shutdown-ack irq Sibi Sankar
  2019-01-08 10:23 ` [PATCH v3 3/3] remoteproc: qcom: Wait for shutdown-ack/ind on sysmon shutdown Sibi Sankar
  0 siblings, 2 replies; 3+ messages in thread
From: Sibi Sankar @ 2019-01-08 10:23 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: robh+dt, andy.gross, david.brown, linux-arm-msm, linux-soc,
	devicetree, linux-kernel, tsoni, clew, akdwived, ohad,
	mark.rutland, linux-remoteproc, dianders, Sibi Sankar

Introduce shutdown-irq binding required for sysmon shutdown for Q6V5 MSS
on SDM845/MSM8996 SoCs and for WCSS Q6V5 on QCS404 SoC.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---

v2:
  * Make shutdown-ack mandatory for MSS on SDM845/MSM8996 and
    for WCSS on QCS404 (Dropping Rob's reviewed-by due to this)

 .../bindings/remoteproc/qcom,adsp.txt           | 17 ++++++++++++++---
 .../bindings/remoteproc/qcom,q6v5.txt           | 15 ++++++++++++---
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt
index 60ee0f73071a..292dfda9770d 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt
@@ -19,13 +19,24 @@ on the Qualcomm ADSP Hexagon core.
 - interrupts-extended:
 	Usage: required
 	Value type: <prop-encoded-array>
-	Definition: must list the watchdog, fatal IRQs ready, handover and
-		    stop-ack IRQs
+	Definition: reference to the interrupts that match interrupt-names
 
 - interrupt-names:
 	Usage: required
 	Value type: <stringlist>
-	Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack"
+	Definition: The interrupts needed depends on the compatible
+		    string:
+	qcom,msm8974-adsp-pil:
+	qcom,msm8996-adsp-pil:
+	qcom,msm8996-slpi-pil:
+	qcom,qcs404-adsp-pas:
+	qcom,qcs404-cdsp-pas:
+	qcom,sdm845-adsp-pas:
+	qcom,sdm845-cdsp-pas:
+		    must be "wdog", "fatal", "ready", "handover", "stop-ack"
+	qcom,qcs404-wcss-pas:
+		    must be "wdog", "fatal", "ready", "handover", "stop-ack",
+		    "shutdown-ack"
 
 - firmware-name:
 	Usage: optional
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
index 401e49ebee39..41ca5df5be5a 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
@@ -28,13 +28,22 @@ on the Qualcomm Hexagon core.
 - interrupts-extended:
 	Usage: required
 	Value type: <prop-encoded-array>
-	Definition: must list the watchdog, fatal IRQs ready, handover and
-		    stop-ack IRQs
+	Definition: reference to the interrupts that match interrupt-names
 
 - interrupt-names:
 	Usage: required
 	Value type: <stringlist>
-	Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack"
+	Definition: The interrupts needed depends on the the compatible
+		    string:
+	qcom,q6v5-pil:
+	qcom,ipq8074-wcss-pil:
+	qcom,msm8916-mss-pil:
+	qcom,msm8974-mss-pil:
+		    must be "wdog", "fatal", "ready", "handover", "stop-ack"
+	qcom,msm8996-mss-pil:
+	qcom,sdm845-mss-pil:
+		    must be "wdog", "fatal", "ready", "handover", "stop-ack",
+		    "shutdown-ack"
 
 - firmware-name:
 	Usage: optional
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v3 2/3] remoteproc: qcom: Add shutdown-ack irq
  2019-01-08 10:23 [PATCH v3 1/3] dt-bindings: remoteproc: qcom: Introduce shutdown-ack irq for Q6V5 Sibi Sankar
@ 2019-01-08 10:23 ` Sibi Sankar
  2019-01-08 10:23 ` [PATCH v3 3/3] remoteproc: qcom: Wait for shutdown-ack/ind on sysmon shutdown Sibi Sankar
  1 sibling, 0 replies; 3+ messages in thread
From: Sibi Sankar @ 2019-01-08 10:23 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: robh+dt, andy.gross, david.brown, linux-arm-msm, linux-soc,
	devicetree, linux-kernel, tsoni, clew, akdwived, ohad,
	mark.rutland, linux-remoteproc, dianders, Sibi Sankar

Add shutdown-ack irq handling required for sysmon shutdown for
Q6V5 MSS on SDM845/MSM8996 and for WCSS Q6V5 on QCS404 SoC.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---

v3:
   * Move shutdown-irq handling back to sysmon and
     modify qcom_add_sysmon_subdev to handle -EPROBE_DEFER
   * Dropped has_shutdown_irq flag

v2:
   * Move shutdown-irq get to Q6V5 from sysmon to handle
     -EPROBE_DEFER cases

 drivers/remoteproc/qcom_common.h    | 16 +++++----
 drivers/remoteproc/qcom_q6v5_adsp.c |  9 +++--
 drivers/remoteproc/qcom_q6v5_mss.c  |  4 ++-
 drivers/remoteproc/qcom_q6v5_pas.c  |  9 +++--
 drivers/remoteproc/qcom_sysmon.c    | 52 +++++++++++++++++++++++++----
 drivers/remoteproc/qcom_wcnss.c     |  5 ++-
 6 files changed, 73 insertions(+), 22 deletions(-)

diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h
index 58de71e4781c..afea598fdc9d 100644
--- a/drivers/remoteproc/qcom_common.h
+++ b/drivers/remoteproc/qcom_common.h
@@ -43,16 +43,18 @@ void qcom_add_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr,
 void qcom_remove_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr);
 
 #if IS_ENABLED(CONFIG_QCOM_SYSMON)
-struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
-					   const char *name,
-					   int ssctl_instance);
+int qcom_add_sysmon_subdev(struct rproc *rproc,
+			   struct qcom_sysmon *rproc_sysmon,
+			   const char *name,
+			   int ssctl_instance);
 void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon);
 #else
-static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
-							 const char *name,
-							 int ssctl_instance)
+static inline int qcom_add_sysmon_subdev(struct rproc *rproc,
+					 struct qcom_sysmon *rproc_sysmon,
+					 const char *name,
+					 int ssctl_instance)
 {
-	return NULL;
+	return 0;
 }
 
 static inline void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon)
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index 79374d1de311..e1db2c7a08bd 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -436,9 +436,12 @@ static int adsp_probe(struct platform_device *pdev)
 
 	qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
 	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
-	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
-					      desc->sysmon_name,
-					      desc->ssctl_id);
+	ret = qcom_add_sysmon_subdev(rproc,
+				     adsp->sysmon,
+				     desc->sysmon_name,
+				     desc->ssctl_id);
+	if (ret)
+		goto disable_pm;
 
 	ret = rproc_add(rproc);
 	if (ret)
diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index c86dc40cfb8c..7a256fdb2f64 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -1340,7 +1340,9 @@ static int q6v5_probe(struct platform_device *pdev)
 	qcom_add_glink_subdev(rproc, &qproc->glink_subdev);
 	qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
 	qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
-	qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
+	ret = qcom_add_sysmon_subdev(rproc, qproc->sysmon, "modem", 0x12);
+	if (ret)
+		goto free_rproc;
 
 	ret = rproc_add(rproc);
 	if (ret)
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index b1e63fcd5fdf..942804b5fafa 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -301,9 +301,12 @@ static int adsp_probe(struct platform_device *pdev)
 	qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
 	qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
 	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
-	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
-					      desc->sysmon_name,
-					      desc->ssctl_id);
+	ret = qcom_add_sysmon_subdev(rproc,
+				     adsp->sysmon,
+				     desc->sysmon_name,
+				     desc->ssctl_id);
+	if (ret)
+		goto free_rproc;
 
 	ret = rproc_add(rproc);
 	if (ret)
diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
index e976a602b015..b17727dfc271 100644
--- a/drivers/remoteproc/qcom_sysmon.c
+++ b/drivers/remoteproc/qcom_sysmon.c
@@ -6,8 +6,10 @@
 #include <linux/module.h>
 #include <linux/notifier.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/notifier.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/remoteproc/qcom_rproc.h>
@@ -25,6 +27,7 @@ struct qcom_sysmon {
 
 	const char *name;
 
+	int shutdown_irq;
 	int ssctl_version;
 	int ssctl_instance;
 
@@ -34,6 +37,7 @@ struct qcom_sysmon {
 
 	struct rpmsg_endpoint *ept;
 	struct completion comp;
+	struct completion shutdown_comp;
 	struct mutex lock;
 
 	bool ssr_ack;
@@ -432,24 +436,35 @@ static int sysmon_notify(struct notifier_block *nb, unsigned long event,
 	return NOTIFY_DONE;
 }
 
+static irqreturn_t sysmon_shutdown_interrupt(int irq, void *data)
+{
+	struct qcom_sysmon *sysmon = data;
+
+	complete(&sysmon->shutdown_comp);
+
+	return IRQ_HANDLED;
+}
+
 /**
  * qcom_add_sysmon_subdev() - create a sysmon subdev for the given remoteproc
  * @rproc:	rproc context to associate the subdev with
+ * @rproc_sysmon: update sysmon context with a new qcom_sysmon object
  * @name:	name of this subdev, to use in SSR
  * @ssctl_instance: instance id of the ssctl QMI service
  *
- * Return: A new qcom_sysmon object, or NULL on failure
+ * Return: 0 on success, negative errno on failure
  */
-struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
-					   const char *name,
-					   int ssctl_instance)
+int qcom_add_sysmon_subdev(struct rproc *rproc,
+			   struct qcom_sysmon *rproc_sysmon,
+			   const char *name,
+			   int ssctl_instance)
 {
 	struct qcom_sysmon *sysmon;
 	int ret;
 
 	sysmon = kzalloc(sizeof(*sysmon), GFP_KERNEL);
 	if (!sysmon)
-		return NULL;
+		return -ENOMEM;
 
 	sysmon->dev = rproc->dev.parent;
 	sysmon->rproc = rproc;
@@ -458,13 +473,35 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
 	sysmon->ssctl_instance = ssctl_instance;
 
 	init_completion(&sysmon->comp);
+	init_completion(&sysmon->shutdown_comp);
 	mutex_init(&sysmon->lock);
 
+	sysmon->shutdown_irq = of_irq_get_byname(sysmon->dev->of_node,
+						 "shutdown-ack");
+	if (sysmon->shutdown_irq < 0) {
+		if (sysmon->shutdown_irq != -ENODATA) {
+			dev_err(sysmon->dev,
+				"failed to retrieve shutdown-ack IRQ\n");
+			return sysmon->shutdown_irq;
+		}
+	} else {
+		ret = devm_request_threaded_irq(sysmon->dev,
+						sysmon->shutdown_irq,
+						NULL, sysmon_shutdown_interrupt,
+						IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+						"q6v5 shutdown-ack", sysmon);
+		if (ret) {
+			dev_err(sysmon->dev,
+				"failed to acquire shutdown-ack IRQ\n");
+			return ret;
+		}
+	}
+
 	ret = qmi_handle_init(&sysmon->qmi, SSCTL_MAX_MSG_LEN, &ssctl_ops, NULL);
 	if (ret < 0) {
 		dev_err(sysmon->dev, "failed to initialize qmi handle\n");
 		kfree(sysmon);
-		return NULL;
+		return ret;
 	}
 
 	qmi_add_lookup(&sysmon->qmi, 43, 0, 0);
@@ -480,8 +517,9 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
 	mutex_lock(&sysmon_lock);
 	list_add(&sysmon->node, &sysmon_list);
 	mutex_unlock(&sysmon_lock);
+	rproc_sysmon = sysmon;
 
-	return sysmon;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(qcom_add_sysmon_subdev);
 
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
index 1152da49a18a..920e85202c5e 100644
--- a/drivers/remoteproc/qcom_wcnss.c
+++ b/drivers/remoteproc/qcom_wcnss.c
@@ -552,7 +552,10 @@ static int wcnss_probe(struct platform_device *pdev)
 	}
 
 	qcom_add_smd_subdev(rproc, &wcnss->smd_subdev);
-	wcnss->sysmon = qcom_add_sysmon_subdev(rproc, "wcnss", WCNSS_SSCTL_ID);
+	ret = qcom_add_sysmon_subdev(rproc, wcnss->sysmon,
+				     "wcnss", WCNSS_SSCTL_ID);
+	if (ret)
+		goto free_rproc;
 
 	ret = rproc_add(rproc);
 	if (ret)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v3 3/3] remoteproc: qcom: Wait for shutdown-ack/ind on sysmon shutdown
  2019-01-08 10:23 [PATCH v3 1/3] dt-bindings: remoteproc: qcom: Introduce shutdown-ack irq for Q6V5 Sibi Sankar
  2019-01-08 10:23 ` [PATCH v3 2/3] remoteproc: qcom: Add shutdown-ack irq Sibi Sankar
@ 2019-01-08 10:23 ` Sibi Sankar
  1 sibling, 0 replies; 3+ messages in thread
From: Sibi Sankar @ 2019-01-08 10:23 UTC (permalink / raw)
  To: bjorn.andersson
  Cc: robh+dt, andy.gross, david.brown, linux-arm-msm, linux-soc,
	devicetree, linux-kernel, tsoni, clew, akdwived, ohad,
	mark.rutland, linux-remoteproc, dianders, Sibi Sankar

After sending a sysmon shutdown request to the SSCTL service on the
subsystem, wait for the service to send shutdown-ack interrupt or
an indication message to signal the completion of graceful shutdown.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---

v2:
   * Correct the shutdown-irq wait time to 10 * HZ

 drivers/remoteproc/qcom_sysmon.c | 42 +++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
index b17727dfc271..19b732e1427d 100644
--- a/drivers/remoteproc/qcom_sysmon.c
+++ b/drivers/remoteproc/qcom_sysmon.c
@@ -37,6 +37,7 @@ struct qcom_sysmon {
 
 	struct rpmsg_endpoint *ept;
 	struct completion comp;
+	struct completion ind_comp;
 	struct completion shutdown_comp;
 	struct mutex lock;
 
@@ -141,6 +142,7 @@ static int sysmon_callback(struct rpmsg_device *rpdev, void *data, int count,
 }
 
 #define SSCTL_SHUTDOWN_REQ		0x21
+#define SSCTL_SHUTDOWN_READY_IND	0x21
 #define SSCTL_SUBSYS_EVENT_REQ		0x23
 
 #define SSCTL_MAX_MSG_LEN		7
@@ -256,6 +258,29 @@ static struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
 	{}
 };
 
+static struct qmi_elem_info ssctl_shutdown_ind_ei[] = {
+	{}
+};
+
+static void sysmon_ind_cb(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
+			  struct qmi_txn *txn, const void *data)
+{
+	struct qcom_sysmon *sysmon = container_of(qmi, struct qcom_sysmon, qmi);
+
+	complete(&sysmon->ind_comp);
+}
+
+static struct qmi_msg_handler qmi_indication_handler[] = {
+	{
+		.type = QMI_INDICATION,
+		.msg_id = SSCTL_SHUTDOWN_READY_IND,
+		.ei = ssctl_shutdown_ind_ei,
+		.decoded_size = 0,
+		.fn = sysmon_ind_cb
+	},
+	{}
+};
+
 /**
  * ssctl_request_shutdown() - request shutdown via SSCTL QMI service
  * @sysmon:	sysmon context
@@ -266,6 +291,8 @@ static void ssctl_request_shutdown(struct qcom_sysmon *sysmon)
 	struct qmi_txn txn;
 	int ret;
 
+	reinit_completion(&sysmon->ind_comp);
+	reinit_completion(&sysmon->shutdown_comp);
 	ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_shutdown_resp_ei, &resp);
 	if (ret < 0) {
 		dev_err(sysmon->dev, "failed to allocate QMI txn\n");
@@ -287,6 +314,17 @@ static void ssctl_request_shutdown(struct qcom_sysmon *sysmon)
 		dev_err(sysmon->dev, "shutdown request failed\n");
 	else
 		dev_dbg(sysmon->dev, "shutdown request completed\n");
+
+	if (sysmon->shutdown_irq > 0) {
+		ret = wait_for_completion_timeout(&sysmon->shutdown_comp,
+						  10 * HZ);
+		if (!ret) {
+			ret = try_wait_for_completion(&sysmon->ind_comp);
+			if (!ret)
+				dev_err(sysmon->dev,
+					"timeout waiting for shutdown ack\n");
+		}
+	}
 }
 
 /**
@@ -473,6 +511,7 @@ int qcom_add_sysmon_subdev(struct rproc *rproc,
 	sysmon->ssctl_instance = ssctl_instance;
 
 	init_completion(&sysmon->comp);
+	init_completion(&sysmon->ind_comp);
 	init_completion(&sysmon->shutdown_comp);
 	mutex_init(&sysmon->lock);
 
@@ -497,7 +536,8 @@ int qcom_add_sysmon_subdev(struct rproc *rproc,
 		}
 	}
 
-	ret = qmi_handle_init(&sysmon->qmi, SSCTL_MAX_MSG_LEN, &ssctl_ops, NULL);
+	ret = qmi_handle_init(&sysmon->qmi, SSCTL_MAX_MSG_LEN, &ssctl_ops,
+			      qmi_indication_handler);
 	if (ret < 0) {
 		dev_err(sysmon->dev, "failed to initialize qmi handle\n");
 		kfree(sysmon);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-01-08 10:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-08 10:23 [PATCH v3 1/3] dt-bindings: remoteproc: qcom: Introduce shutdown-ack irq for Q6V5 Sibi Sankar
2019-01-08 10:23 ` [PATCH v3 2/3] remoteproc: qcom: Add shutdown-ack irq Sibi Sankar
2019-01-08 10:23 ` [PATCH v3 3/3] remoteproc: qcom: Wait for shutdown-ack/ind on sysmon shutdown Sibi Sankar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.