drivers/gpu/drm/lima/lima_gem.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/lima/lima_gem.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/lima/lima_gem.c
Extension
.c
Size
9303 bytes
Lines
417
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!pages) {
			dma_resv_unlock(bo->base.base.resv);
			return -ENOMEM;
		}

		bo->base.pages = pages;
		refcount_set(&bo->base.pages_use_count, 1);

		mapping_set_unevictable(mapping);
	}

	for (i = old_size >> PAGE_SHIFT; i < new_size >> PAGE_SHIFT; i++) {
		struct page *page = shmem_read_mapping_page(mapping, i);

		if (IS_ERR(page)) {
			dma_resv_unlock(bo->base.base.resv);
			return PTR_ERR(page);
		}
		pages[i] = page;
	}

	dma_resv_unlock(bo->base.base.resv);

	ret = sg_alloc_table_from_pages(&sgt, pages, i, 0,
					new_size, GFP_KERNEL);
	if (ret)
		return ret;

	if (bo->base.sgt) {
		dma_unmap_sgtable(dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0);
		sg_free_table(bo->base.sgt);
	} else {
		bo->base.sgt = kmalloc_obj(*bo->base.sgt);
		if (!bo->base.sgt) {
			ret = -ENOMEM;
			goto err_out0;
		}
	}

	ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
	if (ret)
		goto err_out1;

	*bo->base.sgt = sgt;

	if (vm) {
		ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT);
		if (ret)
			goto err_out2;
	}

	bo->heap_size = new_size;
	return 0;

err_out2:
	dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
err_out1:
	kfree(bo->base.sgt);
	bo->base.sgt = NULL;
err_out0:
	sg_free_table(&sgt);
	return ret;
}

int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
			   u32 size, u32 flags, u32 *handle)
{
	int err;
	gfp_t mask;
	struct drm_gem_shmem_object *shmem;
	struct drm_gem_object *obj;
	struct lima_bo *bo;
	bool is_heap = flags & LIMA_BO_FLAG_HEAP;

	shmem = drm_gem_shmem_create(dev, size);
	if (IS_ERR(shmem))
		return PTR_ERR(shmem);

	obj = &shmem->base;

	/* Mali Utgard GPU can only support 32bit address space */
	mask = mapping_gfp_mask(obj->filp->f_mapping);
	mask &= ~__GFP_HIGHMEM;
	mask |= __GFP_DMA32;
	mapping_set_gfp_mask(obj->filp->f_mapping, mask);

	if (is_heap) {
		bo = to_lima_bo(obj);
		err = lima_heap_alloc(bo, NULL);
		if (err)

Annotation

Implementation Notes