aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-04-15 09:37:16 -0400
committerDave Airlie <airlied@redhat.com>2013-04-15 23:11:44 -0400
commit87d24fc3abb0666b23b6136d81dc29014b3c76dd (patch)
treeab8081b523689085bce24a38e207452e03319bff /drivers/gpu/drm/drm_crtc.c
parent28184f22178ec9cfadd72e37e99921fdefa95f89 (diff)
drm: Destroy property blobs at mode config cleanup time
Property blob objects need to be destroyed when cleaning up to avoid memory leaks. Go through the list of all blobs in the drm_mode_config_cleanup() function and destroy them. The drm_mode_config_cleanup() function needs to be moved after the drm_property_destroy_blob() declaration. Move drm_mode_config_init() as well to keep the functions together. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c208
1 files changed, 107 insertions, 101 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index a3b63cf31eeb..957fb70e8d0e 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1120,44 +1120,6 @@ int drm_mode_create_dirty_info_property(struct drm_device *dev)
1120} 1120}
1121EXPORT_SYMBOL(drm_mode_create_dirty_info_property); 1121EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1122 1122
1123/**
1124 * drm_mode_config_init - initialize DRM mode_configuration structure
1125 * @dev: DRM device
1126 *
1127 * Initialize @dev's mode_config structure, used for tracking the graphics
1128 * configuration of @dev.
1129 *
1130 * Since this initializes the modeset locks, no locking is possible. Which is no
1131 * problem, since this should happen single threaded at init time. It is the
1132 * driver's problem to ensure this guarantee.
1133 *
1134 */
1135void drm_mode_config_init(struct drm_device *dev)
1136{
1137 mutex_init(&dev->mode_config.mutex);
1138 mutex_init(&dev->mode_config.idr_mutex);
1139 mutex_init(&dev->mode_config.fb_lock);
1140 INIT_LIST_HEAD(&dev->mode_config.fb_list);
1141 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
1142 INIT_LIST_HEAD(&dev->mode_config.connector_list);
1143 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
1144 INIT_LIST_HEAD(&dev->mode_config.property_list);
1145 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
1146 INIT_LIST_HEAD(&dev->mode_config.plane_list);
1147 idr_init(&dev->mode_config.crtc_idr);
1148
1149 drm_modeset_lock_all(dev);
1150 drm_mode_create_standard_connector_properties(dev);
1151 drm_modeset_unlock_all(dev);
1152
1153 /* Just to be sure */
1154 dev->mode_config.num_fb = 0;
1155 dev->mode_config.num_connector = 0;
1156 dev->mode_config.num_crtc = 0;
1157 dev->mode_config.num_encoder = 0;
1158}
1159EXPORT_SYMBOL(drm_mode_config_init);
1160
1161int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) 1123int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
1162{ 1124{
1163 uint32_t total_objects = 0; 1125 uint32_t total_objects = 0;
@@ -1203,69 +1165,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
1203EXPORT_SYMBOL(drm_mode_group_init_legacy_group); 1165EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
1204 1166
1205/** 1167/**
1206 * drm_mode_config_cleanup - free up DRM mode_config info
1207 * @dev: DRM device
1208 *
1209 * Free up all the connectors and CRTCs associated with this DRM device, then
1210 * free up the framebuffers and associated buffer objects.
1211 *
1212 * Note that since this /should/ happen single-threaded at driver/device
1213 * teardown time, no locking is required. It's the driver's job to ensure that
1214 * this guarantee actually holds true.
1215 *
1216 * FIXME: cleanup any dangling user buffer objects too
1217 */
1218void drm_mode_config_cleanup(struct drm_device *dev)
1219{
1220 struct drm_connector *connector, *ot;
1221 struct drm_crtc *crtc, *ct;
1222 struct drm_encoder *encoder, *enct;
1223 struct drm_framebuffer *fb, *fbt;
1224 struct drm_property *property, *pt;
1225 struct drm_plane *plane, *plt;
1226
1227 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
1228 head) {
1229 encoder->funcs->destroy(encoder);
1230 }
1231
1232 list_for_each_entry_safe(connector, ot,
1233 &dev->mode_config.connector_list, head) {
1234 connector->funcs->destroy(connector);
1235 }
1236
1237 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
1238 head) {
1239 drm_property_destroy(dev, property);
1240 }
1241
1242 /*
1243 * Single-threaded teardown context, so it's not required to grab the
1244 * fb_lock to protect against concurrent fb_list access. Contrary, it
1245 * would actually deadlock with the drm_framebuffer_cleanup function.
1246 *
1247 * Also, if there are any framebuffers left, that's a driver leak now,
1248 * so politely WARN about this.
1249 */
1250 WARN_ON(!list_empty(&dev->mode_config.fb_list));
1251 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
1252 drm_framebuffer_remove(fb);
1253 }
1254
1255 list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
1256 head) {
1257 plane->funcs->destroy(plane);
1258 }
1259
1260 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
1261 crtc->funcs->destroy(crtc);
1262 }
1263
1264 idr_destroy(&dev->mode_config.crtc_idr);
1265}
1266EXPORT_SYMBOL(drm_mode_config_cleanup);
1267
1268/**
1269 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo 1168 * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1270 * @out: drm_mode_modeinfo struct to return to the user 1169 * @out: drm_mode_modeinfo struct to return to the user
1271 * @in: drm_display_mode to use 1170 * @in: drm_display_mode to use
@@ -4064,3 +3963,110 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
4064 } 3963 }
4065} 3964}
4066EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); 3965EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
3966
3967/**
3968 * drm_mode_config_init - initialize DRM mode_configuration structure
3969 * @dev: DRM device
3970 *
3971 * Initialize @dev's mode_config structure, used for tracking the graphics
3972 * configuration of @dev.
3973 *
3974 * Since this initializes the modeset locks, no locking is possible. Which is no
3975 * problem, since this should happen single threaded at init time. It is the
3976 * driver's problem to ensure this guarantee.
3977 *
3978 */
3979void drm_mode_config_init(struct drm_device *dev)
3980{
3981 mutex_init(&dev->mode_config.mutex);
3982 mutex_init(&dev->mode_config.idr_mutex);
3983 mutex_init(&dev->mode_config.fb_lock);
3984 INIT_LIST_HEAD(&dev->mode_config.fb_list);
3985 INIT_LIST_HEAD(&dev->mode_config.crtc_list);
3986 INIT_LIST_HEAD(&dev->mode_config.connector_list);
3987 INIT_LIST_HEAD(&dev->mode_config.encoder_list);
3988 INIT_LIST_HEAD(&dev->mode_config.property_list);
3989 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
3990 INIT_LIST_HEAD(&dev->mode_config.plane_list);
3991 idr_init(&dev->mode_config.crtc_idr);
3992
3993 drm_modeset_lock_all(dev);
3994 drm_mode_create_standard_connector_properties(dev);
3995 drm_modeset_unlock_all(dev);
3996
3997 /* Just to be sure */
3998 dev->mode_config.num_fb = 0;
3999 dev->mode_config.num_connector = 0;
4000 dev->mode_config.num_crtc = 0;
4001 dev->mode_config.num_encoder = 0;
4002}
4003EXPORT_SYMBOL(drm_mode_config_init);
4004
4005/**
4006 * drm_mode_config_cleanup - free up DRM mode_config info
4007 * @dev: DRM device
4008 *
4009 * Free up all the connectors and CRTCs associated with this DRM device, then
4010 * free up the framebuffers and associated buffer objects.
4011 *
4012 * Note that since this /should/ happen single-threaded at driver/device
4013 * teardown time, no locking is required. It's the driver's job to ensure that
4014 * this guarantee actually holds true.
4015 *
4016 * FIXME: cleanup any dangling user buffer objects too
4017 */
4018void drm_mode_config_cleanup(struct drm_device *dev)
4019{
4020 struct drm_connector *connector, *ot;
4021 struct drm_crtc *crtc, *ct;
4022 struct drm_encoder *encoder, *enct;
4023 struct drm_framebuffer *fb, *fbt;
4024 struct drm_property *property, *pt;
4025 struct drm_property_blob *blob, *bt;
4026 struct drm_plane *plane, *plt;
4027
4028 list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
4029 head) {
4030 encoder->funcs->destroy(encoder);
4031 }
4032
4033 list_for_each_entry_safe(connector, ot,
4034 &dev->mode_config.connector_list, head) {
4035 connector->funcs->destroy(connector);
4036 }
4037
4038 list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
4039 head) {
4040 drm_property_destroy(dev, property);
4041 }
4042
4043 list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
4044 head) {
4045 drm_property_destroy_blob(dev, blob);
4046 }
4047
4048 /*
4049 * Single-threaded teardown context, so it's not required to grab the
4050 * fb_lock to protect against concurrent fb_list access. Contrary, it
4051 * would actually deadlock with the drm_framebuffer_cleanup function.
4052 *
4053 * Also, if there are any framebuffers left, that's a driver leak now,
4054 * so politely WARN about this.
4055 */
4056 WARN_ON(!list_empty(&dev->mode_config.fb_list));
4057 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
4058 drm_framebuffer_remove(fb);
4059 }
4060
4061 list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
4062 head) {
4063 plane->funcs->destroy(plane);
4064 }
4065
4066 list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
4067 crtc->funcs->destroy(crtc);
4068 }
4069
4070 idr_destroy(&dev->mode_config.crtc_idr);
4071}
4072EXPORT_SYMBOL(drm_mode_config_cleanup);