On Fri, Jan 07, 2022 at 10:58:40PM +0200, Andy Shevchenko wrote: > On Fri, Jan 7, 2022 at 10:50 PM Andy Shevchenko > <andy.shevchenko@xxxxxxxxx> wrote: > > On Fri, Jan 7, 2022 at 7:08 PM Gabriel L. Somlo <gsomlo@xxxxxxxxx> wrote: > > > On Fri, Jan 07, 2022 at 12:06:16PM -0500, Gabriel Somlo wrote: > > ... > > > > Any more ordering or devm vs. non-devm mixing violations here? If so, > > > can you please link me to an example or some docs where I ould figure > > > out what it is I'm still doing wrong? > > > > Device managed resources are attached to the instance of the device > > object and removed in the order they have been attached to, but with > > the caveat that they have no clue about non-managed calls in between. > > Now you may figure out what happens. Ex.: > > > > probe() > > A > > devm_B > > C > > devm_D > > > > remove() > > un_C > > un_A > > > > WRONG! > > For the sake of comprehensivity of the examples the right one(s) depicted below: > > ->probe() > > 1) > devm_A > devm_B > C > D > > 2) > A > B > C > D > > 3) > devm_A > devm_B > devm_C > devm_D > > Hint: > `git log --no-merges --grep devm_add_action_or_reset` Thanks again! As far as I can tell, I *meant* (but failed to) use `devm_request_irq()`, which would then have justified the absence of `free_irq()` on the probe() function's error path! Similarly, I would no longer have to call it during remove() either: diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c index d96da0bcba55..38952f169a27 100644 --- a/drivers/mmc/host/litex_mmc.c +++ b/drivers/mmc/host/litex_mmc.c @@ -486,8 +486,8 @@ static int litex_mmc_irq_init(struct litex_mmc_host *host) if (IS_ERR(host->sdirq)) return PTR_ERR(host->sdirq); - ret = request_irq(host->irq, litex_mmc_interrupt, 0, - "litex-mmc", host->mmc); + ret = devm_request_irq(dev, host->irq, litex_mmc_interrupt, 0, + "litex-mmc", host->mmc); if (ret < 0) { dev_warn(dev, "IRQ request error %d, using polling\n", ret); goto use_polling; @@ -626,20 +626,16 @@ static int litex_mmc_probe(struct platform_device *pdev) return 0; err: - if (host->irq > 0) - free_irq(host->irq, mmc); mmc_free_host(mmc); return ret; } static int litex_mmc_remove(struct platform_device *pdev) { - struct litex_mmc_host *host = dev_get_drvdata(&pdev->dev); + struct litex_mmc_host *host = platform_get_drvdata(pdev); struct mmc_host *mmc = host->mmc; mmc_remove_host(mmc); - if (host->irq > 0) - free_irq(host->irq, mmc); mmc_free_host(mmc); return 0; I'll send out v8 shortly, hopeuflly with all ordering and devm-ness issues fixed. Thanks, --Gabriel