drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
Extension
.c
Size
8989 bytes
Lines
332
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 (!ret) {
			iccsense->power_w_max  = entry.avg_w;
			iccsense->power_w_crit = entry.max_w;
		}
	}

	if (nvbios_iccsense_parse(bios, &stbl) || !stbl.nr_entry)
		return 0;

	iccsense->data_valid = true;
	for (i = 0; i < stbl.nr_entry; ++i) {
		struct pwr_rail_t *pwr_rail = &stbl.rail[i];
		struct nvkm_iccsense_sensor *sensor;
		int r;

		if (pwr_rail->mode != 1 || !pwr_rail->resistor_count)
			continue;

		sensor = nvkm_iccsense_get_sensor(iccsense, pwr_rail->extdev_id);
		if (!sensor)
			continue;

		if (!sensor->config)
			sensor->config = pwr_rail->config;
		else if (sensor->config != pwr_rail->config)
			nvkm_error(subdev, "config mismatch found for extdev %i\n", pwr_rail->extdev_id);

		for (r = 0; r < pwr_rail->resistor_count; ++r) {
			struct nvkm_iccsense_rail *rail;
			struct pwr_rail_resistor_t *res = &pwr_rail->resistors[r];
			int (*read)(struct nvkm_iccsense *,
				    struct nvkm_iccsense_rail *);

			if (!res->mohm || !res->enabled)
				continue;

			switch (sensor->type) {
			case NVBIOS_EXTDEV_INA209:
				read = nvkm_iccsense_ina209_read;
				break;
			case NVBIOS_EXTDEV_INA219:
				read = nvkm_iccsense_ina219_read;
				break;
			case NVBIOS_EXTDEV_INA3221:
				read = nvkm_iccsense_ina3221_read;
				break;
			default:
				continue;
			}

			rail = kmalloc_obj(*rail);
			if (!rail)
				return -ENOMEM;

			rail->read = read;
			rail->sensor = sensor;
			rail->idx = r;
			rail->mohm = res->mohm;
			nvkm_debug(subdev, "create rail for extdev %i: { idx: %i, mohm: %i }\n", pwr_rail->extdev_id, r, rail->mohm);
			list_add_tail(&rail->head, &iccsense->rails);
		}
	}
	return 0;
}

static int
nvkm_iccsense_init(struct nvkm_subdev *subdev)
{
	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
	struct nvkm_iccsense_sensor *sensor;
	list_for_each_entry(sensor, &iccsense->sensors, head)
		nvkm_iccsense_sensor_config(iccsense, sensor);
	return 0;
}

static const struct nvkm_subdev_func
iccsense_func = {
	.oneinit = nvkm_iccsense_oneinit,
	.init = nvkm_iccsense_init,
	.dtor = nvkm_iccsense_dtor,
};

void
nvkm_iccsense_ctor(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
		   struct nvkm_iccsense *iccsense)
{
	nvkm_subdev_ctor(&iccsense_func, device, type, inst, &iccsense->subdev);
}

int

Annotation

Implementation Notes