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:
Родитель
7f3cdaf795
Коммит
6c6bd2075f
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче