diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-08-29 04:27:51 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-08-29 09:37:13 -0400 |
commit | 949619f32eee37a6385de1e976523501c8256768 (patch) | |
tree | ca63ccb5ee58b89e664f7a7a0a3a6b9310193f42 | |
parent | e03e6de03e931bd3d93b1e2a9dc7d0bf0b505287 (diff) |
drm: Extract drm_mode_object.[hc]
Just for the struct drm_mode_object base class. The header file was
already partially extracted to help untangle the include loops.
v2:
- Also move the generic get/set property ioctls. At first this seemed
like a bad idea since it requires making drm_mode_crtc_set_obj_prop
non-static. But eventually that will get split away too (like
the connector version already is) for both crtc and planes. Hence I
reconsidered.
- drm_mode_object.[hc] instead of drm_modeset.[hc], which requires
renaming the drm_modeset.h header I already started building up.
This is more consistent (matches the name of the main structure),
and I want to be able to use drm_modeset.[hc] for the basic modeset
init/cleanup functionality like drm_mode_config_init.
Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160829082757.17913-3-daniel.vetter@ffwll.ch
-rw-r--r-- | Documentation/gpu/drm-kms.rst | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 413 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc_internal.h | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_mode_object.c | 435 | ||||
-rw-r--r-- | include/drm/drm_connector.h | 2 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 12 | ||||
-rw-r--r-- | include/drm/drm_encoder.h | 2 | ||||
-rw-r--r-- | include/drm/drm_framebuffer.h | 2 | ||||
-rw-r--r-- | include/drm/drm_mode_object.h (renamed from include/drm/drm_modeset.h) | 10 | ||||
-rw-r--r-- | include/drm/drm_modes.h | 2 |
11 files changed, 492 insertions, 449 deletions
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 47c2835b7c2d..b164472f2157 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst | |||
@@ -15,6 +15,15 @@ be setup by initializing the following fields. | |||
15 | - struct drm_mode_config_funcs \*funcs; | 15 | - struct drm_mode_config_funcs \*funcs; |
16 | Mode setting functions. | 16 | Mode setting functions. |
17 | 17 | ||
18 | Modeset Base Object Abstraction | ||
19 | =============================== | ||
20 | |||
21 | .. kernel-doc:: include/drm/drm_mode_object.h | ||
22 | :internal: | ||
23 | |||
24 | .. kernel-doc:: drivers/gpu/drm/drm_mode_object.c | ||
25 | :export: | ||
26 | |||
18 | KMS Data Structures | 27 | KMS Data Structures |
19 | =================== | 28 | =================== |
20 | 29 | ||
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index efdb4176230f..59979f3f3648 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ | |||
14 | drm_rect.o drm_vma_manager.o drm_flip_work.o \ | 14 | drm_rect.o drm_vma_manager.o drm_flip_work.o \ |
15 | drm_modeset_lock.o drm_atomic.o drm_bridge.o \ | 15 | drm_modeset_lock.o drm_atomic.o drm_bridge.o \ |
16 | drm_framebuffer.o drm_connector.o drm_blend.o \ | 16 | drm_framebuffer.o drm_connector.o drm_blend.o \ |
17 | drm_encoder.o | 17 | drm_encoder.o drm_mode_object.o |
18 | 18 | ||
19 | drm-$(CONFIG_COMPAT) += drm_ioc32.o | 19 | drm-$(CONFIG_COMPAT) += drm_ioc32.o |
20 | drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o | 20 | drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 219cd4ee23b7..c9dc031d9b36 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -57,162 +57,6 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = { | |||
57 | /* | 57 | /* |
58 | * Optional properties | 58 | * Optional properties |
59 | */ | 59 | */ |
60 | /* | ||
61 | * Internal function to assign a slot in the object idr and optionally | ||
62 | * register the object into the idr. | ||
63 | */ | ||
64 | int drm_mode_object_get_reg(struct drm_device *dev, | ||
65 | struct drm_mode_object *obj, | ||
66 | uint32_t obj_type, | ||
67 | bool register_obj, | ||
68 | void (*obj_free_cb)(struct kref *kref)) | ||
69 | { | ||
70 | int ret; | ||
71 | |||
72 | mutex_lock(&dev->mode_config.idr_mutex); | ||
73 | ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL); | ||
74 | if (ret >= 0) { | ||
75 | /* | ||
76 | * Set up the object linking under the protection of the idr | ||
77 | * lock so that other users can't see inconsistent state. | ||
78 | */ | ||
79 | obj->id = ret; | ||
80 | obj->type = obj_type; | ||
81 | if (obj_free_cb) { | ||
82 | obj->free_cb = obj_free_cb; | ||
83 | kref_init(&obj->refcount); | ||
84 | } | ||
85 | } | ||
86 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
87 | |||
88 | return ret < 0 ? ret : 0; | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * drm_mode_object_get - allocate a new modeset identifier | ||
93 | * @dev: DRM device | ||
94 | * @obj: object pointer, used to generate unique ID | ||
95 | * @obj_type: object type | ||
96 | * | ||
97 | * Create a unique identifier based on @ptr in @dev's identifier space. Used | ||
98 | * for tracking modes, CRTCs and connectors. Note that despite the _get postfix | ||
99 | * modeset identifiers are _not_ reference counted. Hence don't use this for | ||
100 | * reference counted modeset objects like framebuffers. | ||
101 | * | ||
102 | * Returns: | ||
103 | * Zero on success, error code on failure. | ||
104 | */ | ||
105 | int drm_mode_object_get(struct drm_device *dev, | ||
106 | struct drm_mode_object *obj, uint32_t obj_type) | ||
107 | { | ||
108 | return drm_mode_object_get_reg(dev, obj, obj_type, true, NULL); | ||
109 | } | ||
110 | |||
111 | void drm_mode_object_register(struct drm_device *dev, | ||
112 | struct drm_mode_object *obj) | ||
113 | { | ||
114 | mutex_lock(&dev->mode_config.idr_mutex); | ||
115 | idr_replace(&dev->mode_config.crtc_idr, obj, obj->id); | ||
116 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * drm_mode_object_unregister - free a modeset identifer | ||
121 | * @dev: DRM device | ||
122 | * @object: object to free | ||
123 | * | ||
124 | * Free @id from @dev's unique identifier pool. | ||
125 | * This function can be called multiple times, and guards against | ||
126 | * multiple removals. | ||
127 | * These modeset identifiers are _not_ reference counted. Hence don't use this | ||
128 | * for reference counted modeset objects like framebuffers. | ||
129 | */ | ||
130 | void drm_mode_object_unregister(struct drm_device *dev, | ||
131 | struct drm_mode_object *object) | ||
132 | { | ||
133 | mutex_lock(&dev->mode_config.idr_mutex); | ||
134 | if (object->id) { | ||
135 | idr_remove(&dev->mode_config.crtc_idr, object->id); | ||
136 | object->id = 0; | ||
137 | } | ||
138 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
139 | } | ||
140 | |||
141 | struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, | ||
142 | uint32_t id, uint32_t type) | ||
143 | { | ||
144 | struct drm_mode_object *obj = NULL; | ||
145 | |||
146 | mutex_lock(&dev->mode_config.idr_mutex); | ||
147 | obj = idr_find(&dev->mode_config.crtc_idr, id); | ||
148 | if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type) | ||
149 | obj = NULL; | ||
150 | if (obj && obj->id != id) | ||
151 | obj = NULL; | ||
152 | |||
153 | if (obj && obj->free_cb) { | ||
154 | if (!kref_get_unless_zero(&obj->refcount)) | ||
155 | obj = NULL; | ||
156 | } | ||
157 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
158 | |||
159 | return obj; | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * drm_mode_object_find - look up a drm object with static lifetime | ||
164 | * @dev: drm device | ||
165 | * @id: id of the mode object | ||
166 | * @type: type of the mode object | ||
167 | * | ||
168 | * This function is used to look up a modeset object. It will acquire a | ||
169 | * reference for reference counted objects. This reference must be dropped again | ||
170 | * by callind drm_mode_object_unreference(). | ||
171 | */ | ||
172 | struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, | ||
173 | uint32_t id, uint32_t type) | ||
174 | { | ||
175 | struct drm_mode_object *obj = NULL; | ||
176 | |||
177 | obj = __drm_mode_object_find(dev, id, type); | ||
178 | return obj; | ||
179 | } | ||
180 | EXPORT_SYMBOL(drm_mode_object_find); | ||
181 | |||
182 | /** | ||
183 | * drm_mode_object_unreference - decr the object refcnt | ||
184 | * @obj: mode_object | ||
185 | * | ||
186 | * This functions decrements the object's refcount if it is a refcounted modeset | ||
187 | * object. It is a no-op on any other object. This is used to drop references | ||
188 | * acquired with drm_mode_object_reference(). | ||
189 | */ | ||
190 | void drm_mode_object_unreference(struct drm_mode_object *obj) | ||
191 | { | ||
192 | if (obj->free_cb) { | ||
193 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); | ||
194 | kref_put(&obj->refcount, obj->free_cb); | ||
195 | } | ||
196 | } | ||
197 | EXPORT_SYMBOL(drm_mode_object_unreference); | ||
198 | |||
199 | /** | ||
200 | * drm_mode_object_reference - incr the object refcnt | ||
201 | * @obj: mode_object | ||
202 | * | ||
203 | * This functions increments the object's refcount if it is a refcounted modeset | ||
204 | * object. It is a no-op on any other object. References should be dropped again | ||
205 | * by calling drm_mode_object_unreference(). | ||
206 | */ | ||
207 | void drm_mode_object_reference(struct drm_mode_object *obj) | ||
208 | { | ||
209 | if (obj->free_cb) { | ||
210 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); | ||
211 | kref_get(&obj->refcount); | ||
212 | } | ||
213 | } | ||
214 | EXPORT_SYMBOL(drm_mode_object_reference); | ||
215 | |||
216 | /** | 60 | /** |
217 | * drm_crtc_force_disable - Forcibly turn off a CRTC | 61 | * drm_crtc_force_disable - Forcibly turn off a CRTC |
218 | * @crtc: CRTC to turn off | 62 | * @crtc: CRTC to turn off |
@@ -1010,45 +854,6 @@ int drm_mode_getcrtc(struct drm_device *dev, | |||
1010 | return 0; | 854 | return 0; |
1011 | } | 855 | } |
1012 | 856 | ||
1013 | /* helper for getconnector and getproperties ioctls */ | ||
1014 | int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, | ||
1015 | uint32_t __user *prop_ptr, | ||
1016 | uint64_t __user *prop_values, | ||
1017 | uint32_t *arg_count_props) | ||
1018 | { | ||
1019 | int props_count; | ||
1020 | int i, ret, copied; | ||
1021 | |||
1022 | props_count = obj->properties->count; | ||
1023 | if (!atomic) | ||
1024 | props_count -= obj->properties->atomic_count; | ||
1025 | |||
1026 | if ((*arg_count_props >= props_count) && props_count) { | ||
1027 | for (i = 0, copied = 0; copied < props_count; i++) { | ||
1028 | struct drm_property *prop = obj->properties->properties[i]; | ||
1029 | uint64_t val; | ||
1030 | |||
1031 | if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic) | ||
1032 | continue; | ||
1033 | |||
1034 | ret = drm_object_property_get_value(obj, prop, &val); | ||
1035 | if (ret) | ||
1036 | return ret; | ||
1037 | |||
1038 | if (put_user(prop->base.id, prop_ptr + copied)) | ||
1039 | return -EFAULT; | ||
1040 | |||
1041 | if (put_user(val, prop_values + copied)) | ||
1042 | return -EFAULT; | ||
1043 | |||
1044 | copied++; | ||
1045 | } | ||
1046 | } | ||
1047 | *arg_count_props = props_count; | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | /** | 857 | /** |
1053 | * drm_mode_getplane_res - enumerate all plane resources | 858 | * drm_mode_getplane_res - enumerate all plane resources |
1054 | * @dev: DRM device | 859 | * @dev: DRM device |
@@ -2291,105 +2096,6 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property) | |||
2291 | EXPORT_SYMBOL(drm_property_destroy); | 2096 | EXPORT_SYMBOL(drm_property_destroy); |
2292 | 2097 | ||
2293 | /** | 2098 | /** |
2294 | * drm_object_attach_property - attach a property to a modeset object | ||
2295 | * @obj: drm modeset object | ||
2296 | * @property: property to attach | ||
2297 | * @init_val: initial value of the property | ||
2298 | * | ||
2299 | * This attaches the given property to the modeset object with the given initial | ||
2300 | * value. Currently this function cannot fail since the properties are stored in | ||
2301 | * a statically sized array. | ||
2302 | */ | ||
2303 | void drm_object_attach_property(struct drm_mode_object *obj, | ||
2304 | struct drm_property *property, | ||
2305 | uint64_t init_val) | ||
2306 | { | ||
2307 | int count = obj->properties->count; | ||
2308 | |||
2309 | if (count == DRM_OBJECT_MAX_PROPERTY) { | ||
2310 | WARN(1, "Failed to attach object property (type: 0x%x). Please " | ||
2311 | "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time " | ||
2312 | "you see this message on the same object type.\n", | ||
2313 | obj->type); | ||
2314 | return; | ||
2315 | } | ||
2316 | |||
2317 | obj->properties->properties[count] = property; | ||
2318 | obj->properties->values[count] = init_val; | ||
2319 | obj->properties->count++; | ||
2320 | if (property->flags & DRM_MODE_PROP_ATOMIC) | ||
2321 | obj->properties->atomic_count++; | ||
2322 | } | ||
2323 | EXPORT_SYMBOL(drm_object_attach_property); | ||
2324 | |||
2325 | /** | ||
2326 | * drm_object_property_set_value - set the value of a property | ||
2327 | * @obj: drm mode object to set property value for | ||
2328 | * @property: property to set | ||
2329 | * @val: value the property should be set to | ||
2330 | * | ||
2331 | * This functions sets a given property on a given object. This function only | ||
2332 | * changes the software state of the property, it does not call into the | ||
2333 | * driver's ->set_property callback. | ||
2334 | * | ||
2335 | * Returns: | ||
2336 | * Zero on success, error code on failure. | ||
2337 | */ | ||
2338 | int drm_object_property_set_value(struct drm_mode_object *obj, | ||
2339 | struct drm_property *property, uint64_t val) | ||
2340 | { | ||
2341 | int i; | ||
2342 | |||
2343 | for (i = 0; i < obj->properties->count; i++) { | ||
2344 | if (obj->properties->properties[i] == property) { | ||
2345 | obj->properties->values[i] = val; | ||
2346 | return 0; | ||
2347 | } | ||
2348 | } | ||
2349 | |||
2350 | return -EINVAL; | ||
2351 | } | ||
2352 | EXPORT_SYMBOL(drm_object_property_set_value); | ||
2353 | |||
2354 | /** | ||
2355 | * drm_object_property_get_value - retrieve the value of a property | ||
2356 | * @obj: drm mode object to get property value from | ||
2357 | * @property: property to retrieve | ||
2358 | * @val: storage for the property value | ||
2359 | * | ||
2360 | * This function retrieves the softare state of the given property for the given | ||
2361 | * property. Since there is no driver callback to retrieve the current property | ||
2362 | * value this might be out of sync with the hardware, depending upon the driver | ||
2363 | * and property. | ||
2364 | * | ||
2365 | * Returns: | ||
2366 | * Zero on success, error code on failure. | ||
2367 | */ | ||
2368 | int drm_object_property_get_value(struct drm_mode_object *obj, | ||
2369 | struct drm_property *property, uint64_t *val) | ||
2370 | { | ||
2371 | int i; | ||
2372 | |||
2373 | /* read-only properties bypass atomic mechanism and still store | ||
2374 | * their value in obj->properties->values[].. mostly to avoid | ||
2375 | * having to deal w/ EDID and similar props in atomic paths: | ||
2376 | */ | ||
2377 | if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) && | ||
2378 | !(property->flags & DRM_MODE_PROP_IMMUTABLE)) | ||
2379 | return drm_atomic_get_property(obj, property, val); | ||
2380 | |||
2381 | for (i = 0; i < obj->properties->count; i++) { | ||
2382 | if (obj->properties->properties[i] == property) { | ||
2383 | *val = obj->properties->values[i]; | ||
2384 | return 0; | ||
2385 | } | ||
2386 | } | ||
2387 | |||
2388 | return -EINVAL; | ||
2389 | } | ||
2390 | EXPORT_SYMBOL(drm_object_property_get_value); | ||
2391 | |||
2392 | /** | ||
2393 | * drm_mode_getproperty_ioctl - get the property metadata | 2099 | * drm_mode_getproperty_ioctl - get the property metadata |
2394 | * @dev: DRM device | 2100 | * @dev: DRM device |
2395 | * @data: ioctl data | 2101 | * @data: ioctl data |
@@ -2934,9 +2640,9 @@ void drm_property_change_valid_put(struct drm_property *property, | |||
2934 | drm_property_unreference_blob(obj_to_blob(ref)); | 2640 | drm_property_unreference_blob(obj_to_blob(ref)); |
2935 | } | 2641 | } |
2936 | 2642 | ||
2937 | static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, | 2643 | int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, |
2938 | struct drm_property *property, | 2644 | struct drm_property *property, |
2939 | uint64_t value) | 2645 | uint64_t value) |
2940 | { | 2646 | { |
2941 | int ret = -EINVAL; | 2647 | int ret = -EINVAL; |
2942 | struct drm_crtc *crtc = obj_to_crtc(obj); | 2648 | struct drm_crtc *crtc = obj_to_crtc(obj); |
@@ -2979,119 +2685,6 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane, | |||
2979 | EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); | 2685 | EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); |
2980 | 2686 | ||
2981 | /** | 2687 | /** |
2982 | * drm_mode_obj_get_properties_ioctl - get the current value of a object's property | ||
2983 | * @dev: DRM device | ||
2984 | * @data: ioctl data | ||
2985 | * @file_priv: DRM file info | ||
2986 | * | ||
2987 | * This function retrieves the current value for an object's property. Compared | ||
2988 | * to the connector specific ioctl this one is extended to also work on crtc and | ||
2989 | * plane objects. | ||
2990 | * | ||
2991 | * Called by the user via ioctl. | ||
2992 | * | ||
2993 | * Returns: | ||
2994 | * Zero on success, negative errno on failure. | ||
2995 | */ | ||
2996 | int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, | ||
2997 | struct drm_file *file_priv) | ||
2998 | { | ||
2999 | struct drm_mode_obj_get_properties *arg = data; | ||
3000 | struct drm_mode_object *obj; | ||
3001 | int ret = 0; | ||
3002 | |||
3003 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
3004 | return -EINVAL; | ||
3005 | |||
3006 | drm_modeset_lock_all(dev); | ||
3007 | |||
3008 | obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); | ||
3009 | if (!obj) { | ||
3010 | ret = -ENOENT; | ||
3011 | goto out; | ||
3012 | } | ||
3013 | if (!obj->properties) { | ||
3014 | ret = -EINVAL; | ||
3015 | goto out_unref; | ||
3016 | } | ||
3017 | |||
3018 | ret = drm_mode_object_get_properties(obj, file_priv->atomic, | ||
3019 | (uint32_t __user *)(unsigned long)(arg->props_ptr), | ||
3020 | (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), | ||
3021 | &arg->count_props); | ||
3022 | |||
3023 | out_unref: | ||
3024 | drm_mode_object_unreference(obj); | ||
3025 | out: | ||
3026 | drm_modeset_unlock_all(dev); | ||
3027 | return ret; | ||
3028 | } | ||
3029 | |||
3030 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, | ||
3031 | struct drm_file *file_priv) | ||
3032 | { | ||
3033 | struct drm_mode_obj_set_property *arg = data; | ||
3034 | struct drm_mode_object *arg_obj; | ||
3035 | struct drm_mode_object *prop_obj; | ||
3036 | struct drm_property *property; | ||
3037 | int i, ret = -EINVAL; | ||
3038 | struct drm_mode_object *ref; | ||
3039 | |||
3040 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
3041 | return -EINVAL; | ||
3042 | |||
3043 | drm_modeset_lock_all(dev); | ||
3044 | |||
3045 | arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); | ||
3046 | if (!arg_obj) { | ||
3047 | ret = -ENOENT; | ||
3048 | goto out; | ||
3049 | } | ||
3050 | if (!arg_obj->properties) | ||
3051 | goto out_unref; | ||
3052 | |||
3053 | for (i = 0; i < arg_obj->properties->count; i++) | ||
3054 | if (arg_obj->properties->properties[i]->base.id == arg->prop_id) | ||
3055 | break; | ||
3056 | |||
3057 | if (i == arg_obj->properties->count) | ||
3058 | goto out_unref; | ||
3059 | |||
3060 | prop_obj = drm_mode_object_find(dev, arg->prop_id, | ||
3061 | DRM_MODE_OBJECT_PROPERTY); | ||
3062 | if (!prop_obj) { | ||
3063 | ret = -ENOENT; | ||
3064 | goto out_unref; | ||
3065 | } | ||
3066 | property = obj_to_property(prop_obj); | ||
3067 | |||
3068 | if (!drm_property_change_valid_get(property, arg->value, &ref)) | ||
3069 | goto out_unref; | ||
3070 | |||
3071 | switch (arg_obj->type) { | ||
3072 | case DRM_MODE_OBJECT_CONNECTOR: | ||
3073 | ret = drm_mode_connector_set_obj_prop(arg_obj, property, | ||
3074 | arg->value); | ||
3075 | break; | ||
3076 | case DRM_MODE_OBJECT_CRTC: | ||
3077 | ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value); | ||
3078 | break; | ||
3079 | case DRM_MODE_OBJECT_PLANE: | ||
3080 | ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj), | ||
3081 | property, arg->value); | ||
3082 | break; | ||
3083 | } | ||
3084 | |||
3085 | drm_property_change_valid_put(property, ref); | ||
3086 | |||
3087 | out_unref: | ||
3088 | drm_mode_object_unreference(arg_obj); | ||
3089 | out: | ||
3090 | drm_modeset_unlock_all(dev); | ||
3091 | return ret; | ||
3092 | } | ||
3093 | |||
3094 | /** | ||
3095 | * drm_mode_crtc_set_gamma_size - set the gamma table size | 2688 | * drm_mode_crtc_set_gamma_size - set the gamma table size |
3096 | * @crtc: CRTC to set the gamma table size for | 2689 | * @crtc: CRTC to set the gamma table size for |
3097 | * @gamma_size: size of the gamma table | 2690 | * @gamma_size: size of the gamma table |
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 54f9a2c85965..2eb1d941ea70 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h | |||
@@ -33,29 +33,14 @@ | |||
33 | 33 | ||
34 | 34 | ||
35 | /* drm_crtc.c */ | 35 | /* drm_crtc.c */ |
36 | int drm_mode_object_get_reg(struct drm_device *dev, | 36 | int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, |
37 | struct drm_mode_object *obj, | 37 | struct drm_property *property, |
38 | uint32_t obj_type, | 38 | uint64_t value); |
39 | bool register_obj, | ||
40 | void (*obj_free_cb)(struct kref *kref)); | ||
41 | void drm_mode_object_register(struct drm_device *dev, | ||
42 | struct drm_mode_object *obj); | ||
43 | int drm_mode_object_get(struct drm_device *dev, | ||
44 | struct drm_mode_object *obj, uint32_t obj_type); | ||
45 | struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, | ||
46 | uint32_t id, uint32_t type); | ||
47 | void drm_mode_object_unregister(struct drm_device *dev, | ||
48 | struct drm_mode_object *object); | ||
49 | int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, | ||
50 | uint32_t __user *prop_ptr, | ||
51 | uint64_t __user *prop_values, | ||
52 | uint32_t *arg_count_props); | ||
53 | bool drm_property_change_valid_get(struct drm_property *property, | 39 | bool drm_property_change_valid_get(struct drm_property *property, |
54 | uint64_t value, | 40 | uint64_t value, |
55 | struct drm_mode_object **ref); | 41 | struct drm_mode_object **ref); |
56 | void drm_property_change_valid_put(struct drm_property *property, | 42 | void drm_property_change_valid_put(struct drm_property *property, |
57 | struct drm_mode_object *ref); | 43 | struct drm_mode_object *ref); |
58 | |||
59 | int drm_plane_check_pixel_format(const struct drm_plane *plane, | 44 | int drm_plane_check_pixel_format(const struct drm_plane *plane, |
60 | u32 format); | 45 | u32 format); |
61 | int drm_crtc_check_viewport(const struct drm_crtc *crtc, | 46 | int drm_crtc_check_viewport(const struct drm_crtc *crtc, |
@@ -76,11 +61,6 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, | |||
76 | void *data, struct drm_file *file_priv); | 61 | void *data, struct drm_file *file_priv); |
77 | 62 | ||
78 | /* IOCTLs */ | 63 | /* IOCTLs */ |
79 | int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, | ||
80 | struct drm_file *file_priv); | ||
81 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, | ||
82 | struct drm_file *file_priv); | ||
83 | |||
84 | int drm_mode_getresources(struct drm_device *dev, | 64 | int drm_mode_getresources(struct drm_device *dev, |
85 | void *data, struct drm_file *file_priv); | 65 | void *data, struct drm_file *file_priv); |
86 | int drm_mode_getplane_res(struct drm_device *dev, void *data, | 66 | int drm_mode_getplane_res(struct drm_device *dev, void *data, |
@@ -113,6 +93,32 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, | |||
113 | int drm_mode_page_flip_ioctl(struct drm_device *dev, | 93 | int drm_mode_page_flip_ioctl(struct drm_device *dev, |
114 | void *data, struct drm_file *file_priv); | 94 | void *data, struct drm_file *file_priv); |
115 | 95 | ||
96 | /* drm_mode_object.c */ | ||
97 | int drm_mode_object_get_reg(struct drm_device *dev, | ||
98 | struct drm_mode_object *obj, | ||
99 | uint32_t obj_type, | ||
100 | bool register_obj, | ||
101 | void (*obj_free_cb)(struct kref *kref)); | ||
102 | void drm_mode_object_register(struct drm_device *dev, | ||
103 | struct drm_mode_object *obj); | ||
104 | int drm_mode_object_get(struct drm_device *dev, | ||
105 | struct drm_mode_object *obj, uint32_t obj_type); | ||
106 | struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, | ||
107 | uint32_t id, uint32_t type); | ||
108 | void drm_mode_object_unregister(struct drm_device *dev, | ||
109 | struct drm_mode_object *object); | ||
110 | int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, | ||
111 | uint32_t __user *prop_ptr, | ||
112 | uint64_t __user *prop_values, | ||
113 | uint32_t *arg_count_props); | ||
114 | |||
115 | /* IOCTL */ | ||
116 | |||
117 | int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, | ||
118 | struct drm_file *file_priv); | ||
119 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, | ||
120 | struct drm_file *file_priv); | ||
121 | |||
116 | /* drm_encoder.c */ | 122 | /* drm_encoder.c */ |
117 | int drm_encoder_register_all(struct drm_device *dev); | 123 | int drm_encoder_register_all(struct drm_device *dev); |
118 | void drm_encoder_unregister_all(struct drm_device *dev); | 124 | void drm_encoder_unregister_all(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c new file mode 100644 index 000000000000..cef9104e8285 --- /dev/null +++ b/drivers/gpu/drm/drm_mode_object.c | |||
@@ -0,0 +1,435 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Intel Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that copyright | ||
7 | * notice and this permission notice appear in supporting documentation, and | ||
8 | * that the name of the copyright holders not be used in advertising or | ||
9 | * publicity pertaining to distribution of the software without specific, | ||
10 | * written prior permission. The copyright holders make no representations | ||
11 | * about the suitability of this software for any purpose. It is provided "as | ||
12 | * is" without express or implied warranty. | ||
13 | * | ||
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||
20 | * OF THIS SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #include <linux/export.h> | ||
24 | #include <drm/drmP.h> | ||
25 | #include <drm/drm_mode_object.h> | ||
26 | |||
27 | #include "drm_crtc_internal.h" | ||
28 | |||
29 | /* | ||
30 | * Internal function to assign a slot in the object idr and optionally | ||
31 | * register the object into the idr. | ||
32 | */ | ||
33 | int drm_mode_object_get_reg(struct drm_device *dev, | ||
34 | struct drm_mode_object *obj, | ||
35 | uint32_t obj_type, | ||
36 | bool register_obj, | ||
37 | void (*obj_free_cb)(struct kref *kref)) | ||
38 | { | ||
39 | int ret; | ||
40 | |||
41 | mutex_lock(&dev->mode_config.idr_mutex); | ||
42 | ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL); | ||
43 | if (ret >= 0) { | ||
44 | /* | ||
45 | * Set up the object linking under the protection of the idr | ||
46 | * lock so that other users can't see inconsistent state. | ||
47 | */ | ||
48 | obj->id = ret; | ||
49 | obj->type = obj_type; | ||
50 | if (obj_free_cb) { | ||
51 | obj->free_cb = obj_free_cb; | ||
52 | kref_init(&obj->refcount); | ||
53 | } | ||
54 | } | ||
55 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
56 | |||
57 | return ret < 0 ? ret : 0; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * drm_mode_object_get - allocate a new modeset identifier | ||
62 | * @dev: DRM device | ||
63 | * @obj: object pointer, used to generate unique ID | ||
64 | * @obj_type: object type | ||
65 | * | ||
66 | * Create a unique identifier based on @ptr in @dev's identifier space. Used | ||
67 | * for tracking modes, CRTCs and connectors. Note that despite the _get postfix | ||
68 | * modeset identifiers are _not_ reference counted. Hence don't use this for | ||
69 | * reference counted modeset objects like framebuffers. | ||
70 | * | ||
71 | * Returns: | ||
72 | * Zero on success, error code on failure. | ||
73 | */ | ||
74 | int drm_mode_object_get(struct drm_device *dev, | ||
75 | struct drm_mode_object *obj, uint32_t obj_type) | ||
76 | { | ||
77 | return drm_mode_object_get_reg(dev, obj, obj_type, true, NULL); | ||
78 | } | ||
79 | |||
80 | void drm_mode_object_register(struct drm_device *dev, | ||
81 | struct drm_mode_object *obj) | ||
82 | { | ||
83 | mutex_lock(&dev->mode_config.idr_mutex); | ||
84 | idr_replace(&dev->mode_config.crtc_idr, obj, obj->id); | ||
85 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * drm_mode_object_unregister - free a modeset identifer | ||
90 | * @dev: DRM device | ||
91 | * @object: object to free | ||
92 | * | ||
93 | * Free @id from @dev's unique identifier pool. | ||
94 | * This function can be called multiple times, and guards against | ||
95 | * multiple removals. | ||
96 | * These modeset identifiers are _not_ reference counted. Hence don't use this | ||
97 | * for reference counted modeset objects like framebuffers. | ||
98 | */ | ||
99 | void drm_mode_object_unregister(struct drm_device *dev, | ||
100 | struct drm_mode_object *object) | ||
101 | { | ||
102 | mutex_lock(&dev->mode_config.idr_mutex); | ||
103 | if (object->id) { | ||
104 | idr_remove(&dev->mode_config.crtc_idr, object->id); | ||
105 | object->id = 0; | ||
106 | } | ||
107 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
108 | } | ||
109 | |||
110 | struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, | ||
111 | uint32_t id, uint32_t type) | ||
112 | { | ||
113 | struct drm_mode_object *obj = NULL; | ||
114 | |||
115 | mutex_lock(&dev->mode_config.idr_mutex); | ||
116 | obj = idr_find(&dev->mode_config.crtc_idr, id); | ||
117 | if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type) | ||
118 | obj = NULL; | ||
119 | if (obj && obj->id != id) | ||
120 | obj = NULL; | ||
121 | |||
122 | if (obj && obj->free_cb) { | ||
123 | if (!kref_get_unless_zero(&obj->refcount)) | ||
124 | obj = NULL; | ||
125 | } | ||
126 | mutex_unlock(&dev->mode_config.idr_mutex); | ||
127 | |||
128 | return obj; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * drm_mode_object_find - look up a drm object with static lifetime | ||
133 | * @dev: drm device | ||
134 | * @id: id of the mode object | ||
135 | * @type: type of the mode object | ||
136 | * | ||
137 | * This function is used to look up a modeset object. It will acquire a | ||
138 | * reference for reference counted objects. This reference must be dropped again | ||
139 | * by callind drm_mode_object_unreference(). | ||
140 | */ | ||
141 | struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, | ||
142 | uint32_t id, uint32_t type) | ||
143 | { | ||
144 | struct drm_mode_object *obj = NULL; | ||
145 | |||
146 | obj = __drm_mode_object_find(dev, id, type); | ||
147 | return obj; | ||
148 | } | ||
149 | EXPORT_SYMBOL(drm_mode_object_find); | ||
150 | |||
151 | /** | ||
152 | * drm_mode_object_unreference - decr the object refcnt | ||
153 | * @obj: mode_object | ||
154 | * | ||
155 | * This functions decrements the object's refcount if it is a refcounted modeset | ||
156 | * object. It is a no-op on any other object. This is used to drop references | ||
157 | * acquired with drm_mode_object_reference(). | ||
158 | */ | ||
159 | void drm_mode_object_unreference(struct drm_mode_object *obj) | ||
160 | { | ||
161 | if (obj->free_cb) { | ||
162 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); | ||
163 | kref_put(&obj->refcount, obj->free_cb); | ||
164 | } | ||
165 | } | ||
166 | EXPORT_SYMBOL(drm_mode_object_unreference); | ||
167 | |||
168 | /** | ||
169 | * drm_mode_object_reference - incr the object refcnt | ||
170 | * @obj: mode_object | ||
171 | * | ||
172 | * This functions increments the object's refcount if it is a refcounted modeset | ||
173 | * object. It is a no-op on any other object. References should be dropped again | ||
174 | * by calling drm_mode_object_unreference(). | ||
175 | */ | ||
176 | void drm_mode_object_reference(struct drm_mode_object *obj) | ||
177 | { | ||
178 | if (obj->free_cb) { | ||
179 | DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); | ||
180 | kref_get(&obj->refcount); | ||
181 | } | ||
182 | } | ||
183 | EXPORT_SYMBOL(drm_mode_object_reference); | ||
184 | |||
185 | /** | ||
186 | * drm_object_attach_property - attach a property to a modeset object | ||
187 | * @obj: drm modeset object | ||
188 | * @property: property to attach | ||
189 | * @init_val: initial value of the property | ||
190 | * | ||
191 | * This attaches the given property to the modeset object with the given initial | ||
192 | * value. Currently this function cannot fail since the properties are stored in | ||
193 | * a statically sized array. | ||
194 | */ | ||
195 | void drm_object_attach_property(struct drm_mode_object *obj, | ||
196 | struct drm_property *property, | ||
197 | uint64_t init_val) | ||
198 | { | ||
199 | int count = obj->properties->count; | ||
200 | |||
201 | if (count == DRM_OBJECT_MAX_PROPERTY) { | ||
202 | WARN(1, "Failed to attach object property (type: 0x%x). Please " | ||
203 | "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time " | ||
204 | "you see this message on the same object type.\n", | ||
205 | obj->type); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | obj->properties->properties[count] = property; | ||
210 | obj->properties->values[count] = init_val; | ||
211 | obj->properties->count++; | ||
212 | if (property->flags & DRM_MODE_PROP_ATOMIC) | ||
213 | obj->properties->atomic_count++; | ||
214 | } | ||
215 | EXPORT_SYMBOL(drm_object_attach_property); | ||
216 | |||
217 | /** | ||
218 | * drm_object_property_set_value - set the value of a property | ||
219 | * @obj: drm mode object to set property value for | ||
220 | * @property: property to set | ||
221 | * @val: value the property should be set to | ||
222 | * | ||
223 | * This functions sets a given property on a given object. This function only | ||
224 | * changes the software state of the property, it does not call into the | ||
225 | * driver's ->set_property callback. | ||
226 | * | ||
227 | * Returns: | ||
228 | * Zero on success, error code on failure. | ||
229 | */ | ||
230 | int drm_object_property_set_value(struct drm_mode_object *obj, | ||
231 | struct drm_property *property, uint64_t val) | ||
232 | { | ||
233 | int i; | ||
234 | |||
235 | for (i = 0; i < obj->properties->count; i++) { | ||
236 | if (obj->properties->properties[i] == property) { | ||
237 | obj->properties->values[i] = val; | ||
238 | return 0; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | return -EINVAL; | ||
243 | } | ||
244 | EXPORT_SYMBOL(drm_object_property_set_value); | ||
245 | |||
246 | /** | ||
247 | * drm_object_property_get_value - retrieve the value of a property | ||
248 | * @obj: drm mode object to get property value from | ||
249 | * @property: property to retrieve | ||
250 | * @val: storage for the property value | ||
251 | * | ||
252 | * This function retrieves the softare state of the given property for the given | ||
253 | * property. Since there is no driver callback to retrieve the current property | ||
254 | * value this might be out of sync with the hardware, depending upon the driver | ||
255 | * and property. | ||
256 | * | ||
257 | * Returns: | ||
258 | * Zero on success, error code on failure. | ||
259 | */ | ||
260 | int drm_object_property_get_value(struct drm_mode_object *obj, | ||
261 | struct drm_property *property, uint64_t *val) | ||
262 | { | ||
263 | int i; | ||
264 | |||
265 | /* read-only properties bypass atomic mechanism and still store | ||
266 | * their value in obj->properties->values[].. mostly to avoid | ||
267 | * having to deal w/ EDID and similar props in atomic paths: | ||
268 | */ | ||
269 | if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) && | ||
270 | !(property->flags & DRM_MODE_PROP_IMMUTABLE)) | ||
271 | return drm_atomic_get_property(obj, property, val); | ||
272 | |||
273 | for (i = 0; i < obj->properties->count; i++) { | ||
274 | if (obj->properties->properties[i] == property) { | ||
275 | *val = obj->properties->values[i]; | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | } | ||
280 | |||
281 | return -EINVAL; | ||
282 | } | ||
283 | EXPORT_SYMBOL(drm_object_property_get_value); | ||
284 | |||
285 | /* helper for getconnector and getproperties ioctls */ | ||
286 | int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, | ||
287 | uint32_t __user *prop_ptr, | ||
288 | uint64_t __user *prop_values, | ||
289 | uint32_t *arg_count_props) | ||
290 | { | ||
291 | int props_count; | ||
292 | int i, ret, copied; | ||
293 | |||
294 | props_count = obj->properties->count; | ||
295 | if (!atomic) | ||
296 | props_count -= obj->properties->atomic_count; | ||
297 | |||
298 | if ((*arg_count_props >= props_count) && props_count) { | ||
299 | for (i = 0, copied = 0; copied < props_count; i++) { | ||
300 | struct drm_property *prop = obj->properties->properties[i]; | ||
301 | uint64_t val; | ||
302 | |||
303 | if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic) | ||
304 | continue; | ||
305 | |||
306 | ret = drm_object_property_get_value(obj, prop, &val); | ||
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
310 | if (put_user(prop->base.id, prop_ptr + copied)) | ||
311 | return -EFAULT; | ||
312 | |||
313 | if (put_user(val, prop_values + copied)) | ||
314 | return -EFAULT; | ||
315 | |||
316 | copied++; | ||
317 | } | ||
318 | } | ||
319 | *arg_count_props = props_count; | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * drm_mode_obj_get_properties_ioctl - get the current value of a object's property | ||
326 | * @dev: DRM device | ||
327 | * @data: ioctl data | ||
328 | * @file_priv: DRM file info | ||
329 | * | ||
330 | * This function retrieves the current value for an object's property. Compared | ||
331 | * to the connector specific ioctl this one is extended to also work on crtc and | ||
332 | * plane objects. | ||
333 | * | ||
334 | * Called by the user via ioctl. | ||
335 | * | ||
336 | * Returns: | ||
337 | * Zero on success, negative errno on failure. | ||
338 | */ | ||
339 | int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, | ||
340 | struct drm_file *file_priv) | ||
341 | { | ||
342 | struct drm_mode_obj_get_properties *arg = data; | ||
343 | struct drm_mode_object *obj; | ||
344 | int ret = 0; | ||
345 | |||
346 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
347 | return -EINVAL; | ||
348 | |||
349 | drm_modeset_lock_all(dev); | ||
350 | |||
351 | obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); | ||
352 | if (!obj) { | ||
353 | ret = -ENOENT; | ||
354 | goto out; | ||
355 | } | ||
356 | if (!obj->properties) { | ||
357 | ret = -EINVAL; | ||
358 | goto out_unref; | ||
359 | } | ||
360 | |||
361 | ret = drm_mode_object_get_properties(obj, file_priv->atomic, | ||
362 | (uint32_t __user *)(unsigned long)(arg->props_ptr), | ||
363 | (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), | ||
364 | &arg->count_props); | ||
365 | |||
366 | out_unref: | ||
367 | drm_mode_object_unreference(obj); | ||
368 | out: | ||
369 | drm_modeset_unlock_all(dev); | ||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, | ||
374 | struct drm_file *file_priv) | ||
375 | { | ||
376 | struct drm_mode_obj_set_property *arg = data; | ||
377 | struct drm_mode_object *arg_obj; | ||
378 | struct drm_mode_object *prop_obj; | ||
379 | struct drm_property *property; | ||
380 | int i, ret = -EINVAL; | ||
381 | struct drm_mode_object *ref; | ||
382 | |||
383 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
384 | return -EINVAL; | ||
385 | |||
386 | drm_modeset_lock_all(dev); | ||
387 | |||
388 | arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); | ||
389 | if (!arg_obj) { | ||
390 | ret = -ENOENT; | ||
391 | goto out; | ||
392 | } | ||
393 | if (!arg_obj->properties) | ||
394 | goto out_unref; | ||
395 | |||
396 | for (i = 0; i < arg_obj->properties->count; i++) | ||
397 | if (arg_obj->properties->properties[i]->base.id == arg->prop_id) | ||
398 | break; | ||
399 | |||
400 | if (i == arg_obj->properties->count) | ||
401 | goto out_unref; | ||
402 | |||
403 | prop_obj = drm_mode_object_find(dev, arg->prop_id, | ||
404 | DRM_MODE_OBJECT_PROPERTY); | ||
405 | if (!prop_obj) { | ||
406 | ret = -ENOENT; | ||
407 | goto out_unref; | ||
408 | } | ||
409 | property = obj_to_property(prop_obj); | ||
410 | |||
411 | if (!drm_property_change_valid_get(property, arg->value, &ref)) | ||
412 | goto out_unref; | ||
413 | |||
414 | switch (arg_obj->type) { | ||
415 | case DRM_MODE_OBJECT_CONNECTOR: | ||
416 | ret = drm_mode_connector_set_obj_prop(arg_obj, property, | ||
417 | arg->value); | ||
418 | break; | ||
419 | case DRM_MODE_OBJECT_CRTC: | ||
420 | ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value); | ||
421 | break; | ||
422 | case DRM_MODE_OBJECT_PLANE: | ||
423 | ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj), | ||
424 | property, arg->value); | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | drm_property_change_valid_put(property, ref); | ||
429 | |||
430 | out_unref: | ||
431 | drm_mode_object_unreference(arg_obj); | ||
432 | out: | ||
433 | drm_modeset_unlock_all(dev); | ||
434 | return ret; | ||
435 | } | ||
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index f1576db6c044..66b7d6744dd2 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
27 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
28 | #include <drm/drm_modeset.h> | 28 | #include <drm/drm_mode_object.h> |
29 | 29 | ||
30 | struct drm_connector_helper_funcs; | 30 | struct drm_connector_helper_funcs; |
31 | struct drm_device; | 31 | struct drm_device; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c459867ecb9c..8ea3e65fe0c2 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <uapi/drm/drm_fourcc.h> | 36 | #include <uapi/drm/drm_fourcc.h> |
37 | #include <drm/drm_modeset_lock.h> | 37 | #include <drm/drm_modeset_lock.h> |
38 | #include <drm/drm_rect.h> | 38 | #include <drm/drm_rect.h> |
39 | #include <drm/drm_modeset.h> | 39 | #include <drm/drm_mode_object.h> |
40 | #include <drm/drm_framebuffer.h> | 40 | #include <drm/drm_framebuffer.h> |
41 | #include <drm/drm_modes.h> | 41 | #include <drm/drm_modes.h> |
42 | #include <drm/drm_connector.h> | 42 | #include <drm/drm_connector.h> |
@@ -2116,16 +2116,6 @@ static inline bool drm_property_type_is(struct drm_property *property, | |||
2116 | return property->flags & type; | 2116 | return property->flags & type; |
2117 | } | 2117 | } |
2118 | 2118 | ||
2119 | extern int drm_object_property_set_value(struct drm_mode_object *obj, | ||
2120 | struct drm_property *property, | ||
2121 | uint64_t val); | ||
2122 | extern int drm_object_property_get_value(struct drm_mode_object *obj, | ||
2123 | struct drm_property *property, | ||
2124 | uint64_t *value); | ||
2125 | |||
2126 | extern void drm_object_attach_property(struct drm_mode_object *obj, | ||
2127 | struct drm_property *property, | ||
2128 | uint64_t init_val); | ||
2129 | extern struct drm_property *drm_property_create(struct drm_device *dev, int flags, | 2119 | extern struct drm_property *drm_property_create(struct drm_device *dev, int flags, |
2130 | const char *name, int num_values); | 2120 | const char *name, int num_values); |
2131 | extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, | 2121 | extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, |
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 3d7350f1fcc1..fce0203094f7 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
27 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
28 | #include <drm/drm_modeset.h> | 28 | #include <drm/drm_mode_object.h> |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * struct drm_encoder_funcs - encoder controls | 31 | * struct drm_encoder_funcs - encoder controls |
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h index 50deb40d3bfd..b2554c50a903 100644 --- a/include/drm/drm_framebuffer.h +++ b/include/drm/drm_framebuffer.h | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
27 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
28 | #include <drm/drm_modeset.h> | 28 | #include <drm/drm_mode_object.h> |
29 | 29 | ||
30 | struct drm_framebuffer; | 30 | struct drm_framebuffer; |
31 | struct drm_file; | 31 | struct drm_file; |
diff --git a/include/drm/drm_modeset.h b/include/drm/drm_mode_object.h index fe910d5efe12..c0e4414299f7 100644 --- a/include/drm/drm_modeset.h +++ b/include/drm/drm_mode_object.h | |||
@@ -67,4 +67,14 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, | |||
67 | void drm_mode_object_reference(struct drm_mode_object *obj); | 67 | void drm_mode_object_reference(struct drm_mode_object *obj); |
68 | void drm_mode_object_unreference(struct drm_mode_object *obj); | 68 | void drm_mode_object_unreference(struct drm_mode_object *obj); |
69 | 69 | ||
70 | int drm_object_property_set_value(struct drm_mode_object *obj, | ||
71 | struct drm_property *property, | ||
72 | uint64_t val); | ||
73 | int drm_object_property_get_value(struct drm_mode_object *obj, | ||
74 | struct drm_property *property, | ||
75 | uint64_t *value); | ||
76 | |||
77 | void drm_object_attach_property(struct drm_mode_object *obj, | ||
78 | struct drm_property *property, | ||
79 | uint64_t init_val); | ||
70 | #endif | 80 | #endif |
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 1621e9b32330..011f199d3bcf 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #ifndef __DRM_MODES_H__ | 27 | #ifndef __DRM_MODES_H__ |
28 | #define __DRM_MODES_H__ | 28 | #define __DRM_MODES_H__ |
29 | 29 | ||
30 | #include <drm/drm_modeset.h> | 30 | #include <drm/drm_mode_object.h> |
31 | #include <drm/drm_connector.h> | 31 | #include <drm/drm_connector.h> |
32 | 32 | ||
33 | /* | 33 | /* |