From 2340dc15f05f595688ae10f6512cef5ad51476d3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 8 Apr 2020 20:01:00 +0200 Subject: drm/tegra: Properly reference count the DDC I2C adapter Use the of_get_i2c_adapter_by_node(), which is similar to the existing call to of_find_i2c_adapter_by_node() except that it also takes a reference to the owner module of the I2C adapter. In order to properly balance this out, call i2c_put_adapter() to release the reference to the I2C adapter and its owner module. For the special case where the DDC comes from the DPAUX, care must be taken to perform the same steps (i.e. get_device() and module_get()) so that the reference counts are all balanced. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/tegra/output.c') diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index e36e5e7c2f69..03382550f7d9 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -112,7 +112,7 @@ int tegra_output_probe(struct tegra_output *output) ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0); if (ddc) { - output->ddc = of_find_i2c_adapter_by_node(ddc); + output->ddc = of_get_i2c_adapter_by_node(ddc); if (!output->ddc) { err = -EPROBE_DEFER; of_node_put(ddc); @@ -173,7 +173,7 @@ void tegra_output_remove(struct tegra_output *output) free_irq(output->hpd_irq, output); if (output->ddc) - put_device(&output->ddc->dev); + i2c_put_adapter(output->ddc); } int tegra_output_init(struct drm_device *drm, struct tegra_output *output) -- cgit v1.2.3 From 3d2e7aec70130af53289eccd41696c15ce2c3e89 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Fri, 14 Aug 2020 01:06:53 +0300 Subject: drm/tegra: output: Don't leak OF node on error The OF node should be put before returning error in tegra_output_probe(), otherwise node's refcount will be leaked. Reviewed-by: Laurent Pinchart Reviewed-by: Sam Ravnborg Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/output.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/tegra/output.c') diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 03382550f7d9..f050c8bac398 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -102,10 +102,10 @@ int tegra_output_probe(struct tegra_output *output) panel = of_parse_phandle(output->of_node, "nvidia,panel", 0); if (panel) { output->panel = of_drm_find_panel(panel); + of_node_put(panel); + if (IS_ERR(output->panel)) return PTR_ERR(output->panel); - - of_node_put(panel); } output->edid = of_get_property(output->of_node, "nvidia,edid", &size); @@ -113,13 +113,13 @@ int tegra_output_probe(struct tegra_output *output) ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0); if (ddc) { output->ddc = of_get_i2c_adapter_by_node(ddc); + of_node_put(ddc); + if (!output->ddc) { err = -EPROBE_DEFER; of_node_put(ddc); return err; } - - of_node_put(ddc); } output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev, -- cgit v1.2.3 From f00b9dd579d0078123e33434c25f37d42747574d Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Fri, 14 Aug 2020 01:06:54 +0300 Subject: drm/tegra: output: Support DRM bridges Newer Tegra device-trees will specify a video output graph which involves a bridge. This patch adds initial support for the DRM bridges to the Tegra DRM output. Acked-by: Sam Ravnborg Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.h | 2 ++ drivers/gpu/drm/tegra/output.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) (limited to 'drivers/gpu/drm/tegra/output.c') diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index b25443255be6..f38de08e0c95 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -116,6 +117,7 @@ struct tegra_output { struct device_node *of_node; struct device *dev; + struct drm_bridge *bridge; struct drm_panel *panel; struct i2c_adapter *ddc; const struct edid *edid; diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index f050c8bac398..925a9199a710 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -99,8 +100,19 @@ int tegra_output_probe(struct tegra_output *output) if (!output->of_node) output->of_node = output->dev->of_node; + err = drm_of_find_panel_or_bridge(output->of_node, -1, -1, + &output->panel, &output->bridge); + if (err && err != -ENODEV) + return err; + panel = of_parse_phandle(output->of_node, "nvidia,panel", 0); if (panel) { + /* + * Don't mix nvidia,panel phandle with the graph in a + * device-tree. + */ + WARN_ON(output->panel || output->bridge); + output->panel = of_drm_find_panel(panel); of_node_put(panel); -- cgit v1.2.3