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;
        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);
                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 */
 
        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);
                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");
        }
 
        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)
 
        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)
 
        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) {
 
                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",
        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;
 }
 
        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;
 
        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);
 
 
        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;
 
        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;
                     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);