The handler for the mbhc switch irq calls into snd_soc_jack_report() which in turn triggers a notifier chain that is blocking, which means it allows its callbacks to sleep. This leads to a "scheduling while atomic" Ooops when the jack notifier callback uses snd_soc_dapm_sync(), for instance.
Fix this by switching from atomic to threaded IRQ handlers.
Fixes: de66b3455023e ("ASoC: codecs: msm8916-wcd-analog: add MBHC support") Signed-off-by: Daniel Mack daniel@zonque.org --- sound/soc/codecs/msm8916-wcd-analog.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 12ee83d52405..52b4b6d836a4 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -1187,10 +1187,12 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) return irq; }
- ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | - IRQF_ONESHOT, - "mbhc switch irq", priv); + ret = devm_request_threaded_irq(dev, irq, NULL, + pm8916_mbhc_switch_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "mbhc switch irq", priv); if (ret) dev_err(dev, "cannot request mbhc switch irq\n");
@@ -1201,10 +1203,12 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) return irq; }
- ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "mbhc btn press irq", priv); + ret = devm_request_threaded_irq(dev, irq, NULL, + mbhc_btn_press_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "mbhc btn press irq", priv); if (ret) dev_err(dev, "cannot request mbhc button press irq\n");
@@ -1214,10 +1218,11 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) return irq; }
- ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "mbhc btn release irq", priv); + ret = devm_request_threaded_irq(dev, irq, NULL, + mbhc_btn_release_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "mbhc btn release irq", priv); if (ret) dev_err(dev, "cannot request mbhc button release irq\n");