Unlike other DRM entities, there's no helper to create a DRM-managed
initialisation of a connector.

Let's create an helper to initialise a connector that would be passed as an
argument, and handle the cleanup through a DRM-managed action.

Signed-off-by: Maxime Ripard <max...@cerno.tech>
---
 drivers/gpu/drm/drm_connector.c | 108 +++++++++++++++++++++++++-------
 include/drm/drm_connector.h     |   4 ++
 2 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 2a78a23836d8..f150270b519f 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -26,6 +26,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_file.h>
+#include <drm/drm_managed.h>
 #include <drm/drm_print.h>
 #include <drm/drm_privacy_screen_consumer.h>
 #include <drm/drm_sysfs.h>
@@ -212,28 +213,10 @@ void drm_connector_free_work_fn(struct work_struct *work)
        }
 }
 
-/**
- * drm_connector_init - Init a preallocated connector
- * @dev: DRM device
- * @connector: the connector to init
- * @funcs: callbacks for this connector
- * @connector_type: user visible type of the connector
- *
- * Initialises a preallocated connector. Connectors should be
- * subclassed as part of driver connector objects.
- *
- * At driver unload time the driver's &drm_connector_funcs.destroy hook
- * should call drm_connector_unregister(), drm_connector_cleanup() and
- * kfree() the connector structure. The connector structure should not
- * be allocated with devm_kzalloc().
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_connector_init(struct drm_device *dev,
-                      struct drm_connector *connector,
-                      const struct drm_connector_funcs *funcs,
-                      int connector_type)
+static int __drm_connector_init(struct drm_device *dev,
+                               struct drm_connector *connector,
+                               const struct drm_connector_funcs *funcs,
+                               int connector_type)
 {
        struct drm_mode_config *config = &dev->mode_config;
        int ret;
@@ -337,6 +320,39 @@ int drm_connector_init(struct drm_device *dev,
 
        return ret;
 }
+
+/**
+ * drm_connector_init - Init a preallocated connector
+ * @dev: DRM device
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ *
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects.
+ *
+ * At driver unload time the driver's &drm_connector_funcs.destroy hook
+ * should call drm_connector_unregister(), drm_connector_cleanup() and
+ * kfree() the connector structure. The connector structure should not
+ * be allocated with devm_kzalloc().
+ *
+ * Note: consider using drmm_connector_init() instead of
+ * drm_connector_init() to let the DRM managed resource infrastructure
+ * take care of cleanup and deallocation.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_init(struct drm_device *dev,
+                      struct drm_connector *connector,
+                      const struct drm_connector_funcs *funcs,
+                      int connector_type)
+{
+       if (WARN_ON(!(funcs && funcs->destroy)))
+               return -EINVAL;
+
+       return __drm_connector_init(dev, connector, funcs, connector_type);
+}
 EXPORT_SYMBOL(drm_connector_init);
 
 /**
@@ -379,6 +395,54 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_connector_init_with_ddc);
 
+static void drm_connector_cleanup_action(struct drm_device *dev,
+                                        void *ptr)
+{
+       struct drm_connector *connector = ptr;
+
+       drm_connector_unregister(connector);
+       drm_connector_cleanup(connector);
+}
+
+/**
+ * drmm_connector_init - Init a preallocated connector
+ * @dev: DRM device
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ *
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects. Cleanup is
+ * automatically handled through registering drm_connector_unregister()
+ * and drm_connector_cleanup() with drm_add_action(). The connector
+ * structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_init(struct drm_device *dev,
+                       struct drm_connector *connector,
+                       const struct drm_connector_funcs *funcs,
+                       int connector_type)
+{
+       int ret;
+
+       if (WARN_ON(funcs && funcs->destroy))
+               return -EINVAL;
+
+       ret = __drm_connector_init(dev, connector, funcs, connector_type);
+       if (ret)
+               return ret;
+
+       ret = drmm_add_action_or_reset(dev, drm_connector_cleanup_action,
+                                      connector);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+EXPORT_SYMBOL(drmm_connector_init);
+
 /**
  * drm_connector_attach_edid_property - attach edid property.
  * @connector: the connector
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 3ac4bf87f257..35a6b6e944b7 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1672,6 +1672,10 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
                                const struct drm_connector_funcs *funcs,
                                int connector_type,
                                struct i2c_adapter *ddc);
+int drmm_connector_init(struct drm_device *dev,
+                       struct drm_connector *connector,
+                       const struct drm_connector_funcs *funcs,
+                       int connector_type);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);
-- 
2.36.1

Reply via email to