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: 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>
This commit is contained in:
Dmitry Osipenko 2020-11-04 19:49:04 +03:00 committed by Krzysztof Kozlowski
parent 7f3cdaf795
commit 6c6bd2075f
5 changed files with 74 additions and 59 deletions

View 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)
{

View 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();

View 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 @@ static int tegra210_emc_probe(struct platform_device *pdev)
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;
}

View 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;

View 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__ */