da55deb2c8b97a4dfcf5f73d7919355eebfca410
[dragonfly.git] / sys / dev / drm / drm_crtc.c
1 /*
2  * Copyright (c) 2006-2008 Intel Corporation
3  * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
4  * Copyright (c) 2008 Red Hat Inc.
5  *
6  * DRM core CRTC related functions
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and its
9  * documentation for any purpose is hereby granted without fee, provided that
10  * the above copyright notice appear in all copies and that both that copyright
11  * notice and this permission notice appear in supporting documentation, and
12  * that the name of the copyright holders not be used in advertising or
13  * publicity pertaining to distribution of the software without specific,
14  * written prior permission.  The copyright holders make no representations
15  * about the suitability of this software for any purpose.  It is provided "as
16  * is" without express or implied warranty.
17  *
18  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  *
26  * Authors:
27  *      Keith Packard
28  *      Eric Anholt <eric@anholt.net>
29  *      Dave Airlie <airlied@linux.ie>
30  *      Jesse Barnes <jesse.barnes@intel.com>
31  */
32 #include <linux/list.h>
33 #include <linux/slab.h>
34 #include <linux/export.h>
35 #include <drm/drmP.h>
36 #include <drm/drm_crtc.h>
37 #include <drm/drm_edid.h>
38 #include <uapi_drm/drm_fourcc.h>
39
40 /**
41  * drm_modeset_lock_all - take all modeset locks
42  * @dev: drm device
43  *
44  * This function takes all modeset locks, suitable where a more fine-grained
45  * scheme isn't (yet) implemented.
46  */
47 void drm_modeset_lock_all(struct drm_device *dev)
48 {
49         struct drm_crtc *crtc;
50
51         mutex_lock(&dev->mode_config.mutex);
52
53         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
54 //              mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
55                 lockmgr(&crtc->mutex, LK_EXCLUSIVE);
56 }
57 EXPORT_SYMBOL(drm_modeset_lock_all);
58
59 /**
60  * drm_modeset_unlock_all - drop all modeset locks
61  * @dev: device
62  */
63 void drm_modeset_unlock_all(struct drm_device *dev)
64 {
65         struct drm_crtc *crtc;
66
67         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
68                 mutex_unlock(&crtc->mutex);
69
70         mutex_unlock(&dev->mode_config.mutex);
71 }
72 EXPORT_SYMBOL(drm_modeset_unlock_all);
73
74 /**
75  * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked
76  * @dev: device
77  */
78 void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
79 {
80         struct drm_crtc *crtc;
81
82 #if 0
83         /* Locking is currently fubar in the panic handler. */
84         if (oops_in_progress)
85                 return;
86 #endif
87
88         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
89                 WARN_ON(!mutex_is_locked(&crtc->mutex));
90
91         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
92 }
93 EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked);
94
95 /* Avoid boilerplate.  I'm tired of typing. */
96 #define DRM_ENUM_NAME_FN(fnname, list)                          \
97         char *fnname(int val)                                   \
98         {                                                       \
99                 int i;                                          \
100                 for (i = 0; i < ARRAY_SIZE(list); i++) {        \
101                         if (list[i].type == val)                \
102                                 return list[i].name;            \
103                 }                                               \
104                 return "(unknown)";                             \
105         }
106
107 /*
108  * Global properties
109  */
110 static struct drm_prop_enum_list drm_dpms_enum_list[] =
111 {       { DRM_MODE_DPMS_ON, "On" },
112         { DRM_MODE_DPMS_STANDBY, "Standby" },
113         { DRM_MODE_DPMS_SUSPEND, "Suspend" },
114         { DRM_MODE_DPMS_OFF, "Off" }
115 };
116
117 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
118
119 /*
120  * Optional properties
121  */
122 static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
123 {
124         { DRM_MODE_SCALE_NONE, "None" },
125         { DRM_MODE_SCALE_FULLSCREEN, "Full" },
126         { DRM_MODE_SCALE_CENTER, "Center" },
127         { DRM_MODE_SCALE_ASPECT, "Full aspect" },
128 };
129
130 static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
131 {
132         { DRM_MODE_DITHERING_OFF, "Off" },
133         { DRM_MODE_DITHERING_ON, "On" },
134         { DRM_MODE_DITHERING_AUTO, "Automatic" },
135 };
136
137 /*
138  * Non-global properties, but "required" for certain connectors.
139  */
140 static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
141 {
142         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
143         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
144         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
145 };
146
147 DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
148
149 static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
150 {
151         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
152         { DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
153         { DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
154 };
155
156 DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
157                  drm_dvi_i_subconnector_enum_list)
158
159 static struct drm_prop_enum_list drm_tv_select_enum_list[] =
160 {
161         { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
162         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
163         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
164         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
165         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
166 };
167
168 DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
169
170 static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
171 {
172         { DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
173         { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
174         { DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
175         { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
176         { DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
177 };
178
179 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
180                  drm_tv_subconnector_enum_list)
181
182 static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
183         { DRM_MODE_DIRTY_OFF,      "Off"      },
184         { DRM_MODE_DIRTY_ON,       "On"       },
185         { DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
186 };
187
188 struct drm_conn_prop_enum_list {
189         int type;
190         char *name;
191         int count;
192 };
193
194 /*
195  * Connector and encoder types.
196  */
197 static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
198 {       { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
199         { DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
200         { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
201         { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
202         { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
203         { DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
204         { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
205         { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
206         { DRM_MODE_CONNECTOR_Component, "Component", 0 },
207         { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
208         { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
209         { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
210         { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
211         { DRM_MODE_CONNECTOR_TV, "TV", 0 },
212         { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
213         { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0},
214 };
215
216 static struct drm_prop_enum_list drm_encoder_enum_list[] =
217 {       { DRM_MODE_ENCODER_NONE, "None" },
218         { DRM_MODE_ENCODER_DAC, "DAC" },
219         { DRM_MODE_ENCODER_TMDS, "TMDS" },
220         { DRM_MODE_ENCODER_LVDS, "LVDS" },
221         { DRM_MODE_ENCODER_TVDAC, "TV" },
222         { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
223 };
224
225 char *drm_get_encoder_name(struct drm_encoder *encoder)
226 {
227         static char buf[32];
228
229         ksnprintf(buf, 32, "%s-%d",
230                  drm_encoder_enum_list[encoder->encoder_type].name,
231                  encoder->base.id);
232         return buf;
233 }
234 EXPORT_SYMBOL(drm_get_encoder_name);
235
236 char *drm_get_connector_name(struct drm_connector *connector)
237 {
238         static char buf[32];
239
240         ksnprintf(buf, 32, "%s-%d",
241                  drm_connector_enum_list[connector->connector_type].name,
242                  connector->connector_type_id);
243         return buf;
244 }
245 EXPORT_SYMBOL(drm_get_connector_name);
246
247 char *drm_get_connector_status_name(enum drm_connector_status status)
248 {
249         if (status == connector_status_connected)
250                 return "connected";
251         else if (status == connector_status_disconnected)
252                 return "disconnected";
253         else
254                 return "unknown";
255 }
256 EXPORT_SYMBOL(drm_get_connector_status_name);
257
258 /**
259  * drm_mode_object_get - allocate a new modeset identifier
260  * @dev: DRM device
261  * @obj: object pointer, used to generate unique ID
262  * @obj_type: object type
263  *
264  * Create a unique identifier based on @ptr in @dev's identifier space.  Used
265  * for tracking modes, CRTCs and connectors.
266  *
267  * RETURNS:
268  * New unique (relative to other objects in @dev) integer identifier for the
269  * object.
270  */
271 static int drm_mode_object_get(struct drm_device *dev,
272                                struct drm_mode_object *obj, uint32_t obj_type)
273 {
274         int ret;
275
276         mutex_lock(&dev->mode_config.idr_mutex);
277         ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
278         if (ret >= 0) {
279                 /*
280                  * Set up the object linking under the protection of the idr
281                  * lock so that other users can't see inconsistent state.
282                  */
283                 obj->id = ret;
284                 obj->type = obj_type;
285         }
286         mutex_unlock(&dev->mode_config.idr_mutex);
287
288         return ret < 0 ? ret : 0;
289 }
290
291 /**
292  * drm_mode_object_put - free a modeset identifer
293  * @dev: DRM device
294  * @object: object to free
295  *
296  * Free @id from @dev's unique identifier pool.
297  */
298 static void drm_mode_object_put(struct drm_device *dev,
299                                 struct drm_mode_object *object)
300 {
301         mutex_lock(&dev->mode_config.idr_mutex);
302         idr_remove(&dev->mode_config.crtc_idr, object->id);
303         mutex_unlock(&dev->mode_config.idr_mutex);
304 }
305
306 /**
307  * drm_mode_object_find - look up a drm object with static lifetime
308  * @dev: drm device
309  * @id: id of the mode object
310  * @type: type of the mode object
311  *
312  * Note that framebuffers cannot be looked up with this functions - since those
313  * are reference counted, they need special treatment.
314  */
315 struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
316                 uint32_t id, uint32_t type)
317 {
318         struct drm_mode_object *obj = NULL;
319
320         /* Framebuffers are reference counted and need their own lookup
321          * function.*/
322         WARN_ON(type == DRM_MODE_OBJECT_FB);
323
324         mutex_lock(&dev->mode_config.idr_mutex);
325         obj = idr_find(&dev->mode_config.crtc_idr, id);
326         if (!obj || (obj->type != type) || (obj->id != id))
327                 obj = NULL;
328         mutex_unlock(&dev->mode_config.idr_mutex);
329
330         return obj;
331 }
332 EXPORT_SYMBOL(drm_mode_object_find);
333
334 /**
335  * drm_framebuffer_init - initialize a framebuffer
336  * @dev: DRM device
337  * @fb: framebuffer to be initialized
338  * @funcs: ... with these functions
339  *
340  * Allocates an ID for the framebuffer's parent mode object, sets its mode
341  * functions & device file and adds it to the master fd list.
342  *
343  * IMPORTANT:
344  * This functions publishes the fb and makes it available for concurrent access
345  * by other users. Which means by this point the fb _must_ be fully set up -
346  * since all the fb attributes are invariant over its lifetime, no further
347  * locking but only correct reference counting is required.
348  *
349  * RETURNS:
350  * Zero on success, error code on failure.
351  */
352 int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
353                          const struct drm_framebuffer_funcs *funcs)
354 {
355         int ret;
356
357         mutex_lock(&dev->mode_config.fb_lock);
358         kref_init(&fb->refcount);
359         INIT_LIST_HEAD(&fb->filp_head);
360         fb->dev = dev;
361         fb->funcs = funcs;
362
363         ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
364         if (ret)
365                 goto out;
366
367         /* Grab the idr reference. */
368         drm_framebuffer_reference(fb);
369
370         dev->mode_config.num_fb++;
371         list_add(&fb->head, &dev->mode_config.fb_list);
372 out:
373         mutex_unlock(&dev->mode_config.fb_lock);
374
375         return 0;
376 }
377 EXPORT_SYMBOL(drm_framebuffer_init);
378
379 static void drm_framebuffer_free(struct kref *kref)
380 {
381         struct drm_framebuffer *fb =
382                         container_of(kref, struct drm_framebuffer, refcount);
383         fb->funcs->destroy(fb);
384 }
385
386 static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev,
387                                                         uint32_t id)
388 {
389         struct drm_mode_object *obj = NULL;
390         struct drm_framebuffer *fb;
391
392         mutex_lock(&dev->mode_config.idr_mutex);
393         obj = idr_find(&dev->mode_config.crtc_idr, id);
394         if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id))
395                 fb = NULL;
396         else
397                 fb = obj_to_fb(obj);
398         mutex_unlock(&dev->mode_config.idr_mutex);
399
400         return fb;
401 }
402
403 /**
404  * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference
405  * @dev: drm device
406  * @id: id of the fb object
407  *
408  * If successful, this grabs an additional reference to the framebuffer -
409  * callers need to make sure to eventually unreference the returned framebuffer
410  * again.
411  */
412 struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
413                                                uint32_t id)
414 {
415         struct drm_framebuffer *fb;
416
417         mutex_lock(&dev->mode_config.fb_lock);
418         fb = __drm_framebuffer_lookup(dev, id);
419         if (fb)
420                 drm_framebuffer_reference(fb);
421         mutex_unlock(&dev->mode_config.fb_lock);
422
423         return fb;
424 }
425 EXPORT_SYMBOL(drm_framebuffer_lookup);
426
427 /**
428  * drm_framebuffer_unreference - unref a framebuffer
429  * @fb: framebuffer to unref
430  *
431  * This functions decrements the fb's refcount and frees it if it drops to zero.
432  */
433 void drm_framebuffer_unreference(struct drm_framebuffer *fb)
434 {
435         DRM_DEBUG("FB ID: %d\n", fb->base.id);
436         kref_put(&fb->refcount, drm_framebuffer_free);
437 }
438 EXPORT_SYMBOL(drm_framebuffer_unreference);
439
440 /**
441  * drm_framebuffer_reference - incr the fb refcnt
442  * @fb: framebuffer
443  */
444 void drm_framebuffer_reference(struct drm_framebuffer *fb)
445 {
446         DRM_DEBUG("FB ID: %d\n", fb->base.id);
447         kref_get(&fb->refcount);
448 }
449 EXPORT_SYMBOL(drm_framebuffer_reference);
450
451 static void drm_framebuffer_free_bug(struct kref *kref)
452 {
453         BUG();
454 }
455
456 static void __drm_framebuffer_unreference(struct drm_framebuffer *fb)
457 {
458         DRM_DEBUG("FB ID: %d\n", fb->base.id);
459         kref_put(&fb->refcount, drm_framebuffer_free_bug);
460 }
461
462 /* dev->mode_config.fb_lock must be held! */
463 static void __drm_framebuffer_unregister(struct drm_device *dev,
464                                          struct drm_framebuffer *fb)
465 {
466         mutex_lock(&dev->mode_config.idr_mutex);
467         idr_remove(&dev->mode_config.crtc_idr, fb->base.id);
468         mutex_unlock(&dev->mode_config.idr_mutex);
469
470         fb->base.id = 0;
471
472         __drm_framebuffer_unreference(fb);
473 }
474
475 /**
476  * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
477  * @fb: fb to unregister
478  *
479  * Drivers need to call this when cleaning up driver-private framebuffers, e.g.
480  * those used for fbdev. Note that the caller must hold a reference of it's own,
481  * i.e. the object may not be destroyed through this call (since it'll lead to a
482  * locking inversion).
483  */
484 void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
485 {
486         struct drm_device *dev = fb->dev;
487
488         mutex_lock(&dev->mode_config.fb_lock);
489         /* Mark fb as reaped and drop idr ref. */
490         __drm_framebuffer_unregister(dev, fb);
491         mutex_unlock(&dev->mode_config.fb_lock);
492 }
493 EXPORT_SYMBOL(drm_framebuffer_unregister_private);
494
495 /**
496  * drm_framebuffer_cleanup - remove a framebuffer object
497  * @fb: framebuffer to remove
498  *
499  * Cleanup references to a user-created framebuffer. This function is intended
500  * to be used from the drivers ->destroy callback.
501  *
502  * Note that this function does not remove the fb from active usuage - if it is
503  * still used anywhere, hilarity can ensue since userspace could call getfb on
504  * the id and get back -EINVAL. Obviously no concern at driver unload time.
505  *
506  * Also, the framebuffer will not be removed from the lookup idr - for
507  * user-created framebuffers this will happen in in the rmfb ioctl. For
508  * driver-private objects (e.g. for fbdev) drivers need to explicitly call
509  * drm_framebuffer_unregister_private.
510  */
511 void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
512 {
513         struct drm_device *dev = fb->dev;
514
515         mutex_lock(&dev->mode_config.fb_lock);
516         list_del(&fb->head);
517         dev->mode_config.num_fb--;
518         mutex_unlock(&dev->mode_config.fb_lock);
519 }
520 EXPORT_SYMBOL(drm_framebuffer_cleanup);
521
522 /**
523  * drm_framebuffer_remove - remove and unreference a framebuffer object
524  * @fb: framebuffer to remove
525  *
526  * Scans all the CRTCs and planes in @dev's mode_config.  If they're
527  * using @fb, removes it, setting it to NULL. Then drops the reference to the
528  * passed-in framebuffer. Might take the modeset locks.
529  *
530  * Note that this function optimizes the cleanup away if the caller holds the
531  * last reference to the framebuffer. It is also guaranteed to not take the
532  * modeset locks in this case.
533  */
534 void drm_framebuffer_remove(struct drm_framebuffer *fb)
535 {
536         struct drm_device *dev = fb->dev;
537         struct drm_crtc *crtc;
538         struct drm_plane *plane;
539         struct drm_mode_set set;
540         int ret;
541
542         WARN_ON(!list_empty(&fb->filp_head));
543
544         /*
545          * drm ABI mandates that we remove any deleted framebuffers from active
546          * useage. But since most sane clients only remove framebuffers they no
547          * longer need, try to optimize this away.
548          *
549          * Since we're holding a reference ourselves, observing a refcount of 1
550          * means that we're the last holder and can skip it. Also, the refcount
551          * can never increase from 1 again, so we don't need any barriers or
552          * locks.
553          *
554          * Note that userspace could try to race with use and instate a new
555          * usage _after_ we've cleared all current ones. End result will be an
556          * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot
557          * in this manner.
558          */
559         if (atomic_read(&fb->refcount.refcount) > 1) {
560                 drm_modeset_lock_all(dev);
561                 /* remove from any CRTC */
562                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
563                         if (crtc->fb == fb) {
564                                 /* should turn off the crtc */
565                                 memset(&set, 0, sizeof(struct drm_mode_set));
566                                 set.crtc = crtc;
567                                 set.fb = NULL;
568                                 ret = drm_mode_set_config_internal(&set);
569                                 if (ret)
570                                         DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
571                         }
572                 }
573
574                 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
575                         if (plane->fb == fb) {
576                                 /* should turn off the crtc */
577                                 ret = plane->funcs->disable_plane(plane);
578                                 if (ret)
579                                         DRM_ERROR("failed to disable plane with busy fb\n");
580                                 /* disconnect the plane from the fb and crtc: */
581                                 __drm_framebuffer_unreference(plane->fb);
582                                 plane->fb = NULL;
583                                 plane->crtc = NULL;
584                         }
585                 }
586                 drm_modeset_unlock_all(dev);
587         }
588
589         drm_framebuffer_unreference(fb);
590 }
591 EXPORT_SYMBOL(drm_framebuffer_remove);
592
593 /**
594  * drm_crtc_init - Initialise a new CRTC object
595  * @dev: DRM device
596  * @crtc: CRTC object to init
597  * @funcs: callbacks for the new CRTC
598  *
599  * Inits a new object created as base part of an driver crtc object.
600  *
601  * RETURNS:
602  * Zero on success, error code on failure.
603  */
604 int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
605                    const struct drm_crtc_funcs *funcs)
606 {
607         int ret;
608
609         crtc->dev = dev;
610         crtc->funcs = funcs;
611         crtc->invert_dimensions = false;
612
613         drm_modeset_lock_all(dev);
614         lockinit(&crtc->mutex, "drmcm", 0, LK_CANRECURSE);
615 //      mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex);
616         lockmgr(&crtc->mutex, LK_EXCLUSIVE);
617
618         ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
619         if (ret)
620                 goto out;
621
622         crtc->base.properties = &crtc->properties;
623
624         list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
625         dev->mode_config.num_crtc++;
626
627  out:
628         drm_modeset_unlock_all(dev);
629
630         return ret;
631 }
632 EXPORT_SYMBOL(drm_crtc_init);
633
634 /**
635  * drm_crtc_cleanup - Cleans up the core crtc usage.
636  * @crtc: CRTC to cleanup
637  *
638  * Cleanup @crtc. Removes from drm modesetting space
639  * does NOT free object, caller does that.
640  */
641 void drm_crtc_cleanup(struct drm_crtc *crtc)
642 {
643         struct drm_device *dev = crtc->dev;
644
645         kfree(crtc->gamma_store);
646         crtc->gamma_store = NULL;
647
648         drm_mode_object_put(dev, &crtc->base);
649         list_del(&crtc->head);
650         dev->mode_config.num_crtc--;
651 }
652 EXPORT_SYMBOL(drm_crtc_cleanup);
653
654 /**
655  * drm_mode_probed_add - add a mode to a connector's probed mode list
656  * @connector: connector the new mode
657  * @mode: mode data
658  *
659  * Add @mode to @connector's mode list for later use.
660  */
661 void drm_mode_probed_add(struct drm_connector *connector,
662                          struct drm_display_mode *mode)
663 {
664         list_add(&mode->head, &connector->probed_modes);
665 }
666 EXPORT_SYMBOL(drm_mode_probed_add);
667
668 /**
669  * drm_mode_remove - remove and free a mode
670  * @connector: connector list to modify
671  * @mode: mode to remove
672  *
673  * Remove @mode from @connector's mode list, then free it.
674  */
675 void drm_mode_remove(struct drm_connector *connector,
676                      struct drm_display_mode *mode)
677 {
678         list_del(&mode->head);
679         drm_mode_destroy(connector->dev, mode);
680 }
681 EXPORT_SYMBOL(drm_mode_remove);
682
683 /**
684  * drm_connector_init - Init a preallocated connector
685  * @dev: DRM device
686  * @connector: the connector to init
687  * @funcs: callbacks for this connector
688  * @connector_type: user visible type of the connector
689  *
690  * Initialises a preallocated connector. Connectors should be
691  * subclassed as part of driver connector objects.
692  *
693  * RETURNS:
694  * Zero on success, error code on failure.
695  */
696 int drm_connector_init(struct drm_device *dev,
697                        struct drm_connector *connector,
698                        const struct drm_connector_funcs *funcs,
699                        int connector_type)
700 {
701         int ret;
702
703         drm_modeset_lock_all(dev);
704
705         ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
706         if (ret)
707                 goto out;
708
709         connector->base.properties = &connector->properties;
710         connector->dev = dev;
711         connector->funcs = funcs;
712         connector->connector_type = connector_type;
713         connector->connector_type_id =
714                 ++drm_connector_enum_list[connector_type].count; /* TODO */
715         INIT_LIST_HEAD(&connector->probed_modes);
716         INIT_LIST_HEAD(&connector->modes);
717         connector->edid_blob_ptr = NULL;
718         connector->status = connector_status_unknown;
719
720         list_add_tail(&connector->head, &dev->mode_config.connector_list);
721         dev->mode_config.num_connector++;
722
723         if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
724                 drm_object_attach_property(&connector->base,
725                                               dev->mode_config.edid_property,
726                                               0);
727
728         drm_object_attach_property(&connector->base,
729                                       dev->mode_config.dpms_property, 0);
730
731  out:
732         drm_modeset_unlock_all(dev);
733
734         return ret;
735 }
736 EXPORT_SYMBOL(drm_connector_init);
737
738 /**
739  * drm_connector_cleanup - cleans up an initialised connector
740  * @connector: connector to cleanup
741  *
742  * Cleans up the connector but doesn't free the object.
743  */
744 void drm_connector_cleanup(struct drm_connector *connector)
745 {
746         struct drm_device *dev = connector->dev;
747         struct drm_display_mode *mode, *t;
748
749         list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
750                 drm_mode_remove(connector, mode);
751
752         list_for_each_entry_safe(mode, t, &connector->modes, head)
753                 drm_mode_remove(connector, mode);
754
755         drm_mode_object_put(dev, &connector->base);
756         list_del(&connector->head);
757         dev->mode_config.num_connector--;
758 }
759 EXPORT_SYMBOL(drm_connector_cleanup);
760
761 void drm_connector_unplug_all(struct drm_device *dev)
762 {
763 #if 0
764         struct drm_connector *connector;
765
766         /* taking the mode config mutex ends up in a clash with sysfs */
767         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
768                 drm_sysfs_connector_remove(connector);
769 #endif
770
771 }
772 EXPORT_SYMBOL(drm_connector_unplug_all);
773
774 int drm_encoder_init(struct drm_device *dev,
775                       struct drm_encoder *encoder,
776                       const struct drm_encoder_funcs *funcs,
777                       int encoder_type)
778 {
779         int ret;
780
781         drm_modeset_lock_all(dev);
782
783         ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
784         if (ret)
785                 goto out;
786
787         encoder->dev = dev;
788         encoder->encoder_type = encoder_type;
789         encoder->funcs = funcs;
790
791         list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
792         dev->mode_config.num_encoder++;
793
794  out:
795         drm_modeset_unlock_all(dev);
796
797         return ret;
798 }
799 EXPORT_SYMBOL(drm_encoder_init);
800
801 void drm_encoder_cleanup(struct drm_encoder *encoder)
802 {
803         struct drm_device *dev = encoder->dev;
804         drm_modeset_lock_all(dev);
805         drm_mode_object_put(dev, &encoder->base);
806         list_del(&encoder->head);
807         dev->mode_config.num_encoder--;
808         drm_modeset_unlock_all(dev);
809 }
810 EXPORT_SYMBOL(drm_encoder_cleanup);
811
812 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
813                    unsigned long possible_crtcs,
814                    const struct drm_plane_funcs *funcs,
815                    const uint32_t *formats, uint32_t format_count,
816                    bool priv)
817 {
818         int ret;
819
820         drm_modeset_lock_all(dev);
821
822         ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
823         if (ret)
824                 goto out;
825
826         plane->base.properties = &plane->properties;
827         plane->dev = dev;
828         plane->funcs = funcs;
829         plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
830             M_DRM, M_WAITOK);
831         if (!plane->format_types) {
832                 DRM_DEBUG_KMS("out of memory when allocating plane\n");
833                 drm_mode_object_put(dev, &plane->base);
834                 ret = -ENOMEM;
835                 goto out;
836         }
837
838         memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
839         plane->format_count = format_count;
840         plane->possible_crtcs = possible_crtcs;
841
842         /* private planes are not exposed to userspace, but depending on
843          * display hardware, might be convenient to allow sharing programming
844          * for the scanout engine with the crtc implementation.
845          */
846         if (!priv) {
847                 list_add_tail(&plane->head, &dev->mode_config.plane_list);
848                 dev->mode_config.num_plane++;
849         } else {
850                 INIT_LIST_HEAD(&plane->head);
851         }
852
853  out:
854         drm_modeset_unlock_all(dev);
855
856         return ret;
857 }
858 EXPORT_SYMBOL(drm_plane_init);
859
860 void drm_plane_cleanup(struct drm_plane *plane)
861 {
862         struct drm_device *dev = plane->dev;
863
864         drm_modeset_lock_all(dev);
865         kfree(plane->format_types);
866         drm_mode_object_put(dev, &plane->base);
867         /* if not added to a list, it must be a private plane */
868         if (!list_empty(&plane->head)) {
869                 list_del(&plane->head);
870                 dev->mode_config.num_plane--;
871         }
872         drm_modeset_unlock_all(dev);
873 }
874 EXPORT_SYMBOL(drm_plane_cleanup);
875
876 /**
877  * drm_mode_create - create a new display mode
878  * @dev: DRM device
879  *
880  * Create a new drm_display_mode, give it an ID, and return it.
881  *
882  * RETURNS:
883  * Pointer to new mode on success, NULL on error.
884  */
885 struct drm_display_mode *drm_mode_create(struct drm_device *dev)
886 {
887         struct drm_display_mode *nmode;
888
889         nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
890         if (!nmode)
891                 return NULL;
892
893         if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
894                 kfree(nmode);
895                 return NULL;
896         }
897
898         return nmode;
899 }
900 EXPORT_SYMBOL(drm_mode_create);
901
902 /**
903  * drm_mode_destroy - remove a mode
904  * @dev: DRM device
905  * @mode: mode to remove
906  *
907  * Free @mode's unique identifier, then free it.
908  */
909 void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
910 {
911         if (!mode)
912                 return;
913
914         drm_mode_object_put(dev, &mode->base);
915
916         kfree(mode);
917 }
918 EXPORT_SYMBOL(drm_mode_destroy);
919
920 static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
921 {
922         struct drm_property *edid;
923         struct drm_property *dpms;
924
925         /*
926          * Standard properties (apply to all connectors)
927          */
928         edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
929                                    DRM_MODE_PROP_IMMUTABLE,
930                                    "EDID", 0);
931         dev->mode_config.edid_property = edid;
932
933         dpms = drm_property_create_enum(dev, 0,
934                                    "DPMS", drm_dpms_enum_list,
935                                    ARRAY_SIZE(drm_dpms_enum_list));
936         dev->mode_config.dpms_property = dpms;
937
938         return 0;
939 }
940
941 /**
942  * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
943  * @dev: DRM device
944  *
945  * Called by a driver the first time a DVI-I connector is made.
946  */
947 int drm_mode_create_dvi_i_properties(struct drm_device *dev)
948 {
949         struct drm_property *dvi_i_selector;
950         struct drm_property *dvi_i_subconnector;
951
952         if (dev->mode_config.dvi_i_select_subconnector_property)
953                 return 0;
954
955         dvi_i_selector =
956                 drm_property_create_enum(dev, 0,
957                                     "select subconnector",
958                                     drm_dvi_i_select_enum_list,
959                                     ARRAY_SIZE(drm_dvi_i_select_enum_list));
960         dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
961
962         dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
963                                     "subconnector",
964                                     drm_dvi_i_subconnector_enum_list,
965                                     ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
966         dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
967
968         return 0;
969 }
970 EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
971
972 /**
973  * drm_create_tv_properties - create TV specific connector properties
974  * @dev: DRM device
975  * @num_modes: number of different TV formats (modes) supported
976  * @modes: array of pointers to strings containing name of each format
977  *
978  * Called by a driver's TV initialization routine, this function creates
979  * the TV specific connector properties for a given device.  Caller is
980  * responsible for allocating a list of format names and passing them to
981  * this routine.
982  */
983 int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
984                                   char *modes[])
985 {
986         struct drm_property *tv_selector;
987         struct drm_property *tv_subconnector;
988         int i;
989
990         if (dev->mode_config.tv_select_subconnector_property)
991                 return 0;
992
993         /*
994          * Basic connector properties
995          */
996         tv_selector = drm_property_create_enum(dev, 0,
997                                           "select subconnector",
998                                           drm_tv_select_enum_list,
999                                           ARRAY_SIZE(drm_tv_select_enum_list));
1000         dev->mode_config.tv_select_subconnector_property = tv_selector;
1001
1002         tv_subconnector =
1003                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1004                                     "subconnector",
1005                                     drm_tv_subconnector_enum_list,
1006                                     ARRAY_SIZE(drm_tv_subconnector_enum_list));
1007         dev->mode_config.tv_subconnector_property = tv_subconnector;
1008
1009         /*
1010          * Other, TV specific properties: margins & TV modes.
1011          */
1012         dev->mode_config.tv_left_margin_property =
1013                 drm_property_create_range(dev, 0, "left margin", 0, 100);
1014
1015         dev->mode_config.tv_right_margin_property =
1016                 drm_property_create_range(dev, 0, "right margin", 0, 100);
1017
1018         dev->mode_config.tv_top_margin_property =
1019                 drm_property_create_range(dev, 0, "top margin", 0, 100);
1020
1021         dev->mode_config.tv_bottom_margin_property =
1022                 drm_property_create_range(dev, 0, "bottom margin", 0, 100);
1023
1024         dev->mode_config.tv_mode_property =
1025                 drm_property_create(dev, DRM_MODE_PROP_ENUM,
1026                                     "mode", num_modes);
1027         for (i = 0; i < num_modes; i++)
1028                 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
1029                                       i, modes[i]);
1030
1031         dev->mode_config.tv_brightness_property =
1032                 drm_property_create_range(dev, 0, "brightness", 0, 100);
1033
1034         dev->mode_config.tv_contrast_property =
1035                 drm_property_create_range(dev, 0, "contrast", 0, 100);
1036
1037         dev->mode_config.tv_flicker_reduction_property =
1038                 drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
1039
1040         dev->mode_config.tv_overscan_property =
1041                 drm_property_create_range(dev, 0, "overscan", 0, 100);
1042
1043         dev->mode_config.tv_saturation_property =
1044                 drm_property_create_range(dev, 0, "saturation", 0, 100);
1045
1046         dev->mode_config.tv_hue_property =
1047                 drm_property_create_range(dev, 0, "hue", 0, 100);
1048
1049         return 0;
1050 }
1051 EXPORT_SYMBOL(drm_mode_create_tv_properties);
1052
1053 /**
1054  * drm_mode_create_scaling_mode_property - create scaling mode property
1055  * @dev: DRM device
1056  *
1057  * Called by a driver the first time it's needed, must be attached to desired
1058  * connectors.
1059  */
1060 int drm_mode_create_scaling_mode_property(struct drm_device *dev)
1061 {
1062         struct drm_property *scaling_mode;
1063
1064         if (dev->mode_config.scaling_mode_property)
1065                 return 0;
1066
1067         scaling_mode =
1068                 drm_property_create_enum(dev, 0, "scaling mode",
1069                                 drm_scaling_mode_enum_list,
1070                                     ARRAY_SIZE(drm_scaling_mode_enum_list));
1071
1072         dev->mode_config.scaling_mode_property = scaling_mode;
1073
1074         return 0;
1075 }
1076 EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
1077
1078 /**
1079  * drm_mode_create_dithering_property - create dithering property
1080  * @dev: DRM device
1081  *
1082  * Called by a driver the first time it's needed, must be attached to desired
1083  * connectors.
1084  */
1085 int drm_mode_create_dithering_property(struct drm_device *dev)
1086 {
1087         struct drm_property *dithering_mode;
1088
1089         if (dev->mode_config.dithering_mode_property)
1090                 return 0;
1091
1092         dithering_mode =
1093                 drm_property_create_enum(dev, 0, "dithering",
1094                                 drm_dithering_mode_enum_list,
1095                                     ARRAY_SIZE(drm_dithering_mode_enum_list));
1096         dev->mode_config.dithering_mode_property = dithering_mode;
1097
1098         return 0;
1099 }
1100 EXPORT_SYMBOL(drm_mode_create_dithering_property);
1101
1102 /**
1103  * drm_mode_create_dirty_property - create dirty property
1104  * @dev: DRM device
1105  *
1106  * Called by a driver the first time it's needed, must be attached to desired
1107  * connectors.
1108  */
1109 int drm_mode_create_dirty_info_property(struct drm_device *dev)
1110 {
1111         struct drm_property *dirty_info;
1112
1113         if (dev->mode_config.dirty_info_property)
1114                 return 0;
1115
1116         dirty_info =
1117                 drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
1118                                     "dirty",
1119                                     drm_dirty_info_enum_list,
1120                                     ARRAY_SIZE(drm_dirty_info_enum_list));
1121         dev->mode_config.dirty_info_property = dirty_info;
1122
1123         return 0;
1124 }
1125 EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1126
1127 static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
1128 {
1129         uint32_t total_objects = 0;
1130
1131         total_objects += dev->mode_config.num_crtc;
1132         total_objects += dev->mode_config.num_connector;
1133         total_objects += dev->mode_config.num_encoder;
1134
1135         group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
1136         if (!group->id_list)
1137                 return -ENOMEM;
1138
1139         group->num_crtcs = 0;
1140         group->num_connectors = 0;
1141         group->num_encoders = 0;
1142         return 0;
1143 }
1144
1145 int drm_mode_group_init_legacy_group(struct drm_device *dev,
1146                                      struct drm_mode_group *group)
1147 {
1148         struct drm_crtc *crtc;
1149         struct drm_encoder *encoder;
1150         struct drm_connector *connector;
1151         int ret;
1152
1153         if ((ret = drm_mode_group_init(dev, group)))
1154                 return ret;
1155
1156         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
1157                 group->id_list[group->num_crtcs++] = crtc->base.id;
1158
1159         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
1160                 group->id_list[group->num_crtcs + group->num_encoders++] =
1161                 encoder->base.id;
1162
1163         list_for_each_entry(connector, &dev->mode_config.connector_list, head)
1164                 group->id_list[group->num_crtcs + group->num_encoders +
1165                                group->num_connectors++] = connector->base.id;
1166
1167         return 0;
1168 }
1169 EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
1170
1171 /**
1172  * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
1173  * @out: drm_mode_modeinfo struct to return to the user
1174  * @in: drm_display_mode to use
1175  *
1176  * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
1177  * the user.
1178  */
1179 static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
1180                                       const struct drm_display_mode *in)
1181 {
1182         WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
1183              in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
1184              in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
1185              in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
1186              in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
1187              "timing values too large for mode info\n");
1188
1189         out->clock = in->clock;
1190         out->hdisplay = in->hdisplay;
1191         out->hsync_start = in->hsync_start;
1192         out->hsync_end = in->hsync_end;
1193         out->htotal = in->htotal;
1194         out->hskew = in->hskew;
1195         out->vdisplay = in->vdisplay;
1196         out->vsync_start = in->vsync_start;
1197         out->vsync_end = in->vsync_end;
1198         out->vtotal = in->vtotal;
1199         out->vscan = in->vscan;
1200         out->vrefresh = in->vrefresh;
1201         out->flags = in->flags;
1202         out->type = in->type;
1203         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1204         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1205 }
1206
1207 /**
1208  * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
1209  * @out: drm_display_mode to return to the user
1210  * @in: drm_mode_modeinfo to use
1211  *
1212  * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
1213  * the caller.
1214  *
1215  * RETURNS:
1216  * Zero on success, errno on failure.
1217  */
1218 static int drm_crtc_convert_umode(struct drm_display_mode *out,
1219                                   const struct drm_mode_modeinfo *in)
1220 {
1221         if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
1222                 return -ERANGE;
1223
1224         out->clock = in->clock;
1225         out->hdisplay = in->hdisplay;
1226         out->hsync_start = in->hsync_start;
1227         out->hsync_end = in->hsync_end;
1228         out->htotal = in->htotal;
1229         out->hskew = in->hskew;
1230         out->vdisplay = in->vdisplay;
1231         out->vsync_start = in->vsync_start;
1232         out->vsync_end = in->vsync_end;
1233         out->vtotal = in->vtotal;
1234         out->vscan = in->vscan;
1235         out->vrefresh = in->vrefresh;
1236         out->flags = in->flags;
1237         out->type = in->type;
1238         strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
1239         out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1240
1241         return 0;
1242 }
1243
1244 /**
1245  * drm_mode_getresources - get graphics configuration
1246  * @dev: drm device for the ioctl
1247  * @data: data pointer for the ioctl
1248  * @file_priv: drm file for the ioctl call
1249  *
1250  * Construct a set of configuration description structures and return
1251  * them to the user, including CRTC, connector and framebuffer configuration.
1252  *
1253  * Called by the user via ioctl.
1254  *
1255  * RETURNS:
1256  * Zero on success, errno on failure.
1257  */
1258 int drm_mode_getresources(struct drm_device *dev, void *data,
1259                           struct drm_file *file_priv)
1260 {
1261         struct drm_mode_card_res *card_res = data;
1262         struct list_head *lh;
1263         struct drm_framebuffer *fb;
1264         struct drm_connector *connector;
1265         struct drm_crtc *crtc;
1266         struct drm_encoder *encoder;
1267         int ret = 0;
1268         int connector_count = 0;
1269         int crtc_count = 0;
1270         int fb_count = 0;
1271         int encoder_count = 0;
1272         int copied = 0, i;
1273         uint32_t __user *fb_id;
1274         uint32_t __user *crtc_id;
1275         uint32_t __user *connector_id;
1276         uint32_t __user *encoder_id;
1277         struct drm_mode_group *mode_group;
1278
1279         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1280                 return -EINVAL;
1281
1282
1283         mutex_lock(&file_priv->fbs_lock);
1284         /*
1285          * For the non-control nodes we need to limit the list of resources
1286          * by IDs in the group list for this node
1287          */
1288         list_for_each(lh, &file_priv->fbs)
1289                 fb_count++;
1290
1291         /* handle this in 4 parts */
1292         /* FBs */
1293         if (card_res->count_fbs >= fb_count) {
1294                 copied = 0;
1295                 fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
1296                 list_for_each_entry(fb, &file_priv->fbs, filp_head) {
1297                         if (put_user(fb->base.id, fb_id + copied)) {
1298                                 mutex_unlock(&file_priv->fbs_lock);
1299                                 return -EFAULT;
1300                         }
1301                         copied++;
1302                 }
1303         }
1304         card_res->count_fbs = fb_count;
1305         mutex_unlock(&file_priv->fbs_lock);
1306
1307         drm_modeset_lock_all(dev);
1308 #if 0
1309         mode_group = &file_priv->master->minor->mode_group;
1310         if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1311 #else
1312         mode_group = NULL; /* XXXKIB */
1313         if (1 || file_priv->master) {
1314 #endif
1315
1316                 list_for_each(lh, &dev->mode_config.crtc_list)
1317                         crtc_count++;
1318
1319                 list_for_each(lh, &dev->mode_config.connector_list)
1320                         connector_count++;
1321
1322                 list_for_each(lh, &dev->mode_config.encoder_list)
1323                         encoder_count++;
1324         } else {
1325
1326                 crtc_count = mode_group->num_crtcs;
1327                 connector_count = mode_group->num_connectors;
1328                 encoder_count = mode_group->num_encoders;
1329         }
1330
1331         card_res->max_height = dev->mode_config.max_height;
1332         card_res->min_height = dev->mode_config.min_height;
1333         card_res->max_width = dev->mode_config.max_width;
1334         card_res->min_width = dev->mode_config.min_width;
1335
1336         /* CRTCs */
1337         if (card_res->count_crtcs >= crtc_count) {
1338                 copied = 0;
1339                 crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr;
1340 #if 0
1341                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1342 #else
1343                 if (1 || file_priv->master) {
1344 #endif
1345                         list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1346                                             head) {
1347                                 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1348                                 if (put_user(crtc->base.id, crtc_id + copied)) {
1349                                         ret = -EFAULT;
1350                                         goto out;
1351                                 }
1352                                 copied++;
1353                         }
1354                 } else {
1355                         for (i = 0; i < mode_group->num_crtcs; i++) {
1356                                 if (put_user(mode_group->id_list[i],
1357                                              crtc_id + copied)) {
1358                                         ret = -EFAULT;
1359                                         goto out;
1360                                 }
1361                                 copied++;
1362                         }
1363                 }
1364         }
1365         card_res->count_crtcs = crtc_count;
1366
1367         /* Encoders */
1368         if (card_res->count_encoders >= encoder_count) {
1369                 copied = 0;
1370                 encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr;
1371 #if 0
1372                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1373 #else
1374                 if (file_priv->master) {
1375 #endif
1376
1377                         list_for_each_entry(encoder,
1378                                             &dev->mode_config.encoder_list,
1379                                             head) {
1380                                 DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id,
1381                                                 drm_get_encoder_name(encoder));
1382                                 if (put_user(encoder->base.id, encoder_id +
1383                                              copied)) {
1384                                         ret = -EFAULT;
1385                                         goto out;
1386                                 }
1387                                 copied++;
1388                         }
1389                 } else {
1390                         for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) {
1391                                 if (put_user(mode_group->id_list[i],
1392                                              encoder_id + copied)) {
1393                                         ret = -EFAULT;
1394                                         goto out;
1395                                 }
1396                                 copied++;
1397                         }
1398
1399                 }
1400         }
1401         card_res->count_encoders = encoder_count;
1402
1403         /* Connectors */
1404         if (card_res->count_connectors >= connector_count) {
1405                 copied = 0;
1406                 connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr;
1407 #if 0
1408                 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1409 #else
1410                 if (file_priv->master) {
1411 #endif
1412                         list_for_each_entry(connector,
1413                                             &dev->mode_config.connector_list,
1414                                             head) {
1415                                 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
1416                                         connector->base.id,
1417                                         drm_get_connector_name(connector));
1418                                 if (put_user(connector->base.id,
1419                                              connector_id + copied)) {
1420                                         ret = -EFAULT;
1421                                         goto out;
1422                                 }
1423                                 copied++;
1424                         }
1425                 } else {
1426                         int start = mode_group->num_crtcs +
1427                                 mode_group->num_encoders;
1428                         for (i = start; i < start + mode_group->num_connectors; i++) {
1429                                 if (put_user(mode_group->id_list[i],
1430                                              connector_id + copied)) {
1431                                         ret = -EFAULT;
1432                                         goto out;
1433                                 }
1434                                 copied++;
1435                         }
1436                 }
1437         }
1438         card_res->count_connectors = connector_count;
1439
1440         DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs,
1441                   card_res->count_connectors, card_res->count_encoders);
1442
1443 out:
1444         drm_modeset_unlock_all(dev);
1445         return ret;
1446 }
1447
1448 /**
1449  * drm_mode_getcrtc - get CRTC configuration
1450  * @dev: drm device for the ioctl
1451  * @data: data pointer for the ioctl
1452  * @file_priv: drm file for the ioctl call
1453  *
1454  * Construct a CRTC configuration structure to return to the user.
1455  *
1456  * Called by the user via ioctl.
1457  *
1458  * RETURNS:
1459  * Zero on success, errno on failure.
1460  */
1461 int drm_mode_getcrtc(struct drm_device *dev,
1462                      void *data, struct drm_file *file_priv)
1463 {
1464         struct drm_mode_crtc *crtc_resp = data;
1465         struct drm_crtc *crtc;
1466         struct drm_mode_object *obj;
1467         int ret = 0;
1468
1469         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1470                 return -EINVAL;
1471
1472         drm_modeset_lock_all(dev);
1473
1474         obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
1475                                    DRM_MODE_OBJECT_CRTC);
1476         if (!obj) {
1477                 ret = -EINVAL;
1478                 goto out;
1479         }
1480         crtc = obj_to_crtc(obj);
1481
1482         crtc_resp->x = crtc->x;
1483         crtc_resp->y = crtc->y;
1484         crtc_resp->gamma_size = crtc->gamma_size;
1485         if (crtc->fb)
1486                 crtc_resp->fb_id = crtc->fb->base.id;
1487         else
1488                 crtc_resp->fb_id = 0;
1489
1490         if (crtc->enabled) {
1491
1492                 drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
1493                 crtc_resp->mode_valid = 1;
1494
1495         } else {
1496                 crtc_resp->mode_valid = 0;
1497         }
1498
1499 out:
1500         drm_modeset_unlock_all(dev);
1501         return ret;
1502 }
1503
1504 /**
1505  * drm_mode_getconnector - get connector configuration
1506  * @dev: drm device for the ioctl
1507  * @data: data pointer for the ioctl
1508  * @file_priv: drm file for the ioctl call
1509  *
1510  * Construct a connector configuration structure to return to the user.
1511  *
1512  * Called by the user via ioctl.
1513  *
1514  * RETURNS:
1515  * Zero on success, errno on failure.
1516  */
1517 int drm_mode_getconnector(struct drm_device *dev, void *data,
1518                           struct drm_file *file_priv)
1519 {
1520         struct drm_mode_get_connector *out_resp = data;
1521         struct drm_mode_object *obj;
1522         struct drm_connector *connector;
1523         struct drm_display_mode *mode;
1524         int mode_count = 0;
1525         int props_count = 0;
1526         int encoders_count = 0;
1527         int ret = 0;
1528         int copied = 0;
1529         int i;
1530         struct drm_mode_modeinfo u_mode;
1531         struct drm_mode_modeinfo __user *mode_ptr;
1532         uint32_t __user *prop_ptr;
1533         uint64_t __user *prop_values;
1534         uint32_t __user *encoder_ptr;
1535
1536         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1537                 return -EINVAL;
1538
1539         memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1540
1541         DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
1542
1543         mutex_lock(&dev->mode_config.mutex);
1544
1545         obj = drm_mode_object_find(dev, out_resp->connector_id,
1546                                    DRM_MODE_OBJECT_CONNECTOR);
1547         if (!obj) {
1548                 ret = -EINVAL;
1549                 goto out;
1550         }
1551         connector = obj_to_connector(obj);
1552
1553         props_count = connector->properties.count;
1554
1555         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1556                 if (connector->encoder_ids[i] != 0) {
1557                         encoders_count++;
1558                 }
1559         }
1560
1561         if (out_resp->count_modes == 0) {
1562                 connector->funcs->fill_modes(connector,
1563                                              dev->mode_config.max_width,
1564                                              dev->mode_config.max_height);
1565         }
1566
1567         /* delayed so we get modes regardless of pre-fill_modes state */
1568         list_for_each_entry(mode, &connector->modes, head)
1569                 mode_count++;
1570
1571         out_resp->connector_id = connector->base.id;
1572         out_resp->connector_type = connector->connector_type;
1573         out_resp->connector_type_id = connector->connector_type_id;
1574         out_resp->mm_width = connector->display_info.width_mm;
1575         out_resp->mm_height = connector->display_info.height_mm;
1576         out_resp->subpixel = connector->display_info.subpixel_order;
1577         out_resp->connection = connector->status;
1578         if (connector->encoder)
1579                 out_resp->encoder_id = connector->encoder->base.id;
1580         else
1581                 out_resp->encoder_id = 0;
1582
1583         /*
1584          * This ioctl is called twice, once to determine how much space is
1585          * needed, and the 2nd time to fill it.
1586          */
1587         if ((out_resp->count_modes >= mode_count) && mode_count) {
1588                 copied = 0;
1589                 mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
1590                 list_for_each_entry(mode, &connector->modes, head) {
1591                         drm_crtc_convert_to_umode(&u_mode, mode);
1592                         if (copy_to_user(mode_ptr + copied,
1593                                          &u_mode, sizeof(u_mode))) {
1594                                 ret = -EFAULT;
1595                                 goto out;
1596                         }
1597                         copied++;
1598                 }
1599         }
1600         out_resp->count_modes = mode_count;
1601
1602         if ((out_resp->count_props >= props_count) && props_count) {
1603                 copied = 0;
1604                 prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr);
1605                 prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr);
1606                 for (i = 0; i < connector->properties.count; i++) {
1607                         if (put_user(connector->properties.ids[i],
1608                                      prop_ptr + copied)) {
1609                                 ret = -EFAULT;
1610                                 goto out;
1611                         }
1612
1613                         if (put_user(connector->properties.values[i],
1614                                      prop_values + copied)) {
1615                                 ret = -EFAULT;
1616                                 goto out;
1617                         }
1618                         copied++;
1619                 }
1620         }
1621         out_resp->count_props = props_count;
1622
1623         if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
1624                 copied = 0;
1625                 encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
1626                 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1627                         if (connector->encoder_ids[i] != 0) {
1628                                 if (put_user(connector->encoder_ids[i],
1629                                              encoder_ptr + copied)) {
1630                                         ret = -EFAULT;
1631                                         goto out;
1632                                 }
1633                                 copied++;
1634                         }
1635                 }
1636         }
1637         out_resp->count_encoders = encoders_count;
1638
1639 out:
1640         mutex_unlock(&dev->mode_config.mutex);
1641
1642         return ret;
1643 }
1644
1645 int drm_mode_getencoder(struct drm_device *dev, void *data,
1646                         struct drm_file *file_priv)
1647 {
1648         struct drm_mode_get_encoder *enc_resp = data;
1649         struct drm_mode_object *obj;
1650         struct drm_encoder *encoder;
1651         int ret = 0;
1652
1653         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1654                 return -EINVAL;
1655
1656         drm_modeset_lock_all(dev);
1657         obj = drm_mode_object_find(dev, enc_resp->encoder_id,
1658                                    DRM_MODE_OBJECT_ENCODER);
1659         if (!obj) {
1660                 ret = -EINVAL;
1661                 goto out;
1662         }
1663         encoder = obj_to_encoder(obj);
1664
1665         if (encoder->crtc)
1666                 enc_resp->crtc_id = encoder->crtc->base.id;
1667         else
1668                 enc_resp->crtc_id = 0;
1669         enc_resp->encoder_type = encoder->encoder_type;
1670         enc_resp->encoder_id = encoder->base.id;
1671         enc_resp->possible_crtcs = encoder->possible_crtcs;
1672         enc_resp->possible_clones = encoder->possible_clones;
1673
1674 out:
1675         drm_modeset_unlock_all(dev);
1676         return ret;
1677 }
1678
1679 /**
1680  * drm_mode_getplane_res - get plane info
1681  * @dev: DRM device
1682  * @data: ioctl data
1683  * @file_priv: DRM file info
1684  *
1685  * Return an plane count and set of IDs.
1686  */
1687 int drm_mode_getplane_res(struct drm_device *dev, void *data,
1688                             struct drm_file *file_priv)
1689 {
1690         struct drm_mode_get_plane_res *plane_resp = data;
1691         struct drm_mode_config *config;
1692         struct drm_plane *plane;
1693         uint32_t __user *plane_ptr;
1694         int copied = 0, ret = 0;
1695
1696         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1697                 return -EINVAL;
1698
1699         drm_modeset_lock_all(dev);
1700         config = &dev->mode_config;
1701
1702         /*
1703          * This ioctl is called twice, once to determine how much space is
1704          * needed, and the 2nd time to fill it.
1705          */
1706         if (config->num_plane &&
1707             (plane_resp->count_planes >= config->num_plane)) {
1708                 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
1709
1710                 list_for_each_entry(plane, &config->plane_list, head) {
1711                         if (put_user(plane->base.id, plane_ptr + copied)) {
1712                                 ret = -EFAULT;
1713                                 goto out;
1714                         }
1715                         copied++;
1716                 }
1717         }
1718         plane_resp->count_planes = config->num_plane;
1719
1720 out:
1721         drm_modeset_unlock_all(dev);
1722         return ret;
1723 }
1724
1725 /**
1726  * drm_mode_getplane - get plane info
1727  * @dev: DRM device
1728  * @data: ioctl data
1729  * @file_priv: DRM file info
1730  *
1731  * Return plane info, including formats supported, gamma size, any
1732  * current fb, etc.
1733  */
1734 int drm_mode_getplane(struct drm_device *dev, void *data,
1735                         struct drm_file *file_priv)
1736 {
1737         struct drm_mode_get_plane *plane_resp = data;
1738         struct drm_mode_object *obj;
1739         struct drm_plane *plane;
1740         uint32_t __user *format_ptr;
1741         int ret = 0;
1742
1743         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1744                 return -EINVAL;
1745
1746         drm_modeset_lock_all(dev);
1747         obj = drm_mode_object_find(dev, plane_resp->plane_id,
1748                                    DRM_MODE_OBJECT_PLANE);
1749         if (!obj) {
1750                 ret = -ENOENT;
1751                 goto out;
1752         }
1753         plane = obj_to_plane(obj);
1754
1755         if (plane->crtc)
1756                 plane_resp->crtc_id = plane->crtc->base.id;
1757         else
1758                 plane_resp->crtc_id = 0;
1759
1760         if (plane->fb)
1761                 plane_resp->fb_id = plane->fb->base.id;
1762         else
1763                 plane_resp->fb_id = 0;
1764
1765         plane_resp->plane_id = plane->base.id;
1766         plane_resp->possible_crtcs = plane->possible_crtcs;
1767         plane_resp->gamma_size = plane->gamma_size;
1768
1769         /*
1770          * This ioctl is called twice, once to determine how much space is
1771          * needed, and the 2nd time to fill it.
1772          */
1773         if (plane->format_count &&
1774             (plane_resp->count_format_types >= plane->format_count)) {
1775                 format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
1776                 if (copy_to_user(format_ptr,
1777                                  plane->format_types,
1778                                  sizeof(uint32_t) * plane->format_count)) {
1779                         ret = -EFAULT;
1780                         goto out;
1781                 }
1782         }
1783         plane_resp->count_format_types = plane->format_count;
1784
1785 out:
1786         drm_modeset_unlock_all(dev);
1787         return ret;
1788 }
1789
1790 /**
1791  * drm_mode_setplane - set up or tear down an plane
1792  * @dev: DRM device
1793  * @data: ioctl data*
1794  * @file_priv: DRM file info
1795  *
1796  * Set plane info, including placement, fb, scaling, and other factors.
1797  * Or pass a NULL fb to disable.
1798  */
1799 int drm_mode_setplane(struct drm_device *dev, void *data,
1800                         struct drm_file *file_priv)
1801 {
1802         struct drm_mode_set_plane *plane_req = data;
1803         struct drm_mode_object *obj;
1804         struct drm_plane *plane;
1805         struct drm_crtc *crtc;
1806         struct drm_framebuffer *fb = NULL, *old_fb = NULL;
1807         int ret = 0;
1808         unsigned int fb_width, fb_height;
1809         int i;
1810
1811         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1812                 return -EINVAL;
1813
1814         /*
1815          * First, find the plane, crtc, and fb objects.  If not available,
1816          * we don't bother to call the driver.
1817          */
1818         obj = drm_mode_object_find(dev, plane_req->plane_id,
1819                                    DRM_MODE_OBJECT_PLANE);
1820         if (!obj) {
1821                 DRM_DEBUG_KMS("Unknown plane ID %d\n",
1822                               plane_req->plane_id);
1823                 return -ENOENT;
1824         }
1825         plane = obj_to_plane(obj);
1826
1827         /* No fb means shut it down */
1828         if (!plane_req->fb_id) {
1829                 drm_modeset_lock_all(dev);
1830                 old_fb = plane->fb;
1831                 plane->funcs->disable_plane(plane);
1832                 plane->crtc = NULL;
1833                 plane->fb = NULL;
1834                 drm_modeset_unlock_all(dev);
1835                 goto out;
1836         }
1837
1838         obj = drm_mode_object_find(dev, plane_req->crtc_id,
1839                                    DRM_MODE_OBJECT_CRTC);
1840         if (!obj) {
1841                 DRM_DEBUG_KMS("Unknown crtc ID %d\n",
1842                               plane_req->crtc_id);
1843                 ret = -ENOENT;
1844                 goto out;
1845         }
1846         crtc = obj_to_crtc(obj);
1847
1848         fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
1849         if (!fb) {
1850                 DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
1851                               plane_req->fb_id);
1852                 ret = -ENOENT;
1853                 goto out;
1854         }
1855
1856         /* Check whether this plane supports the fb pixel format. */
1857         for (i = 0; i < plane->format_count; i++)
1858                 if (fb->pixel_format == plane->format_types[i])
1859                         break;
1860         if (i == plane->format_count) {
1861                 DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format);
1862                 ret = -EINVAL;
1863                 goto out;
1864         }
1865
1866         fb_width = fb->width << 16;
1867         fb_height = fb->height << 16;
1868
1869         /* Make sure source coordinates are inside the fb. */
1870         if (plane_req->src_w > fb_width ||
1871             plane_req->src_x > fb_width - plane_req->src_w ||
1872             plane_req->src_h > fb_height ||
1873             plane_req->src_y > fb_height - plane_req->src_h) {
1874                 DRM_DEBUG_KMS("Invalid source coordinates "
1875                               "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
1876                               plane_req->src_w >> 16,
1877                               ((plane_req->src_w & 0xffff) * 15625) >> 10,
1878                               plane_req->src_h >> 16,
1879                               ((plane_req->src_h & 0xffff) * 15625) >> 10,
1880                               plane_req->src_x >> 16,
1881                               ((plane_req->src_x & 0xffff) * 15625) >> 10,
1882                               plane_req->src_y >> 16,
1883                               ((plane_req->src_y & 0xffff) * 15625) >> 10);
1884                 ret = -ENOSPC;
1885                 goto out;
1886         }
1887
1888         /* Give drivers some help against integer overflows */
1889         if (plane_req->crtc_w > INT_MAX ||
1890             plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
1891             plane_req->crtc_h > INT_MAX ||
1892             plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
1893                 DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
1894                               plane_req->crtc_w, plane_req->crtc_h,
1895                               plane_req->crtc_x, plane_req->crtc_y);
1896                 ret = -ERANGE;
1897                 goto out;
1898         }
1899
1900         drm_modeset_lock_all(dev);
1901         ret = plane->funcs->update_plane(plane, crtc, fb,
1902                                          plane_req->crtc_x, plane_req->crtc_y,
1903                                          plane_req->crtc_w, plane_req->crtc_h,
1904                                          plane_req->src_x, plane_req->src_y,
1905                                          plane_req->src_w, plane_req->src_h);
1906         if (!ret) {
1907                 old_fb = plane->fb;
1908                 plane->crtc = crtc;
1909                 plane->fb = fb;
1910                 fb = NULL;
1911         }
1912         drm_modeset_unlock_all(dev);
1913
1914 out:
1915         if (fb)
1916                 drm_framebuffer_unreference(fb);
1917         if (old_fb)
1918                 drm_framebuffer_unreference(old_fb);
1919
1920         return ret;
1921 }
1922
1923 /**
1924  * drm_mode_set_config_internal - helper to call ->set_config
1925  * @set: modeset config to set
1926  *
1927  * This is a little helper to wrap internal calls to the ->set_config driver
1928  * interface. The only thing it adds is correct refcounting dance.
1929  */
1930 int drm_mode_set_config_internal(struct drm_mode_set *set)
1931 {
1932         struct drm_crtc *crtc = set->crtc;
1933         struct drm_framebuffer *fb, *old_fb;
1934         int ret;
1935
1936         old_fb = crtc->fb;
1937         fb = set->fb;
1938
1939         ret = crtc->funcs->set_config(set);
1940         if (ret == 0) {
1941                 if (old_fb)
1942                         drm_framebuffer_unreference(old_fb);
1943                 if (fb)
1944                         drm_framebuffer_reference(fb);
1945         }
1946
1947         return ret;
1948 }
1949 EXPORT_SYMBOL(drm_mode_set_config_internal);
1950
1951 /**
1952  * drm_mode_setcrtc - set CRTC configuration
1953  * @dev: drm device for the ioctl
1954  * @data: data pointer for the ioctl
1955  * @file_priv: drm file for the ioctl call
1956  *
1957  * Build a new CRTC configuration based on user request.
1958  *
1959  * Called by the user via ioctl.
1960  *
1961  * RETURNS:
1962  * Zero on success, errno on failure.
1963  */
1964 int drm_mode_setcrtc(struct drm_device *dev, void *data,
1965                      struct drm_file *file_priv)
1966 {
1967         struct drm_mode_config *config = &dev->mode_config;
1968         struct drm_mode_crtc *crtc_req = data;
1969         struct drm_mode_object *obj;
1970         struct drm_crtc *crtc;
1971         struct drm_connector **connector_set = NULL, *connector;
1972         struct drm_framebuffer *fb = NULL;
1973         struct drm_display_mode *mode = NULL;
1974         struct drm_mode_set set;
1975         uint32_t __user *set_connectors_ptr;
1976         int ret;
1977         int i;
1978
1979         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1980                 return -EINVAL;
1981
1982         /* For some reason crtc x/y offsets are signed internally. */
1983         if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
1984                 return -ERANGE;
1985
1986         drm_modeset_lock_all(dev);
1987         obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1988                                    DRM_MODE_OBJECT_CRTC);
1989         if (!obj) {
1990                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1991                 ret = -EINVAL;
1992                 goto out;
1993         }
1994         crtc = obj_to_crtc(obj);
1995         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
1996
1997         if (crtc_req->mode_valid) {
1998                 int hdisplay, vdisplay;
1999                 /* If we have a mode we need a framebuffer. */
2000                 /* If we pass -1, set the mode with the currently bound fb */
2001                 if (crtc_req->fb_id == -1) {
2002                         if (!crtc->fb) {
2003                                 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
2004                                 ret = -EINVAL;
2005                                 goto out;
2006                         }
2007                         fb = crtc->fb;
2008                         /* Make refcounting symmetric with the lookup path. */
2009                         drm_framebuffer_reference(fb);
2010                 } else {
2011                         fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
2012                         if (!fb) {
2013                                 DRM_DEBUG_KMS("Unknown FB ID%d\n",
2014                                                 crtc_req->fb_id);
2015                                 ret = -EINVAL;
2016                                 goto out;
2017                         }
2018                 }
2019
2020                 mode = drm_mode_create(dev);
2021                 if (!mode) {
2022                         ret = -ENOMEM;
2023                         goto out;
2024                 }
2025
2026                 ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
2027                 if (ret) {
2028                         DRM_DEBUG_KMS("Invalid mode\n");
2029                         goto out;
2030                 }
2031
2032                 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
2033
2034                 hdisplay = mode->hdisplay;
2035                 vdisplay = mode->vdisplay;
2036
2037                 if (crtc->invert_dimensions)
2038                         swap(hdisplay, vdisplay);
2039
2040                 if (hdisplay > fb->width ||
2041                     vdisplay > fb->height ||
2042                     crtc_req->x > fb->width - hdisplay ||
2043                     crtc_req->y > fb->height - vdisplay) {
2044                         DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
2045                                       fb->width, fb->height,
2046                                       hdisplay, vdisplay, crtc_req->x, crtc_req->y,
2047                                       crtc->invert_dimensions ? " (inverted)" : "");
2048                         ret = -ENOSPC;
2049                         goto out;
2050                 }
2051         }
2052
2053         if (crtc_req->count_connectors == 0 && mode) {
2054                 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
2055                 ret = -EINVAL;
2056                 goto out;
2057         }
2058
2059         if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
2060                 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
2061                           crtc_req->count_connectors);
2062                 ret = -EINVAL;
2063                 goto out;
2064         }
2065
2066         if (crtc_req->count_connectors > 0) {
2067                 u32 out_id;
2068
2069                 /* Avoid unbounded kernel memory allocation */
2070                 if (crtc_req->count_connectors > config->num_connector) {
2071                         ret = -EINVAL;
2072                         goto out;
2073                 }
2074
2075                 connector_set = kmalloc(crtc_req->count_connectors *
2076                                         sizeof(struct drm_connector *),
2077                                         M_DRM, M_WAITOK);
2078                 if (!connector_set) {
2079                         ret = -ENOMEM;
2080                         goto out;
2081                 }
2082
2083                 for (i = 0; i < crtc_req->count_connectors; i++) {
2084                         set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
2085                         if (get_user(out_id, &set_connectors_ptr[i])) {
2086                                 ret = -EFAULT;
2087                                 goto out;
2088                         }
2089
2090                         obj = drm_mode_object_find(dev, out_id,
2091                                                    DRM_MODE_OBJECT_CONNECTOR);
2092                         if (!obj) {
2093                                 DRM_DEBUG_KMS("Connector id %d unknown\n",
2094                                                 out_id);
2095                                 ret = -EINVAL;
2096                                 goto out;
2097                         }
2098                         connector = obj_to_connector(obj);
2099                         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
2100                                         connector->base.id,
2101                                         drm_get_connector_name(connector));
2102
2103                         connector_set[i] = connector;
2104                 }
2105         }
2106
2107         set.crtc = crtc;
2108         set.x = crtc_req->x;
2109         set.y = crtc_req->y;
2110         set.mode = mode;
2111         set.connectors = connector_set;
2112         set.num_connectors = crtc_req->count_connectors;
2113         set.fb = fb;
2114         ret = drm_mode_set_config_internal(&set);
2115
2116 out:
2117         if (fb)
2118                 drm_framebuffer_unreference(fb);
2119
2120         kfree(connector_set);
2121         drm_mode_destroy(dev, mode);
2122         drm_modeset_unlock_all(dev);
2123         return ret;
2124 }
2125
2126 int drm_mode_cursor_ioctl(struct drm_device *dev,
2127                         void *data, struct drm_file *file_priv)
2128 {
2129         struct drm_mode_cursor *req = data;
2130         struct drm_mode_object *obj;
2131         struct drm_crtc *crtc;
2132         int ret = 0;
2133
2134         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2135                 return -EINVAL;
2136
2137         if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
2138                 return -EINVAL;
2139
2140         obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
2141         if (!obj) {
2142                 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
2143                 return -EINVAL;
2144         }
2145         crtc = obj_to_crtc(obj);
2146
2147         mutex_lock(&crtc->mutex);
2148         if (req->flags & DRM_MODE_CURSOR_BO) {
2149                 if (!crtc->funcs->cursor_set) {
2150                         ret = -ENXIO;
2151                         goto out;
2152                 }
2153                 /* Turns off the cursor if handle is 0 */
2154                 ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
2155                                               req->width, req->height);
2156         }
2157
2158         if (req->flags & DRM_MODE_CURSOR_MOVE) {
2159                 if (crtc->funcs->cursor_move) {
2160                         ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
2161                 } else {
2162                         ret = -EFAULT;
2163                         goto out;
2164                 }
2165         }
2166 out:
2167         mutex_unlock(&crtc->mutex);
2168
2169         return ret;
2170 }
2171
2172 /* Original addfb only supported RGB formats, so figure out which one */
2173 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
2174 {
2175         uint32_t fmt;
2176
2177         switch (bpp) {
2178         case 8:
2179                 fmt = DRM_FORMAT_C8;
2180                 break;
2181         case 16:
2182                 if (depth == 15)
2183                         fmt = DRM_FORMAT_XRGB1555;
2184                 else
2185                         fmt = DRM_FORMAT_RGB565;
2186                 break;
2187         case 24:
2188                 fmt = DRM_FORMAT_RGB888;
2189                 break;
2190         case 32:
2191                 if (depth == 24)
2192                         fmt = DRM_FORMAT_XRGB8888;
2193                 else if (depth == 30)
2194                         fmt = DRM_FORMAT_XRGB2101010;
2195                 else
2196                         fmt = DRM_FORMAT_ARGB8888;
2197                 break;
2198         default:
2199                 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
2200                 fmt = DRM_FORMAT_XRGB8888;
2201                 break;
2202         }
2203
2204         return fmt;
2205 }
2206 EXPORT_SYMBOL(drm_mode_legacy_fb_format);
2207
2208 /**
2209  * drm_mode_addfb - add an FB to the graphics configuration
2210  * @dev: drm device for the ioctl
2211  * @data: data pointer for the ioctl
2212  * @file_priv: drm file for the ioctl call
2213  *
2214  * Add a new FB to the specified CRTC, given a user request.
2215  *
2216  * Called by the user via ioctl.
2217  *
2218  * RETURNS:
2219  * Zero on success, errno on failure.
2220  */
2221 int drm_mode_addfb(struct drm_device *dev,
2222                    void *data, struct drm_file *file_priv)
2223 {
2224         struct drm_mode_fb_cmd *or = data;
2225         struct drm_mode_fb_cmd2 r = {};
2226         struct drm_mode_config *config = &dev->mode_config;
2227         struct drm_framebuffer *fb;
2228         int ret = 0;
2229
2230         /* Use new struct with format internally */
2231         r.fb_id = or->fb_id;
2232         r.width = or->width;
2233         r.height = or->height;
2234         r.pitches[0] = or->pitch;
2235         r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
2236         r.handles[0] = or->handle;
2237
2238         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2239                 return -EINVAL;
2240
2241         if ((config->min_width > r.width) || (r.width > config->max_width))
2242                 return -EINVAL;
2243
2244         if ((config->min_height > r.height) || (r.height > config->max_height))
2245                 return -EINVAL;
2246
2247         fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
2248         if (IS_ERR(fb)) {
2249                 DRM_DEBUG_KMS("could not create framebuffer\n");
2250                 return PTR_ERR(fb);
2251         }
2252
2253         mutex_lock(&file_priv->fbs_lock);
2254         or->fb_id = fb->base.id;
2255         list_add(&fb->filp_head, &file_priv->fbs);
2256         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2257         mutex_unlock(&file_priv->fbs_lock);
2258
2259         return ret;
2260 }
2261
2262 static int format_check(const struct drm_mode_fb_cmd2 *r)
2263 {
2264         uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
2265
2266         switch (format) {
2267         case DRM_FORMAT_C8:
2268         case DRM_FORMAT_RGB332:
2269         case DRM_FORMAT_BGR233:
2270         case DRM_FORMAT_XRGB4444:
2271         case DRM_FORMAT_XBGR4444:
2272         case DRM_FORMAT_RGBX4444:
2273         case DRM_FORMAT_BGRX4444:
2274         case DRM_FORMAT_ARGB4444:
2275         case DRM_FORMAT_ABGR4444:
2276         case DRM_FORMAT_RGBA4444:
2277         case DRM_FORMAT_BGRA4444:
2278         case DRM_FORMAT_XRGB1555:
2279         case DRM_FORMAT_XBGR1555:
2280         case DRM_FORMAT_RGBX5551:
2281         case DRM_FORMAT_BGRX5551:
2282         case DRM_FORMAT_ARGB1555:
2283         case DRM_FORMAT_ABGR1555:
2284         case DRM_FORMAT_RGBA5551:
2285         case DRM_FORMAT_BGRA5551:
2286         case DRM_FORMAT_RGB565:
2287         case DRM_FORMAT_BGR565:
2288         case DRM_FORMAT_RGB888:
2289         case DRM_FORMAT_BGR888:
2290         case DRM_FORMAT_XRGB8888:
2291         case DRM_FORMAT_XBGR8888:
2292         case DRM_FORMAT_RGBX8888:
2293         case DRM_FORMAT_BGRX8888:
2294         case DRM_FORMAT_ARGB8888:
2295         case DRM_FORMAT_ABGR8888:
2296         case DRM_FORMAT_RGBA8888:
2297         case DRM_FORMAT_BGRA8888:
2298         case DRM_FORMAT_XRGB2101010:
2299         case DRM_FORMAT_XBGR2101010:
2300         case DRM_FORMAT_RGBX1010102:
2301         case DRM_FORMAT_BGRX1010102:
2302         case DRM_FORMAT_ARGB2101010:
2303         case DRM_FORMAT_ABGR2101010:
2304         case DRM_FORMAT_RGBA1010102:
2305         case DRM_FORMAT_BGRA1010102:
2306         case DRM_FORMAT_YUYV:
2307         case DRM_FORMAT_YVYU:
2308         case DRM_FORMAT_UYVY:
2309         case DRM_FORMAT_VYUY:
2310         case DRM_FORMAT_AYUV:
2311         case DRM_FORMAT_NV12:
2312         case DRM_FORMAT_NV21:
2313         case DRM_FORMAT_NV16:
2314         case DRM_FORMAT_NV61:
2315         case DRM_FORMAT_NV24:
2316         case DRM_FORMAT_NV42:
2317         case DRM_FORMAT_YUV410:
2318         case DRM_FORMAT_YVU410:
2319         case DRM_FORMAT_YUV411:
2320         case DRM_FORMAT_YVU411:
2321         case DRM_FORMAT_YUV420:
2322         case DRM_FORMAT_YVU420:
2323         case DRM_FORMAT_YUV422:
2324         case DRM_FORMAT_YVU422:
2325         case DRM_FORMAT_YUV444:
2326         case DRM_FORMAT_YVU444:
2327                 return 0;
2328         default:
2329                 return -EINVAL;
2330         }
2331 }
2332
2333 static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
2334 {
2335         int ret, hsub, vsub, num_planes, i;
2336
2337         ret = format_check(r);
2338         if (ret) {
2339                 DRM_DEBUG_KMS("bad framebuffer format 0x%08x\n", r->pixel_format);
2340                 return ret;
2341         }
2342
2343         hsub = drm_format_horz_chroma_subsampling(r->pixel_format);
2344         vsub = drm_format_vert_chroma_subsampling(r->pixel_format);
2345         num_planes = drm_format_num_planes(r->pixel_format);
2346
2347         if (r->width == 0 || r->width % hsub) {
2348                 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height);
2349                 return -EINVAL;
2350         }
2351
2352         if (r->height == 0 || r->height % vsub) {
2353                 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
2354                 return -EINVAL;
2355         }
2356
2357         for (i = 0; i < num_planes; i++) {
2358                 unsigned int width = r->width / (i != 0 ? hsub : 1);
2359                 unsigned int height = r->height / (i != 0 ? vsub : 1);
2360                 unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);
2361
2362                 if (!r->handles[i]) {
2363                         DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
2364                         return -EINVAL;
2365                 }
2366
2367                 if ((uint64_t) width * cpp > UINT_MAX)
2368                         return -ERANGE;
2369
2370                 if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
2371                         return -ERANGE;
2372
2373                 if (r->pitches[i] < width * cpp) {
2374                         DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
2375                         return -EINVAL;
2376                 }
2377         }
2378
2379         return 0;
2380 }
2381
2382 /**
2383  * drm_mode_addfb2 - add an FB to the graphics configuration
2384  * @dev: drm device for the ioctl
2385  * @data: data pointer for the ioctl
2386  * @file_priv: drm file for the ioctl call
2387  *
2388  * Add a new FB to the specified CRTC, given a user request with format.
2389  *
2390  * Called by the user via ioctl.
2391  *
2392  * RETURNS:
2393  * Zero on success, errno on failure.
2394  */
2395 int drm_mode_addfb2(struct drm_device *dev,
2396                     void *data, struct drm_file *file_priv)
2397 {
2398         struct drm_mode_fb_cmd2 *r = data;
2399         struct drm_mode_config *config = &dev->mode_config;
2400         struct drm_framebuffer *fb;
2401         int ret;
2402
2403         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2404                 return -EINVAL;
2405
2406         if (r->flags & ~DRM_MODE_FB_INTERLACED) {
2407                 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
2408                 return -EINVAL;
2409         }
2410
2411         if ((config->min_width > r->width) || (r->width > config->max_width)) {
2412                 DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
2413                           r->width, config->min_width, config->max_width);
2414                 return -EINVAL;
2415         }
2416         if ((config->min_height > r->height) || (r->height > config->max_height)) {
2417                 DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
2418                           r->height, config->min_height, config->max_height);
2419                 return -EINVAL;
2420         }
2421
2422         ret = framebuffer_check(r);
2423         if (ret)
2424                 return ret;
2425
2426         fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
2427         if (IS_ERR(fb)) {
2428                 DRM_DEBUG_KMS("could not create framebuffer\n");
2429                 return PTR_ERR(fb);
2430         }
2431
2432         mutex_lock(&file_priv->fbs_lock);
2433         r->fb_id = fb->base.id;
2434         list_add(&fb->filp_head, &file_priv->fbs);
2435         DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2436         mutex_unlock(&file_priv->fbs_lock);
2437
2438
2439         return ret;
2440 }
2441
2442 /**
2443  * drm_mode_rmfb - remove an FB from the configuration
2444  * @dev: drm device for the ioctl
2445  * @data: data pointer for the ioctl
2446  * @file_priv: drm file for the ioctl call
2447  *
2448  * Remove the FB specified by the user.
2449  *
2450  * Called by the user via ioctl.
2451  *
2452  * RETURNS:
2453  * Zero on success, errno on failure.
2454  */
2455 int drm_mode_rmfb(struct drm_device *dev,
2456                    void *data, struct drm_file *file_priv)
2457 {
2458         struct drm_framebuffer *fb = NULL;
2459         struct drm_framebuffer *fbl = NULL;
2460         uint32_t *id = data;
2461         int found = 0;
2462
2463         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2464                 return -EINVAL;
2465
2466         mutex_lock(&file_priv->fbs_lock);
2467         mutex_lock(&dev->mode_config.fb_lock);
2468         fb = __drm_framebuffer_lookup(dev, *id);
2469         if (!fb)
2470                 goto fail_lookup;
2471
2472         list_for_each_entry(fbl, &file_priv->fbs, filp_head)
2473                 if (fb == fbl)
2474                         found = 1;
2475         if (!found)
2476                 goto fail_lookup;
2477
2478         /* Mark fb as reaped, we still have a ref from fpriv->fbs. */
2479         __drm_framebuffer_unregister(dev, fb);
2480
2481         list_del_init(&fb->filp_head);
2482         mutex_unlock(&dev->mode_config.fb_lock);
2483         mutex_unlock(&file_priv->fbs_lock);
2484
2485         drm_framebuffer_remove(fb);
2486
2487         return 0;
2488
2489 fail_lookup:
2490         mutex_unlock(&dev->mode_config.fb_lock);
2491         mutex_unlock(&file_priv->fbs_lock);
2492
2493         return -EINVAL;
2494 }
2495
2496 /**
2497  * drm_mode_getfb - get FB info
2498  * @dev: drm device for the ioctl
2499  * @data: data pointer for the ioctl
2500  * @file_priv: drm file for the ioctl call
2501  *
2502  * Lookup the FB given its ID and return info about it.
2503  *
2504  * Called by the user via ioctl.
2505  *
2506  * RETURNS:
2507  * Zero on success, errno on failure.
2508  */
2509 int drm_mode_getfb(struct drm_device *dev,
2510                    void *data, struct drm_file *file_priv)
2511 {
2512         struct drm_mode_fb_cmd *r = data;
2513         struct drm_framebuffer *fb;
2514         int ret;
2515
2516         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2517                 return -EINVAL;
2518
2519         fb = drm_framebuffer_lookup(dev, r->fb_id);
2520         if (!fb)
2521                 return -EINVAL;
2522
2523         r->height = fb->height;
2524         r->width = fb->width;
2525         r->depth = fb->depth;
2526         r->bpp = fb->bits_per_pixel;
2527         r->pitch = fb->pitches[0];
2528         if (fb->funcs->create_handle)
2529                 ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
2530         else
2531                 ret = -ENODEV;
2532
2533         drm_framebuffer_unreference(fb);
2534
2535         return ret;
2536 }
2537
2538 int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
2539                            void *data, struct drm_file *file_priv)
2540 {
2541         struct drm_clip_rect __user *clips_ptr;
2542         struct drm_clip_rect *clips = NULL;
2543         struct drm_mode_fb_dirty_cmd *r = data;
2544         struct drm_framebuffer *fb;
2545         unsigned flags;
2546         int num_clips;
2547         int ret;
2548
2549         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2550                 return -EINVAL;
2551
2552         fb = drm_framebuffer_lookup(dev, r->fb_id);
2553         if (!fb)
2554                 return -EINVAL;
2555
2556         num_clips = r->num_clips;
2557         clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
2558
2559         if (!num_clips != !clips_ptr) {
2560                 ret = -EINVAL;
2561                 goto out_err1;
2562         }
2563
2564         flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
2565
2566         /* If userspace annotates copy, clips must come in pairs */
2567         if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
2568                 ret = -EINVAL;
2569                 goto out_err1;
2570         }
2571
2572         if (num_clips && clips_ptr) {
2573                 if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
2574                         ret = -EINVAL;
2575                         goto out_err1;
2576                 }
2577                 clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
2578                 if (!clips) {
2579                         ret = -ENOMEM;
2580                         goto out_err1;
2581                 }
2582
2583                 ret = copy_from_user(clips, clips_ptr,
2584                                      num_clips * sizeof(*clips));
2585                 if (ret) {
2586                         ret = -EFAULT;
2587                         goto out_err2;
2588                 }
2589         }
2590
2591         if (fb->funcs->dirty) {
2592                 drm_modeset_lock_all(dev);
2593                 ret = fb->funcs->dirty(fb, file_priv, flags, r->color,
2594                                        clips, num_clips);
2595                 drm_modeset_unlock_all(dev);
2596         } else {
2597                 ret = -ENOSYS;
2598         }
2599
2600 out_err2:
2601         kfree(clips);
2602 out_err1:
2603         drm_framebuffer_unreference(fb);
2604
2605         return ret;
2606 }
2607
2608
2609 /**
2610  * drm_fb_release - remove and free the FBs on this file
2611  * @priv: drm file for the ioctl
2612  *
2613  * Destroy all the FBs associated with @filp.
2614  *
2615  * Called by the user via ioctl.
2616  *
2617  * RETURNS:
2618  * Zero on success, errno on failure.
2619  */
2620 void drm_fb_release(struct drm_file *priv)
2621 {
2622 #if 0
2623         struct drm_device *dev = priv->minor->dev;
2624 #else
2625         struct drm_device *dev = priv->dev;
2626 #endif
2627         struct drm_framebuffer *fb, *tfb;
2628
2629         mutex_lock(&priv->fbs_lock);
2630         list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
2631
2632                 mutex_lock(&dev->mode_config.fb_lock);
2633                 /* Mark fb as reaped, we still have a ref from fpriv->fbs. */
2634                 __drm_framebuffer_unregister(dev, fb);
2635                 mutex_unlock(&dev->mode_config.fb_lock);
2636
2637                 list_del_init(&fb->filp_head);
2638
2639                 /* This will also drop the fpriv->fbs reference. */
2640                 drm_framebuffer_remove(fb);
2641         }
2642         mutex_unlock(&priv->fbs_lock);
2643 }
2644
2645 struct drm_property *drm_property_create(struct drm_device *dev, int flags,
2646                                          const char *name, int num_values)
2647 {
2648         struct drm_property *property = NULL;
2649         int ret;
2650
2651         property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
2652         if (!property)
2653                 return NULL;
2654
2655         if (num_values) {
2656                 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
2657                 if (!property->values)
2658                         goto fail;
2659         }
2660
2661         ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
2662         if (ret)
2663                 goto fail;
2664
2665         property->flags = flags;
2666         property->num_values = num_values;
2667         INIT_LIST_HEAD(&property->enum_blob_list);
2668
2669         if (name) {
2670                 strncpy(property->name, name, DRM_PROP_NAME_LEN);
2671                 property->name[DRM_PROP_NAME_LEN-1] = '\0';
2672         }
2673
2674         list_add_tail(&property->head, &dev->mode_config.property_list);
2675         return property;
2676 fail:
2677         kfree(property->values);
2678         kfree(property);
2679         return NULL;
2680 }
2681 EXPORT_SYMBOL(drm_property_create);
2682
2683 struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
2684                                          const char *name,
2685                                          const struct drm_prop_enum_list *props,
2686                                          int num_values)
2687 {
2688         struct drm_property *property;
2689         int i, ret;
2690
2691         flags |= DRM_MODE_PROP_ENUM;
2692
2693         property = drm_property_create(dev, flags, name, num_values);
2694         if (!property)
2695                 return NULL;
2696
2697         for (i = 0; i < num_values; i++) {
2698                 ret = drm_property_add_enum(property, i,
2699                                       props[i].type,
2700                                       props[i].name);
2701                 if (ret) {
2702                         drm_property_destroy(dev, property);
2703                         return NULL;
2704                 }
2705         }
2706
2707         return property;
2708 }
2709 EXPORT_SYMBOL(drm_property_create_enum);
2710
2711 struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
2712                                          int flags, const char *name,
2713                                          const struct drm_prop_enum_list *props,
2714                                          int num_values)
2715 {
2716         struct drm_property *property;
2717         int i, ret;
2718
2719         flags |= DRM_MODE_PROP_BITMASK;
2720
2721         property = drm_property_create(dev, flags, name, num_values);
2722         if (!property)
2723                 return NULL;
2724
2725         for (i = 0; i < num_values; i++) {
2726                 ret = drm_property_add_enum(property, i,
2727                                       props[i].type,
2728                                       props[i].name);
2729                 if (ret) {
2730                         drm_property_destroy(dev, property);
2731                         return NULL;
2732                 }
2733         }
2734
2735         return property;
2736 }
2737 EXPORT_SYMBOL(drm_property_create_bitmask);
2738
2739 struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
2740                                          const char *name,
2741                                          uint64_t min, uint64_t max)
2742 {
2743         struct drm_property *property;
2744
2745         flags |= DRM_MODE_PROP_RANGE;
2746
2747         property = drm_property_create(dev, flags, name, 2);
2748         if (!property)
2749                 return NULL;
2750
2751         property->values[0] = min;
2752         property->values[1] = max;
2753
2754         return property;
2755 }
2756 EXPORT_SYMBOL(drm_property_create_range);
2757
2758 int drm_property_add_enum(struct drm_property *property, int index,
2759                           uint64_t value, const char *name)
2760 {
2761         struct drm_property_enum *prop_enum;
2762
2763         if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
2764                 return -EINVAL;
2765
2766         /*
2767          * Bitmask enum properties have the additional constraint of values
2768          * from 0 to 63
2769          */
2770         if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
2771                 return -EINVAL;
2772
2773         if (!list_empty(&property->enum_blob_list)) {
2774                 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2775                         if (prop_enum->value == value) {
2776                                 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2777                                 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2778                                 return 0;
2779                         }
2780                 }
2781         }
2782
2783         prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
2784         if (!prop_enum)
2785                 return -ENOMEM;
2786
2787         strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
2788         prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
2789         prop_enum->value = value;
2790
2791         property->values[index] = value;
2792         list_add_tail(&prop_enum->head, &property->enum_blob_list);
2793         return 0;
2794 }
2795 EXPORT_SYMBOL(drm_property_add_enum);
2796
2797 void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
2798 {
2799         struct drm_property_enum *prop_enum, *pt;
2800
2801         list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
2802                 list_del(&prop_enum->head);
2803                 kfree(prop_enum);
2804         }
2805
2806         if (property->num_values)
2807                 kfree(property->values);
2808         drm_mode_object_put(dev, &property->base);
2809         list_del(&property->head);
2810         kfree(property);
2811 }
2812 EXPORT_SYMBOL(drm_property_destroy);
2813
2814 void drm_object_attach_property(struct drm_mode_object *obj,
2815                                 struct drm_property *property,
2816                                 uint64_t init_val)
2817 {
2818         int count = obj->properties->count;
2819
2820         if (count == DRM_OBJECT_MAX_PROPERTY) {
2821                 WARN(1, "Failed to attach object property (type: 0x%x). Please "
2822                         "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
2823                         "you see this message on the same object type.\n",
2824                         obj->type);
2825                 return;
2826         }
2827
2828         obj->properties->ids[count] = property->base.id;
2829         obj->properties->values[count] = init_val;
2830         obj->properties->count++;
2831 }
2832 EXPORT_SYMBOL(drm_object_attach_property);
2833
2834 int drm_object_property_set_value(struct drm_mode_object *obj,
2835                                   struct drm_property *property, uint64_t val)
2836 {
2837         int i;
2838
2839         for (i = 0; i < obj->properties->count; i++) {
2840                 if (obj->properties->ids[i] == property->base.id) {
2841                         obj->properties->values[i] = val;
2842                         return 0;
2843                 }
2844         }
2845
2846         return -EINVAL;
2847 }
2848 EXPORT_SYMBOL(drm_object_property_set_value);
2849
2850 int drm_object_property_get_value(struct drm_mode_object *obj,
2851                                   struct drm_property *property, uint64_t *val)
2852 {
2853         int i;
2854
2855         for (i = 0; i < obj->properties->count; i++) {
2856                 if (obj->properties->ids[i] == property->base.id) {
2857                         *val = obj->properties->values[i];
2858                         return 0;
2859                 }
2860         }
2861
2862         return -EINVAL;
2863 }
2864 EXPORT_SYMBOL(drm_object_property_get_value);
2865
2866 int drm_mode_getproperty_ioctl(struct drm_device *dev,
2867                                void *data, struct drm_file *file_priv)
2868 {
2869         struct drm_mode_object *obj;
2870         struct drm_mode_get_property *out_resp = data;
2871         struct drm_property *property;
2872         int enum_count = 0;
2873         int blob_count = 0;
2874         int value_count = 0;
2875         int ret = 0, i;
2876         int copied;
2877         struct drm_property_enum *prop_enum;
2878         struct drm_mode_property_enum __user *enum_ptr;
2879         struct drm_property_blob *prop_blob;
2880         uint32_t __user *blob_id_ptr;
2881         uint64_t __user *values_ptr;
2882         uint32_t __user *blob_length_ptr;
2883
2884         if (!drm_core_check_feature(dev, DRIVER_MODESET))
2885                 return -EINVAL;
2886
2887         drm_modeset_lock_all(dev);
2888         obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
2889         if (!obj) {
2890                 ret = -EINVAL;
2891                 goto done;
2892         }
2893         property = obj_to_property(obj);
2894
2895         if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
2896                 list_for_each_entry(prop_enum, &property->enum_blob_list, head)
2897                         enum_count++;
2898         } else if (property->flags & DRM_MODE_PROP_BLOB) {
2899                 list_for_each_entry(prop_blob, &property->enum_blob_list, head)
2900                         blob_count++;
2901         }
2902
2903         value_count = property->num_values;
2904
2905         strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN);
2906         out_resp->name[DRM_PROP_NAME_LEN-1] = 0;
2907         out_resp->flags = property->flags;
2908
2909         if ((out_resp->count_values >= value_count) && value_count) {
2910                 values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
2911                 for (i = 0; i < value_count; i++) {
2912                         if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
2913                                 ret = -EFAULT;
2914                                 goto done;
2915                         }
2916                 }
2917         }
2918         out_resp->count_values = value_count;
2919
2920         if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
2921                 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
2922                         copied = 0;
2923                         enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
2924                         list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
2925
2926                                 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
2927                                         ret = -EFAULT;
2928                                         goto done;
2929                                 }
2930
2931                                 if (copy_to_user(&enum_ptr[copied].name,
2932                                                  &prop_enum->name, DRM_PROP_NAME_LEN)) {
2933                                         ret = -EFAULT;
2934                                         goto done;
2935                                 }
2936                                 copied++;
2937                         }
2938                 }
2939                 out_resp->count_enum_blobs = enum_count;
2940         }
2941
2942         if (property->flags & DRM_MODE_PROP_BLOB) {
2943                 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
2944                         copied = 0;
2945                         blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
2946                         blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;
2947
2948                         list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
2949                                 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
2950                                         ret = -EFAULT;
2951                                         goto done;
2952                                 }
2953
2954                                 if (put_user(prop_blob->length, blob_length_ptr + copied)) {
2955                                         ret = -EFAULT;
2956                                         goto done;
2957                                 }
2958
2959                                 copied++;
2960                         }
2961                 }
2962                 out_resp->count_enum_blobs = blob_count;
2963         }
2964 done:
2965         drm_modeset_unlock_all(dev);
2966         return ret;
2967 }
2968
2969 static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
2970                                                           void *data)
2971 {
2972         struct drm_property_blob *blob;
2973         int ret;
2974
2975         if (!length || !data)
2976                 return NULL;
2977
2978         blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
2979         if (!blob)
2980                 return NULL;
2981
2982         ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
2983         if (ret) {
2984                 kfree(blob);
2985                 return NULL;
2986         }
2987
2988         blob->length = length;
2989
2990         memcpy(blob->data, data, length);
2991
2992         list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
2993         return blob;
2994 }
2995
2996 static void drm_property_destroy_blob(struct drm_device *dev,
2997                                struct drm_property_blob *blob)
2998 {
2999         drm_mode_object_put(dev, &blob->base);
3000         list_del(&blob->head);
3001         kfree(blob);
3002 }
3003
3004 int drm_mode_getblob_ioctl(struct drm_device *dev,
3005                            void *data, struct drm_file *file_priv)
3006 {
3007         struct drm_mode_object *obj;
3008         struct drm_mode_get_blob *out_resp = data;
3009         struct drm_property_blob *blob;
3010         int ret = 0;
3011         void __user *blob_ptr;
3012
3013         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3014                 return -EINVAL;
3015
3016         drm_modeset_lock_all(dev);
3017         obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
3018         if (!obj) {
3019                 ret = -EINVAL;
3020                 goto done;
3021         }
3022         blob = obj_to_blob(obj);
3023
3024         if (out_resp->length == blob->length) {
3025                 blob_ptr = (void __user *)(unsigned long)out_resp->data;
3026                 if (copy_to_user(blob_ptr, blob->data, blob->length)){
3027                         ret = -EFAULT;
3028                         goto done;
3029                 }
3030         }
3031         out_resp->length = blob->length;
3032
3033 done:
3034         drm_modeset_unlock_all(dev);
3035         return ret;
3036 }
3037
3038 int drm_mode_connector_update_edid_property(struct drm_connector *connector,
3039                                             struct edid *edid)
3040 {
3041         struct drm_device *dev = connector->dev;
3042         int ret, size;
3043
3044         if (connector->edid_blob_ptr)
3045                 drm_property_destroy_blob(dev, connector->edid_blob_ptr);
3046
3047         /* Delete edid, when there is none. */
3048         if (!edid) {
3049                 connector->edid_blob_ptr = NULL;
3050                 ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);
3051                 return ret;
3052         }
3053
3054         size = EDID_LENGTH * (1 + edid->extensions);
3055         connector->edid_blob_ptr = drm_property_create_blob(connector->dev,
3056                                                             size, edid);
3057         if (!connector->edid_blob_ptr)
3058                 return -EINVAL;
3059
3060         ret = drm_object_property_set_value(&connector->base,
3061                                                dev->mode_config.edid_property,
3062                                                connector->edid_blob_ptr->base.id);
3063
3064         return ret;
3065 }
3066 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
3067
3068 static bool drm_property_change_is_valid(struct drm_property *property,
3069                                          uint64_t value)
3070 {
3071         if (property->flags & DRM_MODE_PROP_IMMUTABLE)
3072                 return false;
3073         if (property->flags & DRM_MODE_PROP_RANGE) {
3074                 if (value < property->values[0] || value > property->values[1])
3075                         return false;
3076                 return true;
3077         } else if (property->flags & DRM_MODE_PROP_BITMASK) {
3078                 int i;
3079                 uint64_t valid_mask = 0;
3080                 for (i = 0; i < property->num_values; i++)
3081                         valid_mask |= (1ULL << property->values[i]);
3082                 return !(value & ~valid_mask);
3083         } else if (property->flags & DRM_MODE_PROP_BLOB) {
3084                 /* Only the driver knows */
3085                 return true;
3086         } else {
3087                 int i;
3088                 for (i = 0; i < property->num_values; i++)
3089                         if (property->values[i] == value)
3090                                 return true;
3091                 return false;
3092         }
3093 }
3094
3095 int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
3096                                        void *data, struct drm_file *file_priv)
3097 {
3098         struct drm_mode_connector_set_property *conn_set_prop = data;
3099         struct drm_mode_obj_set_property obj_set_prop = {
3100                 .value = conn_set_prop->value,
3101                 .prop_id = conn_set_prop->prop_id,
3102                 .obj_id = conn_set_prop->connector_id,
3103                 .obj_type = DRM_MODE_OBJECT_CONNECTOR
3104         };
3105
3106         /* It does all the locking and checking we need */
3107         return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv);
3108 }
3109
3110 static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
3111                                            struct drm_property *property,
3112                                            uint64_t value)
3113 {
3114         int ret = -EINVAL;
3115         struct drm_connector *connector = obj_to_connector(obj);
3116
3117         /* Do DPMS ourselves */
3118         if (property == connector->dev->mode_config.dpms_property) {
3119                 if (connector->funcs->dpms)
3120                         (*connector->funcs->dpms)(connector, (int)value);
3121                 ret = 0;
3122         } else if (connector->funcs->set_property)
3123                 ret = connector->funcs->set_property(connector, property, value);
3124
3125         /* store the property value if successful */
3126         if (!ret)
3127                 drm_object_property_set_value(&connector->base, property, value);
3128         return ret;
3129 }
3130
3131 static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
3132                                       struct drm_property *property,
3133                                       uint64_t value)
3134 {
3135         int ret = -EINVAL;
3136         struct drm_crtc *crtc = obj_to_crtc(obj);
3137
3138         if (crtc->funcs->set_property)
3139                 ret = crtc->funcs->set_property(crtc, property, value);
3140         if (!ret)
3141                 drm_object_property_set_value(obj, property, value);
3142
3143         return ret;
3144 }
3145
3146 static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
3147                                       struct drm_property *property,
3148                                       uint64_t value)
3149 {
3150         int ret = -EINVAL;
3151         struct drm_plane *plane = obj_to_plane(obj);
3152
3153         if (plane->funcs->set_property)
3154                 ret = plane->funcs->set_property(plane, property, value);
3155         if (!ret)
3156                 drm_object_property_set_value(obj, property, value);
3157
3158         return ret;
3159 }
3160
3161 int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
3162                                       struct drm_file *file_priv)
3163 {
3164         struct drm_mode_obj_get_properties *arg = data;
3165         struct drm_mode_object *obj;
3166         int ret = 0;
3167         int i;
3168         int copied = 0;
3169         int props_count = 0;
3170         uint32_t __user *props_ptr;
3171         uint64_t __user *prop_values_ptr;
3172
3173         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3174                 return -EINVAL;
3175
3176         drm_modeset_lock_all(dev);
3177
3178         obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
3179         if (!obj) {
3180                 ret = -EINVAL;
3181                 goto out;
3182         }
3183         if (!obj->properties) {
3184                 ret = -EINVAL;
3185                 goto out;
3186         }
3187
3188         props_count = obj->properties->count;
3189
3190         /* This ioctl is called twice, once to determine how much space is
3191          * needed, and the 2nd time to fill it. */
3192         if ((arg->count_props >= props_count) && props_count) {
3193                 copied = 0;
3194                 props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
3195                 prop_values_ptr = (uint64_t __user *)(unsigned long)
3196                                   (arg->prop_values_ptr);
3197                 for (i = 0; i < props_count; i++) {
3198                         if (put_user(obj->properties->ids[i],
3199                                      props_ptr + copied)) {
3200                                 ret = -EFAULT;
3201                                 goto out;
3202                         }
3203                         if (put_user(obj->properties->values[i],
3204                                      prop_values_ptr + copied)) {
3205                                 ret = -EFAULT;
3206                                 goto out;
3207                         }
3208                         copied++;
3209                 }
3210         }
3211         arg->count_props = props_count;
3212 out:
3213         drm_modeset_unlock_all(dev);
3214         return ret;
3215 }
3216
3217 int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
3218                                     struct drm_file *file_priv)
3219 {
3220         struct drm_mode_obj_set_property *arg = data;
3221         struct drm_mode_object *arg_obj;
3222         struct drm_mode_object *prop_obj;
3223         struct drm_property *property;
3224         int ret = -EINVAL;
3225         int i;
3226
3227         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3228                 return -EINVAL;
3229
3230         drm_modeset_lock_all(dev);
3231
3232         arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
3233         if (!arg_obj)
3234                 goto out;
3235         if (!arg_obj->properties)
3236                 goto out;
3237
3238         for (i = 0; i < arg_obj->properties->count; i++)
3239                 if (arg_obj->properties->ids[i] == arg->prop_id)
3240                         break;
3241
3242         if (i == arg_obj->properties->count)
3243                 goto out;
3244
3245         prop_obj = drm_mode_object_find(dev, arg->prop_id,
3246                                         DRM_MODE_OBJECT_PROPERTY);
3247         if (!prop_obj)
3248                 goto out;
3249         property = obj_to_property(prop_obj);
3250
3251         if (!drm_property_change_is_valid(property, arg->value))
3252                 goto out;
3253
3254         switch (arg_obj->type) {
3255         case DRM_MODE_OBJECT_CONNECTOR:
3256                 ret = drm_mode_connector_set_obj_prop(arg_obj, property,
3257                                                       arg->value);
3258                 break;
3259         case DRM_MODE_OBJECT_CRTC:
3260                 ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
3261                 break;
3262         case DRM_MODE_OBJECT_PLANE:
3263                 ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value);
3264                 break;
3265         }
3266
3267 out:
3268         drm_modeset_unlock_all(dev);
3269         return ret;
3270 }
3271
3272 int drm_mode_connector_attach_encoder(struct drm_connector *connector,
3273                                       struct drm_encoder *encoder)
3274 {
3275         int i;
3276
3277         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
3278                 if (connector->encoder_ids[i] == 0) {
3279                         connector->encoder_ids[i] = encoder->base.id;
3280                         return 0;
3281                 }
3282         }
3283         return -ENOMEM;
3284 }
3285 EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
3286
3287 void drm_mode_connector_detach_encoder(struct drm_connector *connector,
3288                                     struct drm_encoder *encoder)
3289 {
3290         int i;
3291         for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
3292                 if (connector->encoder_ids[i] == encoder->base.id) {
3293                         connector->encoder_ids[i] = 0;
3294                         if (connector->encoder == encoder)
3295                                 connector->encoder = NULL;
3296                         break;
3297                 }
3298         }
3299 }
3300 EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
3301
3302 int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
3303                                   int gamma_size)
3304 {
3305         crtc->gamma_size = gamma_size;
3306
3307         crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
3308         if (!crtc->gamma_store) {
3309                 crtc->gamma_size = 0;
3310                 return -ENOMEM;
3311         }
3312
3313         return 0;
3314 }
3315 EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
3316
3317 int drm_mode_gamma_set_ioctl(struct drm_device *dev,
3318                              void *data, struct drm_file *file_priv)
3319 {
3320         struct drm_mode_crtc_lut *crtc_lut = data;
3321         struct drm_mode_object *obj;
3322         struct drm_crtc *crtc;
3323         void *r_base, *g_base, *b_base;
3324         int size;
3325         int ret = 0;
3326
3327         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3328                 return -EINVAL;
3329
3330         drm_modeset_lock_all(dev);
3331         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
3332         if (!obj) {
3333                 ret = -EINVAL;
3334                 goto out;
3335         }
3336         crtc = obj_to_crtc(obj);
3337
3338         if (crtc->funcs->gamma_set == NULL) {
3339                 ret = -ENOSYS;
3340                 goto out;
3341         }
3342
3343         /* memcpy into gamma store */
3344         if (crtc_lut->gamma_size != crtc->gamma_size) {
3345                 ret = -EINVAL;
3346                 goto out;
3347         }
3348
3349         size = crtc_lut->gamma_size * (sizeof(uint16_t));
3350         r_base = crtc->gamma_store;
3351         if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) {
3352                 ret = -EFAULT;
3353                 goto out;
3354         }
3355
3356         g_base = (char *)r_base + size;
3357         if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) {
3358                 ret = -EFAULT;
3359                 goto out;
3360         }
3361
3362         b_base = (char *)r_base + size;
3363         if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) {
3364                 ret = -EFAULT;
3365                 goto out;
3366         }
3367
3368         crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
3369
3370 out:
3371         drm_modeset_unlock_all(dev);
3372         return ret;
3373
3374 }
3375
3376 int drm_mode_gamma_get_ioctl(struct drm_device *dev,
3377                              void *data, struct drm_file *file_priv)
3378 {
3379         struct drm_mode_crtc_lut *crtc_lut = data;
3380         struct drm_mode_object *obj;
3381         struct drm_crtc *crtc;
3382         void *r_base, *g_base, *b_base;
3383         int size;
3384         int ret = 0;
3385
3386         if (!drm_core_check_feature(dev, DRIVER_MODESET))
3387                 return -EINVAL;
3388
3389         drm_modeset_lock_all(dev);
3390         obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
3391         if (!obj) {
3392                 ret = -EINVAL;
3393                 goto out;
3394         }
3395         crtc = obj_to_crtc(obj);
3396
3397         /* memcpy into gamma store */
3398         if (crtc_lut->gamma_size != crtc->gamma_size) {
3399                 ret = -EINVAL;
3400                 goto out;
3401         }
3402
3403         size = crtc_lut->gamma_size * (sizeof(uint16_t));
3404         r_base = crtc->gamma_store;
3405         if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) {
3406                 ret = -EFAULT;
3407                 goto out;
3408         }
3409
3410         g_base = (char *)r_base + size;
3411         if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) {
3412                 ret = -EFAULT;
3413                 goto out;
3414         }
3415
3416         b_base = (char *)g_base + size;
3417         if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) {
3418                 ret = -EFAULT;
3419                 goto out;
3420         }
3421 out:
3422         drm_modeset_unlock_all(dev);
3423         return ret;
3424 }
3425
3426 /*
3427  * The Linux version of kfree() is a macro and can't be called
3428  * directly via a function pointer
3429  */
3430 static void drm_kms_free(void *arg)
3431 {
3432         kfree(arg);
3433 }
3434
3435 int drm_mode_page_flip_ioctl(struct drm_device *dev,
3436                              void *data, struct drm_file *file_priv)
3437 {
3438         struct drm_mode_crtc_page_flip *page_flip = data;
3439         struct drm_mode_object *obj;
3440         struct drm_crtc *crtc;
3441         struct drm_framebuffer *fb = NULL, *old_fb = NULL;
3442         struct drm_pending_vblank_event *e = NULL;
3443         int hdisplay, vdisplay;
3444         int ret = -EINVAL;
3445
3446         if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
3447             page_flip->reserved != 0)
3448                 return -EINVAL;
3449
3450         obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
3451         if (!obj)
3452                 return -EINVAL;
3453         crtc = obj_to_crtc(obj);
3454
3455         mutex_lock(&crtc->mutex);
3456         if (crtc->fb == NULL) {
3457                 /* The framebuffer is currently unbound, presumably
3458                  * due to a hotplug event, that userspace has not
3459                  * yet discovered.
3460                  */
3461                 ret = -EBUSY;
3462                 goto out;
3463         }
3464
3465         if (crtc->funcs->page_flip == NULL)
3466                 goto out;
3467
3468         fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
3469         if (!fb)
3470                 goto out;
3471
3472         hdisplay = crtc->mode.hdisplay;
3473         vdisplay = crtc->mode.vdisplay;
3474
3475         if (crtc->invert_dimensions)
3476                 swap(hdisplay, vdisplay);
3477
3478         if (hdisplay > fb->width ||
3479             vdisplay > fb->height ||
3480             crtc->x > fb->width - hdisplay ||
3481             crtc->y > fb->height - vdisplay) {
3482                 DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
3483                               fb->width, fb->height, hdisplay, vdisplay, crtc->x, crtc->y,
3484                               crtc->invert_dimensions ? " (inverted)" : "");
3485                 ret = -ENOSPC;
3486                 goto out;
3487         }
3488
3489         if (crtc->fb->pixel_format != fb->pixel_format) {
3490                 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
3491                 ret = -EINVAL;
3492                 goto out;
3493         }
3494
3495         if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
3496                 ret = -ENOMEM;
3497                 lockmgr(&dev->event_lock, LK_EXCLUSIVE);
3498                 if (file_priv->event_space < sizeof e->event) {
3499                         lockmgr(&dev->event_lock, LK_RELEASE);
3500                         goto out;
3501                 }
3502                 file_priv->event_space -= sizeof e->event;
3503                 lockmgr(&dev->event_lock, LK_RELEASE);
3504
3505                 e = kzalloc(sizeof *e, GFP_KERNEL);
3506                 if (e == NULL) {
3507                         lockmgr(&dev->event_lock, LK_EXCLUSIVE);
3508                         file_priv->event_space += sizeof e->event;
3509                         lockmgr(&dev->event_lock, LK_RELEASE);
3510                         goto out;
3511                 }
3512
3513                 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
3514                 e->event.base.length = sizeof e->event;
3515                 e->event.user_data = page_flip->user_data;
3516                 e->base.event = &e->event.base;
3517                 e->base.file_priv = file_priv;
3518                 e->base.destroy =
3519                         (void (*) (struct drm_pending_event *))drm_kms_free;
3520         }
3521
3522         old_fb = crtc->fb;
3523         ret = crtc->funcs->page_flip(crtc, fb, e);
3524         if (ret) {
3525                 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
3526                         lockmgr(&dev->event_lock, LK_EXCLUSIVE);
3527                         file_priv->event_space += sizeof e->event;
3528                         lockmgr(&dev->event_lock, LK_RELEASE);
3529                         kfree(e);
3530                 }
3531                 /* Keep the old fb, don't unref it. */
3532                 old_fb = NULL;
3533         } else {
3534                 /*
3535                  * Warn if the driver hasn't properly updated the crtc->fb
3536                  * field to reflect that the new framebuffer is now used.
3537                  * Failing to do so will screw with the reference counting
3538                  * on framebuffers.
3539                  */
3540                 WARN_ON(crtc->fb != fb);
3541                 /* Unref only the old framebuffer. */
3542                 fb = NULL;
3543         }
3544
3545 out:
3546         if (fb)
3547                 drm_framebuffer_unreference(fb);
3548         if (old_fb)
3549                 drm_framebuffer_unreference(old_fb);
3550         mutex_unlock(&crtc->mutex);
3551
3552         return ret;
3553 }
3554
3555 void drm_mode_config_reset(struct drm_device *dev)
3556 {
3557         struct drm_crtc *crtc;
3558         struct drm_encoder *encoder;
3559         struct drm_connector *connector;
3560
3561         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
3562                 if (crtc->funcs->reset)
3563                         crtc->funcs->reset(crtc);
3564
3565         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
3566                 if (encoder->funcs->reset)
3567                         encoder->funcs->reset(encoder);
3568
3569         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
3570                 connector->status = connector_status_unknown;
3571
3572                 if (connector->funcs->reset)
3573                         connector->funcs->reset(connector);
3574         }
3575 }
3576 EXPORT_SYMBOL(drm_mode_config_reset);
3577
3578 int drm_mode_create_dumb_ioctl(struct drm_device *dev,
3579                                void *data, struct drm_file *file_priv)
3580 {
3581         struct drm_mode_create_dumb *args = data;
3582
3583         if (!dev->driver->dumb_create)
3584                 return -ENOSYS;
3585         return dev->driver->dumb_create(file_priv, dev, args);
3586 }
3587
3588 int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
3589                              void *data, struct drm_file *file_priv)
3590 {
3591         struct drm_mode_map_dumb *args = data;
3592
3593         /* call driver ioctl to get mmap offset */
3594         if (!dev->driver->dumb_map_offset)
3595                 return -ENOSYS;
3596
3597         return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
3598 }
3599
3600 int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
3601                                 void *data, struct drm_file *file_priv)
3602 {
3603         struct drm_mode_destroy_dumb *args = data;
3604
3605         if (!dev->driver->dumb_destroy)
3606                 return -ENOSYS;
3607
3608         return dev->driver->dumb_destroy(file_priv, dev, args->handle);
3609 }
3610
3611 /*
3612  * Just need to support RGB formats here for compat with code that doesn't
3613  * use pixel formats directly yet.
3614  */
3615 void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
3616                           int *bpp)
3617 {
3618         switch (format) {
3619         case DRM_FORMAT_C8:
3620         case DRM_FORMAT_RGB332:
3621         case DRM_FORMAT_BGR233:
3622                 *depth = 8;
3623                 *bpp = 8;
3624                 break;
3625         case DRM_FORMAT_XRGB1555:
3626         case DRM_FORMAT_XBGR1555:
3627         case DRM_FORMAT_RGBX5551:
3628         case DRM_FORMAT_BGRX5551:
3629         case DRM_FORMAT_ARGB1555:
3630         case DRM_FORMAT_ABGR1555:
3631         case DRM_FORMAT_RGBA5551:
3632         case DRM_FORMAT_BGRA5551:
3633                 *depth = 15;
3634                 *bpp = 16;
3635                 break;
3636         case DRM_FORMAT_RGB565:
3637         case DRM_FORMAT_BGR565:
3638                 *depth = 16;
3639                 *bpp = 16;
3640                 break;
3641         case DRM_FORMAT_RGB888:
3642         case DRM_FORMAT_BGR888:
3643                 *depth = 24;
3644                 *bpp = 24;
3645                 break;
3646         case DRM_FORMAT_XRGB8888:
3647         case DRM_FORMAT_XBGR8888:
3648         case DRM_FORMAT_RGBX8888:
3649         case DRM_FORMAT_BGRX8888:
3650                 *depth = 24;
3651                 *bpp = 32;
3652                 break;
3653         case DRM_FORMAT_XRGB2101010:
3654         case DRM_FORMAT_XBGR2101010:
3655         case DRM_FORMAT_RGBX1010102:
3656         case DRM_FORMAT_BGRX1010102:
3657         case DRM_FORMAT_ARGB2101010:
3658         case DRM_FORMAT_ABGR2101010:
3659         case DRM_FORMAT_RGBA1010102:
3660         case DRM_FORMAT_BGRA1010102:
3661                 *depth = 30;
3662                 *bpp = 32;
3663                 break;
3664         case DRM_FORMAT_ARGB8888:
3665         case DRM_FORMAT_ABGR8888:
3666         case DRM_FORMAT_RGBA8888:
3667         case DRM_FORMAT_BGRA8888:
3668                 *depth = 32;
3669                 *bpp = 32;
3670                 break;
3671         default:
3672                 DRM_DEBUG_KMS("unsupported pixel format\n");
3673                 *depth = 0;
3674                 *bpp = 0;
3675                 break;
3676         }
3677 }
3678 EXPORT_SYMBOL(drm_fb_get_bpp_depth);
3679
3680 /**
3681  * drm_format_num_planes - get the number of planes for format
3682  * @format: pixel format (DRM_FORMAT_*)
3683  *
3684  * RETURNS:
3685  * The number of planes used by the specified pixel format.
3686  */
3687 int drm_format_num_planes(uint32_t format)
3688 {
3689         switch (format) {
3690         case DRM_FORMAT_YUV410:
3691         case DRM_FORMAT_YVU410:
3692         case DRM_FORMAT_YUV411:
3693         case DRM_FORMAT_YVU411:
3694         case DRM_FORMAT_YUV420:
3695         case DRM_FORMAT_YVU420:
3696         case DRM_FORMAT_YUV422:
3697         case DRM_FORMAT_YVU422:
3698         case DRM_FORMAT_YUV444:
3699         case DRM_FORMAT_YVU444:
3700                 return 3;
3701         case DRM_FORMAT_NV12:
3702         case DRM_FORMAT_NV21:
3703         case DRM_FORMAT_NV16:
3704         case DRM_FORMAT_NV61:
3705         case DRM_FORMAT_NV24:
3706         case DRM_FORMAT_NV42:
3707                 return 2;
3708         default:
3709                 return 1;
3710         }
3711 }
3712 EXPORT_SYMBOL(drm_format_num_planes);
3713
3714 /**
3715  * drm_format_plane_cpp - determine the bytes per pixel value
3716  * @format: pixel format (DRM_FORMAT_*)
3717  * @plane: plane index
3718  *
3719  * RETURNS:
3720  * The bytes per pixel value for the specified plane.
3721  */
3722 int drm_format_plane_cpp(uint32_t format, int plane)
3723 {
3724         unsigned int depth;
3725         int bpp;
3726
3727         if (plane >= drm_format_num_planes(format))
3728                 return 0;
3729
3730         switch (format) {
3731         case DRM_FORMAT_YUYV:
3732         case DRM_FORMAT_YVYU:
3733         case DRM_FORMAT_UYVY:
3734         case DRM_FORMAT_VYUY:
3735                 return 2;
3736         case DRM_FORMAT_NV12:
3737         case DRM_FORMAT_NV21:
3738         case DRM_FORMAT_NV16:
3739         case DRM_FORMAT_NV61:
3740         case DRM_FORMAT_NV24:
3741         case DRM_FORMAT_NV42:
3742                 return plane ? 2 : 1;
3743         case DRM_FORMAT_YUV410:
3744         case DRM_FORMAT_YVU410:
3745         case DRM_FORMAT_YUV411:
3746         case DRM_FORMAT_YVU411:
3747         case DRM_FORMAT_YUV420:
3748         case DRM_FORMAT_YVU420:
3749         case DRM_FORMAT_YUV422:
3750         case DRM_FORMAT_YVU422:
3751         case DRM_FORMAT_YUV444:
3752         case DRM_FORMAT_YVU444:
3753                 return 1;
3754         default:
3755                 drm_fb_get_bpp_depth(format, &depth, &bpp);
3756                 return bpp >> 3;
3757         }
3758 }
3759 EXPORT_SYMBOL(drm_format_plane_cpp);
3760
3761 /**
3762  * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
3763  * @format: pixel format (DRM_FORMAT_*)
3764  *
3765  * RETURNS:
3766  * The horizontal chroma subsampling factor for the
3767  * specified pixel format.
3768  */
3769 int drm_format_horz_chroma_subsampling(uint32_t format)
3770 {
3771         switch (format) {
3772         case DRM_FORMAT_YUV411:
3773         case DRM_FORMAT_YVU411:
3774         case DRM_FORMAT_YUV410:
3775         case DRM_FORMAT_YVU410:
3776                 return 4;
3777         case DRM_FORMAT_YUYV:
3778         case DRM_FORMAT_YVYU:
3779         case DRM_FORMAT_UYVY:
3780         case DRM_FORMAT_VYUY:
3781         case DRM_FORMAT_NV12:
3782         case DRM_FORMAT_NV21:
3783         case DRM_FORMAT_NV16:
3784         case DRM_FORMAT_NV61:
3785         case DRM_FORMAT_YUV422:
3786         case DRM_FORMAT_YVU422:
3787         case DRM_FORMAT_YUV420:
3788         case DRM_FORMAT_YVU420:
3789                 return 2;
3790         default:
3791                 return 1;
3792         }
3793 }
3794 EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
3795
3796 /**
3797  * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
3798  * @format: pixel format (DRM_FORMAT_*)
3799  *
3800  * RETURNS:
3801  * The vertical chroma subsampling factor for the
3802  * specified pixel format.
3803  */
3804 int drm_format_vert_chroma_subsampling(uint32_t format)
3805 {
3806         switch (format) {
3807         case DRM_FORMAT_YUV410:
3808         case DRM_FORMAT_YVU410:
3809                 return 4;
3810         case DRM_FORMAT_YUV420:
3811         case DRM_FORMAT_YVU420:
3812         case DRM_FORMAT_NV12:
3813         case DRM_FORMAT_NV21:
3814                 return 2;
3815         default:
3816                 return 1;
3817         }
3818 }
3819 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
3820
3821 /**
3822  * drm_mode_config_init - initialize DRM mode_configuration structure
3823  * @dev: DRM device
3824  *
3825  * Initialize @dev's mode_config structure, used for tracking the graphics
3826  * configuration of @dev.
3827  *
3828  * Since this initializes the modeset locks, no locking is possible. Which is no
3829  * problem, since this should happen single threaded at init time. It is the
3830  * driver's problem to ensure this guarantee.
3831  *
3832  */
3833 void drm_mode_config_init(struct drm_device *dev)
3834 {
3835         lockinit(&dev->mode_config.mutex, "drmmcm", 0, LK_CANRECURSE);
3836         lockinit(&dev->mode_config.idr_mutex, "mcfgidr", 0, LK_CANRECURSE);
3837         lockinit(&dev->mode_config.fb_lock, "drmfbl", 0, LK_CANRECURSE);
3838         INIT_LIST_HEAD(&dev->mode_config.fb_list);
3839         INIT_LIST_HEAD(&dev->mode_config.crtc_list);
3840         INIT_LIST_HEAD(&dev->mode_config.connector_list);
3841         INIT_LIST_HEAD(&dev->mode_config.encoder_list);
3842         INIT_LIST_HEAD(&dev->mode_config.property_list);
3843         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
3844         INIT_LIST_HEAD(&dev->mode_config.plane_list);
3845         idr_init(&dev->mode_config.crtc_idr);
3846
3847         drm_modeset_lock_all(dev);
3848         drm_mode_create_standard_connector_properties(dev);
3849         drm_modeset_unlock_all(dev);
3850
3851         /* Just to be sure */
3852         dev->mode_config.num_fb = 0;
3853         dev->mode_config.num_connector = 0;
3854         dev->mode_config.num_crtc = 0;
3855         dev->mode_config.num_encoder = 0;
3856 }
3857 EXPORT_SYMBOL(drm_mode_config_init);
3858
3859 /**
3860  * drm_mode_config_cleanup - free up DRM mode_config info
3861  * @dev: DRM device
3862  *
3863  * Free up all the connectors and CRTCs associated with this DRM device, then
3864  * free up the framebuffers and associated buffer objects.
3865  *
3866  * Note that since this /should/ happen single-threaded at driver/device
3867  * teardown time, no locking is required. It's the driver's job to ensure that
3868  * this guarantee actually holds true.
3869  *
3870  * FIXME: cleanup any dangling user buffer objects too
3871  */
3872 void drm_mode_config_cleanup(struct drm_device *dev)
3873 {
3874         struct drm_connector *connector, *ot;
3875         struct drm_crtc *crtc, *ct;
3876         struct drm_encoder *encoder, *enct;
3877         struct drm_framebuffer *fb, *fbt;
3878         struct drm_property *property, *pt;
3879         struct drm_property_blob *blob, *bt;
3880         struct drm_plane *plane, *plt;
3881
3882         list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
3883                                  head) {
3884                 encoder->funcs->destroy(encoder);
3885         }
3886
3887         list_for_each_entry_safe(connector, ot,
3888                                  &dev->mode_config.connector_list, head) {
3889                 connector->funcs->destroy(connector);
3890         }
3891
3892         list_for_each_entry_safe(property, pt, &dev->mode_config.property_list,
3893                                  head) {
3894                 drm_property_destroy(dev, property);
3895         }
3896
3897         list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
3898                                  head) {
3899                 drm_property_destroy_blob(dev, blob);
3900         }
3901
3902         /*
3903          * Single-threaded teardown context, so it's not required to grab the
3904          * fb_lock to protect against concurrent fb_list access. Contrary, it
3905          * would actually deadlock with the drm_framebuffer_cleanup function.
3906          *
3907          * Also, if there are any framebuffers left, that's a driver leak now,
3908          * so politely WARN about this.
3909          */
3910         WARN_ON(!list_empty(&dev->mode_config.fb_list));
3911         list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
3912                 drm_framebuffer_remove(fb);
3913         }
3914
3915         list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
3916                                  head) {
3917                 plane->funcs->destroy(plane);
3918         }
3919
3920         list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
3921                 crtc->funcs->destroy(crtc);
3922         }
3923
3924         idr_destroy(&dev->mode_config.crtc_idr);
3925 }
3926 EXPORT_SYMBOL(drm_mode_config_cleanup);