2017-09-29 12:59:33

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH 0/3] Simplify panel bridge cleanup

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

--
2.7.4


2017-09-29 12:59:36

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH 1/3] drm/bridge: make drm_panel_bridge_remove more robust

Make sure that bridge parameter is not NULL and can be safely
cast into a panel_bridge structure.

Signed-off-by: Benjamin Gaignard <[email protected]>
---
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);
--
2.7.4

2017-09-29 12:59:41

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH 3/3] drm/stm: ltdc: remove bridge from driver internal structure

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 <[email protected]>
---
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, &ltdc_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;
--
2.7.4

2017-09-29 12:59:39

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH 2/3] drm/drm_of: add drm_of_panel_bridge_remove function

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 <[email protected]>
---
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,
--
2.7.4

2017-09-29 15:05:18

by Philippe Cornu

[permalink] [raw]
Subject: Re: [PATCH 0/3] Simplify panel bridge cleanup

Hi Benjamin,
and many thanks for this cleanup patchset.

Reviewed-by: Philippe Cornu <[email protected]>
Tested-by: Philippe Cornu <[email protected]>

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