[RFC 8/9] drm/client: Add drm_client_init_from_id() and drm_client_modeset_set()
Noralf Trønnes
noralf at tronnes.org
Sun Feb 16 17:21:16 UTC 2020
drm_client_init_from_id() provides a way for clients to add a client based
on the minor. drm_client_modeset_set() provides a way to set the modeset
for clients that handles connectors and display mode on their own.
Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
---
drivers/gpu/drm/drm_client.c | 37 ++++++++++++++++++++
drivers/gpu/drm/drm_client_modeset.c | 52 ++++++++++++++++++++++++++++
include/drm/drm_client.h | 4 +++
3 files changed, 93 insertions(+)
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index d9a2e3695525..dbd73fe8d987 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -112,6 +112,43 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
}
EXPORT_SYMBOL(drm_client_init);
+/**
+ * drm_client_init_from_id - Initialise a DRM client
+ * @minor_id: DRM minor id
+ * @client: DRM client
+ * @name: Client name
+ * @funcs: DRM client functions (optional)
+ *
+ * This function looks up the drm_device using the minor id and initializes the client.
+ * It also registeres the client to avoid a possible race with DRM device unregister.
+ *
+ * See drm_client_init() and drm_client_register().
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_init_from_id(unsigned int minor_id, struct drm_client_dev *client,
+ const char *name, const struct drm_client_funcs *funcs)
+{
+ struct drm_minor *minor;
+ int ret;
+
+ minor = drm_minor_acquire(minor_id);
+ if (IS_ERR(minor))
+ return PTR_ERR(minor);
+
+ mutex_lock(&minor->dev->clientlist_mutex);
+ ret = drm_client_init(minor->dev, client, name, funcs);
+ if (!ret)
+ list_add(&client->list, &minor->dev->clientlist);
+ mutex_unlock(&minor->dev->clientlist_mutex);
+
+ drm_minor_release(minor);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_client_init_from_id);
+
/**
* drm_client_register - Register client
* @client: DRM client
diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
index 895b73f23079..9396267e646c 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -807,6 +807,58 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
}
EXPORT_SYMBOL(drm_client_modeset_probe);
+/**
+ * drm_client_modeset_set() - Set modeset
+ * @client: DRM client
+ * @connector: Connector
+ * @mode: Display mode
+ * @fb: Framebuffer
+ *
+ * This function releases any current modeset info and sets the new modeset in
+ * the client's modeset array.
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_modeset_set(struct drm_client_dev *client, struct drm_connector *connector,
+ struct drm_display_mode *mode, struct drm_framebuffer *fb)
+{
+ struct drm_mode_set *modeset;
+ int ret = -ENOENT;
+
+ mutex_lock(&client->modeset_mutex);
+
+ drm_client_modeset_release(client);
+
+ if (!connector || !mode || !fb) {
+ ret = 0;
+ goto unlock;
+ }
+
+ drm_client_for_each_modeset(modeset, client) {
+ if (!connector_has_possible_crtc(connector, modeset->crtc))
+ continue;
+
+ modeset->mode = drm_mode_duplicate(client->dev, mode);
+ if (!modeset->mode) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ drm_connector_get(connector);
+ modeset->connectors[modeset->num_connectors++] = connector;
+
+ modeset->fb = fb;
+ ret = 0;
+ break;
+ }
+unlock:
+ mutex_unlock(&client->modeset_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_client_modeset_set);
+
/**
* drm_client_rotation() - Check the initial rotation value
* @modeset: DRM modeset
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index 5cf2c5dd8b1e..97e4157d07c5 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -104,6 +104,8 @@ struct drm_client_dev {
int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
const char *name, const struct drm_client_funcs *funcs);
+int drm_client_init_from_id(unsigned int minor_id, struct drm_client_dev *client,
+ const char *name, const struct drm_client_funcs *funcs);
void drm_client_release(struct drm_client_dev *client);
void drm_client_register(struct drm_client_dev *client);
@@ -155,6 +157,8 @@ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer);
int drm_client_modeset_create(struct drm_client_dev *client);
void drm_client_modeset_free(struct drm_client_dev *client);
int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height);
+int drm_client_modeset_set(struct drm_client_dev *client, struct drm_connector *connector,
+ struct drm_display_mode *mode, struct drm_framebuffer *fb);
bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation);
int drm_client_modeset_commit_force(struct drm_client_dev *client);
int drm_client_modeset_commit(struct drm_client_dev *client);
--
2.23.0
More information about the dri-devel
mailing list