drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c
Extension
.c
Size
11959 bytes
Lines
398
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

#include "priv.h"
#include <core/falcon.h>
#include <core/firmware.h>
#include <nvfw/fw.h>
#include <nvfw/ls.h>

void
nvkm_acr_lsfw_del(struct nvkm_acr_lsfw *lsfw)
{
	nvkm_blob_dtor(&lsfw->img);
	kfree(lsfw->sigs);
	nvkm_firmware_put(lsfw->sig);
	list_del(&lsfw->head);
	kfree(lsfw);
}

void
nvkm_acr_lsfw_del_all(struct nvkm_acr *acr)
{
	struct nvkm_acr_lsfw *lsfw, *lsft;
	list_for_each_entry_safe(lsfw, lsft, &acr->lsfw, head) {
		nvkm_acr_lsfw_del(lsfw);
	}
}

static struct nvkm_acr_lsfw *
nvkm_acr_lsfw_get(struct nvkm_acr *acr, enum nvkm_acr_lsf_id id)
{
	struct nvkm_acr_lsfw *lsfw;
	list_for_each_entry(lsfw, &acr->lsfw, head) {
		if (lsfw->id == id)
			return lsfw;
	}
	return NULL;
}

struct nvkm_acr_lsfw *
nvkm_acr_lsfw_add(const struct nvkm_acr_lsf_func *func, struct nvkm_acr *acr,
		 struct nvkm_falcon *falcon, enum nvkm_acr_lsf_id id)
{
	struct nvkm_acr_lsfw *lsfw;

	if (!acr || list_empty(&acr->hsfw))
		return ERR_PTR(-ENOSYS);

	lsfw = nvkm_acr_lsfw_get(acr, id);
	if (lsfw && lsfw->func) {
		nvkm_error(&acr->subdev, "LSFW %d redefined\n", id);
		return ERR_PTR(-EEXIST);
	}

	if (!lsfw) {
		if (!(lsfw = kzalloc_obj(*lsfw)))
			return ERR_PTR(-ENOMEM);

		lsfw->id = id;
		list_add_tail(&lsfw->head, &acr->lsfw);
	}

	lsfw->func = func;
	lsfw->falcon = falcon;
	return lsfw;
}

static struct nvkm_acr_lsfw *
nvkm_acr_lsfw_load_sig_image_desc_(struct nvkm_subdev *subdev,
				   struct nvkm_falcon *falcon,
				   enum nvkm_acr_lsf_id id,
				   const char *path, int ver,
				   const struct nvkm_acr_lsf_func *func,
				   const struct firmware **pdesc)
{
	struct nvkm_acr *acr = subdev->device->acr;
	struct nvkm_acr_lsfw *lsfw;
	int ret;

	if (IS_ERR((lsfw = nvkm_acr_lsfw_add(func, acr, falcon, id))))
		return lsfw;

	ret = nvkm_firmware_load_name(subdev, path, "sig", ver, &lsfw->sig);
	if (ret)
		goto done;

	ret = nvkm_firmware_load_blob(subdev, path, "image", ver, &lsfw->img);
	if (ret)
		goto done;

	ret = nvkm_firmware_load_name(subdev, path, "desc", ver, pdesc);
done:
	if (ret) {

Annotation

Implementation Notes