drivers/thermal/thermal_hwmon.c

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

File Facts

System
Linux kernel
Corpus path
drivers/thermal/thermal_hwmon.c
Extension
.c
Size
4959 bytes
Lines
202
Domain
Driver Families
Bucket
drivers/thermal
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 thermal_hwmon_device {
	char name[THERMAL_HWMON_NAME_LENGTH];
	struct device *device;
	struct list_head node;
	struct thermal_zone_device *tz;
};

static LIST_HEAD(thermal_hwmon_list);

static DEFINE_MUTEX(thermal_hwmon_list_lock);

static ssize_t
temp1_input_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
	struct thermal_zone_device *tz = hwmon->tz;
	int temperature;
	int ret;

	ret = thermal_zone_get_temp(tz, &temperature);
	if (ret)
		return ret;

	return sysfs_emit(buf, "%d\n", temperature);
}

static ssize_t
temp1_crit_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
	struct thermal_zone_device *tz = hwmon->tz;
	int temperature;
	int ret;

	guard(thermal_zone)(tz);

	ret = tz->ops.get_crit_temp(tz, &temperature);
	if (ret)
		return ret;

	return sysfs_emit(buf, "%d\n", temperature);
}

static DEVICE_ATTR_RO(temp1_input);
static DEVICE_ATTR_RO(temp1_crit);

static struct attribute *thermal_hwmon_attrs[] = {
	&dev_attr_temp1_input.attr,
	&dev_attr_temp1_crit.attr,
	NULL,
};

static umode_t thermal_hwmon_attr_is_visible(struct kobject *kobj,
					     struct attribute *a, int n)
{
	if (a == &dev_attr_temp1_input.attr)
		return a->mode;

	if (a == &dev_attr_temp1_crit.attr) {
		struct thermal_hwmon_device *hwmon = dev_get_drvdata(kobj_to_dev(kobj));
		struct thermal_zone_device *tz = hwmon->tz;
		int dummy;

		if (tz->ops.get_crit_temp && !tz->ops.get_crit_temp(tz, &dummy))
			return a->mode;
	}

	return 0;
}

static const struct attribute_group thermal_hwmon_group = {
	.attrs	= thermal_hwmon_attrs,
	.is_visible = thermal_hwmon_attr_is_visible,
};

__ATTRIBUTE_GROUPS(thermal_hwmon);

int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
{
	struct thermal_hwmon_device *hwmon;

	hwmon = kzalloc_obj(*hwmon);
	if (!hwmon)
		return -ENOMEM;

	hwmon->tz = tz;
	/*
	 * Append the thermal zone ID preceded by an underline character to the
	 * type to disambiguate the sensors command output.
	 */

Annotation

Implementation Notes