]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/mipi-dsi: Create devm device registration
authorMaxime Ripard <maxime@cerno.tech>
Fri, 10 Sep 2021 10:11:57 +0000 (12:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 1 Feb 2025 17:22:25 +0000 (18:22 +0100)
[ Upstream commit a1419fb4a73e47f0eab2985dff594ed52397471b ]

Devices that take their data through the MIPI-DSI bus but are controlled
through a secondary bus like I2C have to register a secondary device on
the MIPI-DSI bus through the mipi_dsi_device_register_full() function.

At removal or when an error occurs, that device needs to be removed
through a call to mipi_dsi_device_unregister().

Let's create a device-managed variant of the registration function that
will automatically unregister the device at unbind.

Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210910101218.1632297-4-maxime@cerno.tech
Stable-dep-of: 81adbd3ff21c ("drm: adv7511: Fix use-after-free in adv7533_attach_dsi()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/drm_mipi_dsi.c
include/drm/drm_mipi_dsi.h

index 107a98484f5035586966762e6a687f87f385abb4..e53a5b14b47b14de210806fd5a0b7a3064ce5202 100644 (file)
@@ -246,6 +246,52 @@ void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
 }
 EXPORT_SYMBOL(mipi_dsi_device_unregister);
 
+static void devm_mipi_dsi_device_unregister(void *arg)
+{
+       struct mipi_dsi_device *dsi = arg;
+
+       mipi_dsi_device_unregister(dsi);
+}
+
+/**
+ * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device
+ * @dev: device to tie the MIPI-DSI device lifetime to
+ * @host: DSI host to which this device is connected
+ * @info: pointer to template containing DSI device information
+ *
+ * Create a MIPI DSI device by using the device information provided by
+ * mipi_dsi_device_info template
+ *
+ * This is the managed version of mipi_dsi_device_register_full() which
+ * automatically calls mipi_dsi_device_unregister() when @dev is
+ * unbound.
+ *
+ * Returns:
+ * A pointer to the newly created MIPI DSI device, or, a pointer encoded
+ * with an error
+ */
+struct mipi_dsi_device *
+devm_mipi_dsi_device_register_full(struct device *dev,
+                                  struct mipi_dsi_host *host,
+                                  const struct mipi_dsi_device_info *info)
+{
+       struct mipi_dsi_device *dsi;
+       int ret;
+
+       dsi = mipi_dsi_device_register_full(host, info);
+       if (IS_ERR(dsi))
+               return dsi;
+
+       ret = devm_add_action_or_reset(dev,
+                                      devm_mipi_dsi_device_unregister,
+                                      dsi);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return dsi;
+}
+EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
+
 static DEFINE_MUTEX(host_lock);
 static LIST_HEAD(host_list);
 
index 0dbed65c0ca5a859e709e224c7c89fd0ddfa809b..af8ed48749eb5be3da55c611760ffe4509ed8e3b 100644 (file)
@@ -224,6 +224,9 @@ struct mipi_dsi_device *
 mipi_dsi_device_register_full(struct mipi_dsi_host *host,
                              const struct mipi_dsi_device_info *info);
 void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
+struct mipi_dsi_device *
+devm_mipi_dsi_device_register_full(struct device *dev, struct mipi_dsi_host *host,
+                                  const struct mipi_dsi_device_info *info);
 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
 int mipi_dsi_attach(struct mipi_dsi_device *dsi);
 int mipi_dsi_detach(struct mipi_dsi_device *dsi);