Merge branch 'pm-cpufreq'
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpu / drm / ttm / ttm_object.c
1 /**************************************************************************
2  *
3  * Copyright (c) 2009-2013 VMware, Inc., Palo Alto, CA., USA
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 /*
28  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
29  *
30  * While no substantial code is shared, the prime code is inspired by
31  * drm_prime.c, with
32  * Authors:
33  *      Dave Airlie <airlied@redhat.com>
34  *      Rob Clark <rob.clark@linaro.org>
35  */
36 /** @file ttm_ref_object.c
37  *
38  * Base- and reference object implementation for the various
39  * ttm objects. Implements reference counting, minimal security checks
40  * and release on file close.
41  */
42
43
44 /**
45  * struct ttm_object_file
46  *
47  * @tdev: Pointer to the ttm_object_device.
48  *
49  * @lock: Lock that protects the ref_list list and the
50  * ref_hash hash tables.
51  *
52  * @ref_list: List of ttm_ref_objects to be destroyed at
53  * file release.
54  *
55  * @ref_hash: Hash tables of ref objects, one per ttm_ref_type,
56  * for fast lookup of ref objects given a base object.
57  */
58
59 #define pr_fmt(fmt) "[TTM] " fmt
60
61 #include <drm/ttm/ttm_object.h>
62 #include <drm/ttm/ttm_module.h>
63 #include <linux/list.h>
64 #include <linux/spinlock.h>
65 #include <linux/slab.h>
66 #include <linux/module.h>
67 #include <linux/atomic.h>
68
69 struct ttm_object_file {
70         struct ttm_object_device *tdev;
71         rwlock_t lock;
72         struct list_head ref_list;
73         struct drm_open_hash ref_hash[TTM_REF_NUM];
74         struct kref refcount;
75 };
76
77 /**
78  * struct ttm_object_device
79  *
80  * @object_lock: lock that protects the object_hash hash table.
81  *
82  * @object_hash: hash table for fast lookup of object global names.
83  *
84  * @object_count: Per device object count.
85  *
86  * This is the per-device data structure needed for ttm object management.
87  */
88
89 struct ttm_object_device {
90         spinlock_t object_lock;
91         struct drm_open_hash object_hash;
92         atomic_t object_count;
93         struct ttm_mem_global *mem_glob;
94         struct dma_buf_ops ops;
95         void (*dmabuf_release)(struct dma_buf *dma_buf);
96         size_t dma_buf_size;
97 };
98
99 /**
100  * struct ttm_ref_object
101  *
102  * @hash: Hash entry for the per-file object reference hash.
103  *
104  * @head: List entry for the per-file list of ref-objects.
105  *
106  * @kref: Ref count.
107  *
108  * @obj: Base object this ref object is referencing.
109  *
110  * @ref_type: Type of ref object.
111  *
112  * This is similar to an idr object, but it also has a hash table entry
113  * that allows lookup with a pointer to the referenced object as a key. In
114  * that way, one can easily detect whether a base object is referenced by
115  * a particular ttm_object_file. It also carries a ref count to avoid creating
116  * multiple ref objects if a ttm_object_file references the same base
117  * object more than once.
118  */
119
120 struct ttm_ref_object {
121         struct drm_hash_item hash;
122         struct list_head head;
123         struct kref kref;
124         enum ttm_ref_type ref_type;
125         struct ttm_base_object *obj;
126         struct ttm_object_file *tfile;
127 };
128
129 static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf);
130
131 static inline struct ttm_object_file *
132 ttm_object_file_ref(struct ttm_object_file *tfile)
133 {
134         kref_get(&tfile->refcount);
135         return tfile;
136 }
137
138 static void ttm_object_file_destroy(struct kref *kref)
139 {
140         struct ttm_object_file *tfile =
141                 container_of(kref, struct ttm_object_file, refcount);
142
143         kfree(tfile);
144 }
145
146
147 static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile)
148 {
149         struct ttm_object_file *tfile = *p_tfile;
150
151         *p_tfile = NULL;
152         kref_put(&tfile->refcount, ttm_object_file_destroy);
153 }
154
155
156 int ttm_base_object_init(struct ttm_object_file *tfile,
157                          struct ttm_base_object *base,
158                          bool shareable,
159                          enum ttm_object_type object_type,
160                          void (*refcount_release) (struct ttm_base_object **),
161                          void (*ref_obj_release) (struct ttm_base_object *,
162                                                   enum ttm_ref_type ref_type))
163 {
164         struct ttm_object_device *tdev = tfile->tdev;
165         int ret;
166
167         base->shareable = shareable;
168         base->tfile = ttm_object_file_ref(tfile);
169         base->refcount_release = refcount_release;
170         base->ref_obj_release = ref_obj_release;
171         base->object_type = object_type;
172         kref_init(&base->refcount);
173         spin_lock(&tdev->object_lock);
174         ret = drm_ht_just_insert_please_rcu(&tdev->object_hash,
175                                             &base->hash,
176                                             (unsigned long)base, 31, 0, 0);
177         spin_unlock(&tdev->object_lock);
178         if (unlikely(ret != 0))
179                 goto out_err0;
180
181         ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
182         if (unlikely(ret != 0))
183                 goto out_err1;
184
185         ttm_base_object_unref(&base);
186
187         return 0;
188 out_err1:
189         spin_lock(&tdev->object_lock);
190         (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash);
191         spin_unlock(&tdev->object_lock);
192 out_err0:
193         return ret;
194 }
195 EXPORT_SYMBOL(ttm_base_object_init);
196
197 static void ttm_release_base(struct kref *kref)
198 {
199         struct ttm_base_object *base =
200             container_of(kref, struct ttm_base_object, refcount);
201         struct ttm_object_device *tdev = base->tfile->tdev;
202
203         spin_lock(&tdev->object_lock);
204         (void)drm_ht_remove_item_rcu(&tdev->object_hash, &base->hash);
205         spin_unlock(&tdev->object_lock);
206
207         /*
208          * Note: We don't use synchronize_rcu() here because it's far
209          * too slow. It's up to the user to free the object using
210          * call_rcu() or ttm_base_object_kfree().
211          */
212
213         if (base->refcount_release) {
214                 ttm_object_file_unref(&base->tfile);
215                 base->refcount_release(&base);
216         }
217 }
218
219 void ttm_base_object_unref(struct ttm_base_object **p_base)
220 {
221         struct ttm_base_object *base = *p_base;
222
223         *p_base = NULL;
224
225         kref_put(&base->refcount, ttm_release_base);
226 }
227 EXPORT_SYMBOL(ttm_base_object_unref);
228
229 struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
230                                                uint32_t key)
231 {
232         struct ttm_object_device *tdev = tfile->tdev;
233         struct ttm_base_object *uninitialized_var(base);
234         struct drm_hash_item *hash;
235         int ret;
236
237         rcu_read_lock();
238         ret = drm_ht_find_item_rcu(&tdev->object_hash, key, &hash);
239
240         if (likely(ret == 0)) {
241                 base = drm_hash_entry(hash, struct ttm_base_object, hash);
242                 ret = kref_get_unless_zero(&base->refcount) ? 0 : -EINVAL;
243         }
244         rcu_read_unlock();
245
246         if (unlikely(ret != 0))
247                 return NULL;
248
249         if (tfile != base->tfile && !base->shareable) {
250                 pr_err("Attempted access of non-shareable object\n");
251                 ttm_base_object_unref(&base);
252                 return NULL;
253         }
254
255         return base;
256 }
257 EXPORT_SYMBOL(ttm_base_object_lookup);
258
259 int ttm_ref_object_add(struct ttm_object_file *tfile,
260                        struct ttm_base_object *base,
261                        enum ttm_ref_type ref_type, bool *existed)
262 {
263         struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
264         struct ttm_ref_object *ref;
265         struct drm_hash_item *hash;
266         struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
267         int ret = -EINVAL;
268
269         if (existed != NULL)
270                 *existed = true;
271
272         while (ret == -EINVAL) {
273                 read_lock(&tfile->lock);
274                 ret = drm_ht_find_item(ht, base->hash.key, &hash);
275
276                 if (ret == 0) {
277                         ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
278                         kref_get(&ref->kref);
279                         read_unlock(&tfile->lock);
280                         break;
281                 }
282
283                 read_unlock(&tfile->lock);
284                 ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
285                                            false, false);
286                 if (unlikely(ret != 0))
287                         return ret;
288                 ref = kmalloc(sizeof(*ref), GFP_KERNEL);
289                 if (unlikely(ref == NULL)) {
290                         ttm_mem_global_free(mem_glob, sizeof(*ref));
291                         return -ENOMEM;
292                 }
293
294                 ref->hash.key = base->hash.key;
295                 ref->obj = base;
296                 ref->tfile = tfile;
297                 ref->ref_type = ref_type;
298                 kref_init(&ref->kref);
299
300                 write_lock(&tfile->lock);
301                 ret = drm_ht_insert_item(ht, &ref->hash);
302
303                 if (likely(ret == 0)) {
304                         list_add_tail(&ref->head, &tfile->ref_list);
305                         kref_get(&base->refcount);
306                         write_unlock(&tfile->lock);
307                         if (existed != NULL)
308                                 *existed = false;
309                         break;
310                 }
311
312                 write_unlock(&tfile->lock);
313                 BUG_ON(ret != -EINVAL);
314
315                 ttm_mem_global_free(mem_glob, sizeof(*ref));
316                 kfree(ref);
317         }
318
319         return ret;
320 }
321 EXPORT_SYMBOL(ttm_ref_object_add);
322
323 static void ttm_ref_object_release(struct kref *kref)
324 {
325         struct ttm_ref_object *ref =
326             container_of(kref, struct ttm_ref_object, kref);
327         struct ttm_base_object *base = ref->obj;
328         struct ttm_object_file *tfile = ref->tfile;
329         struct drm_open_hash *ht;
330         struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
331
332         ht = &tfile->ref_hash[ref->ref_type];
333         (void)drm_ht_remove_item(ht, &ref->hash);
334         list_del(&ref->head);
335         write_unlock(&tfile->lock);
336
337         if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release)
338                 base->ref_obj_release(base, ref->ref_type);
339
340         ttm_base_object_unref(&ref->obj);
341         ttm_mem_global_free(mem_glob, sizeof(*ref));
342         kfree(ref);
343         write_lock(&tfile->lock);
344 }
345
346 int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
347                               unsigned long key, enum ttm_ref_type ref_type)
348 {
349         struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
350         struct ttm_ref_object *ref;
351         struct drm_hash_item *hash;
352         int ret;
353
354         write_lock(&tfile->lock);
355         ret = drm_ht_find_item(ht, key, &hash);
356         if (unlikely(ret != 0)) {
357                 write_unlock(&tfile->lock);
358                 return -EINVAL;
359         }
360         ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
361         kref_put(&ref->kref, ttm_ref_object_release);
362         write_unlock(&tfile->lock);
363         return 0;
364 }
365 EXPORT_SYMBOL(ttm_ref_object_base_unref);
366
367 void ttm_object_file_release(struct ttm_object_file **p_tfile)
368 {
369         struct ttm_ref_object *ref;
370         struct list_head *list;
371         unsigned int i;
372         struct ttm_object_file *tfile = *p_tfile;
373
374         *p_tfile = NULL;
375         write_lock(&tfile->lock);
376
377         /*
378          * Since we release the lock within the loop, we have to
379          * restart it from the beginning each time.
380          */
381
382         while (!list_empty(&tfile->ref_list)) {
383                 list = tfile->ref_list.next;
384                 ref = list_entry(list, struct ttm_ref_object, head);
385                 ttm_ref_object_release(&ref->kref);
386         }
387
388         for (i = 0; i < TTM_REF_NUM; ++i)
389                 drm_ht_remove(&tfile->ref_hash[i]);
390
391         write_unlock(&tfile->lock);
392         ttm_object_file_unref(&tfile);
393 }
394 EXPORT_SYMBOL(ttm_object_file_release);
395
396 struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
397                                              unsigned int hash_order)
398 {
399         struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
400         unsigned int i;
401         unsigned int j = 0;
402         int ret;
403
404         if (unlikely(tfile == NULL))
405                 return NULL;
406
407         rwlock_init(&tfile->lock);
408         tfile->tdev = tdev;
409         kref_init(&tfile->refcount);
410         INIT_LIST_HEAD(&tfile->ref_list);
411
412         for (i = 0; i < TTM_REF_NUM; ++i) {
413                 ret = drm_ht_create(&tfile->ref_hash[i], hash_order);
414                 if (ret) {
415                         j = i;
416                         goto out_err;
417                 }
418         }
419
420         return tfile;
421 out_err:
422         for (i = 0; i < j; ++i)
423                 drm_ht_remove(&tfile->ref_hash[i]);
424
425         kfree(tfile);
426
427         return NULL;
428 }
429 EXPORT_SYMBOL(ttm_object_file_init);
430
431 struct ttm_object_device *
432 ttm_object_device_init(struct ttm_mem_global *mem_glob,
433                        unsigned int hash_order,
434                        const struct dma_buf_ops *ops)
435 {
436         struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL);
437         int ret;
438
439         if (unlikely(tdev == NULL))
440                 return NULL;
441
442         tdev->mem_glob = mem_glob;
443         spin_lock_init(&tdev->object_lock);
444         atomic_set(&tdev->object_count, 0);
445         ret = drm_ht_create(&tdev->object_hash, hash_order);
446         if (ret != 0)
447                 goto out_no_object_hash;
448
449         tdev->ops = *ops;
450         tdev->dmabuf_release = tdev->ops.release;
451         tdev->ops.release = ttm_prime_dmabuf_release;
452         tdev->dma_buf_size = ttm_round_pot(sizeof(struct dma_buf)) +
453                 ttm_round_pot(sizeof(struct file));
454         return tdev;
455
456 out_no_object_hash:
457         kfree(tdev);
458         return NULL;
459 }
460 EXPORT_SYMBOL(ttm_object_device_init);
461
462 void ttm_object_device_release(struct ttm_object_device **p_tdev)
463 {
464         struct ttm_object_device *tdev = *p_tdev;
465
466         *p_tdev = NULL;
467
468         spin_lock(&tdev->object_lock);
469         drm_ht_remove(&tdev->object_hash);
470         spin_unlock(&tdev->object_lock);
471
472         kfree(tdev);
473 }
474 EXPORT_SYMBOL(ttm_object_device_release);
475
476 /**
477  * get_dma_buf_unless_doomed - get a dma_buf reference if possible.
478  *
479  * @dma_buf: Non-refcounted pointer to a struct dma-buf.
480  *
481  * Obtain a file reference from a lookup structure that doesn't refcount
482  * the file, but synchronizes with its release method to make sure it has
483  * not been freed yet. See for example kref_get_unless_zero documentation.
484  * Returns true if refcounting succeeds, false otherwise.
485  *
486  * Nobody really wants this as a public API yet, so let it mature here
487  * for some time...
488  */
489 static bool __must_check get_dma_buf_unless_doomed(struct dma_buf *dmabuf)
490 {
491         return atomic_long_inc_not_zero(&dmabuf->file->f_count) != 0L;
492 }
493
494 /**
495  * ttm_prime_refcount_release - refcount release method for a prime object.
496  *
497  * @p_base: Pointer to ttm_base_object pointer.
498  *
499  * This is a wrapper that calls the refcount_release founction of the
500  * underlying object. At the same time it cleans up the prime object.
501  * This function is called when all references to the base object we
502  * derive from are gone.
503  */
504 static void ttm_prime_refcount_release(struct ttm_base_object **p_base)
505 {
506         struct ttm_base_object *base = *p_base;
507         struct ttm_prime_object *prime;
508
509         *p_base = NULL;
510         prime = container_of(base, struct ttm_prime_object, base);
511         BUG_ON(prime->dma_buf != NULL);
512         mutex_destroy(&prime->mutex);
513         if (prime->refcount_release)
514                 prime->refcount_release(&base);
515 }
516
517 /**
518  * ttm_prime_dmabuf_release - Release method for the dma-bufs we export
519  *
520  * @dma_buf:
521  *
522  * This function first calls the dma_buf release method the driver
523  * provides. Then it cleans up our dma_buf pointer used for lookup,
524  * and finally releases the reference the dma_buf has on our base
525  * object.
526  */
527 static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf)
528 {
529         struct ttm_prime_object *prime =
530                 (struct ttm_prime_object *) dma_buf->priv;
531         struct ttm_base_object *base = &prime->base;
532         struct ttm_object_device *tdev = base->tfile->tdev;
533
534         if (tdev->dmabuf_release)
535                 tdev->dmabuf_release(dma_buf);
536         mutex_lock(&prime->mutex);
537         if (prime->dma_buf == dma_buf)
538                 prime->dma_buf = NULL;
539         mutex_unlock(&prime->mutex);
540         ttm_mem_global_free(tdev->mem_glob, tdev->dma_buf_size);
541         ttm_base_object_unref(&base);
542 }
543
544 /**
545  * ttm_prime_fd_to_handle - Get a base object handle from a prime fd
546  *
547  * @tfile: A struct ttm_object_file identifying the caller.
548  * @fd: The prime / dmabuf fd.
549  * @handle: The returned handle.
550  *
551  * This function returns a handle to an object that previously exported
552  * a dma-buf. Note that we don't handle imports yet, because we simply
553  * have no consumers of that implementation.
554  */
555 int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
556                            int fd, u32 *handle)
557 {
558         struct ttm_object_device *tdev = tfile->tdev;
559         struct dma_buf *dma_buf;
560         struct ttm_prime_object *prime;
561         struct ttm_base_object *base;
562         int ret;
563
564         dma_buf = dma_buf_get(fd);
565         if (IS_ERR(dma_buf))
566                 return PTR_ERR(dma_buf);
567
568         if (dma_buf->ops != &tdev->ops)
569                 return -ENOSYS;
570
571         prime = (struct ttm_prime_object *) dma_buf->priv;
572         base = &prime->base;
573         *handle = base->hash.key;
574         ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
575
576         dma_buf_put(dma_buf);
577
578         return ret;
579 }
580 EXPORT_SYMBOL_GPL(ttm_prime_fd_to_handle);
581
582 /**
583  * ttm_prime_handle_to_fd - Return a dma_buf fd from a ttm prime object
584  *
585  * @tfile: Struct ttm_object_file identifying the caller.
586  * @handle: Handle to the object we're exporting from.
587  * @flags: flags for dma-buf creation. We just pass them on.
588  * @prime_fd: The returned file descriptor.
589  *
590  */
591 int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
592                            uint32_t handle, uint32_t flags,
593                            int *prime_fd)
594 {
595         struct ttm_object_device *tdev = tfile->tdev;
596         struct ttm_base_object *base;
597         struct dma_buf *dma_buf;
598         struct ttm_prime_object *prime;
599         int ret;
600
601         base = ttm_base_object_lookup(tfile, handle);
602         if (unlikely(base == NULL ||
603                      base->object_type != ttm_prime_type)) {
604                 ret = -ENOENT;
605                 goto out_unref;
606         }
607
608         prime = container_of(base, struct ttm_prime_object, base);
609         if (unlikely(!base->shareable)) {
610                 ret = -EPERM;
611                 goto out_unref;
612         }
613
614         ret = mutex_lock_interruptible(&prime->mutex);
615         if (unlikely(ret != 0)) {
616                 ret = -ERESTARTSYS;
617                 goto out_unref;
618         }
619
620         dma_buf = prime->dma_buf;
621         if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) {
622
623                 /*
624                  * Need to create a new dma_buf, with memory accounting.
625                  */
626                 ret = ttm_mem_global_alloc(tdev->mem_glob, tdev->dma_buf_size,
627                                            false, true);
628                 if (unlikely(ret != 0)) {
629                         mutex_unlock(&prime->mutex);
630                         goto out_unref;
631                 }
632
633                 dma_buf = dma_buf_export(prime, &tdev->ops,
634                                          prime->size, flags);
635                 if (IS_ERR(dma_buf)) {
636                         ret = PTR_ERR(dma_buf);
637                         ttm_mem_global_free(tdev->mem_glob,
638                                             tdev->dma_buf_size);
639                         mutex_unlock(&prime->mutex);
640                         goto out_unref;
641                 }
642
643                 /*
644                  * dma_buf has taken the base object reference
645                  */
646                 base = NULL;
647                 prime->dma_buf = dma_buf;
648         }
649         mutex_unlock(&prime->mutex);
650
651         ret = dma_buf_fd(dma_buf, flags);
652         if (ret >= 0) {
653                 *prime_fd = ret;
654                 ret = 0;
655         } else
656                 dma_buf_put(dma_buf);
657
658 out_unref:
659         if (base)
660                 ttm_base_object_unref(&base);
661         return ret;
662 }
663 EXPORT_SYMBOL_GPL(ttm_prime_handle_to_fd);
664
665 /**
666  * ttm_prime_object_init - Initialize a ttm_prime_object
667  *
668  * @tfile: struct ttm_object_file identifying the caller
669  * @size: The size of the dma_bufs we export.
670  * @prime: The object to be initialized.
671  * @shareable: See ttm_base_object_init
672  * @type: See ttm_base_object_init
673  * @refcount_release: See ttm_base_object_init
674  * @ref_obj_release: See ttm_base_object_init
675  *
676  * Initializes an object which is compatible with the drm_prime model
677  * for data sharing between processes and devices.
678  */
679 int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size,
680                           struct ttm_prime_object *prime, bool shareable,
681                           enum ttm_object_type type,
682                           void (*refcount_release) (struct ttm_base_object **),
683                           void (*ref_obj_release) (struct ttm_base_object *,
684                                                    enum ttm_ref_type ref_type))
685 {
686         mutex_init(&prime->mutex);
687         prime->size = PAGE_ALIGN(size);
688         prime->real_type = type;
689         prime->dma_buf = NULL;
690         prime->refcount_release = refcount_release;
691         return ttm_base_object_init(tfile, &prime->base, shareable,
692                                     ttm_prime_type,
693                                     ttm_prime_refcount_release,
694                                     ref_obj_release);
695 }
696 EXPORT_SYMBOL(ttm_prime_object_init);