The goal of this series is to simplify driver code when they need to clean up a previously allocated panel bridge. Few drivers have "is_panel_bridge" flag to be able to distinguish a drm_panel_bridge from "simple" drm_bridge. To remove this flag I propose to - let drm_panel_bridge_remove() check if the bridge provided in parameter is really a drm_panel_bridge. - add drm_of_panel_bridge_remove() to remove a bridge given DT port and endpoint Finally that allow to remove drm_bridge structure and "is_panel_bridge" flag from stm driver internal structure.
Benjamin Gaignard (3): drm/bridge: make drm_panel_bridge_remove more robust drm/drm_of: add drm_of_panel_bridge_remove function drm/stm: ltdc: remove bridge from driver internal structure
drivers/gpu/drm/bridge/panel.c | 10 +++++++++- drivers/gpu/drm/drm_of.c | 33 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/stm/ltdc.c | 16 +++++----------- drivers/gpu/drm/stm/ltdc.h | 2 -- include/drm/drm_of.h | 8 ++++++++ 5 files changed, 55 insertions(+), 14 deletions(-)
Make sure that bridge parameter is not NULL and can be safely cast into a panel_bridge structure.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@linaro.org --- drivers/gpu/drm/bridge/panel.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index e0cca19..6d99d4a 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -188,7 +188,15 @@ EXPORT_SYMBOL(drm_panel_bridge_add); */ void drm_panel_bridge_remove(struct drm_bridge *bridge) { - struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); + struct panel_bridge *panel_bridge; + + if (!bridge) + return; + + if (bridge->funcs != &panel_bridge_bridge_funcs) + return; + + panel_bridge = drm_bridge_to_panel_bridge(bridge);
drm_bridge_remove(bridge); devm_kfree(panel_bridge->panel->dev, bridge);
This function is the pendant of drm_of_find_panel_or_bridge() to remove a previously allocated panel_bridge. Given a specific port and endpoint it remove the panel bridge. Since drm_panel_bridge_remove() will check that bridge parameter is not NULL and is a real drm_panel_bridge and no a simple bridge it is safe to call it directly.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@linaro.org --- drivers/gpu/drm/drm_of.c | 33 +++++++++++++++++++++++++++++++++ include/drm/drm_of.h | 8 ++++++++ 2 files changed, 41 insertions(+)
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 8dafbdf..6b54f17 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -260,3 +260,36 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, return ret; } EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge); + +#ifdef CONFIG_DRM_PANEL_BRIDGE +/* + * drm_of_panel_bridge_remove - remove panel bridge + * @np: device tree node containing panel bridge output ports + * + * Remove the panel bridge of a given DT node's port and endpoint number + * + * Returns zero if successful, or one of the standard error codes if it fails. + */ +int drm_of_panel_bridge_remove(const struct device_node *np, + int port, int endpoint) +{ + struct drm_bridge *bridge; + struct device_node *remote; + + remote = of_graph_get_remote_node(np, port, endpoint); + if (!remote) + return -ENODEV; + + bridge = of_drm_find_bridge(remote); + drm_panel_bridge_remove(bridge); + + return 0; +} +#else +int drm_of_panel_bridge_remove(const struct device_node *np, + int port, int endpoint) +{ + return -EINVAL; +} +#endif +EXPORT_SYMBOL_GPL(drm_of_panel_bridge_remove); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 104dd51..390966e 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -29,6 +29,8 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, int port, int endpoint, struct drm_panel **panel, struct drm_bridge **bridge); +int drm_of_panel_bridge_remove(const struct device_node *np, + int port, int endpoint); #else static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, struct device_node *port) @@ -65,6 +67,12 @@ static inline int drm_of_find_panel_or_bridge(const struct device_node *np, { return -EINVAL; } + +static inline int drm_of_panel_bridge_remove(const struct device_node *np, + int port, int endpoint) +{ + return -EINVAL; +} #endif
static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,
With a call to drm_of_panel_bridge_remove() we could remove the bridge without store it in ldtc internal driver structure.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@linaro.org --- drivers/gpu/drm/stm/ltdc.c | 16 +++++----------- drivers/gpu/drm/stm/ltdc.h | 2 -- 2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index d394a03..735c908 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -791,9 +791,8 @@ static const struct drm_encoder_funcs ltdc_encoder_funcs = { .destroy = drm_encoder_cleanup, };
-static int ltdc_encoder_init(struct drm_device *ddev) +static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge) { - struct ltdc_device *ldev = ddev->dev_private; struct drm_encoder *encoder; int ret;
@@ -807,7 +806,7 @@ static int ltdc_encoder_init(struct drm_device *ddev) drm_encoder_init(ddev, encoder, <dc_encoder_funcs, DRM_MODE_ENCODER_DPI, NULL);
- ret = drm_bridge_attach(encoder, ldev->bridge, NULL); + ret = drm_bridge_attach(encoder, bridge, NULL); if (ret) { drm_encoder_cleanup(encoder); return -EINVAL; @@ -936,12 +935,9 @@ int ltdc_load(struct drm_device *ddev) ret = PTR_ERR(bridge); goto err; } - ldev->is_panel_bridge = true; }
- ldev->bridge = bridge; - - ret = ltdc_encoder_init(ddev); + ret = ltdc_encoder_init(ddev, bridge); if (ret) { DRM_ERROR("Failed to init encoder\n"); goto err; @@ -972,8 +968,7 @@ int ltdc_load(struct drm_device *ddev) return 0;
err: - if (ldev->is_panel_bridge) - drm_panel_bridge_remove(bridge); + drm_panel_bridge_remove(bridge);
clk_disable_unprepare(ldev->pixel_clk);
@@ -986,8 +981,7 @@ void ltdc_unload(struct drm_device *ddev)
DRM_DEBUG_DRIVER("\n");
- if (ldev->is_panel_bridge) - drm_panel_bridge_remove(ldev->bridge); + drm_of_panel_bridge_remove(ddev->dev->of_node, 0, 0);
clk_disable_unprepare(ldev->pixel_clk); } diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h index bc6d6f6..ae43755 100644 --- a/drivers/gpu/drm/stm/ltdc.h +++ b/drivers/gpu/drm/stm/ltdc.h @@ -24,8 +24,6 @@ struct ltdc_device { struct drm_fbdev_cma *fbdev; void __iomem *regs; struct clk *pixel_clk; /* lcd pixel clock */ - struct drm_bridge *bridge; - bool is_panel_bridge; struct mutex err_lock; /* protecting error_status */ struct ltdc_caps caps; u32 error_status;
Hi Benjamin, and many thanks for this cleanup patchset.
Reviewed-by: Philippe Cornu philippe.cornu@st.com Tested-by: Philippe Cornu philippe.cornu@st.com
Philippe :-)
On 09/29/2017 02:59 PM, Benjamin Gaignard wrote:
The goal of this series is to simplify driver code when they need to clean up a previously allocated panel bridge. Few drivers have "is_panel_bridge" flag to be able to distinguish a drm_panel_bridge from "simple" drm_bridge. To remove this flag I propose to
- let drm_panel_bridge_remove() check if the bridge provided in parameter is really a drm_panel_bridge.
- add drm_of_panel_bridge_remove() to remove a bridge given DT port and endpoint
Finally that allow to remove drm_bridge structure and "is_panel_bridge" flag from stm driver internal structure.
Benjamin Gaignard (3): drm/bridge: make drm_panel_bridge_remove more robust drm/drm_of: add drm_of_panel_bridge_remove function drm/stm: ltdc: remove bridge from driver internal structure
drivers/gpu/drm/bridge/panel.c | 10 +++++++++- drivers/gpu/drm/drm_of.c | 33 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/stm/ltdc.c | 16 +++++----------- drivers/gpu/drm/stm/ltdc.h | 2 -- include/drm/drm_of.h | 8 ++++++++ 5 files changed, 55 insertions(+), 14 deletions(-)
On Fri, Sep 29, 2017 at 03:03:54PM +0000, Philippe CORNU wrote:
Hi Benjamin, and many thanks for this cleanup patchset.
Reviewed-by: Philippe Cornu philippe.cornu@st.com Tested-by: Philippe Cornu philippe.cornu@st.com
Can you pls either convert vc4 and dw-mipi too, or add an entry to our todo list in Documentation/gpu/todo.rst?
Thanks, Daniel
Philippe :-)
On 09/29/2017 02:59 PM, Benjamin Gaignard wrote:
The goal of this series is to simplify driver code when they need to clean up a previously allocated panel bridge. Few drivers have "is_panel_bridge" flag to be able to distinguish a drm_panel_bridge from "simple" drm_bridge. To remove this flag I propose to
- let drm_panel_bridge_remove() check if the bridge provided in parameter is really a drm_panel_bridge.
- add drm_of_panel_bridge_remove() to remove a bridge given DT port and endpoint
Finally that allow to remove drm_bridge structure and "is_panel_bridge" flag from stm driver internal structure.
Benjamin Gaignard (3): drm/bridge: make drm_panel_bridge_remove more robust drm/drm_of: add drm_of_panel_bridge_remove function drm/stm: ltdc: remove bridge from driver internal structure
drivers/gpu/drm/bridge/panel.c | 10 +++++++++- drivers/gpu/drm/drm_of.c | 33 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/stm/ltdc.c | 16 +++++----------- drivers/gpu/drm/stm/ltdc.h | 2 -- include/drm/drm_of.h | 8 ++++++++ 5 files changed, 55 insertions(+), 14 deletions(-)
dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org