drivers/gpu/drm/tegra/uapi.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tegra/uapi.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tegra/uapi.c
Extension
.c
Size
8344 bytes
Lines
363
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 (!context->channel) {
			err = -EBUSY;
			goto free;
		}
	}

	/* Only allocate context if the engine supports context isolation. */
	if (device_iommu_mapped(client->base.dev) && client->ops->can_use_memory_ctx) {
		bool supported;

		err = client->ops->can_use_memory_ctx(client, &supported);
		if (err)
			goto put_channel;

		if (supported) {
			struct pid *pid = get_task_pid(current, PIDTYPE_TGID);
			context->memory_context = host1x_memory_context_alloc(
				host, client->base.dev, pid);
			put_pid(pid);
		}

		if (IS_ERR(context->memory_context)) {
			if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) {
				err = PTR_ERR(context->memory_context);
				goto put_channel;
			} else {
				/*
				 * OK, HW does not support contexts or contexts
				 * are disabled.
				 */
				context->memory_context = NULL;
			}
		}
	}

	err = xa_alloc(&fpriv->contexts, &args->context, context, XA_LIMIT(1, U32_MAX),
		       GFP_KERNEL);
	if (err < 0)
		goto put_memctx;

	context->client = client;
	xa_init_flags(&context->mappings, XA_FLAGS_ALLOC1);

	args->version = client->version;
	args->capabilities = 0;

	if (device_get_dma_attr(client->base.dev) == DEV_DMA_COHERENT)
		args->capabilities |= DRM_TEGRA_CHANNEL_CAP_CACHE_COHERENT;

	return 0;

put_memctx:
	if (context->memory_context)
		host1x_memory_context_put(context->memory_context);
put_channel:
	host1x_channel_put(context->channel);
free:
	kfree(context);

	return err;
}

int tegra_drm_ioctl_channel_close(struct drm_device *drm, void *data, struct drm_file *file)
{
	struct tegra_drm_file *fpriv = file->driver_priv;
	struct drm_tegra_channel_close *args = data;
	struct tegra_drm_context *context;

	mutex_lock(&fpriv->lock);

	context = xa_load(&fpriv->contexts, args->context);
	if (!context) {
		mutex_unlock(&fpriv->lock);
		return -EINVAL;
	}

	xa_erase(&fpriv->contexts, args->context);

	mutex_unlock(&fpriv->lock);

	tegra_drm_channel_context_close(context);

	return 0;
}

int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_file *file)
{
	struct tegra_drm_file *fpriv = file->driver_priv;
	struct drm_tegra_channel_map *args = data;
	struct tegra_drm_mapping *mapping;

Annotation

Implementation Notes