Skip to content

Commit a547582

Browse files
jhovoldbroonie
authored andcommitted
ASoC: codecs: wcd-mbhc-v2: fix resource leaks on component remove
The MBHC resources must be released on component probe failure and removal so can not be tied to the lifetime of the component device. This is specifically needed to allow probe deferrals of the sound card which otherwise fails when reprobing the codec component: snd-sc8280xp sound: ASoC: failed to instantiate card -517 genirq: Flags mismatch irq 299. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr) wcd938x_codec audio-codec: Failed to request mbhc interrupts -16 wcd938x_codec audio-codec: mbhc initialization failed wcd938x_codec audio-codec: ASoC: error at snd_soc_component_probe on audio-codec: -16 snd-sc8280xp sound: ASoC: failed to instantiate card -16 Fixes: 0e5c9e7 ("ASoC: codecs: wcd: add multi button Headset detection support") Cc: stable@vger.kernel.org # 5.14 Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Link: https://lore.kernel.org/r/20230705123018.30903-7-johan+linaro@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 798590c commit a547582

1 file changed

Lines changed: 41 additions & 16 deletions

File tree

sound/soc/codecs/wcd-mbhc-v2.c

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
14541454
return ERR_PTR(-EINVAL);
14551455
}
14561456

1457-
mbhc = devm_kzalloc(dev, sizeof(*mbhc), GFP_KERNEL);
1457+
mbhc = kzalloc(sizeof(*mbhc), GFP_KERNEL);
14581458
if (!mbhc)
14591459
return ERR_PTR(-ENOMEM);
14601460

@@ -1474,61 +1474,76 @@ struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
14741474

14751475
INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug);
14761476

1477-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_sw_intr, NULL,
1477+
ret = request_threaded_irq(mbhc->intr_ids->mbhc_sw_intr, NULL,
14781478
wcd_mbhc_mech_plug_detect_irq,
14791479
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
14801480
"mbhc sw intr", mbhc);
14811481
if (ret)
1482-
goto err;
1482+
goto err_free_mbhc;
14831483

1484-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_press_intr, NULL,
1484+
ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_press_intr, NULL,
14851485
wcd_mbhc_btn_press_handler,
14861486
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
14871487
"Button Press detect", mbhc);
14881488
if (ret)
1489-
goto err;
1489+
goto err_free_sw_intr;
14901490

1491-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_release_intr, NULL,
1491+
ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_release_intr, NULL,
14921492
wcd_mbhc_btn_release_handler,
14931493
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
14941494
"Button Release detect", mbhc);
14951495
if (ret)
1496-
goto err;
1496+
goto err_free_btn_press_intr;
14971497

1498-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_ins_intr, NULL,
1498+
ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_ins_intr, NULL,
14991499
wcd_mbhc_adc_hs_ins_irq,
15001500
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
15011501
"Elect Insert", mbhc);
15021502
if (ret)
1503-
goto err;
1503+
goto err_free_btn_release_intr;
15041504

15051505
disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr);
15061506

1507-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_rem_intr, NULL,
1507+
ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_rem_intr, NULL,
15081508
wcd_mbhc_adc_hs_rem_irq,
15091509
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
15101510
"Elect Remove", mbhc);
15111511
if (ret)
1512-
goto err;
1512+
goto err_free_hs_ins_intr;
15131513

15141514
disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr);
15151515

1516-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_left_ocp, NULL,
1516+
ret = request_threaded_irq(mbhc->intr_ids->hph_left_ocp, NULL,
15171517
wcd_mbhc_hphl_ocp_irq,
15181518
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
15191519
"HPH_L OCP detect", mbhc);
15201520
if (ret)
1521-
goto err;
1521+
goto err_free_hs_rem_intr;
15221522

1523-
ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_right_ocp, NULL,
1523+
ret = request_threaded_irq(mbhc->intr_ids->hph_right_ocp, NULL,
15241524
wcd_mbhc_hphr_ocp_irq,
15251525
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
15261526
"HPH_R OCP detect", mbhc);
15271527
if (ret)
1528-
goto err;
1528+
goto err_free_hph_left_ocp;
15291529

15301530
return mbhc;
1531-
err:
1531+
1532+
err_free_hph_left_ocp:
1533+
free_irq(mbhc->intr_ids->hph_left_ocp, mbhc);
1534+
err_free_hs_rem_intr:
1535+
free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc);
1536+
err_free_hs_ins_intr:
1537+
free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc);
1538+
err_free_btn_release_intr:
1539+
free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc);
1540+
err_free_btn_press_intr:
1541+
free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc);
1542+
err_free_sw_intr:
1543+
free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc);
1544+
err_free_mbhc:
1545+
kfree(mbhc);
1546+
15321547
dev_err(dev, "Failed to request mbhc interrupts %d\n", ret);
15331548

15341549
return ERR_PTR(ret);
@@ -1537,9 +1552,19 @@ EXPORT_SYMBOL(wcd_mbhc_init);
15371552

15381553
void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
15391554
{
1555+
free_irq(mbhc->intr_ids->hph_right_ocp, mbhc);
1556+
free_irq(mbhc->intr_ids->hph_left_ocp, mbhc);
1557+
free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc);
1558+
free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc);
1559+
free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc);
1560+
free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc);
1561+
free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc);
1562+
15401563
mutex_lock(&mbhc->lock);
15411564
wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
15421565
mutex_unlock(&mbhc->lock);
1566+
1567+
kfree(mbhc);
15431568
}
15441569
EXPORT_SYMBOL(wcd_mbhc_deinit);
15451570

0 commit comments

Comments
 (0)