From: Richard Fitzgerald <rf@opensource.cirrus.com>
To: broonie@kernel.org
Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
patches@opensource.cirrus.com
Subject: [PATCH v2] ASoC: cs35l56: Share common SoundWire interrupt enable/disable code
Date: Fri, 29 May 2026 15:03:50 +0100 [thread overview]
Message-ID: <20260529140350.408557-1-rf@opensource.cirrus.com> (raw)
Move the duplicated SoundWire interrupt enable/disable code into shared
functions. These new functions are in cs35l56.c to prevent circular
dependency between cs35l56.c and cs35l56-sdw.c
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
Changes in V2:
- Put the new code in cs35l56.c instead of cs35l56-shared.c, so it's all
in modules that already have a dependency on the SoundWire core.
sound/soc/codecs/cs35l56-sdw.c | 43 +++++--------------------
sound/soc/codecs/cs35l56.c | 59 ++++++++++++++++++++++++++--------
sound/soc/codecs/cs35l56.h | 5 +++
3 files changed, 58 insertions(+), 49 deletions(-)
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
index c21568f57c631..847e88f3b2044 100644
--- a/sound/soc/codecs/cs35l56-sdw.c
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -230,11 +230,8 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral)
* cs35l56_init can return with !init_done if it triggered
* a soft reset.
*/
- if (cs35l56->base.init_done) {
- /* Enable SoundWire interrupts */
- sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1,
- CS35L56_SDW_INT_MASK_CODEC_IRQ);
- }
+ if (cs35l56->base.init_done)
+ cs35l56_unmask_soundwire_interrupts(cs35l56->sdw_peripheral);
out:
pm_runtime_put_autosuspend(cs35l56->base.dev);
@@ -259,15 +256,11 @@ static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral,
pm_runtime_get_noresume(cs35l56->base.dev);
/*
- * Mask and clear until it has been handled. The read of GEN_INT_STAT_1
- * is required as per the SoundWire spec for interrupt status bits
- * to clear. GEN_INT_MASK_1 masks the _inputs_ to GEN_INT_STAT1.
+ * Mask and clear until it has been handled.
* None of the interrupts are time-critical so use the
* power-efficient queue.
*/
- sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
- sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
- sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
+ cs35l56_mask_soundwire_interrupts(peripheral);
queue_work(system_power_efficient_wq, &cs35l56->sdw_irq_work);
return 0;
@@ -283,8 +276,7 @@ static void cs35l56_sdw_irq_work(struct work_struct *work)
/* unmask interrupts */
if (!cs35l56->sdw_irq_no_unmask)
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
- CS35L56_SDW_INT_MASK_CODEC_IRQ);
+ cs35l56_unmask_soundwire_interrupts(cs35l56->sdw_peripheral);
pm_runtime_put_autosuspend(cs35l56->base.dev);
}
@@ -441,9 +433,7 @@ static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev)
if (ret)
return ret;
- /* Re-enable SoundWire interrupts */
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
- CS35L56_SDW_INT_MASK_CODEC_IRQ);
+ cs35l56_unmask_soundwire_interrupts(cs35l56->sdw_peripheral);
return 0;
}
@@ -455,18 +445,7 @@ static int __maybe_unused cs35l56_sdw_system_suspend(struct device *dev)
if (!cs35l56->base.init_done)
return 0;
- /*
- * Disable SoundWire interrupts.
- * Flush - don't cancel because that could leave an unbalanced pm_runtime_get.
- */
- cs35l56->sdw_irq_no_unmask = true;
- flush_work(&cs35l56->sdw_irq_work);
-
- /* Mask interrupts and flush in case sdw_irq_work was queued again */
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
- sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1);
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
- flush_work(&cs35l56->sdw_irq_work);
+ cs35l56_disable_sdw_interrupts(cs35l56);
return cs35l56_system_suspend(dev);
}
@@ -542,13 +521,7 @@ static void cs35l56_sdw_remove(struct sdw_slave *peripheral)
{
struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
- /* Disable SoundWire interrupts */
- cs35l56->sdw_irq_no_unmask = true;
- flush_work(&cs35l56->sdw_irq_work);
- sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
- sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
- sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
- flush_work(&cs35l56->sdw_irq_work);
+ cs35l56_disable_sdw_interrupts(cs35l56);
cs35l56_remove(cs35l56);
}
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 80158913a60e0..b4b126753c101 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -37,6 +37,49 @@
#include "wm_adsp.h"
#include "cs35l56.h"
+void cs35l56_mask_soundwire_interrupts(struct sdw_slave *peripheral)
+{
+ /*
+ * The read of GEN_INT_STAT_1 is required as per the SoundWire spec
+ * for interrupt status bits to clear.
+ * GEN_INT_MASK_1 masks the _inputs_ to GEN_INT_STAT1.
+ */
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
+ sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_mask_soundwire_interrupts, "SND_SOC_CS35L56_CORE");
+
+void cs35l56_unmask_soundwire_interrupts(struct sdw_slave *peripheral)
+{
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, CS35L56_SDW_INT_MASK_CODEC_IRQ);
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_unmask_soundwire_interrupts, "SND_SOC_CS35L56_CORE");
+
+void cs35l56_disable_sdw_interrupts(struct cs35l56_private *cs35l56)
+{
+ if (!cs35l56->sdw_peripheral)
+ return;
+
+ cs35l56->sdw_irq_no_unmask = true;
+ flush_work(&cs35l56->sdw_irq_work);
+
+ /* Mask interrupts and flush in case sdw_irq_work was queued again */
+ cs35l56_mask_soundwire_interrupts(cs35l56->sdw_peripheral);
+ flush_work(&cs35l56->sdw_irq_work);
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_disable_sdw_interrupts, "SND_SOC_CS35L56_CORE");
+
+void cs35l56_enable_sdw_interrupts(struct cs35l56_private *cs35l56)
+{
+ if (!cs35l56->sdw_peripheral)
+ return;
+
+ cs35l56->sdw_irq_no_unmask = false;
+ cs35l56_unmask_soundwire_interrupts(cs35l56->sdw_peripheral);
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_enable_sdw_interrupts, "SND_SOC_CS35L56_CORE");
+
static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
@@ -790,14 +833,7 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
* Setting sdw_irq_no_unmask prevents the handler re-enabling
* the SoundWire interrupt.
*/
- if (cs35l56->sdw_peripheral) {
- cs35l56->sdw_irq_no_unmask = true;
- flush_work(&cs35l56->sdw_irq_work);
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
- sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1);
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
- flush_work(&cs35l56->sdw_irq_work);
- }
+ cs35l56_disable_sdw_interrupts(cs35l56);
ret = cs35l56_firmware_shutdown(&cs35l56->base);
if (ret)
@@ -849,12 +885,7 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
err_unlock:
mutex_unlock(&cs35l56->base.irq_lock);
err:
- /* Re-enable SoundWire interrupts */
- if (cs35l56->sdw_peripheral) {
- cs35l56->sdw_irq_no_unmask = false;
- sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
- CS35L56_SDW_INT_MASK_CODEC_IRQ);
- }
+ cs35l56_enable_sdw_interrupts(cs35l56);
}
static void cs35l56_dsp_work(struct work_struct *work)
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
index d029fa3f86565..6a27ef2b7569a 100644
--- a/sound/soc/codecs/cs35l56.h
+++ b/sound/soc/codecs/cs35l56.h
@@ -66,6 +66,11 @@ static inline struct cs35l56_private *cs35l56_private_from_base(struct cs35l56_b
extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi;
+void cs35l56_mask_soundwire_interrupts(struct sdw_slave *peripheral);
+void cs35l56_unmask_soundwire_interrupts(struct sdw_slave *peripheral);
+void cs35l56_disable_sdw_interrupts(struct cs35l56_private *cs35l56);
+void cs35l56_enable_sdw_interrupts(struct cs35l56_private *cs35l56);
+
int cs35l56_system_suspend(struct device *dev);
int cs35l56_system_suspend_late(struct device *dev);
int cs35l56_system_suspend_no_irq(struct device *dev);
--
2.47.3
next reply other threads:[~2026-05-29 14:03 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-29 14:03 Richard Fitzgerald [this message]
2026-06-02 14:48 ` [PATCH v2] ASoC: cs35l56: Share common SoundWire interrupt enable/disable code 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=20260529140350.408557-1-rf@opensource.cirrus.com \
--to=rf@opensource.cirrus.com \
--cc=broonie@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=patches@opensource.cirrus.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 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.