From 0cbce868fffaf115a26d6cb45516627cf13cc3d2 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 9 Jun 2025 15:30:41 +0100 Subject: [PATCH] ASoC: cs42l43: Remove unnecessary work functions Now the SoundWire IRQ lock has been changed in the core, it is no longer necessary to use a bunch of work functions to dodge mutex inversions. Signed-off-by: Charles Keepax Acked-by: Mark Brown Link: https://lore.kernel.org/r/20250609143041.495049-4-ckeepax@opensource.cirrus.com Signed-off-by: Vinod Koul --- sound/soc/codecs/cs42l43-jack.c | 46 +++++++++++++-------------------- sound/soc/codecs/cs42l43.c | 24 ++++------------- sound/soc/codecs/cs42l43.h | 5 ---- 3 files changed, 23 insertions(+), 52 deletions(-) diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c index 6165ac16c3a95..72a4150709de8 100644 --- a/sound/soc/codecs/cs42l43-jack.c +++ b/sound/soc/codecs/cs42l43-jack.c @@ -362,14 +362,15 @@ static void cs42l43_stop_button_detect(struct cs42l43_codec *priv) priv->button_detect_running = false; } +#define CS42L43_BUTTON_COMB_US 11000 #define CS42L43_BUTTON_COMB_MAX 512 #define CS42L43_BUTTON_ROUT 2210 -void cs42l43_button_press_work(struct work_struct *work) +irqreturn_t cs42l43_button_press(int irq, void *data) { - struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, - button_press_work.work); + struct cs42l43_codec *priv = data; struct cs42l43 *cs42l43 = priv->core; + irqreturn_t iret = IRQ_NONE; unsigned int buttons = 0; unsigned int val = 0; int i, ret; @@ -377,7 +378,7 @@ void cs42l43_button_press_work(struct work_struct *work) ret = pm_runtime_resume_and_get(priv->dev); if (ret) { dev_err(priv->dev, "Failed to resume for button press: %d\n", ret); - return; + return iret; } mutex_lock(&priv->jack_lock); @@ -387,6 +388,9 @@ void cs42l43_button_press_work(struct work_struct *work) goto error; } + // Wait for 2 full cycles of comb filter to ensure good reading + usleep_range(2 * CS42L43_BUTTON_COMB_US, 2 * CS42L43_BUTTON_COMB_US + 50); + regmap_read(cs42l43->regmap, CS42L43_DETECT_STATUS_1, &val); /* Bail if jack removed, the button is irrelevant and likely invalid */ @@ -420,34 +424,27 @@ void cs42l43_button_press_work(struct work_struct *work) snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS); + iret = IRQ_HANDLED; + error: mutex_unlock(&priv->jack_lock); pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); -} - -irqreturn_t cs42l43_button_press(int irq, void *data) -{ - struct cs42l43_codec *priv = data; - - // Wait for 2 full cycles of comb filter to ensure good reading - queue_delayed_work(system_wq, &priv->button_press_work, - msecs_to_jiffies(20)); - return IRQ_HANDLED; + return iret; } -void cs42l43_button_release_work(struct work_struct *work) +irqreturn_t cs42l43_button_release(int irq, void *data) { - struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, - button_release_work); + struct cs42l43_codec *priv = data; + irqreturn_t iret = IRQ_NONE; int ret; ret = pm_runtime_resume_and_get(priv->dev); if (ret) { dev_err(priv->dev, "Failed to resume for button release: %d\n", ret); - return; + return iret; } mutex_lock(&priv->jack_lock); @@ -456,6 +453,8 @@ void cs42l43_button_release_work(struct work_struct *work) dev_dbg(priv->dev, "Button release IRQ\n"); snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS); + + iret = IRQ_HANDLED; } else { dev_dbg(priv->dev, "Spurious button release IRQ\n"); } @@ -464,15 +463,8 @@ void cs42l43_button_release_work(struct work_struct *work) pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); -} -irqreturn_t cs42l43_button_release(int irq, void *data) -{ - struct cs42l43_codec *priv = data; - - queue_work(system_wq, &priv->button_release_work); - - return IRQ_HANDLED; + return iret; } void cs42l43_bias_sense_timeout(struct work_struct *work) @@ -787,8 +779,6 @@ irqreturn_t cs42l43_tip_sense(int irq, void *data) cancel_delayed_work(&priv->bias_sense_timeout); cancel_delayed_work(&priv->tip_sense_work); - cancel_delayed_work(&priv->button_press_work); - cancel_work(&priv->button_release_work); // Ensure delay after suspend is long enough to avoid false detection if (priv->suspend_jack_debounce) diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c index ea84ac64c775e..41a0f4529ea1f 100644 --- a/sound/soc/codecs/cs42l43.c +++ b/sound/soc/codecs/cs42l43.c @@ -167,13 +167,14 @@ static void cs42l43_hp_ilimit_clear_work(struct work_struct *work) snd_soc_dapm_mutex_unlock(dapm); } -static void cs42l43_hp_ilimit_work(struct work_struct *work) +static irqreturn_t cs42l43_hp_ilimit(int irq, void *data) { - struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec, - hp_ilimit_work); + struct cs42l43_codec *priv = data; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(priv->component); struct cs42l43 *cs42l43 = priv->core; + dev_dbg(priv->dev, "headphone ilimit IRQ\n"); + snd_soc_dapm_mutex_lock(dapm); if (priv->hp_ilimit_count < CS42L43_HP_ILIMIT_MAX_COUNT) { @@ -183,7 +184,7 @@ static void cs42l43_hp_ilimit_work(struct work_struct *work) priv->hp_ilimit_count++; snd_soc_dapm_mutex_unlock(dapm); - return; + return IRQ_HANDLED; } dev_err(priv->dev, "Disabling headphone for %dmS, due to frequent current limit\n", @@ -218,15 +219,6 @@ static void cs42l43_hp_ilimit_work(struct work_struct *work) priv->hp_ilimited = false; snd_soc_dapm_mutex_unlock(dapm); -} - -static irqreturn_t cs42l43_hp_ilimit(int irq, void *data) -{ - struct cs42l43_codec *priv = data; - - dev_dbg(priv->dev, "headphone ilimit IRQ\n"); - - queue_work(system_long_wq, &priv->hp_ilimit_work); return IRQ_HANDLED; } @@ -2159,10 +2151,7 @@ static void cs42l43_component_remove(struct snd_soc_component *component) cancel_delayed_work_sync(&priv->bias_sense_timeout); cancel_delayed_work_sync(&priv->tip_sense_work); - cancel_delayed_work_sync(&priv->button_press_work); - cancel_work_sync(&priv->button_release_work); - cancel_work_sync(&priv->hp_ilimit_work); cancel_delayed_work_sync(&priv->hp_ilimit_clear_work); priv->component = NULL; @@ -2314,10 +2303,7 @@ static int cs42l43_codec_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&priv->tip_sense_work, cs42l43_tip_sense_work); INIT_DELAYED_WORK(&priv->bias_sense_timeout, cs42l43_bias_sense_timeout); - INIT_DELAYED_WORK(&priv->button_press_work, cs42l43_button_press_work); INIT_DELAYED_WORK(&priv->hp_ilimit_clear_work, cs42l43_hp_ilimit_clear_work); - INIT_WORK(&priv->button_release_work, cs42l43_button_release_work); - INIT_WORK(&priv->hp_ilimit_work, cs42l43_hp_ilimit_work); pm_runtime_set_autosuspend_delay(priv->dev, 100); pm_runtime_use_autosuspend(priv->dev); diff --git a/sound/soc/codecs/cs42l43.h b/sound/soc/codecs/cs42l43.h index 1cd9d8a71c439..3ea36362b11a4 100644 --- a/sound/soc/codecs/cs42l43.h +++ b/sound/soc/codecs/cs42l43.h @@ -88,8 +88,6 @@ struct cs42l43_codec { struct delayed_work tip_sense_work; struct delayed_work bias_sense_timeout; - struct delayed_work button_press_work; - struct work_struct button_release_work; struct completion type_detect; struct completion load_detect; @@ -99,7 +97,6 @@ struct cs42l43_codec { int jack_override; bool suspend_jack_debounce; - struct work_struct hp_ilimit_work; struct delayed_work hp_ilimit_clear_work; bool hp_ilimited; int hp_ilimit_count; @@ -134,8 +131,6 @@ int cs42l43_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jack, void *d); void cs42l43_bias_sense_timeout(struct work_struct *work); void cs42l43_tip_sense_work(struct work_struct *work); -void cs42l43_button_press_work(struct work_struct *work); -void cs42l43_button_release_work(struct work_struct *work); irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data); irqreturn_t cs42l43_button_press(int irq, void *data); irqreturn_t cs42l43_button_release(int irq, void *data); -- 2.47.2