drivers/gpu/drm/msm/msm_syncobj.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/msm_syncobj.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/msm_syncobj.c
Extension
.c
Size
4069 bytes
Lines
173
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

min(syncobj_stride, sizeof(syncobj_desc)))) {
			ret = -EFAULT;
			break;
		}

		if (syncobj_desc.point &&
		    !drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) {
			ret = UERR(EOPNOTSUPP, dev, "syncobj timeline unsupported");
			break;
		}

		if (syncobj_desc.flags & ~MSM_SYNCOBJ_FLAGS) {
			ret = UERR(EINVAL, dev, "invalid syncobj flags: %x", syncobj_desc.flags);
			break;
		}

		ret = drm_sched_job_add_syncobj_dependency(job, file,
						   syncobj_desc.handle,
						   syncobj_desc.point);
		if (ret)
			break;

		if (syncobj_desc.flags & MSM_SYNCOBJ_RESET) {
			syncobjs[i] = drm_syncobj_find(file, syncobj_desc.handle);
			if (!syncobjs[i]) {
				ret = UERR(EINVAL, dev, "invalid syncobj handle: %u", i);
				break;
			}
		}
	}

	if (ret) {
		for (j = 0; j <= i; ++j) {
			if (syncobjs[j])
				drm_syncobj_put(syncobjs[j]);
		}
		kfree(syncobjs);
		return ERR_PTR(ret);
	}
	return syncobjs;
}

void
msm_syncobj_reset(struct drm_syncobj **syncobjs, uint32_t nr_syncobjs)
{
	uint32_t i;

	for (i = 0; syncobjs && i < nr_syncobjs; ++i) {
		if (syncobjs[i])
			drm_syncobj_replace_fence(syncobjs[i], NULL);
	}
}

struct msm_syncobj_post_dep *
msm_syncobj_parse_post_deps(struct drm_device *dev,
			    struct drm_file *file,
			    uint64_t syncobjs_addr,
			    uint32_t nr_syncobjs,
			    size_t syncobj_stride)
{
	struct msm_syncobj_post_dep *post_deps;
	struct drm_msm_syncobj syncobj_desc = {0};
	int ret = 0;
	uint32_t i, j;

	post_deps = kzalloc_objs(*post_deps, nr_syncobjs,
				 GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
	if (!post_deps)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < nr_syncobjs; ++i) {
		uint64_t address = syncobjs_addr + i * syncobj_stride;

		if (copy_from_user(&syncobj_desc,
			           u64_to_user_ptr(address),
			           min(syncobj_stride, sizeof(syncobj_desc)))) {
			ret = -EFAULT;
			break;
		}

		post_deps[i].point = syncobj_desc.point;

		if (syncobj_desc.flags) {
			ret = UERR(EINVAL, dev, "invalid syncobj flags");
			break;
		}

		if (syncobj_desc.point) {
			if (!drm_core_check_feature(dev,
			                            DRIVER_SYNCOBJ_TIMELINE)) {

Annotation

Implementation Notes