* [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown
@ 2026-04-20 15:06 Osama Abdelkader
2026-04-20 15:06 ` [PATCH 2/2] drm/kmb: unwind partially enabled DSI clocks on error Osama Abdelkader
2026-05-06 13:18 ` [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown Osama Abdelkader
0 siblings, 2 replies; 3+ messages in thread
From: Osama Abdelkader @ 2026-04-20 15:06 UTC (permalink / raw)
To: Anitha Chrisanthus, Edmund Dea, David Airlie, Simona Vetter,
dri-devel, linux-kernel
Cc: Osama Abdelkader
Tear down and clear the global DSI host/device/bridge singleton state
when unregistering the host so probe retries and remove/reprobe cycles
start from a clean state.
Guard the clock-disable path in kmb_dsi_host_unregister() to avoid
dereferencing error pointers from early probe failure paths.
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
---
drivers/gpu/drm/kmb/kmb_dsi.c | 44 ++++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index aeb2f9f98f23..500dc00ba6ae 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -5,6 +5,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/mfd/syscon.h>
@@ -182,8 +183,18 @@ static void kmb_dsi_clk_disable(struct kmb_dsi *kmb_dsi)
void kmb_dsi_host_unregister(struct kmb_dsi *kmb_dsi)
{
- kmb_dsi_clk_disable(kmb_dsi);
- mipi_dsi_host_unregister(kmb_dsi->host);
+ if (!IS_ERR_OR_NULL(kmb_dsi))
+ kmb_dsi_clk_disable(kmb_dsi);
+
+ if (dsi_host) {
+ mipi_dsi_host_unregister(dsi_host);
+ kfree(dsi_host);
+ dsi_host = NULL;
+ }
+
+ kfree(dsi_device);
+ dsi_device = NULL;
+ adv_bridge = NULL;
}
/*
@@ -217,6 +228,8 @@ static const struct mipi_dsi_host_ops kmb_dsi_host_ops = {
int kmb_dsi_host_bridge_init(struct device *dev)
{
struct device_node *encoder_node, *dsi_out;
+ bool host_registered = false;
+ int ret;
/* Create and register MIPI DSI host */
if (!dsi_host) {
@@ -230,25 +243,38 @@ int kmb_dsi_host_bridge_init(struct device *dev)
dsi_device = kzalloc_obj(*dsi_device);
if (!dsi_device) {
kfree(dsi_host);
+ dsi_host = NULL;
return -ENOMEM;
}
}
dsi_host->dev = dev;
- mipi_dsi_host_register(dsi_host);
+ ret = mipi_dsi_host_register(dsi_host);
+ if (ret) {
+ DRM_ERROR("failed to register dsi host\n");
+ kfree(dsi_device);
+ dsi_device = NULL;
+ kfree(dsi_host);
+ dsi_host = NULL;
+ return ret;
+ }
+
+ host_registered = true;
}
/* Find ADV7535 node and initialize it */
dsi_out = of_graph_get_endpoint_by_regs(dev->of_node, 0, 1);
if (!dsi_out) {
DRM_ERROR("Failed to get dsi_out node info from DT\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_unregister_host;
}
encoder_node = of_graph_get_remote_port_parent(dsi_out);
if (!encoder_node) {
of_node_put(dsi_out);
DRM_ERROR("Failed to get bridge info from DT\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_unregister_host;
}
/* Locate drm bridge from the hdmi encoder DT node */
adv_bridge = of_drm_find_bridge(encoder_node);
@@ -256,10 +282,16 @@ int kmb_dsi_host_bridge_init(struct device *dev)
of_node_put(encoder_node);
if (!adv_bridge) {
DRM_DEBUG("Wait for external bridge driver DT\n");
- return -EPROBE_DEFER;
+ ret = -EPROBE_DEFER;
+ goto err_unregister_host;
}
return 0;
+
+err_unregister_host:
+ if (host_registered)
+ kmb_dsi_host_unregister(NULL);
+ return ret;
}
static u32 mipi_get_datatype_params(u32 data_type, u32 data_mode,
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 2/2] drm/kmb: unwind partially enabled DSI clocks on error
2026-04-20 15:06 [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown Osama Abdelkader
@ 2026-04-20 15:06 ` Osama Abdelkader
2026-05-06 13:18 ` [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown Osama Abdelkader
1 sibling, 0 replies; 3+ messages in thread
From: Osama Abdelkader @ 2026-04-20 15:06 UTC (permalink / raw)
To: Anitha Chrisanthus, Edmund Dea, David Airlie, Simona Vetter,
dri-devel, linux-kernel
Cc: Osama Abdelkader
If enabling clk_mipi_ecfg or clk_mipi_cfg fails, disable any clocks that
were successfully prepared/enabled earlier in kmb_dsi_clk_enable().
This avoids leaking enabled clocks on probe failure paths.
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
---
drivers/gpu/drm/kmb/kmb_dsi.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index 500dc00ba6ae..3ec16b1aa16c 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -1526,17 +1526,23 @@ static int kmb_dsi_clk_enable(struct kmb_dsi *kmb_dsi)
ret = clk_prepare_enable(kmb_dsi->clk_mipi_ecfg);
if (ret) {
dev_err(dev, "Failed to enable MIPI_ECFG clock: %d\n", ret);
- return ret;
+ goto err_disable_mipi;
}
ret = clk_prepare_enable(kmb_dsi->clk_mipi_cfg);
if (ret) {
dev_err(dev, "Failed to enable MIPI_CFG clock: %d\n", ret);
- return ret;
+ goto err_disable_mipi_ecfg;
}
dev_info(dev, "SUCCESS : enabled MIPI clocks\n");
return 0;
+
+err_disable_mipi_ecfg:
+ clk_disable_unprepare(kmb_dsi->clk_mipi_ecfg);
+err_disable_mipi:
+ clk_disable_unprepare(kmb_dsi->clk_mipi);
+ return ret;
}
int kmb_dsi_clk_init(struct kmb_dsi *kmb_dsi)
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown
2026-04-20 15:06 [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown Osama Abdelkader
2026-04-20 15:06 ` [PATCH 2/2] drm/kmb: unwind partially enabled DSI clocks on error Osama Abdelkader
@ 2026-05-06 13:18 ` Osama Abdelkader
1 sibling, 0 replies; 3+ messages in thread
From: Osama Abdelkader @ 2026-05-06 13:18 UTC (permalink / raw)
To: Anitha Chrisanthus, Edmund Dea, David Airlie, Simona Vetter,
dri-devel, linux-kernel
On Mon, Apr 20, 2026 at 05:06:57PM +0200, Osama Abdelkader wrote:
> Tear down and clear the global DSI host/device/bridge singleton state
> when unregistering the host so probe retries and remove/reprobe cycles
> start from a clean state.
>
> Guard the clock-disable path in kmb_dsi_host_unregister() to avoid
> dereferencing error pointers from early probe failure paths.
> Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
> ---
> drivers/gpu/drm/kmb/kmb_dsi.c | 44 ++++++++++++++++++++++++++++++-----
> 1 file changed, 38 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
> index aeb2f9f98f23..500dc00ba6ae 100644
> --- a/drivers/gpu/drm/kmb/kmb_dsi.c
> +++ b/drivers/gpu/drm/kmb/kmb_dsi.c
> @@ -5,6 +5,7 @@
>
> #include <linux/clk.h>
> #include <linux/delay.h>
> +#include <linux/err.h>
> #include <linux/of.h>
> #include <linux/of_graph.h>
> #include <linux/mfd/syscon.h>
> @@ -182,8 +183,18 @@ static void kmb_dsi_clk_disable(struct kmb_dsi *kmb_dsi)
>
> void kmb_dsi_host_unregister(struct kmb_dsi *kmb_dsi)
> {
> - kmb_dsi_clk_disable(kmb_dsi);
> - mipi_dsi_host_unregister(kmb_dsi->host);
> + if (!IS_ERR_OR_NULL(kmb_dsi))
> + kmb_dsi_clk_disable(kmb_dsi);
> +
> + if (dsi_host) {
> + mipi_dsi_host_unregister(dsi_host);
> + kfree(dsi_host);
> + dsi_host = NULL;
> + }
> +
> + kfree(dsi_device);
> + dsi_device = NULL;
> + adv_bridge = NULL;
> }
>
> /*
> @@ -217,6 +228,8 @@ static const struct mipi_dsi_host_ops kmb_dsi_host_ops = {
> int kmb_dsi_host_bridge_init(struct device *dev)
> {
> struct device_node *encoder_node, *dsi_out;
> + bool host_registered = false;
> + int ret;
>
> /* Create and register MIPI DSI host */
> if (!dsi_host) {
> @@ -230,25 +243,38 @@ int kmb_dsi_host_bridge_init(struct device *dev)
> dsi_device = kzalloc_obj(*dsi_device);
> if (!dsi_device) {
> kfree(dsi_host);
> + dsi_host = NULL;
> return -ENOMEM;
> }
> }
>
> dsi_host->dev = dev;
> - mipi_dsi_host_register(dsi_host);
> + ret = mipi_dsi_host_register(dsi_host);
> + if (ret) {
> + DRM_ERROR("failed to register dsi host\n");
> + kfree(dsi_device);
> + dsi_device = NULL;
> + kfree(dsi_host);
> + dsi_host = NULL;
> + return ret;
> + }
> +
> + host_registered = true;
> }
>
> /* Find ADV7535 node and initialize it */
> dsi_out = of_graph_get_endpoint_by_regs(dev->of_node, 0, 1);
> if (!dsi_out) {
> DRM_ERROR("Failed to get dsi_out node info from DT\n");
> - return -EINVAL;
> + ret = -EINVAL;
> + goto err_unregister_host;
> }
> encoder_node = of_graph_get_remote_port_parent(dsi_out);
> if (!encoder_node) {
> of_node_put(dsi_out);
> DRM_ERROR("Failed to get bridge info from DT\n");
> - return -EINVAL;
> + ret = -EINVAL;
> + goto err_unregister_host;
> }
> /* Locate drm bridge from the hdmi encoder DT node */
> adv_bridge = of_drm_find_bridge(encoder_node);
> @@ -256,10 +282,16 @@ int kmb_dsi_host_bridge_init(struct device *dev)
> of_node_put(encoder_node);
> if (!adv_bridge) {
> DRM_DEBUG("Wait for external bridge driver DT\n");
> - return -EPROBE_DEFER;
> + ret = -EPROBE_DEFER;
> + goto err_unregister_host;
> }
>
> return 0;
> +
> +err_unregister_host:
> + if (host_registered)
> + kmb_dsi_host_unregister(NULL);
> + return ret;
> }
>
> static u32 mipi_get_datatype_params(u32 data_type, u32 data_mode,
> --
> 2.43.0
>
ping.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-06 13:18 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 15:06 [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown Osama Abdelkader
2026-04-20 15:06 ` [PATCH 2/2] drm/kmb: unwind partially enabled DSI clocks on error Osama Abdelkader
2026-05-06 13:18 ` [PATCH 1/2] drm/kmb: reset DSI host singleton state on teardown Osama Abdelkader
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.