Commit 6c6bd207 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Krzysztof Kozlowski
Browse files

memory: tegra: Add and use devm_tegra_memory_controller_get()



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: default avatarDmitry Osipenko <digetx@gmail.com>
Acked-by: default avatarThierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20201104164923.21238-29-digetx@gmail.com


Signed-off-by: default avatarKrzysztof Kozlowski <krzk@kernel.org>
parent 7f3cdaf7
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -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)
{
+3 −15
Original line number Diff line number Diff line
@@ -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();

+10 −29
Original line number Diff line number Diff line
@@ -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;
}
+3 −15
Original line number Diff line number Diff line
@@ -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;
+10 −0
Original line number Diff line number Diff line
@@ -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__ */