dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Yuho Choi <dbgh9129@gmail.com>
To: Anitha Chrisanthus <anitha.chrisanthus@intel.com>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	Yuho Choi <dbgh9129@gmail.com>
Subject: [PATCH v1] drm/kmb: Fix device reference leaks in probe
Date: Mon,  8 Jun 2026 17:13:41 -0400	[thread overview]
Message-ID: <20260608211341.123939-1-dbgh9129@gmail.com> (raw)

kmb_probe() takes a reference to its own platform device only to keep a
local dev pointer, and passes an extra reference to the DSI platform
device into kmb_dsi_host_bridge_init(). Neither reference is released.

The DSI platform device returned by of_find_device_by_node() also carries
a reference that is not put on probe failure or after successful setup.

Use borrowed device pointers where no ownership is needed. Keep an owned
reference only for the registered DSI host device, and drop it when the
host is unregistered. Release the temporary of_find_device_by_node()
reference on all probe exits.

Fixes: 7f7b96a8a0a1 ("drm/kmb: Add support for KeemBay Display")
Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
---
 drivers/gpu/drm/kmb/kmb_drv.c | 32 ++++++++++++++++++++------------
 drivers/gpu/drm/kmb/kmb_dsi.c | 31 ++++++++++++++++++++++++++-----
 2 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
index 7c2eb1152fc2..f8ef618e3a81 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.c
+++ b/drivers/gpu/drm/kmb/kmb_drv.c
@@ -479,7 +479,7 @@ static void kmb_remove(struct platform_device *pdev)
 
 static int kmb_probe(struct platform_device *pdev)
 {
-	struct device *dev = get_device(&pdev->dev);
+	struct device *dev = &pdev->dev;
 	struct kmb_drm_private *kmb;
 	int ret = 0;
 	struct device_node *dsi_in;
@@ -515,20 +515,24 @@ static int kmb_probe(struct platform_device *pdev)
 
 	of_node_put(dsi_in);
 	of_node_put(dsi_node);
-	ret = kmb_dsi_host_bridge_init(get_device(&dsi_pdev->dev));
+	ret = kmb_dsi_host_bridge_init(&dsi_pdev->dev);
 
-	if (ret == -EPROBE_DEFER) {
-		return -EPROBE_DEFER;
-	} else if (ret) {
-		DRM_ERROR("probe failed to initialize DSI host bridge\n");
-		return ret;
+	if (ret) {
+		if (ret != -EPROBE_DEFER) {
+			DRM_ERROR("probe failed to initialize DSI host bridge\n");
+			kmb_dsi_host_unregister(NULL);
+		}
+		goto err_put_dsi_pdev;
 	}
 
 	/* Create DRM device */
 	kmb = devm_drm_dev_alloc(dev, &kmb_driver,
 				 struct kmb_drm_private, drm);
-	if (IS_ERR(kmb))
-		return PTR_ERR(kmb);
+	if (IS_ERR(kmb)) {
+		ret = PTR_ERR(kmb);
+		kmb_dsi_host_unregister(NULL);
+		goto err_put_dsi_pdev;
+	}
 
 	dev_set_drvdata(dev, &kmb->drm);
 
@@ -537,11 +541,11 @@ static int kmb_probe(struct platform_device *pdev)
 	if (IS_ERR(kmb->kmb_dsi)) {
 		drm_err(&kmb->drm, "failed to initialize DSI\n");
 		ret = PTR_ERR(kmb->kmb_dsi);
-		goto err_free1;
+		dev_set_drvdata(dev, NULL);
+		kmb_dsi_host_unregister(NULL);
+		goto err_put_dsi_pdev;
 	}
 
-	kmb->kmb_dsi->dev = &dsi_pdev->dev;
-	kmb->kmb_dsi->pdev = dsi_pdev;
 	ret = kmb_hw_init(&kmb->drm, 0);
 	if (ret)
 		goto err_free1;
@@ -565,6 +569,7 @@ static int kmb_probe(struct platform_device *pdev)
 
 	drm_client_setup(&kmb->drm, NULL);
 
+	put_device(&dsi_pdev->dev);
 	return 0;
 
  err_register:
@@ -578,6 +583,9 @@ static int kmb_probe(struct platform_device *pdev)
 	dev_set_drvdata(dev, NULL);
 	kmb_dsi_host_unregister(kmb->kmb_dsi);
 
+ err_put_dsi_pdev:
+	put_device(&dsi_pdev->dev);
+
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index aeb2f9f98f23..025384a6fb69 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -182,8 +182,19 @@ 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);
+	struct device *dev;
+
+	if (kmb_dsi)
+		kmb_dsi_clk_disable(kmb_dsi);
+
+	if (!dsi_host || !dsi_host->dev)
+		return;
+
+	mipi_dsi_host_unregister(dsi_host);
+
+	dev = dsi_host->dev;
+	dsi_host->dev = NULL;
+	put_device(dev);
 }
 
 /*
@@ -217,6 +228,7 @@ 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;
+	int ret;
 
 	/* Create and register MIPI DSI host */
 	if (!dsi_host) {
@@ -230,12 +242,20 @@ 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);
+	if (!dsi_host->dev) {
+		dsi_host->dev = get_device(dev);
+		ret = mipi_dsi_host_register(dsi_host);
+		if (ret) {
+			put_device(dsi_host->dev);
+			dsi_host->dev = NULL;
+			return ret;
+		}
 	}
 
 	/* Find ADV7535 node and initialize it */
@@ -1410,7 +1430,6 @@ int kmb_dsi_mode_set(struct kmb_dsi *kmb_dsi, struct drm_display_mode *mode,
 struct kmb_dsi *kmb_dsi_init(struct platform_device *pdev)
 {
 	struct kmb_dsi *kmb_dsi;
-	struct device *dev = get_device(&pdev->dev);
 
 	kmb_dsi = devm_kzalloc(dev, sizeof(*kmb_dsi), GFP_KERNEL);
 	if (!kmb_dsi) {
@@ -1420,6 +1439,8 @@ struct kmb_dsi *kmb_dsi_init(struct platform_device *pdev)
 
 	kmb_dsi->host = dsi_host;
 	kmb_dsi->host->ops = &kmb_dsi_host_ops;
+	kmb_dsi->dev = &pdev->dev;
+	kmb_dsi->pdev = pdev;
 
 	dsi_device->host = kmb_dsi->host;
 	kmb_dsi->device = dsi_device;
-- 
2.43.0


             reply	other threads:[~2026-06-08 21:13 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-08 21:13 Yuho Choi [this message]
2026-06-08 21:28 ` [PATCH v1] drm/kmb: Fix device reference leaks in probe sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260608211341.123939-1-dbgh9129@gmail.com \
    --to=dbgh9129@gmail.com \
    --cc=airlied@gmail.com \
    --cc=anitha.chrisanthus@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=simona@ffwll.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox