Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: broonie@kernel.org
Cc: lgirdwood@gmail.com, yung-chuan.liao@linux.intel.com,
	pierre-louis.bossart@linux.dev, shumingf@realtek.com,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
	patches@opensource.cirrus.com
Subject: [PATCH v4 7/7] ASoC: SDCA: Move kcontrol search out of IRQ
Date: Tue, 21 Jul 2026 15:36:36 +0100	[thread overview]
Message-ID: <20260721143636.361814-8-ckeepax@opensource.cirrus.com> (raw)
In-Reply-To: <20260721143636.361814-1-ckeepax@opensource.cirrus.com>

Now that the IRQs are always registered after all the ALSA
controls are created it is possible to search for the control
at the point the IRQ is requested. Move the control search out
of the IRQ handler and do it at IRQ request time.

This also fixes a potential issue when the card was torn down
and reprobed without destroying the codec device, the kctl
pointer stored by the IRQ handler would not be updated to the
new control on the second probe.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---

New since v3.

 include/sound/sdca_jack.h        |  1 +
 sound/soc/sdca/sdca_interrupts.c | 12 +++++++++
 sound/soc/sdca/sdca_jack.c       | 43 +++++++++++++++++++-------------
 3 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/include/sound/sdca_jack.h b/include/sound/sdca_jack.h
index 59de40b7d7d01..871ba2d8146a3 100644
--- a/include/sound/sdca_jack.h
+++ b/include/sound/sdca_jack.h
@@ -28,6 +28,7 @@ struct jack_state {
 };
 
 int sdca_jack_alloc_state(struct sdca_interrupt *interrupt);
+int sdca_jack_init_state(struct sdca_interrupt *interrupt);
 void sdca_jack_free_state(struct sdca_interrupt *interrupt);
 
 int sdca_jack_process(struct sdca_interrupt *interrupt);
diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c
index 6f0d8c0fe622d..42fbd3af8a754 100644
--- a/sound/soc/sdca/sdca_interrupts.c
+++ b/sound/soc/sdca/sdca_interrupts.c
@@ -521,6 +521,8 @@ int sdca_irq_populate(struct sdca_function_data *function,
 
 	for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
 		struct sdca_interrupt *interrupt = &info->irqs[i];
+		struct sdca_control *control = interrupt->control;
+		struct sdca_entity *entity = interrupt->entity;
 		int irq;
 
 		if (interrupt->function != function || interrupt->irq)
@@ -528,6 +530,16 @@ int sdca_irq_populate(struct sdca_function_data *function,
 
 		interrupt->component = component;
 
+		switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
+		case SDCA_CTL_TYPE_S(GE, DETECTED_MODE):
+			ret = sdca_jack_init_state(interrupt);
+			if (ret)
+				return ret;
+			break;
+		default:
+			break;
+		}
+
 		irq = interrupt->control->interrupt_position;
 		ret = sdca_irq_request_locked(dev, info, irq, interrupt->name,
 					      interrupt->handler, interrupt);
diff --git a/sound/soc/sdca/sdca_jack.c b/sound/soc/sdca/sdca_jack.c
index 3c84d17244a28..73f8067906a90 100644
--- a/sound/soc/sdca/sdca_jack.c
+++ b/sound/soc/sdca/sdca_jack.c
@@ -47,23 +47,6 @@ int sdca_jack_process(struct sdca_interrupt *interrupt)
 
 	guard(rwsem_write)(rwsem);
 
-	if (!kctl) {
-		const char *name __free(kfree) = kasprintf(GFP_KERNEL, "%s %s",
-							   interrupt->entity->label,
-							   SDCA_CTL_SELECTED_MODE_NAME);
-
-		if (!name)
-			return -ENOMEM;
-
-		kctl = snd_soc_component_get_kcontrol(component, name);
-		if (!kctl) {
-			dev_err(dev, "control not found: %s\n", name);
-			return -ENODEV;
-		}
-
-		state->kctl = kctl;
-	}
-
 	reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id,
 			   interrupt->control->sel, 0);
 
@@ -148,6 +131,32 @@ void sdca_jack_free_state(struct sdca_interrupt *interrupt)
 }
 EXPORT_SYMBOL_NS_GPL(sdca_jack_free_state, "SND_SOC_SDCA");
 
+/**
+ * sdca_jack_init_state - Initialise transient state for a jack interrupt
+ * @interrupt: SDCA interrupt structure.
+ *
+ * Return: Zero on success or a negative error code.
+ */
+int sdca_jack_init_state(struct sdca_interrupt *interrupt)
+{
+	struct jack_state *jack_state = interrupt->priv;
+	const char *name __free(kfree) = kasprintf(GFP_KERNEL, "%s %s",
+						   interrupt->entity->label,
+						   SDCA_CTL_SELECTED_MODE_NAME);
+
+	if (!name)
+		return -ENOMEM;
+
+	jack_state->kctl = snd_soc_component_get_kcontrol(interrupt->component, name);
+	if (!jack_state->kctl) {
+		dev_err(interrupt->dev, "control not found: %s\n", name);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(sdca_jack_init_state, "SND_SOC_SDCA");
+
 static int type_get_mask(enum sdca_terminal_type type)
 {
 	switch (type) {
-- 
2.47.3


  parent reply	other threads:[~2026-07-21 14:37 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21 14:36 [PATCH v4 0/7] Fix races on creation of SDCA jack detection Charles Keepax
2026-07-21 14:36 ` [PATCH v4 1/7] ASoC: SDCA: Rename sdca_irq_allocate() to include devm Charles Keepax
2026-07-21 14:36 ` [PATCH v4 2/7] ASoC: SDCA: Add sdca_irq_cleanup_late() Charles Keepax
2026-07-21 14:36 ` [PATCH v4 3/7] ASoC: SDCA: Remove devm from primary IRQ cleanup Charles Keepax
2026-07-21 14:36 ` [PATCH v4 4/7] ASoC: SDCA: Populate IRQ data earlier Charles Keepax
2026-07-21 14:36 ` [PATCH v4 5/7] ASoC: Add a component fixup_controls callback Charles Keepax
2026-07-21 14:36 ` [PATCH v4 6/7] ASoC: SDCA: Switch to fixup_controls callback for IRQ registration Charles Keepax
2026-07-21 14:36 ` Charles Keepax [this message]
2026-07-27 17:47 ` [PATCH v4 0/7] Fix races on creation of SDCA jack detection 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=20260721143636.361814-8-ckeepax@opensource.cirrus.com \
    --to=ckeepax@opensource.cirrus.com \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=patches@opensource.cirrus.com \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=shumingf@realtek.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