drivers/thermal/tegra/tegra-bpmp-thermal.c

Source file repositories/reference/linux-study-clean/drivers/thermal/tegra/tegra-bpmp-thermal.c

File Facts

System
Linux kernel
Corpus path
drivers/thermal/tegra/tegra-bpmp-thermal.c
Extension
.c
Size
8068 bytes
Lines
329
Domain
Driver Families
Bucket
drivers/thermal
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

struct tegra_bpmp_thermal_zone {
	struct tegra_bpmp_thermal *tegra;
	struct thermal_zone_device *tzd;
	struct work_struct tz_device_update_work;
	unsigned int idx;
};

struct tegra_bpmp_thermal {
	struct device *dev;
	struct tegra_bpmp *bpmp;
	unsigned int num_zones;
	struct tegra_bpmp_thermal_zone **zones;
};

static int __tegra_bpmp_thermal_get_temp(struct tegra_bpmp_thermal_zone *zone,
					 int *out_temp)
{
	struct mrq_thermal_host_to_bpmp_request req;
	union mrq_thermal_bpmp_to_host_response reply;
	struct tegra_bpmp_message msg;
	int err;

	memset(&req, 0, sizeof(req));
	req.type = CMD_THERMAL_GET_TEMP;
	req.get_temp.zone = zone->idx;

	memset(&msg, 0, sizeof(msg));
	msg.mrq = MRQ_THERMAL;
	msg.tx.data = &req;
	msg.tx.size = sizeof(req);
	msg.rx.data = &reply;
	msg.rx.size = sizeof(reply);

	err = tegra_bpmp_transfer(zone->tegra->bpmp, &msg);
	if (err)
		return err;
	if (msg.rx.ret == -BPMP_EFAULT)
		return -EAGAIN;
	if (msg.rx.ret)
		return -EINVAL;

	*out_temp = reply.get_temp.temp;

	return 0;
}

static int tegra_bpmp_thermal_get_temp(struct thermal_zone_device *tz, int *out_temp)
{
	struct tegra_bpmp_thermal_zone *zone = thermal_zone_device_priv(tz);

	return __tegra_bpmp_thermal_get_temp(zone, out_temp);
}

static int tegra_bpmp_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)
{
	struct tegra_bpmp_thermal_zone *zone = thermal_zone_device_priv(tz);
	struct mrq_thermal_host_to_bpmp_request req;
	struct tegra_bpmp_message msg;
	int err;

	memset(&req, 0, sizeof(req));
	req.type = CMD_THERMAL_SET_TRIP;
	req.set_trip.zone = zone->idx;
	req.set_trip.enabled = true;
	req.set_trip.low = low;
	req.set_trip.high = high;

	memset(&msg, 0, sizeof(msg));
	msg.mrq = MRQ_THERMAL;
	msg.tx.data = &req;
	msg.tx.size = sizeof(req);

	err = tegra_bpmp_transfer(zone->tegra->bpmp, &msg);
	if (err)
		return err;
	if (msg.rx.ret)
		return -EINVAL;

	return 0;
}

static void tz_device_update_work_fn(struct work_struct *work)
{
	struct tegra_bpmp_thermal_zone *zone;

	zone = container_of(work, struct tegra_bpmp_thermal_zone,
			    tz_device_update_work);

	thermal_zone_device_update(zone->tzd, THERMAL_TRIP_VIOLATED);
}

Annotation

Implementation Notes