{
        struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 
+       /* Prevent race with interrupt handler */
+       mutex_lock(&cs42l42->jack_detect_mutex);
        cs42l42->jack = jk;
 
+       if (jk) {
+               switch (cs42l42->hs_type) {
+               case CS42L42_PLUG_CTIA:
+               case CS42L42_PLUG_OMTP:
+                       snd_soc_jack_report(jk, SND_JACK_HEADSET, SND_JACK_HEADSET);
+                       break;
+               case CS42L42_PLUG_HEADPHONE:
+                       snd_soc_jack_report(jk, SND_JACK_HEADPHONE, SND_JACK_HEADPHONE);
+                       break;
+               default:
+                       break;
+               }
+       }
+       mutex_unlock(&cs42l42->jack_detect_mutex);
+
        return 0;
 }
 
                CS42L42_M_DETECT_FT_MASK |
                CS42L42_M_HSBIAS_HIZ_MASK);
 
+       mutex_lock(&cs42l42->jack_detect_mutex);
+
        /* Check auto-detect status */
        if ((~masks[5]) & irq_params_table[5].mask) {
                if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
                }
        }
 
+       mutex_unlock(&cs42l42->jack_detect_mutex);
+
        return IRQ_HANDLED;
 }
 
 
        cs42l42->dev = &i2c_client->dev;
        i2c_set_clientdata(i2c_client, cs42l42);
+       mutex_init(&cs42l42->jack_detect_mutex);
 
        cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap);
        if (IS_ERR(cs42l42->regmap)) {
 
 #ifndef __CS42L42_H__
 #define __CS42L42_H__
 
+#include <linux/mutex.h>
 #include <sound/jack.h>
 
 #define CS42L42_PAGE_REGISTER  0x00    /* Page Select Register */
        struct gpio_desc *reset_gpio;
        struct completion pdn_done;
        struct snd_soc_jack *jack;
+       struct mutex jack_detect_mutex;
        int pll_config;
        int bclk;
        u32 sclk;