From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>,
Daniel Vetter <daniel@ffwll.ch>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>,
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Subject: [PATCH] drm/mipi-dsi: Fix devm unregister & detach
Date: Wed, 19 Jun 2024 12:07:48 +0300 [thread overview]
Message-ID: <20240619-dsi-devres-fix-v1-1-a5c59310a52e@ideasonboard.com> (raw)
From: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
When a bridge driver uses devm_mipi_dsi_device_register_full() or
devm_mipi_dsi_attach(), the resource management is moved to devres,
which releases the resource automatically when the bridge driver is
unbound.
However, if the DSI host goes away first, the host unregistration code
will automatically detach and unregister any DSI peripherals, without
notifying the devres about it. So when the bridge driver later is
unbound, the resources are released a second time, leading to crash.
Fix this by recording the device that was used when calling the above
mentioned functions into the struct mipi_dsi_device, and when the
unregister or detach is called, remove the devres action if needed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
---
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_mipi_dsi.c | 44 ++++++++++++++++++++++++++++++++----------
include/drm/drm_mipi_dsi.h | 6 ++++++
2 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 795001bb7ff1..a78c4b6cae70 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -237,13 +237,15 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
}
EXPORT_SYMBOL(mipi_dsi_device_register_full);
+static void mipi_dsi_do_device_unregister(struct mipi_dsi_device *dsi, bool devres);
+
/**
* mipi_dsi_device_unregister - unregister MIPI DSI device
* @dsi: DSI peripheral device
*/
void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
{
- device_unregister(&dsi->dev);
+ mipi_dsi_do_device_unregister(dsi, false);
}
EXPORT_SYMBOL(mipi_dsi_device_unregister);
@@ -251,7 +253,15 @@ static void devm_mipi_dsi_device_unregister(void *arg)
{
struct mipi_dsi_device *dsi = arg;
- mipi_dsi_device_unregister(dsi);
+ mipi_dsi_do_device_unregister(dsi, true);
+}
+
+static void mipi_dsi_do_device_unregister(struct mipi_dsi_device *dsi, bool devres)
+{
+ if (!devres && dsi->devres_register_dev)
+ devm_remove_action(dsi->devres_register_dev, devm_mipi_dsi_device_unregister, dsi);
+
+ device_unregister(&dsi->dev);
}
/**
@@ -289,6 +299,8 @@ devm_mipi_dsi_device_register_full(struct device *dev,
if (ret)
return ERR_PTR(ret);
+ dsi->devres_register_dev = dev;
+
return dsi;
}
EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
@@ -386,17 +398,35 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi)
}
EXPORT_SYMBOL(mipi_dsi_attach);
+static int mipi_dsi_do_detach(struct mipi_dsi_device *dsi, bool devres);
+
/**
* mipi_dsi_detach - detach a DSI device from its DSI host
* @dsi: DSI peripheral
*/
int mipi_dsi_detach(struct mipi_dsi_device *dsi)
+{
+ return mipi_dsi_do_detach(dsi, false);
+}
+EXPORT_SYMBOL(mipi_dsi_detach);
+
+static void devm_mipi_dsi_detach(void *arg)
+{
+ struct mipi_dsi_device *dsi = arg;
+
+ mipi_dsi_do_detach(dsi, true);
+}
+
+static int mipi_dsi_do_detach(struct mipi_dsi_device *dsi, bool devres)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
if (WARN_ON(!dsi->attached))
return -EINVAL;
+ if (!devres && dsi->devres_attach_dev)
+ devm_remove_action(dsi->devres_attach_dev, devm_mipi_dsi_detach, dsi);
+
if (!ops || !ops->detach)
return -ENOSYS;
@@ -404,14 +434,6 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi)
return ops->detach(dsi->host, dsi);
}
-EXPORT_SYMBOL(mipi_dsi_detach);
-
-static void devm_mipi_dsi_detach(void *arg)
-{
- struct mipi_dsi_device *dsi = arg;
-
- mipi_dsi_detach(dsi);
-}
/**
* devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host
@@ -437,6 +459,8 @@ int devm_mipi_dsi_attach(struct device *dev,
if (ret)
return ret;
+ dsi->devres_attach_dev = dev;
+
return 0;
}
EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 82b1cc434ea3..f68aee6813db 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -181,6 +181,9 @@ struct mipi_dsi_device_info {
* be set to the real limits of the hardware, zero is only accepted for
* legacy drivers
* @dsc: panel/bridge DSC pps payload to be sent
+ * devres_register_dev: device that was used with
+ * devm_mipi_dsi_device_register_full() or NULL
+ * devres_attach_dev: device that was used with devm_mipi_dsi_attach() or NULL
*/
struct mipi_dsi_device {
struct mipi_dsi_host *host;
@@ -195,6 +198,9 @@ struct mipi_dsi_device {
unsigned long hs_rate;
unsigned long lp_rate;
struct drm_dsc_config *dsc;
+
+ struct device *devres_register_dev;
+ struct device *devres_attach_dev;
};
#define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
---
base-commit: 6ba59ff4227927d3a8530fc2973b80e94b54d58f
change-id: 20240619-dsi-devres-fix-8d55852b406a
Best regards,
--
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
next reply other threads:[~2024-06-19 9:07 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-19 9:07 Tomi Valkeinen [this message]
2024-06-26 8:49 ` Maxime Ripard
2024-06-26 9:55 ` Tomi Valkeinen
2024-06-26 15:07 ` Maxime Ripard
2024-06-26 15:53 ` Tomi Valkeinen
2024-07-02 11:43 ` Maxime Ripard
2024-07-15 8:32 ` Tomi Valkeinen
2024-07-25 11:28 ` Maxime Ripard
2024-08-07 12:19 ` Tomi Valkeinen
2024-09-02 9:26 ` Maxime Ripard
2024-09-02 10:50 ` Daniel Vetter
2024-09-02 12:31 ` Tomi Valkeinen
2024-09-03 7:40 ` Simona Vetter
2024-09-03 8:27 ` Tomi Valkeinen
2024-09-03 11:14 ` Simona Vetter
2024-09-03 11:56 ` Maxime Ripard
2024-09-03 12:43 ` Simona Vetter
2024-09-03 13:05 ` Tomi Valkeinen
2024-09-03 17:36 ` Simona Vetter
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=20240619-dsi-devres-fix-v1-1-a5c59310a52e@ideasonboard.com \
--to=tomi.valkeinen@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=tomi.valkeinen+renesas@ideasonboard.com \
--cc=tzimmermann@suse.de \
/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
all inboxes | Powered by JetHome®