From aea8bdbdce5a40f6196cb714c828ee21b3c555e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Sat, 5 Oct 2013 16:25:20 +0200 Subject: [PATCH] drm: Use Linux idr functions in drm_crtc code Reducing differences with Linux 3.8 --- sys/dev/drm/drm_crtc.c | 41 ++++++++++++++++++++++-------- sys/dev/drm/include/drm/drm_crtc.h | 28 +++++++++++++++++++- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/sys/dev/drm/drm_crtc.c b/sys/dev/drm/drm_crtc.c index 1eefe24257..0131ce08e7 100644 --- a/sys/dev/drm/drm_crtc.c +++ b/sys/dev/drm/drm_crtc.c @@ -219,13 +219,22 @@ char *drm_get_connector_status_name(enum drm_connector_status status) static int drm_mode_object_get(struct drm_device *dev, struct drm_mode_object *obj, uint32_t obj_type) { - int new_id; + int new_id = 0; int ret; - new_id = 0; - ret = drm_gem_name_create(&dev->mode_config.crtc_names, obj, &new_id); - if (ret != 0) - return (ret); +again: + if (idr_pre_get(&dev->mode_config.crtc_idr/*, GFP_KERNEL*/) == 0) { + DRM_ERROR("Ran out memory getting a mode number\n"); + return -ENOMEM; + } + + spin_lock(&dev->mode_config.idr_mutex); + ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id); + spin_unlock(&dev->mode_config.idr_mutex); + if (ret == -EAGAIN) + goto again; + else if (ret) + return ret; obj->id = new_id; obj->type = obj_type; @@ -245,18 +254,21 @@ static int drm_mode_object_get(struct drm_device *dev, static void drm_mode_object_put(struct drm_device *dev, struct drm_mode_object *object) { - - drm_gem_names_remove(&dev->mode_config.crtc_names, object->id); + spin_lock(&dev->mode_config.idr_mutex); + idr_remove(&dev->mode_config.crtc_idr, object->id); + spin_unlock(&dev->mode_config.idr_mutex); } struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) { - struct drm_mode_object *obj; + struct drm_mode_object *obj = NULL; - obj = drm_gem_name_ref(&dev->mode_config.crtc_names, id, NULL); + spin_lock(&dev->mode_config.idr_mutex); + obj = idr_find(&dev->mode_config.crtc_idr, id); if (!obj || (obj->type != type) || (obj->id != id)) obj = NULL; + spin_unlock(&dev->mode_config.idr_mutex); return obj; } @@ -882,6 +894,7 @@ int drm_mode_create_dirty_info_property(struct drm_device *dev) void drm_mode_config_init(struct drm_device *dev) { lockinit(&dev->mode_config.lock, "kmslk", 0, LK_CANRECURSE); + spin_init(&dev->mode_config.idr_mutex); INIT_LIST_HEAD(&dev->mode_config.fb_list); INIT_LIST_HEAD(&dev->mode_config.crtc_list); INIT_LIST_HEAD(&dev->mode_config.connector_list); @@ -889,7 +902,7 @@ void drm_mode_config_init(struct drm_device *dev) INIT_LIST_HEAD(&dev->mode_config.property_list); INIT_LIST_HEAD(&dev->mode_config.property_blob_list); INIT_LIST_HEAD(&dev->mode_config.plane_list); - drm_gem_names_init(&dev->mode_config.crtc_names); + idr_init(&dev->mode_config.crtc_idr); lockmgr(&dev->mode_config.lock, LK_EXCLUSIVE); drm_mode_create_standard_connector_properties(dev); @@ -993,7 +1006,13 @@ void drm_mode_config_cleanup(struct drm_device *dev) head) { plane->funcs->destroy(plane); } - drm_gem_names_fini(&dev->mode_config.crtc_names); + + list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { + crtc->funcs->destroy(crtc); + } + + idr_remove_all(&dev->mode_config.crtc_idr); + idr_destroy(&dev->mode_config.crtc_idr); } /** diff --git a/sys/dev/drm/include/drm/drm_crtc.h b/sys/dev/drm/include/drm/drm_crtc.h index 7277745f0a..e3a957a7d4 100644 --- a/sys/dev/drm/include/drm/drm_crtc.h +++ b/sys/dev/drm/include/drm/drm_crtc.h @@ -27,6 +27,8 @@ #ifndef __DRM_CRTC_H__ #define __DRM_CRTC_H__ +#include + #include "drm_gem_names.h" #include @@ -637,11 +639,35 @@ struct drm_mode_group { /** * drm_mode_config - Mode configuration control structure + * @mutex: mutex protecting KMS related lists and structures + * @idr_mutex: mutex for KMS ID allocation and management + * @crtc_idr: main KMS ID tracking object + * @num_fb: number of fbs available + * @fb_list: list of framebuffers available + * @num_connector: number of connectors on this device + * @connector_list: list of connector objects + * @num_encoder: number of encoders on this device + * @encoder_list: list of encoder objects + * @num_crtc: number of CRTCs on this device + * @crtc_list: list of CRTC objects + * @min_width: minimum pixel width on this device + * @min_height: minimum pixel height on this device + * @max_width: maximum pixel width on this device + * @max_height: maximum pixel height on this device + * @funcs: core driver provided mode setting functions + * @fb_base: base address of the framebuffer + * @poll_enabled: track polling status for this device + * @output_poll_work: delayed work for polling in process context + * @*_property: core property tracking * + * Core mode resource tracking structure. All CRTC, encoders, and connectors + * enumerated by the driver are added here, as are global properties. Some + * global restrictions are also here, e.g. dimension restrictions. */ struct drm_mode_config { struct lock lock; /* protects configuration (mode lists etc.) */ - struct drm_gem_names crtc_names; /* use this idr for all IDs, fb, crtc, connector, modes */ + struct spinlock idr_mutex; /* for IDR management */ + struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ /* this is limited to one for now */ int num_fb; struct list_head fb_list; -- 2.41.0