From: Dmitry Osipenko <digetx@xxxxxxxxx> Multiple Tegra drivers need to retrieve Memory Controller and hence there is quite some duplication of the retrieval code among the drivers. Let's add a new common helper for the retrieval of the MC. Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> Signed-off-by: Nicolin Chen <nicoleotsuka@xxxxxxxxx> --- Changelog v2->v3: * Replaced with Dimtry's devm_tegra_get_memory_controller() v1->v2: * N/A drivers/memory/tegra/mc.c | 39 +++++++++++++++++++++++++++++++++++++++ include/soc/tegra/mc.h | 17 +++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index ec8403557ed4..dd691dc3738e 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -42,6 +42,45 @@ 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); +} + +struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev) +{ + struct platform_device *pdev; + struct device_node *np; + struct tegra_mc *mc; + int err; + + np = of_find_matching_node_and_match(NULL, tegra_mc_of_match, NULL); + 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(mc->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_get_memory_controller); + static int tegra_mc_block_dma_common(struct tegra_mc *mc, const struct tegra_mc_reset *rst) { diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 1238e35653d1..c05142e3e244 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -184,4 +184,21 @@ 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 +/** + * devm_tegra_get_memory_controller() - Get the tegra_mc pointer. + * @dev: Device that will be interacted with + * + * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc. + * + * The mc->dev counter will be automatically put by the device management code. + */ +struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev); +#else +static inline struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev) +{ + return ERR_PTR(-ENODEV); +} +#endif + #endif /* __SOC_TEGRA_MC_H__ */ -- 2.17.1