Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
To: lgirdwood@gmail.com, broonie@kernel.org
Cc: linux-sound@vger.kernel.org, kai.vehmanen@linux.intel.com,
	ranjani.sridharan@linux.intel.com,
	yung-chuan.liao@linux.intel.com, pierre-louis.bossart@linux.dev,
	liam.r.girdwood@intel.com, guennadi.liakhovetski@linux.intel.com
Subject: [PATCH for v6.15] ASoC: SOF: hda/ptl: Move mic privacy change notification sending to a work
Date: Mon, 31 Mar 2025 10:06:23 +0300	[thread overview]
Message-ID: <20250331070623.5985-1-peter.ujfalusi@linux.intel.com> (raw)

IPC message cannot be sent from the irq thread directly as the message will
not receive the reply (interrupts are disabled) and it will time out - the
reply is going to be received right after the we leave the irq thread.
This is a different case compared to the delayed IPC messages due to DSP
busy state.

Add support for sending the mic privacy change notification to the firmware
from a work instead of the process callback.

The work needs to be canceled if there is a chance that it might be running
on module remove or before system/runtime suspend.

Fixes: 4a43c3241ec3 ("ASoC: SOF: Intel: ptl: Add support for mic privacy")
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
---
 sound/soc/sof/intel/hda-dsp.c |  8 ++++++++
 sound/soc/sof/intel/hda.c     |  4 ++++
 sound/soc/sof/intel/hda.h     |  8 ++++++++
 sound/soc/sof/intel/ptl.c     | 33 +++++++++++++++++++++++++++++----
 4 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index ccf8eefdca70..f64e8a6a9a33 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -991,6 +991,10 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
 	if (!sdev->dspless_mode_selected) {
 		/* cancel any attempt for DSP D0I3 */
 		cancel_delayed_work_sync(&hda->d0i3_work);
+
+		/* Cancel the microphone privacy work if mic privacy is active */
+		if (hda->mic_privacy.active)
+			cancel_work_sync(&hda->mic_privacy.work);
 	}
 
 	/* stop hda controller and power dsp off */
@@ -1017,6 +1021,10 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
 	if (!sdev->dspless_mode_selected) {
 		/* cancel any attempt for DSP D0I3 */
 		cancel_delayed_work_sync(&hda->d0i3_work);
+
+		/* Cancel the microphone privacy work if mic privacy is active */
+		if (hda->mic_privacy.active)
+			cancel_work_sync(&hda->mic_privacy.work);
 	}
 
 	if (target_state == SOF_DSP_PM_D0) {
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 6b1ada566476..b34e5fdf10f1 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -968,6 +968,10 @@ void hda_dsp_remove(struct snd_sof_dev *sdev)
 	if (sdev->dspless_mode_selected)
 		goto skip_disable_dsp;
 
+	/* Cancel the microphone privacy work if mic privacy is active */
+	if (hda->mic_privacy.active)
+		cancel_work_sync(&hda->mic_privacy.work);
+
 	/* no need to check for error as the DSP will be disabled anyway */
 	if (chip && chip->power_down_dsp)
 		chip->power_down_dsp(sdev);
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 76154627fc17..108cad04879e 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -487,6 +487,11 @@ enum sof_hda_D0_substate {
 	SOF_HDA_DSP_PM_D0I3,	/* low power D0 substate */
 };
 
+struct sof_ace3_mic_privacy {
+	bool active;
+	struct work_struct work;
+};
+
 /* represents DSP HDA controller frontend - i.e. host facing control */
 struct sof_intel_hda_dev {
 	bool imrboot_supported;
@@ -542,6 +547,9 @@ struct sof_intel_hda_dev {
 	/* Intel NHLT information */
 	struct nhlt_acpi_table *nhlt;
 
+	/* work queue for mic privacy state change notification sending */
+	struct sof_ace3_mic_privacy mic_privacy;
+
 	/*
 	 * Pointing to the IPC message if immediate sending was not possible
 	 * because the downlink communication channel was BUSY at the time.
diff --git a/sound/soc/sof/intel/ptl.c b/sound/soc/sof/intel/ptl.c
index 8fa4bdceedd9..aa0b772178bc 100644
--- a/sound/soc/sof/intel/ptl.c
+++ b/sound/soc/sof/intel/ptl.c
@@ -27,22 +27,44 @@ static bool sof_ptl_check_mic_privacy_irq(struct snd_sof_dev *sdev, bool alt,
 	return hdac_bus_eml_is_mic_privacy_changed(sof_to_bus(sdev), alt, elid);
 }
 
+static void sof_ptl_mic_privacy_work(struct work_struct *work)
+{
+	struct sof_intel_hda_dev *hdev = container_of(work,
+						      struct sof_intel_hda_dev,
+						      mic_privacy.work);
+	struct hdac_bus *bus = &hdev->hbus.core;
+	struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev);
+	bool state;
+
+	/*
+	 * The microphone privacy state is only available via Soundwire shim
+	 * in PTL
+	 * The work is only scheduled on change.
+	 */
+	state = hdac_bus_eml_get_mic_privacy_state(bus, 1,
+						   AZX_REG_ML_LEPTR_ID_SDW);
+	sof_ipc4_mic_privacy_state_change(sdev, state);
+}
+
 static void sof_ptl_process_mic_privacy(struct snd_sof_dev *sdev, bool alt,
 					int elid)
 {
-	bool state;
+	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
 
 	if (!alt || elid != AZX_REG_ML_LEPTR_ID_SDW)
 		return;
 
-	state = hdac_bus_eml_get_mic_privacy_state(sof_to_bus(sdev), alt, elid);
-
-	sof_ipc4_mic_privacy_state_change(sdev, state);
+	/*
+	 * Schedule the work to read the microphone privacy state and send IPC
+	 * message about the new state to the firmware
+	 */
+	schedule_work(&hdev->mic_privacy.work);
 }
 
 static void sof_ptl_set_mic_privacy(struct snd_sof_dev *sdev,
 				    struct sof_ipc4_intel_mic_privacy_cap *caps)
 {
+	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
 	u32 micpvcp;
 
 	if (!caps || !caps->capabilities_length)
@@ -58,6 +80,9 @@ static void sof_ptl_set_mic_privacy(struct snd_sof_dev *sdev,
 	hdac_bus_eml_set_mic_privacy_mask(sof_to_bus(sdev), true,
 					  AZX_REG_ML_LEPTR_ID_SDW,
 					  PTL_MICPVCP_GET_SDW_MASK(micpvcp));
+
+	INIT_WORK(&hdev->mic_privacy.work, sof_ptl_mic_privacy_work);
+	hdev->mic_privacy.active = true;
 }
 
 int sof_ptl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops)
-- 
2.49.0


             reply	other threads:[~2025-03-31  7:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-31  7:06 Peter Ujfalusi [this message]
2025-03-31 15:13 ` [PATCH for v6.15] ASoC: SOF: hda/ptl: Move mic privacy change notification sending to a work Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250331070623.5985-1-peter.ujfalusi@linux.intel.com \
    --to=peter.ujfalusi@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=guennadi.liakhovetski@linux.intel.com \
    --cc=kai.vehmanen@linux.intel.com \
    --cc=lgirdwood@gmail.com \
    --cc=liam.r.girdwood@intel.com \
    --cc=linux-sound@vger.kernel.org \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=ranjani.sridharan@linux.intel.com \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox