drivers/gpu/drm/nouveau/nvkm/core/event.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/core/event.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/core/event.c
Extension
.c
Size
5749 bytes
Lines
215
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 (--event->refs[index * event->types_nr + type] == 0) {
			nvkm_trace(event->subdev, "event: blocking %d on %d\n", type, index);
			if (event->func->fini)
				event->func->fini(event, 1 << type, index);
		}
	}
}

static void
nvkm_event_get(struct nvkm_event *event, u32 types, int index)
{
	assert_spin_locked(&event->refs_lock);

	nvkm_trace(event->subdev, "event: incr %08x on %d\n", types, index);

	while (types) {
		int type = __ffs(types); types &= ~(1 << type);
		if (++event->refs[index * event->types_nr + type] == 1) {
			nvkm_trace(event->subdev, "event: allowing %d on %d\n", type, index);
			if (event->func->init)
				event->func->init(event, 1 << type, index);
		}
	}
}

static void
nvkm_event_ntfy_state(struct nvkm_event_ntfy *ntfy)
{
	struct nvkm_event *event = ntfy->event;
	unsigned long flags;

	nvkm_trace(event->subdev, "event: ntfy state changed\n");
	spin_lock_irqsave(&event->refs_lock, flags);

	if (atomic_read(&ntfy->allowed) != ntfy->running) {
		if (ntfy->running) {
			nvkm_event_put(ntfy->event, ntfy->bits, ntfy->id);
			ntfy->running = false;
		} else {
			nvkm_event_get(ntfy->event, ntfy->bits, ntfy->id);
			ntfy->running = true;
		}
	}

	spin_unlock_irqrestore(&event->refs_lock, flags);
}

static void
nvkm_event_ntfy_remove(struct nvkm_event_ntfy *ntfy)
{
	write_lock_irq(&ntfy->event->list_lock);
	list_del_init(&ntfy->head);
	write_unlock_irq(&ntfy->event->list_lock);
}

static void
nvkm_event_ntfy_insert(struct nvkm_event_ntfy *ntfy)
{
	write_lock_irq(&ntfy->event->list_lock);
	list_add_tail(&ntfy->head, &ntfy->event->ntfy);
	write_unlock_irq(&ntfy->event->list_lock);
}

static void
nvkm_event_ntfy_block_(struct nvkm_event_ntfy *ntfy, bool wait)
{
	struct nvkm_subdev *subdev = ntfy->event->subdev;

	nvkm_trace(subdev, "event: ntfy block %08x on %d wait:%d\n", ntfy->bits, ntfy->id, wait);

	if (atomic_xchg(&ntfy->allowed, 0) == 1) {
		nvkm_event_ntfy_state(ntfy);
		if (wait)
			nvkm_event_ntfy_remove(ntfy);
	}
}

void
nvkm_event_ntfy_block(struct nvkm_event_ntfy *ntfy)
{
	if (ntfy->event)
		nvkm_event_ntfy_block_(ntfy, ntfy->wait);
}

void
nvkm_event_ntfy_allow(struct nvkm_event_ntfy *ntfy)
{
	nvkm_trace(ntfy->event->subdev, "event: ntfy allow %08x on %d\n", ntfy->bits, ntfy->id);

	if (atomic_xchg(&ntfy->allowed, 1) == 0) {

Annotation

Implementation Notes