Rev 3192 | Rev 3746 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3192 | Rev 3480 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | #include |
35 | #include |
36 | #include |
36 | #include |
37 | #include |
37 | #include |
38 | #include |
38 | #include |
Line -... | Line 39... | ||
- | 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 | } |
|
- | 56 | EXPORT_SYMBOL(drm_modeset_lock_all); |
|
- | 57 | ||
- | 58 | /** |
|
- | 59 | * drm_modeset_unlock_all - drop all modeset locks |
|
- | 60 | * @dev: device |
|
- | 61 | */ |
|
- | 62 | void drm_modeset_unlock_all(struct drm_device *dev) |
|
- | 63 | { |
|
- | 64 | struct drm_crtc *crtc; |
|
- | 65 | ||
- | 66 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
|
- | 67 | mutex_unlock(&crtc->mutex); |
|
- | 68 | ||
- | 69 | mutex_unlock(&dev->mode_config.mutex); |
|
- | 70 | } |
|
- | 71 | EXPORT_SYMBOL(drm_modeset_unlock_all); |
|
- | 72 | ||
- | 73 | /** |
|
- | 74 | * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked |
|
- | 75 | * @dev: device |
|
- | 76 | */ |
|
- | 77 | void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) |
|
- | 78 | { |
|
- | 79 | struct drm_crtc *crtc; |
|
- | 80 | ||
- | 81 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
|
- | 82 | WARN_ON(!mutex_is_locked(&crtc->mutex)); |
|
- | 83 | ||
- | 84 | WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
|
- | 85 | } |
|
- | 86 | EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); |
|
39 | 87 | ||
40 | /* Avoid boilerplate. I'm tired of typing. */ |
88 | /* Avoid boilerplate. I'm tired of typing. */ |
41 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
89 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
42 | char *fnname(int val) \ |
90 | char *fnname(int val) \ |
43 | { \ |
91 | { \ |
Line 201... | Line 249... | ||
201 | else |
249 | else |
202 | return "unknown"; |
250 | return "unknown"; |
203 | } |
251 | } |
Line 204... | Line 252... | ||
204 | 252 | ||
205 | /** |
253 | /** |
206 | * drm_mode_object_get - allocate a new identifier |
254 | * drm_mode_object_get - allocate a new modeset identifier |
207 | * @dev: DRM device |
255 | * @dev: DRM device |
208 | * @ptr: object pointer, used to generate unique ID |
256 | * @obj: object pointer, used to generate unique ID |
209 | * @type: object type |
- | |
210 | * |
- | |
211 | * LOCKING: |
257 | * @obj_type: object type |
212 | * |
258 | * |
213 | * Create a unique identifier based on @ptr in @dev's identifier space. Used |
259 | * Create a unique identifier based on @ptr in @dev's identifier space. Used |
214 | * for tracking modes, CRTCs and connectors. |
260 | * for tracking modes, CRTCs and connectors. |
215 | * |
261 | * |
Line 218... | Line 264... | ||
218 | * object. |
264 | * object. |
219 | */ |
265 | */ |
220 | static int drm_mode_object_get(struct drm_device *dev, |
266 | static int drm_mode_object_get(struct drm_device *dev, |
221 | struct drm_mode_object *obj, uint32_t obj_type) |
267 | struct drm_mode_object *obj, uint32_t obj_type) |
222 | { |
268 | { |
223 | int new_id = 0; |
- | |
224 | int ret; |
269 | int ret; |
Line 225... | Line -... | ||
225 | - | ||
226 | again: |
- | |
227 | if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { |
- | |
228 | DRM_ERROR("Ran out memory getting a mode number\n"); |
- | |
229 | return -ENOMEM; |
- | |
230 | } |
- | |
231 | 270 | ||
232 | mutex_lock(&dev->mode_config.idr_mutex); |
271 | mutex_lock(&dev->mode_config.idr_mutex); |
- | 272 | ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL); |
|
- | 273 | if (ret >= 0) { |
|
- | 274 | /* |
|
- | 275 | * Set up the object linking under the protection of the idr |
|
- | 276 | * lock so that other users can't see inconsistent state. |
|
- | 277 | */ |
|
- | 278 | obj->id = ret; |
|
- | 279 | obj->type = obj_type; |
|
233 | ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id); |
280 | } |
234 | mutex_unlock(&dev->mode_config.idr_mutex); |
- | |
235 | if (ret == -EAGAIN) |
- | |
236 | goto again; |
- | |
237 | else if (ret) |
- | |
Line 238... | Line -... | ||
238 | return ret; |
- | |
239 | 281 | mutex_unlock(&dev->mode_config.idr_mutex); |
|
240 | obj->id = new_id; |
- | |
241 | obj->type = obj_type; |
282 | |
Line 242... | Line 283... | ||
242 | return 0; |
283 | return ret < 0 ? ret : 0; |
243 | } |
284 | } |
244 | 285 | ||
245 | /** |
286 | /** |
246 | * drm_mode_object_put - free an identifer |
- | |
247 | * @dev: DRM device |
- | |
248 | * @id: ID to free |
- | |
249 | * |
287 | * drm_mode_object_put - free a modeset identifer |
250 | * LOCKING: |
288 | * @dev: DRM device |
251 | * Caller must hold DRM mode_config lock. |
289 | * @object: object to free |
252 | * |
290 | * |
253 | * Free @id from @dev's unique identifier pool. |
291 | * Free @id from @dev's unique identifier pool. |
Line 258... | Line 296... | ||
258 | mutex_lock(&dev->mode_config.idr_mutex); |
296 | mutex_lock(&dev->mode_config.idr_mutex); |
259 | idr_remove(&dev->mode_config.crtc_idr, object->id); |
297 | idr_remove(&dev->mode_config.crtc_idr, object->id); |
260 | mutex_unlock(&dev->mode_config.idr_mutex); |
298 | mutex_unlock(&dev->mode_config.idr_mutex); |
261 | } |
299 | } |
Line -... | Line 300... | ||
- | 300 | ||
- | 301 | /** |
|
- | 302 | * drm_mode_object_find - look up a drm object with static lifetime |
|
- | 303 | * @dev: drm device |
|
- | 304 | * @id: id of the mode object |
|
- | 305 | * @type: type of the mode object |
|
- | 306 | * |
|
- | 307 | * Note that framebuffers cannot be looked up with this functions - since those |
|
- | 308 | * are reference counted, they need special treatment. |
|
262 | 309 | */ |
|
263 | struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, |
310 | struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, |
264 | uint32_t id, uint32_t type) |
311 | uint32_t id, uint32_t type) |
265 | { |
312 | { |
Line -... | Line 313... | ||
- | 313 | struct drm_mode_object *obj = NULL; |
|
- | 314 | ||
- | 315 | /* Framebuffers are reference counted and need their own lookup |
|
- | 316 | * function.*/ |
|
266 | struct drm_mode_object *obj = NULL; |
317 | WARN_ON(type == DRM_MODE_OBJECT_FB); |
267 | 318 | ||
268 | mutex_lock(&dev->mode_config.idr_mutex); |
319 | mutex_lock(&dev->mode_config.idr_mutex); |
269 | obj = idr_find(&dev->mode_config.crtc_idr, id); |
320 | obj = idr_find(&dev->mode_config.crtc_idr, id); |
270 | if (!obj || (obj->type != type) || (obj->id != id)) |
321 | if (!obj || (obj->type != type) || (obj->id != id)) |
Line 276... | Line 327... | ||
276 | EXPORT_SYMBOL(drm_mode_object_find); |
327 | EXPORT_SYMBOL(drm_mode_object_find); |
Line 277... | Line 328... | ||
277 | 328 | ||
278 | /** |
329 | /** |
279 | * drm_framebuffer_init - initialize a framebuffer |
330 | * drm_framebuffer_init - initialize a framebuffer |
280 | * @dev: DRM device |
- | |
281 | * |
331 | * @dev: DRM device |
282 | * LOCKING: |
332 | * @fb: framebuffer to be initialized |
283 | * Caller must hold mode config lock. |
333 | * @funcs: ... with these functions |
284 | * |
334 | * |
285 | * Allocates an ID for the framebuffer's parent mode object, sets its mode |
335 | * Allocates an ID for the framebuffer's parent mode object, sets its mode |
286 | * functions & device file and adds it to the master fd list. |
336 | * functions & device file and adds it to the master fd list. |
- | 337 | * |
|
- | 338 | * IMPORTANT: |
|
- | 339 | * This functions publishes the fb and makes it available for concurrent access |
|
- | 340 | * by other users. Which means by this point the fb _must_ be fully set up - |
|
- | 341 | * since all the fb attributes are invariant over its lifetime, no further |
|
- | 342 | * locking but only correct reference counting is required. |
|
287 | * |
343 | * |
288 | * RETURNS: |
344 | * RETURNS: |
289 | * Zero on success, error code on failure. |
345 | * Zero on success, error code on failure. |
290 | */ |
346 | */ |
291 | int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, |
347 | int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, |
292 | const struct drm_framebuffer_funcs *funcs) |
348 | const struct drm_framebuffer_funcs *funcs) |
293 | { |
349 | { |
Line -... | Line 350... | ||
- | 350 | int ret; |
|
- | 351 | ||
- | 352 | mutex_lock(&dev->mode_config.fb_lock); |
|
- | 353 | kref_init(&fb->refcount); |
|
- | 354 | INIT_LIST_HEAD(&fb->filp_head); |
|
- | 355 | fb->dev = dev; |
|
294 | int ret; |
356 | fb->funcs = funcs; |
295 | 357 | ||
296 | ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); |
358 | ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); |
- | 359 | if (ret) |
|
- | 360 | goto out; |
|
- | 361 | ||
Line 297... | Line -... | ||
297 | if (ret) |
- | |
298 | return ret; |
- | |
299 | 362 | /* Grab the idr reference. */ |
|
300 | fb->dev = dev; |
363 | drm_framebuffer_reference(fb); |
- | 364 | ||
- | 365 | dev->mode_config.num_fb++; |
|
Line 301... | Line 366... | ||
301 | fb->funcs = funcs; |
366 | list_add(&fb->head, &dev->mode_config.fb_list); |
302 | dev->mode_config.num_fb++; |
367 | out: |
303 | list_add(&fb->head, &dev->mode_config.fb_list); |
368 | mutex_unlock(&dev->mode_config.fb_lock); |
Line -... | Line 369... | ||
- | 369 | ||
- | 370 | return 0; |
|
- | 371 | } |
|
- | 372 | EXPORT_SYMBOL(drm_framebuffer_init); |
|
- | 373 | ||
- | 374 | static void drm_framebuffer_free(struct kref *kref) |
|
- | 375 | { |
|
- | 376 | struct drm_framebuffer *fb = |
|
- | 377 | container_of(kref, struct drm_framebuffer, refcount); |
|
- | 378 | fb->funcs->destroy(fb); |
|
- | 379 | } |
|
- | 380 | ||
- | 381 | static struct drm_framebuffer *__drm_framebuffer_lookup(struct drm_device *dev, |
|
- | 382 | uint32_t id) |
|
- | 383 | { |
|
- | 384 | struct drm_mode_object *obj = NULL; |
|
- | 385 | struct drm_framebuffer *fb; |
|
- | 386 | ||
- | 387 | mutex_lock(&dev->mode_config.idr_mutex); |
|
- | 388 | obj = idr_find(&dev->mode_config.crtc_idr, id); |
|
- | 389 | if (!obj || (obj->type != DRM_MODE_OBJECT_FB) || (obj->id != id)) |
|
- | 390 | fb = NULL; |
|
- | 391 | else |
|
- | 392 | fb = obj_to_fb(obj); |
|
- | 393 | mutex_unlock(&dev->mode_config.idr_mutex); |
|
- | 394 | ||
- | 395 | return fb; |
|
- | 396 | } |
|
- | 397 | ||
- | 398 | /** |
|
- | 399 | * drm_framebuffer_lookup - look up a drm framebuffer and grab a reference |
|
- | 400 | * @dev: drm device |
|
- | 401 | * @id: id of the fb object |
|
- | 402 | * |
|
- | 403 | * If successful, this grabs an additional reference to the framebuffer - |
|
- | 404 | * callers need to make sure to eventually unreference the returned framebuffer |
|
- | 405 | * again. |
|
- | 406 | */ |
|
- | 407 | struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, |
|
- | 408 | uint32_t id) |
|
- | 409 | { |
|
- | 410 | struct drm_framebuffer *fb; |
|
- | 411 | ||
- | 412 | mutex_lock(&dev->mode_config.fb_lock); |
|
- | 413 | fb = __drm_framebuffer_lookup(dev, id); |
|
- | 414 | if (fb) |
|
- | 415 | kref_get(&fb->refcount); |
|
- | 416 | mutex_unlock(&dev->mode_config.fb_lock); |
|
- | 417 | ||
- | 418 | return fb; |
|
- | 419 | } |
|
- | 420 | EXPORT_SYMBOL(drm_framebuffer_lookup); |
|
- | 421 | ||
- | 422 | /** |
|
- | 423 | * drm_framebuffer_unreference - unref a framebuffer |
|
- | 424 | * @fb: framebuffer to unref |
|
- | 425 | * |
|
- | 426 | * This functions decrements the fb's refcount and frees it if it drops to zero. |
|
- | 427 | */ |
|
- | 428 | void drm_framebuffer_unreference(struct drm_framebuffer *fb) |
|
- | 429 | { |
|
- | 430 | DRM_DEBUG("FB ID: %d\n", fb->base.id); |
|
- | 431 | kref_put(&fb->refcount, drm_framebuffer_free); |
|
- | 432 | } |
|
- | 433 | EXPORT_SYMBOL(drm_framebuffer_unreference); |
|
- | 434 | ||
- | 435 | /** |
|
- | 436 | * drm_framebuffer_reference - incr the fb refcnt |
|
- | 437 | * @fb: framebuffer |
|
- | 438 | */ |
|
- | 439 | void drm_framebuffer_reference(struct drm_framebuffer *fb) |
|
- | 440 | { |
|
- | 441 | DRM_DEBUG("FB ID: %d\n", fb->base.id); |
|
- | 442 | kref_get(&fb->refcount); |
|
- | 443 | } |
|
- | 444 | EXPORT_SYMBOL(drm_framebuffer_reference); |
|
- | 445 | ||
- | 446 | static void drm_framebuffer_free_bug(struct kref *kref) |
|
- | 447 | { |
|
- | 448 | BUG(); |
|
- | 449 | } |
|
- | 450 | ||
- | 451 | static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) |
|
- | 452 | { |
|
- | 453 | DRM_DEBUG("FB ID: %d\n", fb->base.id); |
|
- | 454 | kref_put(&fb->refcount, drm_framebuffer_free_bug); |
|
- | 455 | } |
|
- | 456 | ||
- | 457 | /* dev->mode_config.fb_lock must be held! */ |
|
- | 458 | static void __drm_framebuffer_unregister(struct drm_device *dev, |
|
- | 459 | struct drm_framebuffer *fb) |
|
- | 460 | { |
|
- | 461 | mutex_lock(&dev->mode_config.idr_mutex); |
|
- | 462 | idr_remove(&dev->mode_config.crtc_idr, fb->base.id); |
|
- | 463 | mutex_unlock(&dev->mode_config.idr_mutex); |
|
- | 464 | ||
- | 465 | fb->base.id = 0; |
|
- | 466 | ||
- | 467 | __drm_framebuffer_unreference(fb); |
|
- | 468 | } |
|
- | 469 | ||
- | 470 | /** |
|
- | 471 | * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr |
|
- | 472 | * @fb: fb to unregister |
|
- | 473 | * |
|
- | 474 | * Drivers need to call this when cleaning up driver-private framebuffers, e.g. |
|
- | 475 | * those used for fbdev. Note that the caller must hold a reference of it's own, |
|
- | 476 | * i.e. the object may not be destroyed through this call (since it'll lead to a |
|
- | 477 | * locking inversion). |
|
- | 478 | */ |
|
- | 479 | void drm_framebuffer_unregister_private(struct drm_framebuffer *fb) |
|
- | 480 | { |
|
- | 481 | struct drm_device *dev = fb->dev; |
|
- | 482 | ||
- | 483 | mutex_lock(&dev->mode_config.fb_lock); |
|
- | 484 | /* Mark fb as reaped and drop idr ref. */ |
|
304 | 485 | __drm_framebuffer_unregister(dev, fb); |
|
305 | return 0; |
486 | mutex_unlock(&dev->mode_config.fb_lock); |
306 | } |
487 | } |
307 | EXPORT_SYMBOL(drm_framebuffer_init); |
488 | EXPORT_SYMBOL(drm_framebuffer_unregister_private); |
308 | - | ||
- | 489 | ||
309 | /** |
490 | /** |
310 | * drm_framebuffer_cleanup - remove a framebuffer object |
491 | * drm_framebuffer_cleanup - remove a framebuffer object |
311 | * @fb: framebuffer to remove |
492 | * @fb: framebuffer to remove |
- | 493 | * |
|
- | 494 | * Cleanup references to a user-created framebuffer. This function is intended |
|
- | 495 | * to be used from the drivers ->destroy callback. |
|
- | 496 | * |
|
- | 497 | * Note that this function does not remove the fb from active usuage - if it is |
|
- | 498 | * still used anywhere, hilarity can ensue since userspace could call getfb on |
|
312 | * |
499 | * the id and get back -EINVAL. Obviously no concern at driver unload time. |
313 | * LOCKING: |
500 | * |
314 | * Caller must hold mode config lock. |
501 | * Also, the framebuffer will not be removed from the lookup idr - for |
315 | * |
502 | * user-created framebuffers this will happen in in the rmfb ioctl. For |
316 | * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes |
503 | * driver-private objects (e.g. for fbdev) drivers need to explicitly call |
317 | * it, setting it to NULL. |
504 | * drm_framebuffer_unregister_private. |
318 | */ |
- | |
319 | void drm_framebuffer_cleanup(struct drm_framebuffer *fb) |
- | |
320 | { |
- | |
321 | struct drm_device *dev = fb->dev; |
- | |
322 | /* |
- | |
323 | * This could be moved to drm_framebuffer_remove(), but for |
- | |
324 | * debugging is nice to keep around the list of fb's that are |
505 | */ |
325 | * no longer associated w/ a drm_file but are not unreferenced |
506 | void drm_framebuffer_cleanup(struct drm_framebuffer *fb) |
326 | * yet. (i915 and omapdrm have debugfs files which will show |
507 | { |
- | 508 | struct drm_device *dev = fb->dev; |
|
327 | * this.) |
509 | |
328 | */ |
510 | mutex_lock(&dev->mode_config.fb_lock); |
Line -... | Line 511... | ||
- | 511 | list_del(&fb->head); |
|
- | 512 | dev->mode_config.num_fb--; |
|
- | 513 | mutex_unlock(&dev->mode_config.fb_lock); |
|
- | 514 | } |
|
- | 515 | EXPORT_SYMBOL(drm_framebuffer_cleanup); |
|
- | 516 | ||
- | 517 | /** |
|
- | 518 | * drm_framebuffer_remove - remove and unreference a framebuffer object |
|
- | 519 | * @fb: framebuffer to remove |
|
- | 520 | * |
|
- | 521 | * Scans all the CRTCs and planes in @dev's mode_config. If they're |
|
- | 522 | * using @fb, removes it, setting it to NULL. Then drops the reference to the |
|
- | 523 | * passed-in framebuffer. Might take the modeset locks. |
|
- | 524 | * |
|
- | 525 | * Note that this function optimizes the cleanup away if the caller holds the |
|
- | 526 | * last reference to the framebuffer. It is also guaranteed to not take the |
|
- | 527 | * modeset locks in this case. |
|
- | 528 | */ |
|
- | 529 | void drm_framebuffer_remove(struct drm_framebuffer *fb) |
|
Line -... | Line 530... | ||
- | 530 | { |
|
Line -... | Line 531... | ||
- | 531 | struct drm_device *dev = fb->dev; |
|
- | 532 | struct drm_crtc *crtc; |
|
- | 533 | struct drm_plane *plane; |
|
- | 534 | struct drm_mode_set set; |
|
- | 535 | int ret; |
|
- | 536 | ||
- | 537 | WARN_ON(!list_empty(&fb->filp_head)); |
|
- | 538 | ||
- | 539 | /* |
|
- | 540 | * drm ABI mandates that we remove any deleted framebuffers from active |
|
- | 541 | * useage. But since most sane clients only remove framebuffers they no |
|
- | 542 | * longer need, try to optimize this away. |
|
- | 543 | * |
|
- | 544 | * Since we're holding a reference ourselves, observing a refcount of 1 |
|
- | 545 | * means that we're the last holder and can skip it. Also, the refcount |
|
- | 546 | * can never increase from 1 again, so we don't need any barriers or |
|
- | 547 | * locks. |
|
- | 548 | * |
|
- | 549 | * Note that userspace could try to race with use and instate a new |
|
- | 550 | * usage _after_ we've cleared all current ones. End result will be an |
|
- | 551 | * in-use fb with fb-id == 0. Userspace is allowed to shoot its own foot |
|
- | 552 | * in this manner. |
|
- | 553 | */ |
|
- | 554 | if (atomic_read(&fb->refcount.refcount) > 1) { |
|
- | 555 | drm_modeset_lock_all(dev); |
|
- | 556 | /* remove from any CRTC */ |
|
- | 557 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
|
- | 558 | if (crtc->fb == fb) { |
|
- | 559 | /* should turn off the crtc */ |
|
Line -... | Line 560... | ||
- | 560 | memset(&set, 0, sizeof(struct drm_mode_set)); |
|
- | 561 | set.crtc = crtc; |
|
- | 562 | set.fb = NULL; |
|
- | 563 | ret = drm_mode_set_config_internal(&set); |
|
- | 564 | if (ret) |
|
- | 565 | DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); |
|
- | 566 | } |
|
- | 567 | } |
|
- | 568 | ||
- | 569 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
|
- | 570 | if (plane->fb == fb) { |
|
- | 571 | /* should turn off the crtc */ |
|
- | 572 | ret = plane->funcs->disable_plane(plane); |
|
- | 573 | if (ret) |
|
- | 574 | DRM_ERROR("failed to disable plane with busy fb\n"); |
|
- | 575 | /* disconnect the plane from the fb and crtc: */ |
|
- | 576 | __drm_framebuffer_unreference(plane->fb); |
|
- | 577 | plane->fb = NULL; |
|
Line 329... | Line 578... | ||
329 | drm_mode_object_put(dev, &fb->base); |
578 | plane->crtc = NULL; |
330 | list_del(&fb->head); |
579 | } |
331 | dev->mode_config.num_fb--; |
580 | } |
332 | } |
581 | drm_modeset_unlock_all(dev); |
333 | EXPORT_SYMBOL(drm_framebuffer_cleanup); |
582 | } |
334 | 583 | ||
335 | - | ||
336 | - | ||
337 | - | ||
338 | 584 | drm_framebuffer_unreference(fb); |
|
339 | /** |
585 | } |
340 | * drm_crtc_init - Initialise a new CRTC object |
586 | EXPORT_SYMBOL(drm_framebuffer_remove); |
341 | * @dev: DRM device |
587 | |
342 | * @crtc: CRTC object to init |
588 | /** |
Line 357... | Line 603... | ||
357 | 603 | ||
358 | crtc->dev = dev; |
604 | crtc->dev = dev; |
359 | crtc->funcs = funcs; |
605 | crtc->funcs = funcs; |
Line -... | Line 606... | ||
- | 606 | crtc->invert_dimensions = false; |
|
- | 607 | ||
360 | crtc->invert_dimensions = false; |
608 | drm_modeset_lock_all(dev); |
Line 361... | Line 609... | ||
361 | 609 | mutex_init(&crtc->mutex); |
|
362 | mutex_lock(&dev->mode_config.mutex); |
610 | mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex); |
363 | 611 | ||
Line 369... | Line 617... | ||
369 | 617 | ||
370 | list_add_tail(&crtc->head, &dev->mode_config.crtc_list); |
618 | list_add_tail(&crtc->head, &dev->mode_config.crtc_list); |
Line 371... | Line 619... | ||
371 | dev->mode_config.num_crtc++; |
619 | dev->mode_config.num_crtc++; |
372 | 620 | ||
Line 373... | Line 621... | ||
373 | out: |
621 | out: |
374 | mutex_unlock(&dev->mode_config.mutex); |
622 | drm_modeset_unlock_all(dev); |
375 | 623 | ||
Line 376... | Line 624... | ||
376 | return ret; |
624 | return ret; |
377 | } |
625 | } |
378 | EXPORT_SYMBOL(drm_crtc_init); |
626 | EXPORT_SYMBOL(drm_crtc_init); |
379 | 627 | ||
380 | /** |
- | |
381 | * drm_crtc_cleanup - Cleans up the core crtc usage. |
- | |
382 | * @crtc: CRTC to cleanup |
- | |
383 | * |
628 | /** |
384 | * LOCKING: |
629 | * drm_crtc_cleanup - Cleans up the core crtc usage. |
385 | * Caller must hold mode config lock. |
630 | * @crtc: CRTC to cleanup |
386 | * |
631 | * |
387 | * Cleanup @crtc. Removes from drm modesetting space |
632 | * Cleanup @crtc. Removes from drm modesetting space |
Line 403... | Line 648... | ||
403 | /** |
648 | /** |
404 | * drm_mode_probed_add - add a mode to a connector's probed mode list |
649 | * drm_mode_probed_add - add a mode to a connector's probed mode list |
405 | * @connector: connector the new mode |
650 | * @connector: connector the new mode |
406 | * @mode: mode data |
651 | * @mode: mode data |
407 | * |
652 | * |
408 | * LOCKING: |
- | |
409 | * Caller must hold mode config lock. |
- | |
410 | * |
- | |
411 | * Add @mode to @connector's mode list for later use. |
653 | * Add @mode to @connector's mode list for later use. |
412 | */ |
654 | */ |
413 | void drm_mode_probed_add(struct drm_connector *connector, |
655 | void drm_mode_probed_add(struct drm_connector *connector, |
414 | struct drm_display_mode *mode) |
656 | struct drm_display_mode *mode) |
415 | { |
657 | { |
Line 420... | Line 662... | ||
420 | /** |
662 | /** |
421 | * drm_mode_remove - remove and free a mode |
663 | * drm_mode_remove - remove and free a mode |
422 | * @connector: connector list to modify |
664 | * @connector: connector list to modify |
423 | * @mode: mode to remove |
665 | * @mode: mode to remove |
424 | * |
666 | * |
425 | * LOCKING: |
- | |
426 | * Caller must hold mode config lock. |
- | |
427 | * |
- | |
428 | * Remove @mode from @connector's mode list, then free it. |
667 | * Remove @mode from @connector's mode list, then free it. |
429 | */ |
668 | */ |
430 | void drm_mode_remove(struct drm_connector *connector, |
669 | void drm_mode_remove(struct drm_connector *connector, |
431 | struct drm_display_mode *mode) |
670 | struct drm_display_mode *mode) |
432 | { |
671 | { |
Line 438... | Line 677... | ||
438 | /** |
677 | /** |
439 | * drm_connector_init - Init a preallocated connector |
678 | * drm_connector_init - Init a preallocated connector |
440 | * @dev: DRM device |
679 | * @dev: DRM device |
441 | * @connector: the connector to init |
680 | * @connector: the connector to init |
442 | * @funcs: callbacks for this connector |
681 | * @funcs: callbacks for this connector |
443 | * @name: user visible name of the connector |
682 | * @connector_type: user visible type of the connector |
444 | * |
- | |
445 | * LOCKING: |
- | |
446 | * Takes mode config lock. |
- | |
447 | * |
683 | * |
448 | * Initialises a preallocated connector. Connectors should be |
684 | * Initialises a preallocated connector. Connectors should be |
449 | * subclassed as part of driver connector objects. |
685 | * subclassed as part of driver connector objects. |
450 | * |
686 | * |
451 | * RETURNS: |
687 | * RETURNS: |
Line 456... | Line 692... | ||
456 | const struct drm_connector_funcs *funcs, |
692 | const struct drm_connector_funcs *funcs, |
457 | int connector_type) |
693 | int connector_type) |
458 | { |
694 | { |
459 | int ret; |
695 | int ret; |
Line 460... | Line 696... | ||
460 | 696 | ||
Line 461... | Line 697... | ||
461 | mutex_lock(&dev->mode_config.mutex); |
697 | drm_modeset_lock_all(dev); |
462 | 698 | ||
463 | ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR); |
699 | ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR); |
Line 486... | Line 722... | ||
486 | 722 | ||
487 | drm_object_attach_property(&connector->base, |
723 | drm_object_attach_property(&connector->base, |
Line 488... | Line 724... | ||
488 | dev->mode_config.dpms_property, 0); |
724 | dev->mode_config.dpms_property, 0); |
489 | 725 | ||
Line 490... | Line 726... | ||
490 | out: |
726 | out: |
491 | mutex_unlock(&dev->mode_config.mutex); |
727 | drm_modeset_unlock_all(dev); |
492 | 728 | ||
Line 493... | Line 729... | ||
493 | return ret; |
729 | return ret; |
494 | } |
730 | } |
495 | EXPORT_SYMBOL(drm_connector_init); |
731 | EXPORT_SYMBOL(drm_connector_init); |
496 | 732 | ||
497 | /** |
- | |
498 | * drm_connector_cleanup - cleans up an initialised connector |
- | |
499 | * @connector: connector to cleanup |
- | |
500 | * |
733 | /** |
501 | * LOCKING: |
734 | * drm_connector_cleanup - cleans up an initialised connector |
502 | * Takes mode config lock. |
735 | * @connector: connector to cleanup |
503 | * |
736 | * |
504 | * Cleans up the connector but doesn't free the object. |
737 | * Cleans up the connector but doesn't free the object. |
Line 515... | Line 748... | ||
515 | drm_mode_remove(connector, mode); |
748 | drm_mode_remove(connector, mode); |
Line 516... | Line 749... | ||
516 | 749 | ||
517 | list_for_each_entry_safe(mode, t, &connector->user_modes, head) |
750 | list_for_each_entry_safe(mode, t, &connector->user_modes, head) |
Line 518... | Line -... | ||
518 | drm_mode_remove(connector, mode); |
- | |
519 | 751 | drm_mode_remove(connector, mode); |
|
520 | mutex_lock(&dev->mode_config.mutex); |
752 | |
521 | drm_mode_object_put(dev, &connector->base); |
753 | drm_mode_object_put(dev, &connector->base); |
522 | list_del(&connector->head); |
- | |
523 | dev->mode_config.num_connector--; |
754 | list_del(&connector->head); |
524 | mutex_unlock(&dev->mode_config.mutex); |
755 | dev->mode_config.num_connector--; |
Line 525... | Line 756... | ||
525 | } |
756 | } |
526 | EXPORT_SYMBOL(drm_connector_cleanup); |
757 | EXPORT_SYMBOL(drm_connector_cleanup); |
Line 541... | Line 772... | ||
541 | const struct drm_encoder_funcs *funcs, |
772 | const struct drm_encoder_funcs *funcs, |
542 | int encoder_type) |
773 | int encoder_type) |
543 | { |
774 | { |
544 | int ret; |
775 | int ret; |
Line 545... | Line 776... | ||
545 | 776 | ||
Line 546... | Line 777... | ||
546 | mutex_lock(&dev->mode_config.mutex); |
777 | drm_modeset_lock_all(dev); |
547 | 778 | ||
548 | ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); |
779 | ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); |
Line 555... | Line 786... | ||
555 | 786 | ||
556 | list_add_tail(&encoder->head, &dev->mode_config.encoder_list); |
787 | list_add_tail(&encoder->head, &dev->mode_config.encoder_list); |
Line 557... | Line 788... | ||
557 | dev->mode_config.num_encoder++; |
788 | dev->mode_config.num_encoder++; |
558 | 789 | ||
Line 559... | Line 790... | ||
559 | out: |
790 | out: |
560 | mutex_unlock(&dev->mode_config.mutex); |
791 | drm_modeset_unlock_all(dev); |
561 | 792 | ||
Line 562... | Line 793... | ||
562 | return ret; |
793 | return ret; |
563 | } |
794 | } |
564 | EXPORT_SYMBOL(drm_encoder_init); |
795 | EXPORT_SYMBOL(drm_encoder_init); |
565 | 796 | ||
566 | void drm_encoder_cleanup(struct drm_encoder *encoder) |
797 | void drm_encoder_cleanup(struct drm_encoder *encoder) |
567 | { |
798 | { |
568 | struct drm_device *dev = encoder->dev; |
799 | struct drm_device *dev = encoder->dev; |
569 | mutex_lock(&dev->mode_config.mutex); |
800 | drm_modeset_lock_all(dev); |
570 | drm_mode_object_put(dev, &encoder->base); |
801 | drm_mode_object_put(dev, &encoder->base); |
571 | list_del(&encoder->head); |
802 | list_del(&encoder->head); |
Line 572... | Line 803... | ||
572 | dev->mode_config.num_encoder--; |
803 | dev->mode_config.num_encoder--; |
573 | mutex_unlock(&dev->mode_config.mutex); |
804 | drm_modeset_unlock_all(dev); |
Line 580... | Line 811... | ||
580 | const uint32_t *formats, uint32_t format_count, |
811 | const uint32_t *formats, uint32_t format_count, |
581 | bool priv) |
812 | bool priv) |
582 | { |
813 | { |
583 | int ret; |
814 | int ret; |
Line 584... | Line 815... | ||
584 | 815 | ||
Line 585... | Line 816... | ||
585 | mutex_lock(&dev->mode_config.mutex); |
816 | drm_modeset_lock_all(dev); |
586 | 817 | ||
587 | ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); |
818 | ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); |
Line 614... | Line 845... | ||
614 | } else { |
845 | } else { |
615 | INIT_LIST_HEAD(&plane->head); |
846 | INIT_LIST_HEAD(&plane->head); |
616 | } |
847 | } |
Line 617... | Line 848... | ||
617 | 848 | ||
618 | out: |
849 | out: |
Line 619... | Line 850... | ||
619 | mutex_unlock(&dev->mode_config.mutex); |
850 | drm_modeset_unlock_all(dev); |
620 | 851 | ||
621 | return ret; |
852 | return ret; |
Line 622... | Line 853... | ||
622 | } |
853 | } |
623 | EXPORT_SYMBOL(drm_plane_init); |
854 | EXPORT_SYMBOL(drm_plane_init); |
624 | 855 | ||
Line 625... | Line 856... | ||
625 | void drm_plane_cleanup(struct drm_plane *plane) |
856 | void drm_plane_cleanup(struct drm_plane *plane) |
626 | { |
857 | { |
627 | struct drm_device *dev = plane->dev; |
858 | struct drm_device *dev = plane->dev; |
628 | 859 | ||
629 | mutex_lock(&dev->mode_config.mutex); |
860 | drm_modeset_lock_all(dev); |
630 | kfree(plane->format_types); |
861 | kfree(plane->format_types); |
631 | drm_mode_object_put(dev, &plane->base); |
862 | drm_mode_object_put(dev, &plane->base); |
632 | /* if not added to a list, it must be a private plane */ |
863 | /* if not added to a list, it must be a private plane */ |
633 | if (!list_empty(&plane->head)) { |
864 | if (!list_empty(&plane->head)) { |
634 | list_del(&plane->head); |
865 | list_del(&plane->head); |
635 | dev->mode_config.num_plane--; |
866 | dev->mode_config.num_plane--; |
Line 636... | Line 867... | ||
636 | } |
867 | } |
637 | mutex_unlock(&dev->mode_config.mutex); |
868 | drm_modeset_unlock_all(dev); |
638 | } |
869 | } |
639 | EXPORT_SYMBOL(drm_plane_cleanup); |
870 | EXPORT_SYMBOL(drm_plane_cleanup); |
640 | - | ||
641 | /** |
- | |
642 | * drm_mode_create - create a new display mode |
- | |
643 | * @dev: DRM device |
871 | |
644 | * |
872 | /** |
645 | * LOCKING: |
873 | * drm_mode_create - create a new display mode |
646 | * Caller must hold DRM mode_config lock. |
874 | * @dev: DRM device |
647 | * |
875 | * |
Line 670... | Line 898... | ||
670 | /** |
898 | /** |
671 | * drm_mode_destroy - remove a mode |
899 | * drm_mode_destroy - remove a mode |
672 | * @dev: DRM device |
900 | * @dev: DRM device |
673 | * @mode: mode to remove |
901 | * @mode: mode to remove |
674 | * |
902 | * |
675 | * LOCKING: |
- | |
676 | * Caller must hold mode config lock. |
- | |
677 | * |
- | |
678 | * Free @mode's unique identifier, then free it. |
903 | * Free @mode's unique identifier, then free it. |
679 | */ |
904 | */ |
680 | void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode) |
905 | void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode) |
681 | { |
906 | { |
682 | if (!mode) |
907 | if (!mode) |
Line 897... | Line 1122... | ||
897 | 1122 | ||
898 | /** |
1123 | /** |
899 | * drm_mode_config_init - initialize DRM mode_configuration structure |
1124 | * drm_mode_config_init - initialize DRM mode_configuration structure |
900 | * @dev: DRM device |
1125 | * @dev: DRM device |
901 | * |
- | |
902 | * LOCKING: |
- | |
903 | * None, should happen single threaded at init time. |
- | |
904 | * |
1126 | * |
905 | * Initialize @dev's mode_config structure, used for tracking the graphics |
1127 | * Initialize @dev's mode_config structure, used for tracking the graphics |
- | 1128 | * configuration of @dev. |
|
- | 1129 | * |
|
- | 1130 | * Since this initializes the modeset locks, no locking is possible. Which is no |
|
- | 1131 | * problem, since this should happen single threaded at init time. It is the |
|
- | 1132 | * driver's problem to ensure this guarantee. |
|
906 | * configuration of @dev. |
1133 | * |
907 | */ |
1134 | */ |
908 | void drm_mode_config_init(struct drm_device *dev) |
1135 | void drm_mode_config_init(struct drm_device *dev) |
909 | { |
1136 | { |
910 | mutex_init(&dev->mode_config.mutex); |
1137 | mutex_init(&dev->mode_config.mutex); |
- | 1138 | mutex_init(&dev->mode_config.idr_mutex); |
|
911 | mutex_init(&dev->mode_config.idr_mutex); |
1139 | mutex_init(&dev->mode_config.fb_lock); |
912 | INIT_LIST_HEAD(&dev->mode_config.fb_list); |
1140 | INIT_LIST_HEAD(&dev->mode_config.fb_list); |
913 | INIT_LIST_HEAD(&dev->mode_config.crtc_list); |
1141 | INIT_LIST_HEAD(&dev->mode_config.crtc_list); |
914 | INIT_LIST_HEAD(&dev->mode_config.connector_list); |
1142 | INIT_LIST_HEAD(&dev->mode_config.connector_list); |
915 | INIT_LIST_HEAD(&dev->mode_config.encoder_list); |
1143 | INIT_LIST_HEAD(&dev->mode_config.encoder_list); |
916 | INIT_LIST_HEAD(&dev->mode_config.property_list); |
1144 | INIT_LIST_HEAD(&dev->mode_config.property_list); |
917 | INIT_LIST_HEAD(&dev->mode_config.property_blob_list); |
1145 | INIT_LIST_HEAD(&dev->mode_config.property_blob_list); |
918 | INIT_LIST_HEAD(&dev->mode_config.plane_list); |
1146 | INIT_LIST_HEAD(&dev->mode_config.plane_list); |
Line 919... | Line 1147... | ||
919 | idr_init(&dev->mode_config.crtc_idr); |
1147 | idr_init(&dev->mode_config.crtc_idr); |
920 | 1148 | ||
921 | mutex_lock(&dev->mode_config.mutex); |
1149 | drm_modeset_lock_all(dev); |
Line 922... | Line 1150... | ||
922 | drm_mode_create_standard_connector_properties(dev); |
1150 | drm_mode_create_standard_connector_properties(dev); |
923 | mutex_unlock(&dev->mode_config.mutex); |
1151 | drm_modeset_unlock_all(dev); |
924 | 1152 | ||
925 | /* Just to be sure */ |
1153 | /* Just to be sure */ |
Line 976... | Line 1204... | ||
976 | 1204 | ||
977 | /** |
1205 | /** |
978 | * drm_mode_config_cleanup - free up DRM mode_config info |
1206 | * drm_mode_config_cleanup - free up DRM mode_config info |
979 | * @dev: DRM device |
1207 | * @dev: DRM device |
980 | * |
- | |
981 | * LOCKING: |
- | |
982 | * Caller must hold mode config lock. |
- | |
983 | * |
1208 | * |
984 | * Free up all the connectors and CRTCs associated with this DRM device, then |
1209 | * Free up all the connectors and CRTCs associated with this DRM device, then |
985 | * free up the framebuffers and associated buffer objects. |
1210 | * free up the framebuffers and associated buffer objects. |
- | 1211 | * |
|
- | 1212 | * Note that since this /should/ happen single-threaded at driver/device |
|
- | 1213 | * teardown time, no locking is required. It's the driver's job to ensure that |
|
- | 1214 | * this guarantee actually holds true. |
|
986 | * |
1215 | * |
987 | * FIXME: cleanup any dangling user buffer objects too |
1216 | * FIXME: cleanup any dangling user buffer objects too |
988 | */ |
1217 | */ |
989 | void drm_mode_config_cleanup(struct drm_device *dev) |
1218 | void drm_mode_config_cleanup(struct drm_device *dev) |
990 | { |
1219 | { |
Line 1008... | Line 1237... | ||
1008 | list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, |
1237 | list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, |
1009 | head) { |
1238 | head) { |
1010 | drm_property_destroy(dev, property); |
1239 | drm_property_destroy(dev, property); |
1011 | } |
1240 | } |
Line -... | Line 1241... | ||
- | 1241 | ||
- | 1242 | /* |
|
- | 1243 | * Single-threaded teardown context, so it's not required to grab the |
|
- | 1244 | * fb_lock to protect against concurrent fb_list access. Contrary, it |
|
- | 1245 | * would actually deadlock with the drm_framebuffer_cleanup function. |
|
- | 1246 | * |
|
- | 1247 | * Also, if there are any framebuffers left, that's a driver leak now, |
|
- | 1248 | * so politely WARN about this. |
|
- | 1249 | */ |
|
- | 1250 | WARN_ON(!list_empty(&dev->mode_config.fb_list)); |
|
- | 1251 | list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { |
|
- | 1252 | drm_framebuffer_remove(fb); |
|
- | 1253 | } |
|
1012 | 1254 | ||
1013 | list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list, |
1255 | list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list, |
1014 | head) { |
1256 | head) { |
1015 | plane->funcs->destroy(plane); |
1257 | plane->funcs->destroy(plane); |
Line 1016... | Line 1258... | ||
1016 | } |
1258 | } |
1017 | 1259 | ||
1018 | list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { |
1260 | list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { |
Line 1019... | Line -... | ||
1019 | crtc->funcs->destroy(crtc); |
- | |
1020 | } |
1261 | crtc->funcs->destroy(crtc); |
1021 | 1262 | } |
|
1022 | idr_remove_all(&dev->mode_config.crtc_idr); |
1263 | |
Line 1023... | Line 1264... | ||
1023 | idr_destroy(&dev->mode_config.crtc_idr); |
1264 | idr_destroy(&dev->mode_config.crtc_idr); |
1024 | } |
1265 | } |
1025 | EXPORT_SYMBOL(drm_mode_config_cleanup); |
1266 | EXPORT_SYMBOL(drm_mode_config_cleanup); |
1026 | 1267 | ||
1027 | /** |
1268 | /** |
1028 | * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo |
- | |
1029 | * @out: drm_mode_modeinfo struct to return to the user |
- | |
1030 | * @in: drm_display_mode to use |
- | |
1031 | * |
1269 | * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo |
1032 | * LOCKING: |
1270 | * @out: drm_mode_modeinfo struct to return to the user |
1033 | * None. |
1271 | * @in: drm_display_mode to use |
1034 | * |
1272 | * |
1035 | * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to |
1273 | * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to |
Line 1066... | Line 1304... | ||
1066 | /** |
1304 | /** |
1067 | * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode |
1305 | * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode |
1068 | * @out: drm_display_mode to return to the user |
1306 | * @out: drm_display_mode to return to the user |
1069 | * @in: drm_mode_modeinfo to use |
1307 | * @in: drm_mode_modeinfo to use |
1070 | * |
1308 | * |
1071 | * LOCKING: |
- | |
1072 | * None. |
- | |
1073 | * |
- | |
1074 | * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to |
1309 | * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to |
1075 | * the caller. |
1310 | * the caller. |
1076 | * |
1311 | * |
1077 | * RETURNS: |
1312 | * RETURNS: |
1078 | * Zero on success, errno on failure. |
1313 | * Zero on success, errno on failure. |
Line 1105... | Line 1340... | ||
1105 | 1340 | ||
1106 | 1341 | ||
1107 | #if 0 |
1342 | #if 0 |
1108 | /** |
1343 | /** |
1109 | * drm_mode_getresources - get graphics configuration |
1344 | * drm_mode_getresources - get graphics configuration |
1110 | * @inode: inode from the ioctl |
- | |
1111 | * @filp: file * from the ioctl |
1345 | * @dev: drm device for the ioctl |
1112 | * @cmd: cmd from ioctl |
- | |
1113 | * @arg: arg from ioctl |
- | |
1114 | * |
- | |
1115 | * LOCKING: |
1346 | * @data: data pointer for the ioctl |
1116 | * Takes mode config lock. |
1347 | * @file_priv: drm file for the ioctl call |
1117 | * |
1348 | * |
1118 | * Construct a set of configuration description structures and return |
1349 | * Construct a set of configuration description structures and return |
1119 | * them to the user, including CRTC, connector and framebuffer configuration. |
1350 | * them to the user, including CRTC, connector and framebuffer configuration. |
Line 1145... | Line 1376... | ||
1145 | struct drm_mode_group *mode_group; |
1376 | struct drm_mode_group *mode_group; |
Line 1146... | Line 1377... | ||
1146 | 1377 | ||
1147 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1378 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 1148... | Line -... | ||
1148 | return -EINVAL; |
- | |
Line -... | Line 1379... | ||
- | 1379 | return -EINVAL; |
|
1149 | 1380 | ||
1150 | mutex_lock(&dev->mode_config.mutex); |
1381 | |
1151 | 1382 | mutex_lock(&file_priv->fbs_lock); |
|
1152 | /* |
1383 | /* |
1153 | * For the non-control nodes we need to limit the list of resources |
1384 | * For the non-control nodes we need to limit the list of resources |
1154 | * by IDs in the group list for this node |
1385 | * by IDs in the group list for this node |
Line -... | Line 1386... | ||
- | 1386 | */ |
|
- | 1387 | list_for_each(lh, &file_priv->fbs) |
|
- | 1388 | fb_count++; |
|
- | 1389 | ||
- | 1390 | /* handle this in 4 parts */ |
|
- | 1391 | /* FBs */ |
|
- | 1392 | if (card_res->count_fbs >= fb_count) { |
|
- | 1393 | copied = 0; |
|
- | 1394 | fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; |
|
- | 1395 | list_for_each_entry(fb, &file_priv->fbs, filp_head) { |
|
- | 1396 | if (put_user(fb->base.id, fb_id + copied)) { |
|
- | 1397 | mutex_unlock(&file_priv->fbs_lock); |
|
- | 1398 | return -EFAULT; |
|
- | 1399 | } |
|
- | 1400 | copied++; |
|
- | 1401 | } |
|
- | 1402 | } |
|
1155 | */ |
1403 | card_res->count_fbs = fb_count; |
1156 | list_for_each(lh, &file_priv->fbs) |
1404 | mutex_unlock(&file_priv->fbs_lock); |
Line 1157... | Line 1405... | ||
1157 | fb_count++; |
1405 | |
1158 | 1406 | drm_modeset_lock_all(dev); |
|
Line 1177... | Line 1425... | ||
1177 | card_res->max_height = dev->mode_config.max_height; |
1425 | card_res->max_height = dev->mode_config.max_height; |
1178 | card_res->min_height = dev->mode_config.min_height; |
1426 | card_res->min_height = dev->mode_config.min_height; |
1179 | card_res->max_width = dev->mode_config.max_width; |
1427 | card_res->max_width = dev->mode_config.max_width; |
1180 | card_res->min_width = dev->mode_config.min_width; |
1428 | card_res->min_width = dev->mode_config.min_width; |
Line 1181... | Line -... | ||
1181 | - | ||
1182 | /* handle this in 4 parts */ |
- | |
1183 | /* FBs */ |
- | |
1184 | if (card_res->count_fbs >= fb_count) { |
- | |
1185 | copied = 0; |
- | |
1186 | fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; |
- | |
1187 | list_for_each_entry(fb, &file_priv->fbs, filp_head) { |
- | |
1188 | if (put_user(fb->base.id, fb_id + copied)) { |
- | |
1189 | ret = -EFAULT; |
- | |
1190 | goto out; |
- | |
1191 | } |
- | |
1192 | copied++; |
- | |
1193 | } |
- | |
1194 | } |
- | |
1195 | card_res->count_fbs = fb_count; |
- | |
1196 | 1429 | ||
1197 | /* CRTCs */ |
1430 | /* CRTCs */ |
1198 | if (card_res->count_crtcs >= crtc_count) { |
1431 | if (card_res->count_crtcs >= crtc_count) { |
1199 | copied = 0; |
1432 | copied = 0; |
1200 | crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; |
1433 | crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; |
Line 1287... | Line 1520... | ||
1287 | 1520 | ||
1288 | DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs, |
1521 | DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs, |
Line 1289... | Line 1522... | ||
1289 | card_res->count_connectors, card_res->count_encoders); |
1522 | card_res->count_connectors, card_res->count_encoders); |
1290 | 1523 | ||
1291 | out: |
1524 | out: |
1292 | mutex_unlock(&dev->mode_config.mutex); |
1525 | drm_modeset_unlock_all(dev); |
Line 1293... | Line 1526... | ||
1293 | return ret; |
1526 | return ret; |
1294 | } |
1527 | } |
1295 | 1528 | ||
1296 | /** |
1529 | /** |
1297 | * drm_mode_getcrtc - get CRTC configuration |
- | |
1298 | * @inode: inode from the ioctl |
1530 | * drm_mode_getcrtc - get CRTC configuration |
1299 | * @filp: file * from the ioctl |
- | |
1300 | * @cmd: cmd from ioctl |
- | |
1301 | * @arg: arg from ioctl |
- | |
1302 | * |
1531 | * @dev: drm device for the ioctl |
1303 | * LOCKING: |
1532 | * @data: data pointer for the ioctl |
1304 | * Takes mode config lock. |
1533 | * @file_priv: drm file for the ioctl call |
1305 | * |
1534 | * |
1306 | * Construct a CRTC configuration structure to return to the user. |
1535 | * Construct a CRTC configuration structure to return to the user. |
Line 1319... | Line 1548... | ||
1319 | int ret = 0; |
1548 | int ret = 0; |
Line 1320... | Line 1549... | ||
1320 | 1549 | ||
1321 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1550 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 1322... | Line 1551... | ||
1322 | return -EINVAL; |
1551 | return -EINVAL; |
Line 1323... | Line 1552... | ||
1323 | 1552 | ||
1324 | mutex_lock(&dev->mode_config.mutex); |
1553 | drm_modeset_lock_all(dev); |
1325 | 1554 | ||
1326 | obj = drm_mode_object_find(dev, crtc_resp->crtc_id, |
1555 | obj = drm_mode_object_find(dev, crtc_resp->crtc_id, |
Line 1347... | Line 1576... | ||
1347 | } else { |
1576 | } else { |
1348 | crtc_resp->mode_valid = 0; |
1577 | crtc_resp->mode_valid = 0; |
1349 | } |
1578 | } |
Line 1350... | Line 1579... | ||
1350 | 1579 | ||
1351 | out: |
1580 | out: |
1352 | mutex_unlock(&dev->mode_config.mutex); |
1581 | drm_modeset_unlock_all(dev); |
1353 | return ret; |
1582 | return ret; |
Line 1354... | Line 1583... | ||
1354 | } |
1583 | } |
1355 | 1584 | ||
1356 | /** |
1585 | /** |
1357 | * drm_mode_getconnector - get connector configuration |
1586 | * drm_mode_getconnector - get connector configuration |
1358 | * @inode: inode from the ioctl |
- | |
1359 | * @filp: file * from the ioctl |
1587 | * @dev: drm device for the ioctl |
1360 | * @cmd: cmd from ioctl |
- | |
1361 | * @arg: arg from ioctl |
- | |
1362 | * |
- | |
1363 | * LOCKING: |
1588 | * @data: data pointer for the ioctl |
1364 | * Takes mode config lock. |
1589 | * @file_priv: drm file for the ioctl call |
1365 | * |
1590 | * |
1366 | * Construct a connector configuration structure to return to the user. |
1591 | * Construct a connector configuration structure to return to the user. |
1367 | * |
1592 | * |
Line 1492... | Line 1717... | ||
1492 | } |
1717 | } |
1493 | out_resp->count_encoders = encoders_count; |
1718 | out_resp->count_encoders = encoders_count; |
Line 1494... | Line 1719... | ||
1494 | 1719 | ||
1495 | out: |
1720 | out: |
- | 1721 | mutex_unlock(&dev->mode_config.mutex); |
|
1496 | mutex_unlock(&dev->mode_config.mutex); |
1722 | |
1497 | return ret; |
1723 | return ret; |
Line 1498... | Line 1724... | ||
1498 | } |
1724 | } |
1499 | 1725 | ||
Line 1506... | Line 1732... | ||
1506 | int ret = 0; |
1732 | int ret = 0; |
Line 1507... | Line 1733... | ||
1507 | 1733 | ||
1508 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1734 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 1509... | Line 1735... | ||
1509 | return -EINVAL; |
1735 | return -EINVAL; |
1510 | 1736 | ||
1511 | mutex_lock(&dev->mode_config.mutex); |
1737 | drm_modeset_lock_all(dev); |
1512 | obj = drm_mode_object_find(dev, enc_resp->encoder_id, |
1738 | obj = drm_mode_object_find(dev, enc_resp->encoder_id, |
1513 | DRM_MODE_OBJECT_ENCODER); |
1739 | DRM_MODE_OBJECT_ENCODER); |
1514 | if (!obj) { |
1740 | if (!obj) { |
Line 1525... | Line 1751... | ||
1525 | enc_resp->encoder_id = encoder->base.id; |
1751 | enc_resp->encoder_id = encoder->base.id; |
1526 | enc_resp->possible_crtcs = encoder->possible_crtcs; |
1752 | enc_resp->possible_crtcs = encoder->possible_crtcs; |
1527 | enc_resp->possible_clones = encoder->possible_clones; |
1753 | enc_resp->possible_clones = encoder->possible_clones; |
Line 1528... | Line 1754... | ||
1528 | 1754 | ||
1529 | out: |
1755 | out: |
1530 | mutex_unlock(&dev->mode_config.mutex); |
1756 | drm_modeset_unlock_all(dev); |
1531 | return ret; |
1757 | return ret; |
Line 1532... | Line 1758... | ||
1532 | } |
1758 | } |
1533 | 1759 | ||
1534 | /** |
1760 | /** |
1535 | * drm_mode_getplane_res - get plane info |
1761 | * drm_mode_getplane_res - get plane info |
1536 | * @dev: DRM device |
1762 | * @dev: DRM device |
1537 | * @data: ioctl data |
1763 | * @data: ioctl data |
1538 | * @file_priv: DRM file info |
- | |
1539 | * |
- | |
1540 | * LOCKING: |
- | |
1541 | * Takes mode config lock. |
1764 | * @file_priv: DRM file info |
1542 | * |
1765 | * |
1543 | * Return an plane count and set of IDs. |
1766 | * Return an plane count and set of IDs. |
1544 | */ |
1767 | */ |
1545 | int drm_mode_getplane_res(struct drm_device *dev, void *data, |
1768 | int drm_mode_getplane_res(struct drm_device *dev, void *data, |
Line 1552... | Line 1775... | ||
1552 | int copied = 0, ret = 0; |
1775 | int copied = 0, ret = 0; |
Line 1553... | Line 1776... | ||
1553 | 1776 | ||
1554 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1777 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 1555... | Line 1778... | ||
1555 | return -EINVAL; |
1778 | return -EINVAL; |
1556 | 1779 | ||
Line 1557... | Line 1780... | ||
1557 | mutex_lock(&dev->mode_config.mutex); |
1780 | drm_modeset_lock_all(dev); |
1558 | config = &dev->mode_config; |
1781 | config = &dev->mode_config; |
1559 | 1782 | ||
Line 1574... | Line 1797... | ||
1574 | } |
1797 | } |
1575 | } |
1798 | } |
1576 | plane_resp->count_planes = config->num_plane; |
1799 | plane_resp->count_planes = config->num_plane; |
Line 1577... | Line 1800... | ||
1577 | 1800 | ||
1578 | out: |
1801 | out: |
1579 | mutex_unlock(&dev->mode_config.mutex); |
1802 | drm_modeset_unlock_all(dev); |
1580 | return ret; |
1803 | return ret; |
Line 1581... | Line 1804... | ||
1581 | } |
1804 | } |
1582 | 1805 | ||
1583 | /** |
1806 | /** |
1584 | * drm_mode_getplane - get plane info |
1807 | * drm_mode_getplane - get plane info |
1585 | * @dev: DRM device |
1808 | * @dev: DRM device |
1586 | * @data: ioctl data |
1809 | * @data: ioctl data |
1587 | * @file_priv: DRM file info |
- | |
1588 | * |
- | |
1589 | * LOCKING: |
- | |
1590 | * Takes mode config lock. |
1810 | * @file_priv: DRM file info |
1591 | * |
1811 | * |
1592 | * Return plane info, including formats supported, gamma size, any |
1812 | * Return plane info, including formats supported, gamma size, any |
1593 | * current fb, etc. |
1813 | * current fb, etc. |
1594 | */ |
1814 | */ |
Line 1602... | Line 1822... | ||
1602 | int ret = 0; |
1822 | int ret = 0; |
Line 1603... | Line 1823... | ||
1603 | 1823 | ||
1604 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1824 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 1605... | Line 1825... | ||
1605 | return -EINVAL; |
1825 | return -EINVAL; |
1606 | 1826 | ||
1607 | mutex_lock(&dev->mode_config.mutex); |
1827 | drm_modeset_lock_all(dev); |
1608 | obj = drm_mode_object_find(dev, plane_resp->plane_id, |
1828 | obj = drm_mode_object_find(dev, plane_resp->plane_id, |
1609 | DRM_MODE_OBJECT_PLANE); |
1829 | DRM_MODE_OBJECT_PLANE); |
1610 | if (!obj) { |
1830 | if (!obj) { |
Line 1642... | Line 1862... | ||
1642 | } |
1862 | } |
1643 | } |
1863 | } |
1644 | plane_resp->count_format_types = plane->format_count; |
1864 | plane_resp->count_format_types = plane->format_count; |
Line 1645... | Line 1865... | ||
1645 | 1865 | ||
1646 | out: |
1866 | out: |
1647 | mutex_unlock(&dev->mode_config.mutex); |
1867 | drm_modeset_unlock_all(dev); |
1648 | return ret; |
1868 | return ret; |
Line 1649... | Line 1869... | ||
1649 | } |
1869 | } |
1650 | 1870 | ||
1651 | /** |
1871 | /** |
1652 | * drm_mode_setplane - set up or tear down an plane |
1872 | * drm_mode_setplane - set up or tear down an plane |
1653 | * @dev: DRM device |
1873 | * @dev: DRM device |
1654 | * @data: ioctl data* |
- | |
1655 | * @file_prive: DRM file info |
- | |
1656 | * |
- | |
1657 | * LOCKING: |
1874 | * @data: ioctl data* |
1658 | * Takes mode config lock. |
1875 | * @file_priv: DRM file info |
1659 | * |
1876 | * |
1660 | * Set plane info, including placement, fb, scaling, and other factors. |
1877 | * Set plane info, including placement, fb, scaling, and other factors. |
1661 | * Or pass a NULL fb to disable. |
1878 | * Or pass a NULL fb to disable. |
Line 1665... | Line 1882... | ||
1665 | { |
1882 | { |
1666 | struct drm_mode_set_plane *plane_req = data; |
1883 | struct drm_mode_set_plane *plane_req = data; |
1667 | struct drm_mode_object *obj; |
1884 | struct drm_mode_object *obj; |
1668 | struct drm_plane *plane; |
1885 | struct drm_plane *plane; |
1669 | struct drm_crtc *crtc; |
1886 | struct drm_crtc *crtc; |
1670 | struct drm_framebuffer *fb; |
1887 | struct drm_framebuffer *fb = NULL, *old_fb = NULL; |
1671 | int ret = 0; |
1888 | int ret = 0; |
1672 | unsigned int fb_width, fb_height; |
1889 | unsigned int fb_width, fb_height; |
1673 | int i; |
1890 | int i; |
Line 1674... | Line 1891... | ||
1674 | 1891 | ||
1675 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1892 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 1676... | Line -... | ||
1676 | return -EINVAL; |
- | |
1677 | - | ||
1678 | mutex_lock(&dev->mode_config.mutex); |
1893 | return -EINVAL; |
1679 | 1894 | ||
1680 | /* |
1895 | /* |
1681 | * First, find the plane, crtc, and fb objects. If not available, |
1896 | * First, find the plane, crtc, and fb objects. If not available, |
1682 | * we don't bother to call the driver. |
1897 | * we don't bother to call the driver. |
1683 | */ |
1898 | */ |
1684 | obj = drm_mode_object_find(dev, plane_req->plane_id, |
1899 | obj = drm_mode_object_find(dev, plane_req->plane_id, |
1685 | DRM_MODE_OBJECT_PLANE); |
1900 | DRM_MODE_OBJECT_PLANE); |
1686 | if (!obj) { |
1901 | if (!obj) { |
1687 | DRM_DEBUG_KMS("Unknown plane ID %d\n", |
1902 | DRM_DEBUG_KMS("Unknown plane ID %d\n", |
1688 | plane_req->plane_id); |
- | |
1689 | ret = -ENOENT; |
1903 | plane_req->plane_id); |
1690 | goto out; |
1904 | return -ENOENT; |
Line 1691... | Line 1905... | ||
1691 | } |
1905 | } |
1692 | plane = obj_to_plane(obj); |
1906 | plane = obj_to_plane(obj); |
- | 1907 | ||
- | 1908 | /* No fb means shut it down */ |
|
1693 | 1909 | if (!plane_req->fb_id) { |
|
1694 | /* No fb means shut it down */ |
1910 | drm_modeset_lock_all(dev); |
1695 | if (!plane_req->fb_id) { |
1911 | old_fb = plane->fb; |
- | 1912 | plane->funcs->disable_plane(plane); |
|
1696 | plane->funcs->disable_plane(plane); |
1913 | plane->crtc = NULL; |
1697 | plane->crtc = NULL; |
1914 | plane->fb = NULL; |
Line 1698... | Line 1915... | ||
1698 | plane->fb = NULL; |
1915 | drm_modeset_unlock_all(dev); |
1699 | goto out; |
1916 | goto out; |
Line 1707... | Line 1924... | ||
1707 | ret = -ENOENT; |
1924 | ret = -ENOENT; |
1708 | goto out; |
1925 | goto out; |
1709 | } |
1926 | } |
1710 | crtc = obj_to_crtc(obj); |
1927 | crtc = obj_to_crtc(obj); |
Line 1711... | Line 1928... | ||
1711 | 1928 | ||
1712 | obj = drm_mode_object_find(dev, plane_req->fb_id, |
- | |
1713 | DRM_MODE_OBJECT_FB); |
1929 | fb = drm_framebuffer_lookup(dev, plane_req->fb_id); |
1714 | if (!obj) { |
1930 | if (!fb) { |
1715 | DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", |
1931 | DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", |
1716 | plane_req->fb_id); |
1932 | plane_req->fb_id); |
1717 | ret = -ENOENT; |
1933 | ret = -ENOENT; |
1718 | goto out; |
1934 | goto out; |
1719 | } |
- | |
Line 1720... | Line 1935... | ||
1720 | fb = obj_to_fb(obj); |
1935 | } |
1721 | 1936 | ||
1722 | /* Check whether this plane supports the fb pixel format. */ |
1937 | /* Check whether this plane supports the fb pixel format. */ |
1723 | for (i = 0; i < plane->format_count; i++) |
1938 | for (i = 0; i < plane->format_count; i++) |
Line 1761... | Line 1976... | ||
1761 | plane_req->crtc_x, plane_req->crtc_y); |
1976 | plane_req->crtc_x, plane_req->crtc_y); |
1762 | ret = -ERANGE; |
1977 | ret = -ERANGE; |
1763 | goto out; |
1978 | goto out; |
1764 | } |
1979 | } |
Line -... | Line 1980... | ||
- | 1980 | ||
1765 | 1981 | drm_modeset_lock_all(dev); |
|
1766 | ret = plane->funcs->update_plane(plane, crtc, fb, |
1982 | ret = plane->funcs->update_plane(plane, crtc, fb, |
1767 | plane_req->crtc_x, plane_req->crtc_y, |
1983 | plane_req->crtc_x, plane_req->crtc_y, |
1768 | plane_req->crtc_w, plane_req->crtc_h, |
1984 | plane_req->crtc_w, plane_req->crtc_h, |
1769 | plane_req->src_x, plane_req->src_y, |
1985 | plane_req->src_x, plane_req->src_y, |
1770 | plane_req->src_w, plane_req->src_h); |
1986 | plane_req->src_w, plane_req->src_h); |
- | 1987 | if (!ret) { |
|
1771 | if (!ret) { |
1988 | old_fb = plane->fb; |
1772 | plane->crtc = crtc; |
1989 | plane->crtc = crtc; |
- | 1990 | plane->fb = fb; |
|
1773 | plane->fb = fb; |
1991 | fb = NULL; |
- | 1992 | } |
|
Line 1774... | Line 1993... | ||
1774 | } |
1993 | drm_modeset_unlock_all(dev); |
- | 1994 | ||
- | 1995 | out: |
|
- | 1996 | if (fb) |
|
1775 | 1997 | drm_framebuffer_unreference(fb); |
|
Line 1776... | Line 1998... | ||
1776 | out: |
1998 | if (old_fb) |
1777 | mutex_unlock(&dev->mode_config.mutex); |
1999 | drm_framebuffer_unreference(old_fb); |
- | 2000 | ||
Line 1778... | Line 2001... | ||
1778 | 2001 | return ret; |
|
1779 | return ret; |
2002 | } |
1780 | } |
- | |
1781 | 2003 | #endif |
|
1782 | /** |
- | |
1783 | * drm_mode_setcrtc - set CRTC configuration |
- | |
1784 | * @inode: inode from the ioctl |
2004 | |
- | 2005 | /** |
|
- | 2006 | * drm_mode_set_config_internal - helper to call ->set_config |
|
- | 2007 | * @set: modeset config to set |
|
- | 2008 | * |
|
- | 2009 | * This is a little helper to wrap internal calls to the ->set_config driver |
|
- | 2010 | * interface. The only thing it adds is correct refcounting dance. |
|
- | 2011 | */ |
|
- | 2012 | int drm_mode_set_config_internal(struct drm_mode_set *set) |
|
- | 2013 | { |
|
- | 2014 | struct drm_crtc *crtc = set->crtc; |
|
1785 | * @filp: file * from the ioctl |
2015 | struct drm_framebuffer *fb, *old_fb; |
- | 2016 | int ret; |
|
- | 2017 | ||
- | 2018 | old_fb = crtc->fb; |
|
- | 2019 | fb = set->fb; |
|
- | 2020 | ||
- | 2021 | ret = crtc->funcs->set_config(set); |
|
- | 2022 | if (ret == 0) { |
|
- | 2023 | if (old_fb) |
|
- | 2024 | drm_framebuffer_unreference(old_fb); |
|
- | 2025 | if (fb) |
|
- | 2026 | drm_framebuffer_reference(fb); |
|
- | 2027 | } |
|
- | 2028 | ||
- | 2029 | return ret; |
|
- | 2030 | } |
|
- | 2031 | EXPORT_SYMBOL(drm_mode_set_config_internal); |
|
1786 | * @cmd: cmd from ioctl |
2032 | |
- | 2033 | #if 0 |
|
- | 2034 | /** |
|
1787 | * @arg: arg from ioctl |
2035 | * drm_mode_setcrtc - set CRTC configuration |
1788 | * |
2036 | * @dev: drm device for the ioctl |
1789 | * LOCKING: |
2037 | * @data: data pointer for the ioctl |
1790 | * Takes mode config lock. |
2038 | * @file_priv: drm file for the ioctl call |
1791 | * |
2039 | * |
Line 1816... | Line 2064... | ||
1816 | 2064 | ||
1817 | /* For some reason crtc x/y offsets are signed internally. */ |
2065 | /* For some reason crtc x/y offsets are signed internally. */ |
1818 | if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX) |
2066 | if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX) |
Line 1819... | Line 2067... | ||
1819 | return -ERANGE; |
2067 | return -ERANGE; |
1820 | 2068 | ||
1821 | mutex_lock(&dev->mode_config.mutex); |
2069 | drm_modeset_lock_all(dev); |
1822 | obj = drm_mode_object_find(dev, crtc_req->crtc_id, |
2070 | obj = drm_mode_object_find(dev, crtc_req->crtc_id, |
1823 | DRM_MODE_OBJECT_CRTC); |
2071 | DRM_MODE_OBJECT_CRTC); |
1824 | if (!obj) { |
2072 | if (!obj) { |
Line 1838... | Line 2086... | ||
1838 | DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); |
2086 | DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); |
1839 | ret = -EINVAL; |
2087 | ret = -EINVAL; |
1840 | goto out; |
2088 | goto out; |
1841 | } |
2089 | } |
1842 | fb = crtc->fb; |
2090 | fb = crtc->fb; |
- | 2091 | /* Make refcounting symmetric with the lookup path. */ |
|
- | 2092 | drm_framebuffer_reference(fb); |
|
1843 | } else { |
2093 | } else { |
1844 | obj = drm_mode_object_find(dev, crtc_req->fb_id, |
2094 | fb = drm_framebuffer_lookup(dev, crtc_req->fb_id); |
1845 | DRM_MODE_OBJECT_FB); |
- | |
1846 | if (!obj) { |
2095 | if (!fb) { |
1847 | DRM_DEBUG_KMS("Unknown FB ID%d\n", |
2096 | DRM_DEBUG_KMS("Unknown FB ID%d\n", |
1848 | crtc_req->fb_id); |
2097 | crtc_req->fb_id); |
1849 | ret = -EINVAL; |
2098 | ret = -EINVAL; |
1850 | goto out; |
2099 | goto out; |
1851 | } |
2100 | } |
1852 | fb = obj_to_fb(obj); |
- | |
1853 | } |
2101 | } |
Line 1854... | Line 2102... | ||
1854 | 2102 | ||
1855 | mode = drm_mode_create(dev); |
2103 | mode = drm_mode_create(dev); |
1856 | if (!mode) { |
2104 | if (!mode) { |
Line 1944... | Line 2192... | ||
1944 | set.y = crtc_req->y; |
2192 | set.y = crtc_req->y; |
1945 | set.mode = mode; |
2193 | set.mode = mode; |
1946 | set.connectors = connector_set; |
2194 | set.connectors = connector_set; |
1947 | set.num_connectors = crtc_req->count_connectors; |
2195 | set.num_connectors = crtc_req->count_connectors; |
1948 | set.fb = fb; |
2196 | set.fb = fb; |
1949 | ret = crtc->funcs->set_config(&set); |
2197 | ret = drm_mode_set_config_internal(&set); |
Line 1950... | Line 2198... | ||
1950 | 2198 | ||
- | 2199 | out: |
|
- | 2200 | if (fb) |
|
- | 2201 | drm_framebuffer_unreference(fb); |
|
1951 | out: |
2202 | |
1952 | kfree(connector_set); |
2203 | kfree(connector_set); |
1953 | drm_mode_destroy(dev, mode); |
2204 | drm_mode_destroy(dev, mode); |
1954 | mutex_unlock(&dev->mode_config.mutex); |
2205 | drm_modeset_unlock_all(dev); |
1955 | return ret; |
2206 | return ret; |
Line 1956... | Line 2207... | ||
1956 | } |
2207 | } |
1957 | 2208 | ||
Line 1967... | Line 2218... | ||
1967 | return -EINVAL; |
2218 | return -EINVAL; |
Line 1968... | Line 2219... | ||
1968 | 2219 | ||
1969 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
2220 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
Line 1970... | Line -... | ||
1970 | return -EINVAL; |
- | |
1971 | 2221 | return -EINVAL; |
|
1972 | mutex_lock(&dev->mode_config.mutex); |
2222 | |
1973 | obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); |
2223 | obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); |
1974 | if (!obj) { |
2224 | if (!obj) { |
1975 | DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); |
- | |
1976 | ret = -EINVAL; |
2225 | DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); |
1977 | goto out; |
2226 | return -EINVAL; |
Line -... | Line 2227... | ||
- | 2227 | } |
|
1978 | } |
2228 | crtc = obj_to_crtc(obj); |
1979 | crtc = obj_to_crtc(obj); |
2229 | |
1980 | 2230 | mutex_lock(&crtc->mutex); |
|
1981 | if (req->flags & DRM_MODE_CURSOR_BO) { |
2231 | if (req->flags & DRM_MODE_CURSOR_BO) { |
1982 | if (!crtc->funcs->cursor_set) { |
2232 | if (!crtc->funcs->cursor_set) { |
Line 1995... | Line 2245... | ||
1995 | ret = -EFAULT; |
2245 | ret = -EFAULT; |
1996 | goto out; |
2246 | goto out; |
1997 | } |
2247 | } |
1998 | } |
2248 | } |
1999 | out: |
2249 | out: |
2000 | mutex_unlock(&dev->mode_config.mutex); |
2250 | mutex_unlock(&crtc->mutex); |
- | 2251 | ||
2001 | return ret; |
2252 | return ret; |
2002 | } |
2253 | } |
2003 | #endif |
2254 | #endif |
2004 | /* Original addfb only supported RGB formats, so figure out which one */ |
2255 | /* Original addfb only supported RGB formats, so figure out which one */ |
2005 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) |
2256 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) |
2006 | { |
2257 | { |
2007 | uint32_t fmt; |
2258 | uint32_t fmt; |
Line 2008... | Line 2259... | ||
2008 | 2259 | ||
2009 | switch (bpp) { |
2260 | switch (bpp) { |
2010 | case 8: |
2261 | case 8: |
2011 | fmt = DRM_FORMAT_RGB332; |
2262 | fmt = DRM_FORMAT_C8; |
2012 | break; |
2263 | break; |
2013 | case 16: |
2264 | case 16: |
2014 | if (depth == 15) |
2265 | if (depth == 15) |
2015 | fmt = DRM_FORMAT_XRGB1555; |
2266 | fmt = DRM_FORMAT_XRGB1555; |
Line 2037... | Line 2288... | ||
2037 | } |
2288 | } |
2038 | EXPORT_SYMBOL(drm_mode_legacy_fb_format); |
2289 | EXPORT_SYMBOL(drm_mode_legacy_fb_format); |
2039 | #if 0 |
2290 | #if 0 |
2040 | /** |
2291 | /** |
2041 | * drm_mode_addfb - add an FB to the graphics configuration |
2292 | * drm_mode_addfb - add an FB to the graphics configuration |
2042 | * @inode: inode from the ioctl |
2293 | * @dev: drm device for the ioctl |
2043 | * @filp: file * from the ioctl |
2294 | * @data: data pointer for the ioctl |
2044 | * @cmd: cmd from ioctl |
- | |
2045 | * @arg: arg from ioctl |
2295 | * @file_priv: drm file for the ioctl call |
2046 | * |
- | |
2047 | * LOCKING: |
- | |
2048 | * Takes mode config lock. |
- | |
2049 | * |
2296 | * |
2050 | * Add a new FB to the specified CRTC, given a user request. |
2297 | * Add a new FB to the specified CRTC, given a user request. |
2051 | * |
2298 | * |
2052 | * Called by the user via ioctl. |
2299 | * Called by the user via ioctl. |
2053 | * |
2300 | * |
Line 2078... | Line 2325... | ||
2078 | return -EINVAL; |
2325 | return -EINVAL; |
Line 2079... | Line 2326... | ||
2079 | 2326 | ||
2080 | if ((config->min_height > r.height) || (r.height > config->max_height)) |
2327 | if ((config->min_height > r.height) || (r.height > config->max_height)) |
Line 2081... | Line -... | ||
2081 | return -EINVAL; |
- | |
2082 | - | ||
2083 | mutex_lock(&dev->mode_config.mutex); |
- | |
2084 | - | ||
2085 | /* TODO check buffer is sufficiently large */ |
- | |
2086 | /* TODO setup destructor callback */ |
2328 | return -EINVAL; |
2087 | 2329 | ||
2088 | fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); |
2330 | fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); |
2089 | if (IS_ERR(fb)) { |
2331 | if (IS_ERR(fb)) { |
2090 | DRM_DEBUG_KMS("could not create framebuffer\n"); |
- | |
2091 | ret = PTR_ERR(fb); |
2332 | DRM_DEBUG_KMS("could not create framebuffer\n"); |
Line -... | Line 2333... | ||
- | 2333 | return PTR_ERR(fb); |
|
2092 | goto out; |
2334 | } |
2093 | } |
2335 | |
2094 | 2336 | mutex_lock(&file_priv->fbs_lock); |
|
- | 2337 | or->fb_id = fb->base.id; |
|
Line 2095... | Line -... | ||
2095 | or->fb_id = fb->base.id; |
- | |
2096 | list_add(&fb->filp_head, &file_priv->fbs); |
- | |
2097 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); |
2338 | list_add(&fb->filp_head, &file_priv->fbs); |
2098 | 2339 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); |
|
Line 2099... | Line 2340... | ||
2099 | out: |
2340 | mutex_unlock(&file_priv->fbs_lock); |
2100 | mutex_unlock(&dev->mode_config.mutex); |
2341 | |
Line 2221... | Line 2462... | ||
2221 | return 0; |
2462 | return 0; |
2222 | } |
2463 | } |
Line 2223... | Line 2464... | ||
2223 | 2464 | ||
2224 | /** |
2465 | /** |
2225 | * drm_mode_addfb2 - add an FB to the graphics configuration |
2466 | * drm_mode_addfb2 - add an FB to the graphics configuration |
2226 | * @inode: inode from the ioctl |
2467 | * @dev: drm device for the ioctl |
2227 | * @filp: file * from the ioctl |
- | |
2228 | * @cmd: cmd from ioctl |
2468 | * @data: data pointer for the ioctl |
2229 | * @arg: arg from ioctl |
- | |
2230 | * |
- | |
2231 | * LOCKING: |
- | |
2232 | * Takes mode config lock. |
2469 | * @file_priv: drm file for the ioctl call |
2233 | * |
2470 | * |
2234 | * Add a new FB to the specified CRTC, given a user request with format. |
2471 | * Add a new FB to the specified CRTC, given a user request with format. |
2235 | * |
2472 | * |
2236 | * Called by the user via ioctl. |
2473 | * Called by the user via ioctl. |
Line 2267... | Line 2504... | ||
2267 | 2504 | ||
2268 | ret = framebuffer_check(r); |
2505 | ret = framebuffer_check(r); |
2269 | if (ret) |
2506 | if (ret) |
Line 2270... | Line -... | ||
2270 | return ret; |
- | |
2271 | - | ||
2272 | mutex_lock(&dev->mode_config.mutex); |
2507 | return ret; |
2273 | 2508 | ||
2274 | fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); |
2509 | fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); |
2275 | if (IS_ERR(fb)) { |
2510 | if (IS_ERR(fb)) { |
2276 | DRM_DEBUG_KMS("could not create framebuffer\n"); |
- | |
2277 | ret = PTR_ERR(fb); |
2511 | DRM_DEBUG_KMS("could not create framebuffer\n"); |
Line -... | Line 2512... | ||
- | 2512 | return PTR_ERR(fb); |
|
2278 | goto out; |
2513 | } |
2279 | } |
2514 | |
2280 | 2515 | mutex_lock(&file_priv->fbs_lock); |
|
- | 2516 | r->fb_id = fb->base.id; |
|
- | 2517 | list_add(&fb->filp_head, &file_priv->fbs); |
|
Line 2281... | Line -... | ||
2281 | r->fb_id = fb->base.id; |
- | |
2282 | list_add(&fb->filp_head, &file_priv->fbs); |
- | |
2283 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); |
2518 | DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); |
2284 | 2519 | mutex_unlock(&file_priv->fbs_lock); |
|
Line 2285... | Line 2520... | ||
2285 | out: |
2520 | |
2286 | mutex_unlock(&dev->mode_config.mutex); |
2521 | |
2287 | return ret; |
2522 | return ret; |
2288 | } |
2523 | } |
2289 | - | ||
2290 | /** |
2524 | |
2291 | * drm_mode_rmfb - remove an FB from the configuration |
- | |
2292 | * @inode: inode from the ioctl |
- | |
2293 | * @filp: file * from the ioctl |
- | |
2294 | * @cmd: cmd from ioctl |
2525 | /** |
2295 | * @arg: arg from ioctl |
2526 | * drm_mode_rmfb - remove an FB from the configuration |
2296 | * |
2527 | * @dev: drm device for the ioctl |
2297 | * LOCKING: |
2528 | * @data: data pointer for the ioctl |
2298 | * Takes mode config lock. |
2529 | * @file_priv: drm file for the ioctl call |
Line 2305... | Line 2536... | ||
2305 | * Zero on success, errno on failure. |
2536 | * Zero on success, errno on failure. |
2306 | */ |
2537 | */ |
2307 | int drm_mode_rmfb(struct drm_device *dev, |
2538 | int drm_mode_rmfb(struct drm_device *dev, |
2308 | void *data, struct drm_file *file_priv) |
2539 | void *data, struct drm_file *file_priv) |
2309 | { |
2540 | { |
2310 | struct drm_mode_object *obj; |
- | |
2311 | struct drm_framebuffer *fb = NULL; |
2541 | struct drm_framebuffer *fb = NULL; |
2312 | struct drm_framebuffer *fbl = NULL; |
2542 | struct drm_framebuffer *fbl = NULL; |
2313 | uint32_t *id = data; |
2543 | uint32_t *id = data; |
2314 | int ret = 0; |
- | |
2315 | int found = 0; |
2544 | int found = 0; |
Line 2316... | Line 2545... | ||
2316 | 2545 | ||
2317 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
2546 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 2318... | Line 2547... | ||
2318 | return -EINVAL; |
2547 | return -EINVAL; |
2319 | 2548 | ||
2320 | mutex_lock(&dev->mode_config.mutex); |
2549 | mutex_lock(&file_priv->fbs_lock); |
2321 | obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); |
2550 | mutex_lock(&dev->mode_config.fb_lock); |
2322 | /* TODO check that we really get a framebuffer back. */ |
- | |
2323 | if (!obj) { |
2551 | fb = __drm_framebuffer_lookup(dev, *id); |
2324 | ret = -EINVAL; |
- | |
2325 | goto out; |
- | |
Line 2326... | Line 2552... | ||
2326 | } |
2552 | if (!fb) |
2327 | fb = obj_to_fb(obj); |
2553 | goto fail_lookup; |
2328 | 2554 | ||
- | 2555 | list_for_each_entry(fbl, &file_priv->fbs, filp_head) |
|
- | 2556 | if (fb == fbl) |
|
Line 2329... | Line 2557... | ||
2329 | list_for_each_entry(fbl, &file_priv->fbs, filp_head) |
2557 | found = 1; |
2330 | if (fb == fbl) |
2558 | if (!found) |
2331 | found = 1; |
- | |
2332 | 2559 | goto fail_lookup; |
|
- | 2560 | ||
- | 2561 | /* Mark fb as reaped, we still have a ref from fpriv->fbs. */ |
|
- | 2562 | __drm_framebuffer_unregister(dev, fb); |
|
Line 2333... | Line 2563... | ||
2333 | if (!found) { |
2563 | |
Line -... | Line 2564... | ||
- | 2564 | list_del_init(&fb->filp_head); |
|
- | 2565 | mutex_unlock(&dev->mode_config.fb_lock); |
|
2334 | ret = -EINVAL; |
2566 | mutex_unlock(&file_priv->fbs_lock); |
2335 | goto out; |
2567 | |
- | 2568 | drm_framebuffer_remove(fb); |
|
- | 2569 | ||
2336 | } |
2570 | return 0; |
2337 | 2571 | ||
Line 2338... | Line 2572... | ||
2338 | drm_framebuffer_remove(fb); |
2572 | fail_lookup: |
2339 | 2573 | mutex_unlock(&dev->mode_config.fb_lock); |
|
2340 | out: |
2574 | mutex_unlock(&file_priv->fbs_lock); |
2341 | mutex_unlock(&dev->mode_config.mutex); |
2575 | |
2342 | return ret; |
- | |
2343 | } |
2576 | return -EINVAL; |
2344 | - | ||
2345 | /** |
- | |
2346 | * drm_mode_getfb - get FB info |
- | |
2347 | * @inode: inode from the ioctl |
2577 | } |
2348 | * @filp: file * from the ioctl |
2578 | |
2349 | * @cmd: cmd from ioctl |
2579 | /** |
2350 | * @arg: arg from ioctl |
2580 | * drm_mode_getfb - get FB info |
2351 | * |
2581 | * @dev: drm device for the ioctl |
Line 2361... | Line 2591... | ||
2361 | */ |
2591 | */ |
2362 | int drm_mode_getfb(struct drm_device *dev, |
2592 | int drm_mode_getfb(struct drm_device *dev, |
2363 | void *data, struct drm_file *file_priv) |
2593 | void *data, struct drm_file *file_priv) |
2364 | { |
2594 | { |
2365 | struct drm_mode_fb_cmd *r = data; |
2595 | struct drm_mode_fb_cmd *r = data; |
2366 | struct drm_mode_object *obj; |
- | |
2367 | struct drm_framebuffer *fb; |
2596 | struct drm_framebuffer *fb; |
2368 | int ret = 0; |
2597 | int ret; |
Line 2369... | Line 2598... | ||
2369 | 2598 | ||
2370 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
2599 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 2371... | Line -... | ||
2371 | return -EINVAL; |
- | |
2372 | 2600 | return -EINVAL; |
|
2373 | mutex_lock(&dev->mode_config.mutex); |
2601 | |
2374 | obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); |
2602 | fb = drm_framebuffer_lookup(dev, r->fb_id); |
2375 | if (!obj) { |
- | |
2376 | ret = -EINVAL; |
- | |
2377 | goto out; |
- | |
Line 2378... | Line 2603... | ||
2378 | } |
2603 | if (!fb) |
2379 | fb = obj_to_fb(obj); |
2604 | return -EINVAL; |
2380 | 2605 | ||
2381 | r->height = fb->height; |
2606 | r->height = fb->height; |
2382 | r->width = fb->width; |
2607 | r->width = fb->width; |
- | 2608 | r->depth = fb->depth; |
|
2383 | r->depth = fb->depth; |
2609 | r->bpp = fb->bits_per_pixel; |
- | 2610 | r->pitch = fb->pitches[0]; |
|
- | 2611 | if (fb->funcs->create_handle) |
|
- | 2612 | ret = fb->funcs->create_handle(fb, file_priv, &r->handle); |
|
- | 2613 | else |
|
Line 2384... | Line -... | ||
2384 | r->bpp = fb->bits_per_pixel; |
- | |
2385 | r->pitch = fb->pitches[0]; |
- | |
2386 | fb->funcs->create_handle(fb, file_priv, &r->handle); |
2614 | ret = -ENODEV; |
2387 | 2615 | ||
Line 2388... | Line 2616... | ||
2388 | out: |
2616 | drm_framebuffer_unreference(fb); |
2389 | mutex_unlock(&dev->mode_config.mutex); |
2617 | |
2390 | return ret; |
2618 | return ret; |
2391 | } |
2619 | } |
2392 | 2620 | ||
2393 | int drm_mode_dirtyfb_ioctl(struct drm_device *dev, |
2621 | int drm_mode_dirtyfb_ioctl(struct drm_device *dev, |
2394 | void *data, struct drm_file *file_priv) |
- | |
2395 | { |
2622 | void *data, struct drm_file *file_priv) |
2396 | struct drm_clip_rect __user *clips_ptr; |
2623 | { |
2397 | struct drm_clip_rect *clips = NULL; |
2624 | struct drm_clip_rect __user *clips_ptr; |
2398 | struct drm_mode_fb_dirty_cmd *r = data; |
2625 | struct drm_clip_rect *clips = NULL; |
Line 2399... | Line 2626... | ||
2399 | struct drm_mode_object *obj; |
2626 | struct drm_mode_fb_dirty_cmd *r = data; |
2400 | struct drm_framebuffer *fb; |
2627 | struct drm_framebuffer *fb; |
Line 2401... | Line -... | ||
2401 | unsigned flags; |
- | |
2402 | int num_clips; |
2628 | unsigned flags; |
2403 | int ret; |
2629 | int num_clips; |
2404 | 2630 | int ret; |
|
2405 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
- | |
2406 | return -EINVAL; |
- | |
2407 | - | ||
Line 2408... | Line 2631... | ||
2408 | mutex_lock(&dev->mode_config.mutex); |
2631 | |
2409 | obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); |
2632 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 2410... | Line 2633... | ||
2410 | if (!obj) { |
2633 | return -EINVAL; |
Line 2447... | Line 2670... | ||
2447 | goto out_err2; |
2670 | goto out_err2; |
2448 | } |
2671 | } |
2449 | } |
2672 | } |
Line 2450... | Line 2673... | ||
2450 | 2673 | ||
- | 2674 | if (fb->funcs->dirty) { |
|
2451 | if (fb->funcs->dirty) { |
2675 | drm_modeset_lock_all(dev); |
2452 | ret = fb->funcs->dirty(fb, file_priv, flags, r->color, |
2676 | ret = fb->funcs->dirty(fb, file_priv, flags, r->color, |
- | 2677 | clips, num_clips); |
|
2453 | clips, num_clips); |
2678 | drm_modeset_unlock_all(dev); |
2454 | } else { |
2679 | } else { |
2455 | ret = -ENOSYS; |
- | |
2456 | goto out_err2; |
2680 | ret = -ENOSYS; |
Line 2457... | Line 2681... | ||
2457 | } |
2681 | } |
2458 | 2682 | ||
2459 | out_err2: |
2683 | out_err2: |
2460 | kfree(clips); |
2684 | kfree(clips); |
- | 2685 | out_err1: |
|
2461 | out_err1: |
2686 | drm_framebuffer_unreference(fb); |
2462 | mutex_unlock(&dev->mode_config.mutex); |
2687 | |
Line 2463... | Line 2688... | ||
2463 | return ret; |
2688 | return ret; |
2464 | } |
2689 | } |
2465 | 2690 | ||
2466 | - | ||
2467 | /** |
- | |
2468 | * drm_fb_release - remove and free the FBs on this file |
- | |
2469 | * @filp: file * from the ioctl |
2691 | |
2470 | * |
2692 | /** |
2471 | * LOCKING: |
2693 | * drm_fb_release - remove and free the FBs on this file |
2472 | * Takes mode config lock. |
2694 | * @priv: drm file for the ioctl |
2473 | * |
2695 | * |
Line 2481... | Line 2703... | ||
2481 | void drm_fb_release(struct drm_file *priv) |
2703 | void drm_fb_release(struct drm_file *priv) |
2482 | { |
2704 | { |
2483 | struct drm_device *dev = priv->minor->dev; |
2705 | struct drm_device *dev = priv->minor->dev; |
2484 | struct drm_framebuffer *fb, *tfb; |
2706 | struct drm_framebuffer *fb, *tfb; |
Line 2485... | Line 2707... | ||
2485 | 2707 | ||
2486 | mutex_lock(&dev->mode_config.mutex); |
2708 | mutex_lock(&priv->fbs_lock); |
- | 2709 | list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { |
|
- | 2710 | ||
- | 2711 | mutex_lock(&dev->mode_config.fb_lock); |
|
- | 2712 | /* Mark fb as reaped, we still have a ref from fpriv->fbs. */ |
|
- | 2713 | __drm_framebuffer_unregister(dev, fb); |
|
- | 2714 | mutex_unlock(&dev->mode_config.fb_lock); |
|
- | 2715 | ||
- | 2716 | list_del_init(&fb->filp_head); |
|
- | 2717 | ||
2487 | list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { |
2718 | /* This will also drop the fpriv->fbs reference. */ |
2488 | drm_framebuffer_remove(fb); |
2719 | drm_framebuffer_remove(fb); |
2489 | } |
2720 | } |
2490 | mutex_unlock(&dev->mode_config.mutex); |
2721 | mutex_unlock(&priv->fbs_lock); |
2491 | } |
2722 | } |
Line 2492... | Line 2723... | ||
2492 | #endif |
2723 | #endif |
2493 | 2724 | ||
Line 2580... | Line 2811... | ||
2580 | 2811 | ||
Line 2581... | Line 2812... | ||
2581 | #if 0 |
2812 | #if 0 |
2582 | 2813 | ||
2583 | /** |
2814 | /** |
2584 | * drm_fb_attachmode - Attach a user mode to an connector |
2815 | * drm_fb_attachmode - Attach a user mode to an connector |
2585 | * @inode: inode from the ioctl |
- | |
2586 | * @filp: file * from the ioctl |
2816 | * @dev: drm device for the ioctl |
2587 | * @cmd: cmd from ioctl |
2817 | * @data: data pointer for the ioctl |
2588 | * @arg: arg from ioctl |
2818 | * @file_priv: drm file for the ioctl call |
2589 | * |
2819 | * |
2590 | * This attaches a user specified mode to an connector. |
2820 | * This attaches a user specified mode to an connector. |
2591 | * Called by the user via ioctl. |
2821 | * Called by the user via ioctl. |
Line 2604... | Line 2834... | ||
2604 | int ret; |
2834 | int ret; |
Line 2605... | Line 2835... | ||
2605 | 2835 | ||
2606 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
2836 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 2607... | Line 2837... | ||
2607 | return -EINVAL; |
2837 | return -EINVAL; |
Line 2608... | Line 2838... | ||
2608 | 2838 | ||
2609 | mutex_lock(&dev->mode_config.mutex); |
2839 | drm_modeset_lock_all(dev); |
2610 | 2840 | ||
2611 | obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); |
2841 | obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); |
Line 2628... | Line 2858... | ||
2628 | goto out; |
2858 | goto out; |
2629 | } |
2859 | } |
Line 2630... | Line 2860... | ||
2630 | 2860 | ||
2631 | drm_mode_attachmode(dev, connector, mode); |
2861 | drm_mode_attachmode(dev, connector, mode); |
2632 | out: |
2862 | out: |
2633 | mutex_unlock(&dev->mode_config.mutex); |
2863 | drm_modeset_unlock_all(dev); |
2634 | return ret; |
2864 | return ret; |
Line 2635... | Line 2865... | ||
2635 | } |
2865 | } |
2636 | 2866 | ||
2637 | 2867 | ||
2638 | /** |
2868 | /** |
2639 | * drm_fb_detachmode - Detach a user specified mode from an connector |
- | |
2640 | * @inode: inode from the ioctl |
2869 | * drm_fb_detachmode - Detach a user specified mode from an connector |
2641 | * @filp: file * from the ioctl |
2870 | * @dev: drm device for the ioctl |
2642 | * @cmd: cmd from ioctl |
2871 | * @data: data pointer for the ioctl |
2643 | * @arg: arg from ioctl |
2872 | * @file_priv: drm file for the ioctl call |
2644 | * |
2873 | * |
2645 | * Called by the user via ioctl. |
2874 | * Called by the user via ioctl. |
Line 2658... | Line 2887... | ||
2658 | int ret; |
2887 | int ret; |
Line 2659... | Line 2888... | ||
2659 | 2888 | ||
2660 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
2889 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 2661... | Line 2890... | ||
2661 | return -EINVAL; |
2890 | return -EINVAL; |
Line 2662... | Line 2891... | ||
2662 | 2891 | ||
2663 | mutex_lock(&dev->mode_config.mutex); |
2892 | drm_modeset_lock_all(dev); |
2664 | 2893 | ||
2665 | obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); |
2894 | obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); |
Line 2675... | Line 2904... | ||
2675 | goto out; |
2904 | goto out; |
2676 | } |
2905 | } |
Line 2677... | Line 2906... | ||
2677 | 2906 | ||
2678 | ret = drm_mode_detachmode(dev, connector, &mode); |
2907 | ret = drm_mode_detachmode(dev, connector, &mode); |
2679 | out: |
2908 | out: |
2680 | mutex_unlock(&dev->mode_config.mutex); |
2909 | drm_modeset_unlock_all(dev); |
2681 | return ret; |
2910 | return ret; |
2682 | } |
2911 | } |
Line 2683... | Line 2912... | ||
2683 | #endif |
2912 | #endif |
Line 2923... | Line 3152... | ||
2923 | uint32_t __user *blob_length_ptr; |
3152 | uint32_t __user *blob_length_ptr; |
Line 2924... | Line 3153... | ||
2924 | 3153 | ||
2925 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3154 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 2926... | Line 3155... | ||
2926 | return -EINVAL; |
3155 | return -EINVAL; |
2927 | 3156 | ||
2928 | mutex_lock(&dev->mode_config.mutex); |
3157 | drm_modeset_lock_all(dev); |
2929 | obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); |
3158 | obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); |
2930 | if (!obj) { |
3159 | if (!obj) { |
2931 | ret = -EINVAL; |
3160 | ret = -EINVAL; |
Line 3001... | Line 3230... | ||
3001 | } |
3230 | } |
3002 | } |
3231 | } |
3003 | out_resp->count_enum_blobs = blob_count; |
3232 | out_resp->count_enum_blobs = blob_count; |
3004 | } |
3233 | } |
3005 | done: |
3234 | done: |
3006 | mutex_unlock(&dev->mode_config.mutex); |
3235 | drm_modeset_unlock_all(dev); |
3007 | return ret; |
3236 | return ret; |
3008 | } |
3237 | } |
3009 | #endif |
3238 | #endif |
Line 3010... | Line 3239... | ||
3010 | 3239 | ||
Line 3054... | Line 3283... | ||
3054 | void __user *blob_ptr; |
3283 | void __user *blob_ptr; |
Line 3055... | Line 3284... | ||
3055 | 3284 | ||
3056 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3285 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 3057... | Line 3286... | ||
3057 | return -EINVAL; |
3286 | return -EINVAL; |
3058 | 3287 | ||
3059 | mutex_lock(&dev->mode_config.mutex); |
3288 | drm_modeset_lock_all(dev); |
3060 | obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); |
3289 | obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); |
3061 | if (!obj) { |
3290 | if (!obj) { |
3062 | ret = -EINVAL; |
3291 | ret = -EINVAL; |
Line 3072... | Line 3301... | ||
3072 | } |
3301 | } |
3073 | } |
3302 | } |
3074 | out_resp->length = blob->length; |
3303 | out_resp->length = blob->length; |
Line 3075... | Line 3304... | ||
3075 | 3304 | ||
3076 | done: |
3305 | done: |
3077 | mutex_unlock(&dev->mode_config.mutex); |
3306 | drm_modeset_unlock_all(dev); |
3078 | return ret; |
3307 | return ret; |
3079 | } |
3308 | } |
Line 3080... | Line 3309... | ||
3080 | #endif |
3309 | #endif |
Line 3175... | Line 3404... | ||
3175 | uint64_t __user *prop_values_ptr; |
3404 | uint64_t __user *prop_values_ptr; |
Line 3176... | Line 3405... | ||
3176 | 3405 | ||
3177 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3406 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 3178... | Line 3407... | ||
3178 | return -EINVAL; |
3407 | return -EINVAL; |
Line 3179... | Line 3408... | ||
3179 | 3408 | ||
3180 | mutex_lock(&dev->mode_config.mutex); |
3409 | drm_modeset_lock_all(dev); |
3181 | 3410 | ||
3182 | obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); |
3411 | obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); |
Line 3212... | Line 3441... | ||
3212 | copied++; |
3441 | copied++; |
3213 | } |
3442 | } |
3214 | } |
3443 | } |
3215 | arg->count_props = props_count; |
3444 | arg->count_props = props_count; |
3216 | out: |
3445 | out: |
3217 | mutex_unlock(&dev->mode_config.mutex); |
3446 | drm_modeset_unlock_all(dev); |
3218 | return ret; |
3447 | return ret; |
3219 | } |
3448 | } |
Line 3220... | Line 3449... | ||
3220 | 3449 | ||
3221 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, |
3450 | int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, |
Line 3229... | Line 3458... | ||
3229 | int i; |
3458 | int i; |
Line 3230... | Line 3459... | ||
3230 | 3459 | ||
3231 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3460 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 3232... | Line 3461... | ||
3232 | return -EINVAL; |
3461 | return -EINVAL; |
Line 3233... | Line 3462... | ||
3233 | 3462 | ||
3234 | mutex_lock(&dev->mode_config.mutex); |
3463 | drm_modeset_lock_all(dev); |
3235 | 3464 | ||
3236 | arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); |
3465 | arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); |
Line 3267... | Line 3496... | ||
3267 | ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value); |
3496 | ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value); |
3268 | break; |
3497 | break; |
3269 | } |
3498 | } |
Line 3270... | Line 3499... | ||
3270 | 3499 | ||
3271 | out: |
3500 | out: |
3272 | mutex_unlock(&dev->mode_config.mutex); |
3501 | drm_modeset_unlock_all(dev); |
3273 | return ret; |
3502 | return ret; |
3274 | } |
3503 | } |
Line 3275... | Line 3504... | ||
3275 | #endif |
3504 | #endif |
Line 3331... | Line 3560... | ||
3331 | int ret = 0; |
3560 | int ret = 0; |
Line 3332... | Line 3561... | ||
3332 | 3561 | ||
3333 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3562 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 3334... | Line 3563... | ||
3334 | return -EINVAL; |
3563 | return -EINVAL; |
3335 | 3564 | ||
3336 | mutex_lock(&dev->mode_config.mutex); |
3565 | drm_modeset_lock_all(dev); |
3337 | obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); |
3566 | obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); |
3338 | if (!obj) { |
3567 | if (!obj) { |
3339 | ret = -EINVAL; |
3568 | ret = -EINVAL; |
Line 3372... | Line 3601... | ||
3372 | } |
3601 | } |
Line 3373... | Line 3602... | ||
3373 | 3602 | ||
Line 3374... | Line 3603... | ||
3374 | crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); |
3603 | crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); |
3375 | 3604 | ||
3376 | out: |
3605 | out: |
Line 3377... | Line 3606... | ||
3377 | mutex_unlock(&dev->mode_config.mutex); |
3606 | drm_modeset_unlock_all(dev); |
Line 3378... | Line 3607... | ||
3378 | return ret; |
3607 | return ret; |
Line 3390... | Line 3619... | ||
3390 | int ret = 0; |
3619 | int ret = 0; |
Line 3391... | Line 3620... | ||
3391 | 3620 | ||
3392 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
3621 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 3393... | Line 3622... | ||
3393 | return -EINVAL; |
3622 | return -EINVAL; |
3394 | 3623 | ||
3395 | mutex_lock(&dev->mode_config.mutex); |
3624 | drm_modeset_lock_all(dev); |
3396 | obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); |
3625 | obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); |
3397 | if (!obj) { |
3626 | if (!obj) { |
3398 | ret = -EINVAL; |
3627 | ret = -EINVAL; |
Line 3423... | Line 3652... | ||
3423 | if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { |
3652 | if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { |
3424 | ret = -EFAULT; |
3653 | ret = -EFAULT; |
3425 | goto out; |
3654 | goto out; |
3426 | } |
3655 | } |
3427 | out: |
3656 | out: |
3428 | mutex_unlock(&dev->mode_config.mutex); |
3657 | drm_modeset_unlock_all(dev); |
3429 | return ret; |
3658 | return ret; |
3430 | } |
3659 | } |
Line 3431... | Line 3660... | ||
3431 | 3660 | ||
Line 3460... | Line 3689... | ||
3460 | */ |
3689 | */ |
3461 | void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, |
3690 | void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, |
3462 | int *bpp) |
3691 | int *bpp) |
3463 | { |
3692 | { |
3464 | switch (format) { |
3693 | switch (format) { |
- | 3694 | case DRM_FORMAT_C8: |
|
3465 | case DRM_FORMAT_RGB332: |
3695 | case DRM_FORMAT_RGB332: |
3466 | case DRM_FORMAT_BGR233: |
3696 | case DRM_FORMAT_BGR233: |
3467 | *depth = 8; |
3697 | *depth = 8; |
3468 | *bpp = 8; |
3698 | *bpp = 8; |
3469 | break; |
3699 | break; |