aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c345
1 files changed, 230 insertions, 115 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 2892d746a1e9..7e4acad3f6f9 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
38#include <drm/drm_edid.h> 38#include <drm/drm_edid.h>
39#include <drm/drm_fourcc.h> 39#include <drm/drm_fourcc.h>
40#include <drm/drm_modeset_lock.h> 40#include <drm/drm_modeset_lock.h>
41#include <drm/drm_atomic.h>
41 42
42#include "drm_crtc_internal.h" 43#include "drm_crtc_internal.h"
43#include "drm_internal.h" 44#include "drm_internal.h"
@@ -830,6 +831,7 @@ int drm_connector_init(struct drm_device *dev,
830 const struct drm_connector_funcs *funcs, 831 const struct drm_connector_funcs *funcs,
831 int connector_type) 832 int connector_type)
832{ 833{
834 struct drm_mode_config *config = &dev->mode_config;
833 int ret; 835 int ret;
834 struct ida *connector_ida = 836 struct ida *connector_ida =
835 &drm_connector_enum_list[connector_type].ida; 837 &drm_connector_enum_list[connector_type].ida;
@@ -868,16 +870,20 @@ int drm_connector_init(struct drm_device *dev,
868 870
869 /* We should add connectors at the end to avoid upsetting the connector 871 /* We should add connectors at the end to avoid upsetting the connector
870 * index too much. */ 872 * index too much. */
871 list_add_tail(&connector->head, &dev->mode_config.connector_list); 873 list_add_tail(&connector->head, &config->connector_list);
872 dev->mode_config.num_connector++; 874 config->num_connector++;
873 875
874 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) 876 if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
875 drm_object_attach_property(&connector->base, 877 drm_object_attach_property(&connector->base,
876 dev->mode_config.edid_property, 878 config->edid_property,
877 0); 879 0);
878 880
879 drm_object_attach_property(&connector->base, 881 drm_object_attach_property(&connector->base,
880 dev->mode_config.dpms_property, 0); 882 config->dpms_property, 0);
883
884 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
885 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
886 }
881 887
882 connector->debugfs_entry = NULL; 888 connector->debugfs_entry = NULL;
883 889
@@ -1168,6 +1174,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1168 const uint32_t *formats, uint32_t format_count, 1174 const uint32_t *formats, uint32_t format_count,
1169 enum drm_plane_type type) 1175 enum drm_plane_type type)
1170{ 1176{
1177 struct drm_mode_config *config = &dev->mode_config;
1171 int ret; 1178 int ret;
1172 1179
1173 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 1180 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -1192,15 +1199,28 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1192 plane->possible_crtcs = possible_crtcs; 1199 plane->possible_crtcs = possible_crtcs;
1193 plane->type = type; 1200 plane->type = type;
1194 1201
1195 list_add_tail(&plane->head, &dev->mode_config.plane_list); 1202 list_add_tail(&plane->head, &config->plane_list);
1196 dev->mode_config.num_total_plane++; 1203 config->num_total_plane++;
1197 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1204 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1198 dev->mode_config.num_overlay_plane++; 1205 config->num_overlay_plane++;
1199 1206
1200 drm_object_attach_property(&plane->base, 1207 drm_object_attach_property(&plane->base,
1201 dev->mode_config.plane_type_property, 1208 config->plane_type_property,
1202 plane->type); 1209 plane->type);
1203 1210
1211 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
1212 drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
1213 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
1214 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
1215 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
1216 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
1217 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
1218 drm_object_attach_property(&plane->base, config->prop_src_x, 0);
1219 drm_object_attach_property(&plane->base, config->prop_src_y, 0);
1220 drm_object_attach_property(&plane->base, config->prop_src_w, 0);
1221 drm_object_attach_property(&plane->base, config->prop_src_h, 0);
1222 }
1223
1204 return 0; 1224 return 0;
1205} 1225}
1206EXPORT_SYMBOL(drm_universal_plane_init); 1226EXPORT_SYMBOL(drm_universal_plane_init);
@@ -1322,50 +1342,109 @@ void drm_plane_force_disable(struct drm_plane *plane)
1322} 1342}
1323EXPORT_SYMBOL(drm_plane_force_disable); 1343EXPORT_SYMBOL(drm_plane_force_disable);
1324 1344
1325static int drm_mode_create_standard_connector_properties(struct drm_device *dev) 1345static int drm_mode_create_standard_properties(struct drm_device *dev)
1326{ 1346{
1327 struct drm_property *edid; 1347 struct drm_property *prop;
1328 struct drm_property *dpms;
1329 struct drm_property *dev_path;
1330 1348
1331 /* 1349 /*
1332 * Standard properties (apply to all connectors) 1350 * Standard properties (apply to all connectors)
1333 */ 1351 */
1334 edid = drm_property_create(dev, DRM_MODE_PROP_BLOB | 1352 prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
1335 DRM_MODE_PROP_IMMUTABLE, 1353 DRM_MODE_PROP_IMMUTABLE,
1336 "EDID", 0); 1354 "EDID", 0);
1337 dev->mode_config.edid_property = edid; 1355 if (!prop)
1356 return -ENOMEM;
1357 dev->mode_config.edid_property = prop;
1338 1358
1339 dpms = drm_property_create_enum(dev, 0, 1359 prop = drm_property_create_enum(dev, 0,
1340 "DPMS", drm_dpms_enum_list, 1360 "DPMS", drm_dpms_enum_list,
1341 ARRAY_SIZE(drm_dpms_enum_list)); 1361 ARRAY_SIZE(drm_dpms_enum_list));
1342 dev->mode_config.dpms_property = dpms; 1362 if (!prop)
1343 1363 return -ENOMEM;
1344 dev_path = drm_property_create(dev, 1364 dev->mode_config.dpms_property = prop;
1345 DRM_MODE_PROP_BLOB |
1346 DRM_MODE_PROP_IMMUTABLE,
1347 "PATH", 0);
1348 dev->mode_config.path_property = dev_path;
1349
1350 dev->mode_config.tile_property = drm_property_create(dev,
1351 DRM_MODE_PROP_BLOB |
1352 DRM_MODE_PROP_IMMUTABLE,
1353 "TILE", 0);
1354 1365
1355 return 0; 1366 prop = drm_property_create(dev,
1356} 1367 DRM_MODE_PROP_BLOB |
1368 DRM_MODE_PROP_IMMUTABLE,
1369 "PATH", 0);
1370 if (!prop)
1371 return -ENOMEM;
1372 dev->mode_config.path_property = prop;
1357 1373
1358static int drm_mode_create_standard_plane_properties(struct drm_device *dev) 1374 prop = drm_property_create(dev,
1359{ 1375 DRM_MODE_PROP_BLOB |
1360 struct drm_property *type; 1376 DRM_MODE_PROP_IMMUTABLE,
1377 "TILE", 0);
1378 if (!prop)
1379 return -ENOMEM;
1380 dev->mode_config.tile_property = prop;
1361 1381
1362 /* 1382 prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1363 * Standard properties (apply to all planes)
1364 */
1365 type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1366 "type", drm_plane_type_enum_list, 1383 "type", drm_plane_type_enum_list,
1367 ARRAY_SIZE(drm_plane_type_enum_list)); 1384 ARRAY_SIZE(drm_plane_type_enum_list));
1368 dev->mode_config.plane_type_property = type; 1385 if (!prop)
1386 return -ENOMEM;
1387 dev->mode_config.plane_type_property = prop;
1388
1389 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1390 "SRC_X", 0, UINT_MAX);
1391 if (!prop)
1392 return -ENOMEM;
1393 dev->mode_config.prop_src_x = prop;
1394
1395 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1396 "SRC_Y", 0, UINT_MAX);
1397 if (!prop)
1398 return -ENOMEM;
1399 dev->mode_config.prop_src_y = prop;
1400
1401 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1402 "SRC_W", 0, UINT_MAX);
1403 if (!prop)
1404 return -ENOMEM;
1405 dev->mode_config.prop_src_w = prop;
1406
1407 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1408 "SRC_H", 0, UINT_MAX);
1409 if (!prop)
1410 return -ENOMEM;
1411 dev->mode_config.prop_src_h = prop;
1412
1413 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1414 "CRTC_X", INT_MIN, INT_MAX);
1415 if (!prop)
1416 return -ENOMEM;
1417 dev->mode_config.prop_crtc_x = prop;
1418
1419 prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
1420 "CRTC_Y", INT_MIN, INT_MAX);
1421 if (!prop)
1422 return -ENOMEM;
1423 dev->mode_config.prop_crtc_y = prop;
1424
1425 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1426 "CRTC_W", 0, INT_MAX);
1427 if (!prop)
1428 return -ENOMEM;
1429 dev->mode_config.prop_crtc_w = prop;
1430
1431 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
1432 "CRTC_H", 0, INT_MAX);
1433 if (!prop)
1434 return -ENOMEM;
1435 dev->mode_config.prop_crtc_h = prop;
1436
1437 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1438 "FB_ID", DRM_MODE_OBJECT_FB);
1439 if (!prop)
1440 return -ENOMEM;
1441 dev->mode_config.prop_fb_id = prop;
1442
1443 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
1444 "CRTC_ID", DRM_MODE_OBJECT_CRTC);
1445 if (!prop)
1446 return -ENOMEM;
1447 dev->mode_config.prop_crtc_id = prop;
1369 1448
1370 return 0; 1449 return 0;
1371} 1450}
@@ -1991,6 +2070,44 @@ static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *conne
1991 return connector->encoder; 2070 return connector->encoder;
1992} 2071}
1993 2072
2073/* helper for getconnector and getproperties ioctls */
2074static int get_properties(struct drm_mode_object *obj, bool atomic,
2075 uint32_t __user *prop_ptr, uint64_t __user *prop_values,
2076 uint32_t *arg_count_props)
2077{
2078 int props_count;
2079 int i, ret, copied;
2080
2081 props_count = obj->properties->count;
2082 if (!atomic)
2083 props_count -= obj->properties->atomic_count;
2084
2085 if ((*arg_count_props >= props_count) && props_count) {
2086 for (i = 0, copied = 0; copied < props_count; i++) {
2087 struct drm_property *prop = obj->properties->properties[i];
2088 uint64_t val;
2089
2090 if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
2091 continue;
2092
2093 ret = drm_object_property_get_value(obj, prop, &val);
2094 if (ret)
2095 return ret;
2096
2097 if (put_user(prop->base.id, prop_ptr + copied))
2098 return -EFAULT;
2099
2100 if (put_user(val, prop_values + copied))
2101 return -EFAULT;
2102
2103 copied++;
2104 }
2105 }
2106 *arg_count_props = props_count;
2107
2108 return 0;
2109}
2110
1994/** 2111/**
1995 * drm_mode_getconnector - get connector configuration 2112 * drm_mode_getconnector - get connector configuration
1996 * @dev: drm device for the ioctl 2113 * @dev: drm device for the ioctl
@@ -2012,15 +2129,12 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2012 struct drm_encoder *encoder; 2129 struct drm_encoder *encoder;
2013 struct drm_display_mode *mode; 2130 struct drm_display_mode *mode;
2014 int mode_count = 0; 2131 int mode_count = 0;
2015 int props_count = 0;
2016 int encoders_count = 0; 2132 int encoders_count = 0;
2017 int ret = 0; 2133 int ret = 0;
2018 int copied = 0; 2134 int copied = 0;
2019 int i; 2135 int i;
2020 struct drm_mode_modeinfo u_mode; 2136 struct drm_mode_modeinfo u_mode;
2021 struct drm_mode_modeinfo __user *mode_ptr; 2137 struct drm_mode_modeinfo __user *mode_ptr;
2022 uint32_t __user *prop_ptr;
2023 uint64_t __user *prop_values;
2024 uint32_t __user *encoder_ptr; 2138 uint32_t __user *encoder_ptr;
2025 2139
2026 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 2140 if (!drm_core_check_feature(dev, DRIVER_MODESET))
@@ -2031,6 +2145,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2031 DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id); 2145 DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
2032 2146
2033 mutex_lock(&dev->mode_config.mutex); 2147 mutex_lock(&dev->mode_config.mutex);
2148 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2034 2149
2035 connector = drm_connector_find(dev, out_resp->connector_id); 2150 connector = drm_connector_find(dev, out_resp->connector_id);
2036 if (!connector) { 2151 if (!connector) {
@@ -2038,8 +2153,6 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2038 goto out; 2153 goto out;
2039 } 2154 }
2040 2155
2041 props_count = connector->properties.count;
2042
2043 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) 2156 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
2044 if (connector->encoder_ids[i] != 0) 2157 if (connector->encoder_ids[i] != 0)
2045 encoders_count++; 2158 encoders_count++;
@@ -2062,14 +2175,11 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2062 out_resp->mm_height = connector->display_info.height_mm; 2175 out_resp->mm_height = connector->display_info.height_mm;
2063 out_resp->subpixel = connector->display_info.subpixel_order; 2176 out_resp->subpixel = connector->display_info.subpixel_order;
2064 out_resp->connection = connector->status; 2177 out_resp->connection = connector->status;
2065 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2066
2067 encoder = drm_connector_get_encoder(connector); 2178 encoder = drm_connector_get_encoder(connector);
2068 if (encoder) 2179 if (encoder)
2069 out_resp->encoder_id = encoder->base.id; 2180 out_resp->encoder_id = encoder->base.id;
2070 else 2181 else
2071 out_resp->encoder_id = 0; 2182 out_resp->encoder_id = 0;
2072 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2073 2183
2074 /* 2184 /*
2075 * This ioctl is called twice, once to determine how much space is 2185 * This ioctl is called twice, once to determine how much space is
@@ -2093,26 +2203,12 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2093 } 2203 }
2094 out_resp->count_modes = mode_count; 2204 out_resp->count_modes = mode_count;
2095 2205
2096 if ((out_resp->count_props >= props_count) && props_count) { 2206 ret = get_properties(&connector->base, file_priv->atomic,
2097 copied = 0; 2207 (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
2098 prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr); 2208 (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
2099 prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr); 2209 &out_resp->count_props);
2100 for (i = 0; i < connector->properties.count; i++) { 2210 if (ret)
2101 if (put_user(connector->properties.ids[i], 2211 goto out;
2102 prop_ptr + copied)) {
2103 ret = -EFAULT;
2104 goto out;
2105 }
2106
2107 if (put_user(connector->properties.values[i],
2108 prop_values + copied)) {
2109 ret = -EFAULT;
2110 goto out;
2111 }
2112 copied++;
2113 }
2114 }
2115 out_resp->count_props = props_count;
2116 2212
2117 if ((out_resp->count_encoders >= encoders_count) && encoders_count) { 2213 if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
2118 copied = 0; 2214 copied = 0;
@@ -2131,6 +2227,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
2131 out_resp->count_encoders = encoders_count; 2227 out_resp->count_encoders = encoders_count;
2132 2228
2133out: 2229out:
2230 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2134 mutex_unlock(&dev->mode_config.mutex); 2231 mutex_unlock(&dev->mode_config.mutex);
2135 2232
2136 return ret; 2233 return ret;
@@ -3823,9 +3920,11 @@ void drm_object_attach_property(struct drm_mode_object *obj,
3823 return; 3920 return;
3824 } 3921 }
3825 3922
3826 obj->properties->ids[count] = property->base.id; 3923 obj->properties->properties[count] = property;
3827 obj->properties->values[count] = init_val; 3924 obj->properties->values[count] = init_val;
3828 obj->properties->count++; 3925 obj->properties->count++;
3926 if (property->flags & DRM_MODE_PROP_ATOMIC)
3927 obj->properties->atomic_count++;
3829} 3928}
3830EXPORT_SYMBOL(drm_object_attach_property); 3929EXPORT_SYMBOL(drm_object_attach_property);
3831 3930
@@ -3848,7 +3947,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
3848 int i; 3947 int i;
3849 3948
3850 for (i = 0; i < obj->properties->count; i++) { 3949 for (i = 0; i < obj->properties->count; i++) {
3851 if (obj->properties->ids[i] == property->base.id) { 3950 if (obj->properties->properties[i] == property) {
3852 obj->properties->values[i] = val; 3951 obj->properties->values[i] = val;
3853 return 0; 3952 return 0;
3854 } 3953 }
@@ -3877,8 +3976,16 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
3877{ 3976{
3878 int i; 3977 int i;
3879 3978
3979 /* read-only properties bypass atomic mechanism and still store
3980 * their value in obj->properties->values[].. mostly to avoid
3981 * having to deal w/ EDID and similar props in atomic paths:
3982 */
3983 if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) &&
3984 !(property->flags & DRM_MODE_PROP_IMMUTABLE))
3985 return drm_atomic_get_property(obj, property, val);
3986
3880 for (i = 0; i < obj->properties->count; i++) { 3987 for (i = 0; i < obj->properties->count; i++) {
3881 if (obj->properties->ids[i] == property->base.id) { 3988 if (obj->properties->properties[i] == property) {
3882 *val = obj->properties->values[i]; 3989 *val = obj->properties->values[i];
3883 return 0; 3990 return 0;
3884 } 3991 }
@@ -4194,14 +4301,24 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
4194} 4301}
4195EXPORT_SYMBOL(drm_mode_connector_update_edid_property); 4302EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
4196 4303
4197static bool drm_property_change_is_valid(struct drm_property *property, 4304/* Some properties could refer to dynamic refcnt'd objects, or things that
4198 uint64_t value) 4305 * need special locking to handle lifetime issues (ie. to ensure the prop
4306 * value doesn't become invalid part way through the property update due to
4307 * race). The value returned by reference via 'obj' should be passed back
4308 * to drm_property_change_valid_put() after the property is set (and the
4309 * object to which the property is attached has a chance to take it's own
4310 * reference).
4311 */
4312bool drm_property_change_valid_get(struct drm_property *property,
4313 uint64_t value, struct drm_mode_object **ref)
4199{ 4314{
4200 int i; 4315 int i;
4201 4316
4202 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 4317 if (property->flags & DRM_MODE_PROP_IMMUTABLE)
4203 return false; 4318 return false;
4204 4319
4320 *ref = NULL;
4321
4205 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) { 4322 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
4206 if (value < property->values[0] || value > property->values[1]) 4323 if (value < property->values[0] || value > property->values[1])
4207 return false; 4324 return false;
@@ -4223,20 +4340,29 @@ static bool drm_property_change_is_valid(struct drm_property *property,
4223 /* Only the driver knows */ 4340 /* Only the driver knows */
4224 return true; 4341 return true;
4225 } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 4342 } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
4226 struct drm_mode_object *obj;
4227
4228 /* a zero value for an object property translates to null: */ 4343 /* a zero value for an object property translates to null: */
4229 if (value == 0) 4344 if (value == 0)
4230 return true; 4345 return true;
4231 /* 4346
4232 * NOTE: use _object_find() directly to bypass restriction on 4347 /* handle refcnt'd objects specially: */
4233 * looking up refcnt'd objects (ie. fb's). For a refcnt'd 4348 if (property->values[0] == DRM_MODE_OBJECT_FB) {
4234 * object this could race against object finalization, so it 4349 struct drm_framebuffer *fb;
4235 * simply tells us that the object *was* valid. Which is good 4350 fb = drm_framebuffer_lookup(property->dev, value);
4236 * enough. 4351 if (fb) {
4237 */ 4352 *ref = &fb->base;
4238 obj = _object_find(property->dev, value, property->values[0]); 4353 return true;
4239 return obj != NULL; 4354 } else {
4355 return false;
4356 }
4357 } else {
4358 return _object_find(property->dev, value, property->values[0]) != NULL;
4359 }
4360 } else {
4361 int i;
4362 for (i = 0; i < property->num_values; i++)
4363 if (property->values[i] == value)
4364 return true;
4365 return false;
4240 } 4366 }
4241 4367
4242 for (i = 0; i < property->num_values; i++) 4368 for (i = 0; i < property->num_values; i++)
@@ -4245,6 +4371,18 @@ static bool drm_property_change_is_valid(struct drm_property *property,
4245 return false; 4371 return false;
4246} 4372}
4247 4373
4374void drm_property_change_valid_put(struct drm_property *property,
4375 struct drm_mode_object *ref)
4376{
4377 if (!ref)
4378 return;
4379
4380 if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
4381 if (property->values[0] == DRM_MODE_OBJECT_FB)
4382 drm_framebuffer_unreference(obj_to_fb(ref));
4383 }
4384}
4385
4248/** 4386/**
4249 * drm_mode_connector_property_set_ioctl - set the current value of a connector property 4387 * drm_mode_connector_property_set_ioctl - set the current value of a connector property
4250 * @dev: DRM device 4388 * @dev: DRM device
@@ -4360,11 +4498,6 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4360 struct drm_mode_obj_get_properties *arg = data; 4498 struct drm_mode_obj_get_properties *arg = data;
4361 struct drm_mode_object *obj; 4499 struct drm_mode_object *obj;
4362 int ret = 0; 4500 int ret = 0;
4363 int i;
4364 int copied = 0;
4365 int props_count = 0;
4366 uint32_t __user *props_ptr;
4367 uint64_t __user *prop_values_ptr;
4368 4501
4369 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 4502 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4370 return -EINVAL; 4503 return -EINVAL;
@@ -4381,30 +4514,11 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4381 goto out; 4514 goto out;
4382 } 4515 }
4383 4516
4384 props_count = obj->properties->count; 4517 ret = get_properties(obj, file_priv->atomic,
4518 (uint32_t __user *)(unsigned long)(arg->props_ptr),
4519 (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
4520 &arg->count_props);
4385 4521
4386 /* This ioctl is called twice, once to determine how much space is
4387 * needed, and the 2nd time to fill it. */
4388 if ((arg->count_props >= props_count) && props_count) {
4389 copied = 0;
4390 props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
4391 prop_values_ptr = (uint64_t __user *)(unsigned long)
4392 (arg->prop_values_ptr);
4393 for (i = 0; i < props_count; i++) {
4394 if (put_user(obj->properties->ids[i],
4395 props_ptr + copied)) {
4396 ret = -EFAULT;
4397 goto out;
4398 }
4399 if (put_user(obj->properties->values[i],
4400 prop_values_ptr + copied)) {
4401 ret = -EFAULT;
4402 goto out;
4403 }
4404 copied++;
4405 }
4406 }
4407 arg->count_props = props_count;
4408out: 4522out:
4409 drm_modeset_unlock_all(dev); 4523 drm_modeset_unlock_all(dev);
4410 return ret; 4524 return ret;
@@ -4433,8 +4547,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4433 struct drm_mode_object *arg_obj; 4547 struct drm_mode_object *arg_obj;
4434 struct drm_mode_object *prop_obj; 4548 struct drm_mode_object *prop_obj;
4435 struct drm_property *property; 4549 struct drm_property *property;
4436 int ret = -EINVAL; 4550 int i, ret = -EINVAL;
4437 int i; 4551 struct drm_mode_object *ref;
4438 4552
4439 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 4553 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4440 return -EINVAL; 4554 return -EINVAL;
@@ -4450,7 +4564,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4450 goto out; 4564 goto out;
4451 4565
4452 for (i = 0; i < arg_obj->properties->count; i++) 4566 for (i = 0; i < arg_obj->properties->count; i++)
4453 if (arg_obj->properties->ids[i] == arg->prop_id) 4567 if (arg_obj->properties->properties[i]->base.id == arg->prop_id)
4454 break; 4568 break;
4455 4569
4456 if (i == arg_obj->properties->count) 4570 if (i == arg_obj->properties->count)
@@ -4464,7 +4578,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4464 } 4578 }
4465 property = obj_to_property(prop_obj); 4579 property = obj_to_property(prop_obj);
4466 4580
4467 if (!drm_property_change_is_valid(property, arg->value)) 4581 if (!drm_property_change_valid_get(property, arg->value, &ref))
4468 goto out; 4582 goto out;
4469 4583
4470 switch (arg_obj->type) { 4584 switch (arg_obj->type) {
@@ -4481,6 +4595,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4481 break; 4595 break;
4482 } 4596 }
4483 4597
4598 drm_property_change_valid_put(property, ref);
4599
4484out: 4600out:
4485 drm_modeset_unlock_all(dev); 4601 drm_modeset_unlock_all(dev);
4486 return ret; 4602 return ret;
@@ -5225,8 +5341,7 @@ void drm_mode_config_init(struct drm_device *dev)
5225 idr_init(&dev->mode_config.tile_idr); 5341 idr_init(&dev->mode_config.tile_idr);
5226 5342
5227 drm_modeset_lock_all(dev); 5343 drm_modeset_lock_all(dev);
5228 drm_mode_create_standard_connector_properties(dev); 5344 drm_mode_create_standard_properties(dev);
5229 drm_mode_create_standard_plane_properties(dev);
5230 drm_modeset_unlock_all(dev); 5345 drm_modeset_unlock_all(dev);
5231 5346
5232 /* Just to be sure */ 5347 /* Just to be sure */