Am 10.06.22 um 11:28 schrieb Maxime Ripard:
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>

Acked-by: Thomas Zimmermann <tzimmerm...@suse.de>

---
  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);

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to