drivers/gpu/drm/etnaviv/etnaviv_drv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/etnaviv/etnaviv_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/etnaviv/etnaviv_drv.c
Extension
.c
Size
18384 bytes
Lines
778
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations fops = {
	.owner = THIS_MODULE,
	DRM_GEM_FOPS,
	.show_fdinfo = drm_show_fdinfo,
};

static const struct drm_driver etnaviv_drm_driver = {
	.driver_features    = DRIVER_GEM | DRIVER_RENDER,
	.open               = etnaviv_open,
	.postclose           = etnaviv_postclose,
	.gem_prime_import_sg_table = etnaviv_gem_prime_import_sg_table,
#ifdef CONFIG_DEBUG_FS
	.debugfs_init       = etnaviv_debugfs_init,
#endif
	.show_fdinfo        = etnaviv_show_fdinfo,
	.ioctls             = etnaviv_ioctls,
	.num_ioctls         = DRM_ETNAVIV_NUM_IOCTLS,
	.fops               = &fops,
	.name               = "etnaviv",
	.desc               = "etnaviv DRM",
	.major              = 1,
	.minor              = 4,
};

/*
 * Platform driver:
 */
static int etnaviv_bind(struct device *dev)
{
	struct etnaviv_drm_private *priv;
	struct drm_device *drm;
	int ret;

	drm = drm_dev_alloc(&etnaviv_drm_driver, dev);
	if (IS_ERR(drm))
		return PTR_ERR(drm);

	priv = kzalloc_obj(*priv);
	if (!priv) {
		dev_err(dev, "failed to allocate private data\n");
		ret = -ENOMEM;
		goto out_put;
	}
	drm->dev_private = priv;

	dma_set_max_seg_size(dev, SZ_2G);

	xa_init_flags(&priv->active_contexts, XA_FLAGS_ALLOC);

	mutex_init(&priv->gem_lock);
	INIT_LIST_HEAD(&priv->gem_list);
	priv->num_gpus = 0;
	priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;

	/*
	 * If the GPU is part of a system with DMA addressing limitations,
	 * request pages for our SHM backend buffers from the DMA32 zone to
	 * hopefully avoid performance killing SWIOTLB bounce buffering.
	 */
	if (dma_addressing_limited(dev)) {
		priv->shm_gfp_mask |= GFP_DMA32;
		priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
	}

	priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
	if (IS_ERR(priv->cmdbuf_suballoc)) {
		dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
		ret = PTR_ERR(priv->cmdbuf_suballoc);
		goto out_free_priv;
	}

	dev_set_drvdata(dev, drm);

	ret = component_bind_all(dev, drm);
	if (ret < 0)
		goto out_destroy_suballoc;

	load_gpu(drm);

	ret = drm_dev_register(drm, 0);
	if (ret)
		goto out_unbind;

	return 0;

out_unbind:
	component_unbind_all(dev, drm);
out_destroy_suballoc:
	etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
out_free_priv:

Annotation

Implementation Notes