[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