drivers/gpu/drm/etnaviv/etnaviv_gem.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/etnaviv/etnaviv_gem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/etnaviv/etnaviv_gem.c- Extension
.c- Size
- 19178 bytes
- Lines
- 759
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
drm/drm_prime.hdrm/drm_print.hlinux/dma-mapping.hlinux/shmem_fs.hlinux/spinlock.hlinux/vmalloc.hetnaviv_drv.hetnaviv_gem.hetnaviv_gpu.hetnaviv_mmu.h
Detected Declarations
function etnaviv_gem_scatter_mapfunction etnaviv_gem_scatterlist_unmapfunction etnaviv_gem_shmem_get_pagesfunction put_pagesfunction etnaviv_gem_put_pagesfunction etnaviv_gem_mmap_objfunction etnaviv_gem_mmapfunction etnaviv_gem_faultfunction etnaviv_gem_mmap_offsetfunction etnaviv_gem_get_vram_mappingfunction list_for_each_entryfunction etnaviv_gem_mapping_unreferencefunction etnaviv_op_to_dma_dirfunction etnaviv_gem_cpu_prepfunction etnaviv_gem_cpu_finifunction etnaviv_gem_wait_bofunction etnaviv_gem_describefunction etnaviv_gem_describe_objectsfunction etnaviv_gem_shmem_releasefunction etnaviv_gem_free_objectfunction list_for_each_entry_safefunction etnaviv_gem_obj_addfunction etnaviv_gem_statusfunction etnaviv_gem_new_implfunction etnaviv_gem_new_handlefunction etnaviv_gem_new_privatefunction etnaviv_gem_userptr_get_pagesfunction etnaviv_gem_userptr_releasefunction etnaviv_gem_userptr_mmap_objfunction etnaviv_gem_new_userptr
Annotated Snippet
if (IS_ERR(sgt)) {
dev_err(dev->dev, "failed to allocate sgt: %ld\n",
PTR_ERR(sgt));
return ERR_CAST(sgt);
}
etnaviv_obj->sgt = sgt;
etnaviv_gem_scatter_map(etnaviv_obj);
}
return etnaviv_obj->pages;
}
void etnaviv_gem_put_pages(struct etnaviv_gem_object *etnaviv_obj)
{
lockdep_assert_held(&etnaviv_obj->lock);
/* when we start tracking the pin count, then do something here */
}
static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
struct vm_area_struct *vma)
{
pgprot_t vm_page_prot;
vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
vm_page_prot = vm_get_page_prot(vma->vm_flags);
if (etnaviv_obj->flags & ETNA_BO_WC) {
vma->vm_page_prot = pgprot_writecombine(vm_page_prot);
} else if (etnaviv_obj->flags & ETNA_BO_UNCACHED) {
vma->vm_page_prot = pgprot_noncached(vm_page_prot);
} else {
/*
* Shunt off cached objs to shmem file so they have their own
* address_space (so unmap_mapping_range does what we want,
* in particular in the case of mmap'd dmabufs)
*/
vma->vm_pgoff = 0;
vma_set_file(vma, etnaviv_obj->base.filp);
vma->vm_page_prot = vm_page_prot;
}
return 0;
}
static int etnaviv_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
{
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
return etnaviv_obj->ops->mmap(etnaviv_obj, vma);
}
static vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
struct drm_gem_object *obj = vma->vm_private_data;
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
struct page **pages;
unsigned long pfn;
pgoff_t pgoff;
int err;
/*
* Make sure we don't parallel update on a fault, nor move or remove
* something from beneath our feet. Note that vmf_insert_page() is
* specifically coded to take care of this, so we don't have to.
*/
err = mutex_lock_interruptible(&etnaviv_obj->lock);
if (err)
return VM_FAULT_NOPAGE;
/* make sure we have pages attached now */
pages = etnaviv_gem_get_pages(etnaviv_obj);
mutex_unlock(&etnaviv_obj->lock);
if (IS_ERR(pages)) {
err = PTR_ERR(pages);
return vmf_error(err);
}
/* We don't use vmf->pgoff since that has the fake offset: */
pgoff = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
pfn = page_to_pfn(pages[pgoff]);
VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address,
pfn, pfn << PAGE_SHIFT);
Annotation
- Immediate include surface: `drm/drm_prime.h`, `drm/drm_print.h`, `linux/dma-mapping.h`, `linux/shmem_fs.h`, `linux/spinlock.h`, `linux/vmalloc.h`, `etnaviv_drv.h`, `etnaviv_gem.h`.
- Detected declarations: `function etnaviv_gem_scatter_map`, `function etnaviv_gem_scatterlist_unmap`, `function etnaviv_gem_shmem_get_pages`, `function put_pages`, `function etnaviv_gem_put_pages`, `function etnaviv_gem_mmap_obj`, `function etnaviv_gem_mmap`, `function etnaviv_gem_fault`, `function etnaviv_gem_mmap_offset`, `function etnaviv_gem_get_vram_mapping`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.