memory: tegra: Add and use devm_tegra_memory_controller_get()
authorDmitry Osipenko <digetx@gmail.com>
Wed, 4 Nov 2020 16:49:04 +0000 (19:49 +0300)
committerKrzysztof Kozlowski <krzk@kernel.org>
Thu, 26 Nov 2020 17:50:29 +0000 (18:50 +0100)
Multiple Tegra drivers need to retrieve Memory Controller and there is
duplication of the retrieval code among the drivers.

Add new devm_tegra_memory_controller_get() helper to remove the code's
duplication and to fix put_device() which was missed in the duplicated
code. Make EMC drivers to use the new helper.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20201104164923.21238-29-digetx@gmail.com
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
drivers/memory/tegra/mc.c
drivers/memory/tegra/tegra124-emc.c
drivers/memory/tegra/tegra210-emc-core.c
drivers/memory/tegra/tegra30-emc.c
include/soc/tegra/mc.h

index ec84035..a72cdca 100644 (file)
@@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
 
+static void tegra_mc_devm_action_put_device(void *data)
+{
+       struct tegra_mc *mc = data;
+
+       put_device(mc->dev);
+}
+
+/**
+ * devm_tegra_memory_controller_get() - get Tegra Memory Controller handle
+ * @dev: device pointer for the consumer device
+ *
+ * This function will search for the Memory Controller node in a device-tree
+ * and retrieve the Memory Controller handle.
+ *
+ * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
+ */
+struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev)
+{
+       struct platform_device *pdev;
+       struct device_node *np;
+       struct tegra_mc *mc;
+       int err;
+
+       np = of_parse_phandle(dev->of_node, "nvidia,memory-controller", 0);
+       if (!np)
+               return ERR_PTR(-ENOENT);
+
+       pdev = of_find_device_by_node(np);
+       of_node_put(np);
+       if (!pdev)
+               return ERR_PTR(-ENODEV);
+
+       mc = platform_get_drvdata(pdev);
+       if (!mc) {
+               put_device(&pdev->dev);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+
+       err = devm_add_action(dev, tegra_mc_devm_action_put_device, mc);
+       if (err) {
+               put_device(mc->dev);
+               return ERR_PTR(err);
+       }
+
+       return mc;
+}
+EXPORT_SYMBOL_GPL(devm_tegra_memory_controller_get);
+
 static int tegra_mc_block_dma_common(struct tegra_mc *mc,
                                     const struct tegra_mc_reset *rst)
 {
index 76ace42..35dbceb 100644 (file)
@@ -1177,7 +1177,6 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
-       struct platform_device *mc;
        struct device_node *np;
        struct tegra_emc *emc;
        struct resource *res;
@@ -1195,20 +1194,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
        if (IS_ERR(emc->regs))
                return PTR_ERR(emc->regs);
 
-       np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-       if (!np) {
-               dev_err(&pdev->dev, "could not get memory controller\n");
-               return -ENOENT;
-       }
-
-       mc = of_find_device_by_node(np);
-       of_node_put(np);
-       if (!mc)
-               return -ENOENT;
-
-       emc->mc = platform_get_drvdata(mc);
-       if (!emc->mc)
-               return -EPROBE_DEFER;
+       emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
+       if (IS_ERR(emc->mc))
+               return PTR_ERR(emc->mc);
 
        ram_code = tegra_read_ram_code();
 
index cdd663b..5f22479 100644 (file)
@@ -1828,7 +1828,6 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 {
        struct thermal_cooling_device *cd;
        unsigned long current_rate;
-       struct platform_device *mc;
        struct tegra210_emc *emc;
        struct device_node *np;
        unsigned int i;
@@ -1846,35 +1845,19 @@ static int tegra210_emc_probe(struct platform_device *pdev)
        spin_lock_init(&emc->lock);
        emc->dev = &pdev->dev;
 
-       np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-       if (!np) {
-               dev_err(&pdev->dev, "could not get memory controller\n");
-               return -ENOENT;
-       }
-
-       mc = of_find_device_by_node(np);
-       of_node_put(np);
-       if (!mc)
-               return -ENOENT;
-
-       emc->mc = platform_get_drvdata(mc);
-       if (!emc->mc) {
-               put_device(&mc->dev);
-               return -EPROBE_DEFER;
-       }
+       emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
+       if (IS_ERR(emc->mc))
+               return PTR_ERR(emc->mc);
 
        emc->regs = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(emc->regs)) {
-               err = PTR_ERR(emc->regs);
-               goto put_mc;
-       }
+       if (IS_ERR(emc->regs))
+               return PTR_ERR(emc->regs);
 
        for (i = 0; i < 2; i++) {
                emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i);
-               if (IS_ERR(emc->channel[i])) {
-                       err = PTR_ERR(emc->channel[i]);
-                       goto put_mc;
-               }
+               if (IS_ERR(emc->channel[i]))
+                       return PTR_ERR(emc->channel[i]);
+
        }
 
        tegra210_emc_detect(emc);
@@ -1884,7 +1867,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
        err = of_reserved_mem_device_init_by_name(emc->dev, np, "nominal");
        if (err < 0) {
                dev_err(emc->dev, "failed to get nominal EMC table: %d\n", err);
-               goto put_mc;
+               return err;
        }
 
        err = of_reserved_mem_device_init_by_name(emc->dev, np, "derated");
@@ -2015,8 +1998,7 @@ detach:
        tegra210_clk_emc_detach(emc->clk);
 release:
        of_reserved_mem_device_release(emc->dev);
-put_mc:
-       put_device(emc->mc->dev);
+
        return err;
 }
 
@@ -2027,7 +2009,6 @@ static int tegra210_emc_remove(struct platform_device *pdev)
        debugfs_remove_recursive(emc->debugfs.root);
        tegra210_clk_emc_detach(emc->clk);
        of_reserved_mem_device_release(emc->dev);
-       put_device(emc->mc->dev);
 
        return 0;
 }
index 055af0e..c58cf31 100644 (file)
@@ -1258,7 +1258,6 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
-       struct platform_device *mc;
        struct device_node *np;
        struct tegra_emc *emc;
        int err;
@@ -1269,17 +1268,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-       if (!np) {
-               dev_err(&pdev->dev, "could not get memory controller node\n");
-               return -ENOENT;
-       }
-
-       mc = of_find_device_by_node(np);
-       of_node_put(np);
-       if (!mc)
-               return -ENOENT;
-
        np = emc_find_node_by_ram_code(&pdev->dev);
        if (!np)
                return -EINVAL;
@@ -1290,9 +1278,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       emc->mc = platform_get_drvdata(mc);
-       if (!emc->mc)
-               return -EPROBE_DEFER;
+       emc->mc = devm_tegra_memory_controller_get(&pdev->dev);
+       if (IS_ERR(emc->mc))
+               return PTR_ERR(emc->mc);
 
        emc->clk_nb.notifier_call = emc_clk_change_notify;
        emc->dev = &pdev->dev;
index 1238e35..d9395af 100644 (file)
@@ -184,4 +184,14 @@ struct tegra_mc {
 int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
 
+#ifdef CONFIG_TEGRA_MC
+struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev);
+#else
+static inline struct tegra_mc *
+devm_tegra_memory_controller_get(struct device *dev)
+{
+       ERR_PTR(-ENODEV);
+}
+#endif
+
 #endif /* __SOC_TEGRA_MC_H__ */