@@ -355,6 +355,30 @@ int drm_connector_init(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_connector_init);
+typedef int (*connector_init_t)(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type);
+
+static int __drm_connector_init_with_ddc(struct drm_device *dev,
+ struct drm_connector *connector,
+ connector_init_t init_func,
+ const struct drm_connector_funcs *funcs,
+ int connector_type,
+ struct i2c_adapter *ddc)
+{
+ int ret;
+
+ ret = init_func(dev, connector, funcs, connector_type);
+ if (ret)
+ return ret;
+
+ /* provide ddc symlink in sysfs */
+ connector->ddc = ddc;
+
+ return ret;
+}
+
/**
* drm_connector_init_with_ddc - Init a preallocated connector
* @dev: DRM device
@@ -373,6 +397,10 @@ EXPORT_SYMBOL(drm_connector_init);
*
* Ensures that the ddc field of the connector is correctly set.
*
+ * Note: consider using drmm_connector_init_with_ddc() instead of
+ * drm_connector_init_with_ddc() to let the DRM managed resource
+ * infrastructure take care of cleanup and deallocation.
+ *
* Returns:
* Zero on success, error code on failure.
*/
@@ -382,16 +410,9 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
int connector_type,
struct i2c_adapter *ddc)
{
- int ret;
-
- ret = drm_connector_init(dev, connector, funcs, connector_type);
- if (ret)
- return ret;
-
- /* provide ddc symlink in sysfs */
- connector->ddc = ddc;
-
- return ret;
+ return __drm_connector_init_with_ddc(dev, connector,
+ drm_connector_init,
+ funcs, connector_type, ddc);
}
EXPORT_SYMBOL(drm_connector_init_with_ddc);
@@ -443,6 +464,37 @@ int drmm_connector_init(struct drm_device *dev,
}
EXPORT_SYMBOL(drmm_connector_init);
+/**
+ * drmm_connector_init_with_ddc - 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
+ * @ddc: pointer to the associated ddc adapter
+ *
+ * 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().
+ *
+ * Ensures that the ddc field of the connector is correctly set.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_init_with_ddc(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type,
+ struct i2c_adapter *ddc)
+{
+ return __drm_connector_init_with_ddc(dev, connector,
+ drmm_connector_init,
+ funcs, connector_type, ddc);
+}
+EXPORT_SYMBOL(drmm_connector_init_with_ddc);
+
/**
* drm_connector_attach_edid_property - attach edid property.
* @connector: the connector
@@ -1676,6 +1676,11 @@ int drmm_connector_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
int connector_type);
+int drmm_connector_init_with_ddc(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type,
+ struct i2c_adapter *ddc);
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);
Let's create a DRM-managed variant of drm_connector_init_with_ddc that will take care of an action of the connector cleanup. Signed-off-by: Maxime Ripard <maxime@cerno.tech> --- drivers/gpu/drm/drm_connector.c | 72 ++++++++++++++++++++++++++++----- include/drm/drm_connector.h | 5 +++ 2 files changed, 67 insertions(+), 10 deletions(-)