[PATCH] drm/mipi-dsi: Fix device_node's refcount bugs
Liang He
windhl at 126.com
Mon Jul 11 08:45:26 UTC 2022
In mipi_dsi_device_register_full(), we should call of_node_get()
when a new reference is created in to dsi->dev.of_node(), and call
of_node_put() in fail path or when it is not used anymore in *_unregister().
The reasons to commit this patch as folllow:
(1) There are totally 16 locations to call (devm_)mipi_dsi_device_register_full()
in current version of kernel source code (5.19rc2), and 13 of them pass 'NULL'
to the function.
(2) Three other call sites have different manners as follow:
<1> ./drm/drm_mipi_dsi.c/of_mipi_dsi_device_add() calls
of_node_get() before pass the reference into above register func.
<2> ./drm/panel/panel-raspberrypi-touchscreen.c/rpi_touchscreen_probe()
calls of_graph_get_remote_port() to get the referenece with refcount
incremented before pass it into above register func.
<3> ./drm/panel/panel-novatek-nt35950.c/nt35950_probe() directly use
the reference without any refcounting to call above register func.
(3) So it is better to move refcounting into register func and also add
the corresponding of_node_put() into in fail path and *_unregister func.
Fixes: c63ae8a9686b ("drm/dsi: Use mipi_dsi_device_register_full() for DSI device creation")
Signed-off-by: Liang He <windhl at 126.com>
---
I have noticed that the of_node_get() is moved into
of_mipi_dsi_device_add() which then call above register func in commit-c63ae8a9686b.
However, as there are different ways to directly call the register, I think it
is better to move the refcounting back into it. Please check it carefully.
drivers/gpu/drm/drm_mipi_dsi.c | 6 ++++--
drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index c40bde96cfdf..856ecb3bcecb 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -173,7 +173,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
}
info.channel = reg;
- info.node = of_node_get(node);
+ info.node = node;
return mipi_dsi_device_register_full(host, &info);
}
@@ -221,12 +221,13 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
return dsi;
}
- dsi->dev.of_node = info->node;
+ dsi->dev.of_node = of_node_get(info->node);
dsi->channel = info->channel;
strlcpy(dsi->name, info->type, sizeof(dsi->name));
ret = mipi_dsi_device_add(dsi);
if (ret) {
+ of_node_put(dsi->dev.of_node);
drm_err(host, "failed to add DSI device %d\n", ret);
kfree(dsi);
return ERR_PTR(ret);
@@ -242,6 +243,7 @@ EXPORT_SYMBOL(mipi_dsi_device_register_full);
*/
void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
{
+ of_node_put(dsi->dev.of_node);
device_unregister(&dsi->dev);
}
EXPORT_SYMBOL(mipi_dsi_device_unregister);
diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 145047e19394..9622f903d4c2 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -424,6 +424,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
of_node_put(endpoint);
ts->dsi = mipi_dsi_device_register_full(host, &info);
+ of_node_put(info.node);
if (IS_ERR(ts->dsi)) {
dev_err(dev, "DSI device registration failed: %ld\n",
PTR_ERR(ts->dsi));
--
2.25.1
More information about the dri-devel
mailing list