drivers/acpi/fan_hwmon.c

Source file repositories/reference/linux-study-clean/drivers/acpi/fan_hwmon.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/fan_hwmon.c
Extension
.c
Size
3867 bytes
Lines
181
Domain
Driver Families
Bucket
drivers/acpi
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

switch (attr) {
		case hwmon_fan_input:
			return 0444;
		case hwmon_fan_target:
			/* Only acpi4 fans support fan control. */
			if (!fan->acpi4)
				return 0;

			/*
			 * When in fine grain control mode, not every fan control value
			 * has an associated fan performance state.
			 */
			if (fan->fif.fine_grain_ctrl)
				return 0;

			return 0444;
		default:
			return 0;
		}
	case hwmon_power:
		switch (attr) {
		case hwmon_power_input:
			/* Only acpi4 fans support fan control. */
			if (!fan->acpi4)
				return 0;

			/*
			 * When in fine grain control mode, not every fan control value
			 * has an associated fan performance state.
			 */
			if (fan->fif.fine_grain_ctrl)
				return 0;

			/*
			 * When all fan performance states contain no valid power data,
			 * when the associated attribute should not be created.
			 */
			for (i = 0; i < fan->fps_count; i++) {
				if (acpi_fan_power_valid(fan->fps[i].power))
					return 0444;
			}

			return 0;
		default:
			return 0;
		}
	default:
		return 0;
	}
}

static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
			       int channel, long *val)
{
	struct acpi_fan *fan = dev_get_drvdata(dev);
	struct acpi_fan_fps *fps;
	struct acpi_fan_fst fst;
	int ret;

	ret = acpi_fan_get_fst(fan->handle, &fst);
	if (ret < 0)
		return ret;

	switch (type) {
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_input:
			if (!acpi_fan_speed_valid(fst.speed))
				return -ENODEV;

			if (fst.speed > LONG_MAX)
				return -EOVERFLOW;

			*val = fst.speed;
			return 0;
		case hwmon_fan_target:
			fps = acpi_fan_get_current_fps(fan, fst.control);
			if (!fps)
				return -EIO;

			if (fps->speed > LONG_MAX)
				return -EOVERFLOW;

			*val = fps->speed;
			return 0;
		default:
			return -EOPNOTSUPP;
		}
	case hwmon_power:
		switch (attr) {

Annotation

Implementation Notes