ASoC: tegra30: ahub: Reset global variable
authorDmitry Osipenko <digetx@gmail.com>
Sun, 14 Mar 2021 15:44:57 +0000 (18:44 +0300)
committerMark Brown <broonie@kernel.org>
Thu, 18 Mar 2021 13:49:43 +0000 (13:49 +0000)
Tegra30 AHUB uses global variable that is never reset by the driver on
a probe failure and on driver removal, meaning that driver will never try
to re-probe and can't be unbound. Make driver to reset the variable.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Link: https://lore.kernel.org/r/20210314154459.15375-16-digetx@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/tegra/tegra30_ahub.c

index d24c26f..409a259 100644 (file)
@@ -518,9 +518,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
        void __iomem *regs_apbif, *regs_ahub;
        int ret = 0;
 
-       if (ahub)
-               return -ENODEV;
-
        match = of_match_device(tegra30_ahub_of_match, &pdev->dev);
        if (!match)
                return -EINVAL;
@@ -544,19 +541,21 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
 
        ret = devm_clk_bulk_get(&pdev->dev, ahub->nclocks, ahub->clocks);
        if (ret)
-               return ret;
+               goto err_unset_ahub;
 
        ret = devm_reset_control_bulk_get_exclusive(&pdev->dev, ahub->nresets,
                                                    ahub->resets);
        if (ret) {
                dev_err(&pdev->dev, "Can't get resets: %d\n", ret);
-               return ret;
+               goto err_unset_ahub;
        }
 
        res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        regs_apbif = devm_ioremap_resource(&pdev->dev, res0);
-       if (IS_ERR(regs_apbif))
-               return PTR_ERR(regs_apbif);
+       if (IS_ERR(regs_apbif)) {
+               ret = PTR_ERR(regs_apbif);
+               goto err_unset_ahub;
+       }
 
        ahub->apbif_addr = res0->start;
 
@@ -565,20 +564,22 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
        if (IS_ERR(ahub->regmap_apbif)) {
                dev_err(&pdev->dev, "apbif regmap init failed\n");
                ret = PTR_ERR(ahub->regmap_apbif);
-               return ret;
+               goto err_unset_ahub;
        }
        regcache_cache_only(ahub->regmap_apbif, true);
 
        regs_ahub = devm_platform_ioremap_resource(pdev, 1);
-       if (IS_ERR(regs_ahub))
-               return PTR_ERR(regs_ahub);
+       if (IS_ERR(regs_ahub)) {
+               ret = PTR_ERR(regs_ahub);
+               goto err_unset_ahub;
+       }
 
        ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub,
                                        &tegra30_ahub_ahub_regmap_config);
        if (IS_ERR(ahub->regmap_ahub)) {
                dev_err(&pdev->dev, "ahub regmap init failed\n");
                ret = PTR_ERR(ahub->regmap_ahub);
-               return ret;
+               goto err_unset_ahub;
        }
        regcache_cache_only(ahub->regmap_ahub, true);
 
@@ -595,19 +596,20 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
 
 err_pm_disable:
        pm_runtime_disable(&pdev->dev);
+err_unset_ahub:
+       ahub = NULL;
 
        return ret;
 }
 
 static int tegra30_ahub_remove(struct platform_device *pdev)
 {
-       if (!ahub)
-               return -ENODEV;
-
        pm_runtime_disable(&pdev->dev);
        if (!pm_runtime_status_suspended(&pdev->dev))
                tegra30_ahub_runtime_suspend(&pdev->dev);
 
+       ahub = NULL;
+
        return 0;
 }