Browse Source

dsp: Defer clients probe, when audio notify probe is not complete.

Audio notify probe is defer and PDR state change is not happening before
the clients calls to audio_notifier_register(). Due to this the
service_data[service][domain].state remains as UNINIT_SERVICE (where service is
PDR domain is ADSP) and due to this audio_notifier_reg_client() return success
without registering to PDR service, which is incorrect. To avoid this, will
defer the client probes when the audio notify probe is incomplete.

Change-Id: Ib96bdb24dd92ea8b81a0201a7b48e917c7b1403c
Signed-off-by: Prasad Kumpatla <[email protected]>
Prasad Kumpatla 2 years ago
parent
commit
e569b3b05e
5 changed files with 57 additions and 2 deletions
  1. 33 2
      dsp/audio_notifier.c
  2. 6 0
      dsp/audio_prm.c
  3. 5 0
      include/dsp/audio_notifier.h
  4. 7 0
      ipc/gpr-lite.c
  5. 6 0
      soc/pinctrl-lpi.c

+ 33 - 2
dsp/audio_notifier.c

@@ -31,6 +31,7 @@ static struct platform_device *adsp_private;
 
 struct adsp_notify_private {
 	struct rproc *rproc_h;
+	bool notifier_probe_complete;
 };
 
 /*
@@ -321,8 +322,12 @@ static int audio_notifier_reg_client(struct client_data *client_data)
 	/* Search through services to find a valid one to register client on. */
 	for (; service >= 0; service--) {
 		/* If a service is not initialized, wait for it to come up. */
-		if (service_data[service][domain].state == UNINIT_SERVICE)
+		if (service_data[service][domain].state == UNINIT_SERVICE) {
+			pr_err_ratelimited("%s: failed in client registration to PDR\n",
+				 __func__);
+			ret = -EINVAL;
 			goto done;
+		}
 		/* Skip unsupported service and domain combinations. */
 		if (service_data[service][domain].state < 0)
 			continue;
@@ -456,7 +461,7 @@ static int audio_notifier_service_cb(unsigned long opcode,
 	data.service = service;
 	data.domain = domain;
 
-	pr_debug("%s: service %s, opcode 0x%lx\n",
+	pr_info("%s: service %s, opcode 0x%lx\n",
 		__func__, service_data[service][domain].name, notifier_opcode);
 
 	mutex_lock(&notifier_mutex);
@@ -608,6 +613,29 @@ static int audio_notifier_late_init(void)
 	return 0;
 }
 
+bool audio_notifier_probe_status(void)
+{
+	struct adsp_notify_private *priv = NULL;
+	struct platform_device *pdev = NULL;
+
+	if (!adsp_private)
+		goto exit;
+
+	pdev = adsp_private;
+	priv = platform_get_drvdata(pdev);
+	if (!priv) {
+		dev_err(&pdev->dev," %s: Private data get failed\n", __func__);
+		goto exit;
+	}
+	if (priv->notifier_probe_complete) {
+		dev_dbg(&pdev->dev, "%s: audio notify probe successfully completed\n",
+			__func__);
+		return true;
+	}
+exit:
+	return false;
+}
+EXPORT_SYMBOL(audio_notifier_probe_status);
 
 static int audio_notify_probe(struct platform_device *pdev)
 {
@@ -623,6 +651,7 @@ static int audio_notify_probe(struct platform_device *pdev)
 		ret = -ENOMEM;
 		return ret;
 	}
+	priv->notifier_probe_complete = false;
 	platform_set_drvdata(pdev, priv);
 	prop = of_find_property(pdev->dev.of_node, "qcom,rproc-handle", &size);
 	if (!prop) {
@@ -646,6 +675,8 @@ static int audio_notify_probe(struct platform_device *pdev)
 	/* Do not return error since PDR enablement is not critical */
 	audio_notifier_late_init();
 
+	priv->notifier_probe_complete = true;
+
 	return 0;
 }
 

+ 6 - 0
dsp/audio_prm.c

@@ -502,6 +502,12 @@ static int audio_prm_probe(struct gpr_device *adev)
 {
 	int ret = 0;
 
+	if (!audio_notifier_probe_status()) {
+		pr_err("%s: Audio notify probe not completed, defer audio prm probe\n",
+				__func__);
+		return -EPROBE_DEFER;
+	}
+
 	ret = audio_notifier_register("audio_prm", AUDIO_NOTIFIER_ADSP_DOMAIN,
 				      &service_nb);
 	if (ret < 0) {

+ 5 - 0
include/dsp/audio_notifier.h

@@ -78,6 +78,7 @@ int audio_notifier_register(char *client_name, int domain,
  *		Error: -#
  */
 int audio_notifier_deregister(char *client_name);
+bool audio_notifier_probe_status(void);
 
 #else
 
@@ -92,6 +93,10 @@ static inline int audio_notifier_deregister(char *client_name)
 	return 0;
 }
 
+static inline bool audio_notifier_probe_status(void)
+{
+	return 0;
+}
 #endif /* CONFIG_MSM_QDSP6_NOTIFIER */
 
 #endif

+ 7 - 0
ipc/gpr-lite.c

@@ -492,6 +492,13 @@ static int gpr_probe(struct rpmsg_device *rpdev)
 {
 	struct device *dev = &rpdev->dev;
 	int ret;
+
+	if (!audio_notifier_probe_status()) {
+		pr_err("%s: Audio notify probe not completed, defer audio gpr probe\n",
+			__func__);
+		return -EPROBE_DEFER;
+	}
+
 	gpr_priv = devm_kzalloc(dev, sizeof(*gpr_priv), GFP_KERNEL);
 	if (!gpr_priv)
 		return -ENOMEM;

+ 6 - 0
soc/pinctrl-lpi.c

@@ -664,6 +664,12 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
 	struct clk *lpass_core_hw_vote = NULL;
 	struct clk *lpass_audio_hw_vote = NULL;
 
+	if (!audio_notifier_probe_status()) {
+		pr_err("%s: Audio notify probe not completed, defer lpi pinctrl probe\n",
+					__func__);
+		return -EPROBE_DEFER;
+	}
+
 	ret = of_property_read_u32(dev->of_node, "reg", &reg);
 	if (ret < 0) {
 		dev_err(dev, "missing base address\n");