~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/gpu/drm/drm_gem.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
129
129
}
130
130
 
131
131
/**
132
 
 * Initialize an already allocate GEM object of the specified size with
 
132
 * Initialize an already allocated GEM object of the specified size with
133
133
 * shmfs backing store.
134
134
 */
135
135
int drm_gem_object_init(struct drm_device *dev,
151
151
EXPORT_SYMBOL(drm_gem_object_init);
152
152
 
153
153
/**
 
154
 * Initialize an already allocated GEM object of the specified size with
 
155
 * no GEM provided backing store. Instead the caller is responsible for
 
156
 * backing the object and handling it.
 
157
 */
 
158
int drm_gem_private_object_init(struct drm_device *dev,
 
159
                        struct drm_gem_object *obj, size_t size)
 
160
{
 
161
        BUG_ON((size & (PAGE_SIZE - 1)) != 0);
 
162
 
 
163
        obj->dev = dev;
 
164
        obj->filp = NULL;
 
165
 
 
166
        kref_init(&obj->refcount);
 
167
        atomic_set(&obj->handle_count, 0);
 
168
        obj->size = size;
 
169
 
 
170
        return 0;
 
171
}
 
172
EXPORT_SYMBOL(drm_gem_private_object_init);
 
173
 
 
174
/**
154
175
 * Allocate a GEM object of the specified size with shmfs backing store
155
176
 */
156
177
struct drm_gem_object *
211
232
        idr_remove(&filp->object_idr, handle);
212
233
        spin_unlock(&filp->table_lock);
213
234
 
 
235
        if (dev->driver->gem_close_object)
 
236
                dev->driver->gem_close_object(obj, filp);
214
237
        drm_gem_object_handle_unreference_unlocked(obj);
215
238
 
216
239
        return 0;
227
250
                       struct drm_gem_object *obj,
228
251
                       u32 *handlep)
229
252
{
230
 
        int     ret;
 
253
        struct drm_device *dev = obj->dev;
 
254
        int ret;
231
255
 
232
256
        /*
233
257
         * Get the user-visible handle using idr.
248
272
                return ret;
249
273
 
250
274
        drm_gem_object_handle_reference(obj);
 
275
 
 
276
        if (dev->driver->gem_open_object) {
 
277
                ret = dev->driver->gem_open_object(obj, file_priv);
 
278
                if (ret) {
 
279
                        drm_gem_handle_delete(file_priv, *handlep);
 
280
                        return ret;
 
281
                }
 
282
        }
 
283
 
251
284
        return 0;
252
285
}
253
286
EXPORT_SYMBOL(drm_gem_handle_create);
254
287
 
 
288
 
 
289
/**
 
290
 * drm_gem_free_mmap_offset - release a fake mmap offset for an object
 
291
 * @obj: obj in question
 
292
 *
 
293
 * This routine frees fake offsets allocated by drm_gem_create_mmap_offset().
 
294
 */
 
295
void
 
296
drm_gem_free_mmap_offset(struct drm_gem_object *obj)
 
297
{
 
298
        struct drm_device *dev = obj->dev;
 
299
        struct drm_gem_mm *mm = dev->mm_private;
 
300
        struct drm_map_list *list = &obj->map_list;
 
301
 
 
302
        drm_ht_remove_item(&mm->offset_hash, &list->hash);
 
303
        drm_mm_put_block(list->file_offset_node);
 
304
        kfree(list->map);
 
305
        list->map = NULL;
 
306
}
 
307
EXPORT_SYMBOL(drm_gem_free_mmap_offset);
 
308
 
 
309
/**
 
310
 * drm_gem_create_mmap_offset - create a fake mmap offset for an object
 
311
 * @obj: obj in question
 
312
 *
 
313
 * GEM memory mapping works by handing back to userspace a fake mmap offset
 
314
 * it can use in a subsequent mmap(2) call.  The DRM core code then looks
 
315
 * up the object based on the offset and sets up the various memory mapping
 
316
 * structures.
 
317
 *
 
318
 * This routine allocates and attaches a fake offset for @obj.
 
319
 */
 
320
int
 
321
drm_gem_create_mmap_offset(struct drm_gem_object *obj)
 
322
{
 
323
        struct drm_device *dev = obj->dev;
 
324
        struct drm_gem_mm *mm = dev->mm_private;
 
325
        struct drm_map_list *list;
 
326
        struct drm_local_map *map;
 
327
        int ret = 0;
 
328
 
 
329
        /* Set the object up for mmap'ing */
 
330
        list = &obj->map_list;
 
331
        list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
 
332
        if (!list->map)
 
333
                return -ENOMEM;
 
334
 
 
335
        map = list->map;
 
336
        map->type = _DRM_GEM;
 
337
        map->size = obj->size;
 
338
        map->handle = obj;
 
339
 
 
340
        /* Get a DRM GEM mmap offset allocated... */
 
341
        list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
 
342
                        obj->size / PAGE_SIZE, 0, 0);
 
343
 
 
344
        if (!list->file_offset_node) {
 
345
                DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
 
346
                ret = -ENOSPC;
 
347
                goto out_free_list;
 
348
        }
 
349
 
 
350
        list->file_offset_node = drm_mm_get_block(list->file_offset_node,
 
351
                        obj->size / PAGE_SIZE, 0);
 
352
        if (!list->file_offset_node) {
 
353
                ret = -ENOMEM;
 
354
                goto out_free_list;
 
355
        }
 
356
 
 
357
        list->hash.key = list->file_offset_node->start;
 
358
        ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
 
359
        if (ret) {
 
360
                DRM_ERROR("failed to add to map hash\n");
 
361
                goto out_free_mm;
 
362
        }
 
363
 
 
364
        return 0;
 
365
 
 
366
out_free_mm:
 
367
        drm_mm_put_block(list->file_offset_node);
 
368
out_free_list:
 
369
        kfree(list->map);
 
370
        list->map = NULL;
 
371
 
 
372
        return ret;
 
373
}
 
374
EXPORT_SYMBOL(drm_gem_create_mmap_offset);
 
375
 
255
376
/** Returns a reference to the object named by the handle. */
256
377
struct drm_gem_object *
257
378
drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
402
523
static int
403
524
drm_gem_object_release_handle(int id, void *ptr, void *data)
404
525
{
 
526
        struct drm_file *file_priv = data;
405
527
        struct drm_gem_object *obj = ptr;
 
528
        struct drm_device *dev = obj->dev;
 
529
 
 
530
        if (dev->driver->gem_close_object)
 
531
                dev->driver->gem_close_object(obj, file_priv);
406
532
 
407
533
        drm_gem_object_handle_unreference_unlocked(obj);
408
534
 
418
544
drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
419
545
{
420
546
        idr_for_each(&file_private->object_idr,
421
 
                     &drm_gem_object_release_handle, NULL);
 
547
                     &drm_gem_object_release_handle, file_private);
422
548
 
423
549
        idr_remove_all(&file_private->object_idr);
424
550
        idr_destroy(&file_private->object_idr);
427
553
void
428
554
drm_gem_object_release(struct drm_gem_object *obj)
429
555
{
430
 
        fput(obj->filp);
 
556
        if (obj->filp)
 
557
            fput(obj->filp);
431
558
}
432
559
EXPORT_SYMBOL(drm_gem_object_release);
433
560