drivers/thermal/thermal_sysfs.c

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

File Facts

System
Linux kernel
Corpus path
drivers/thermal/thermal_sysfs.c
Extension
.c
Size
21540 bytes
Lines
881
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 cooling_dev_stats {
	spinlock_t lock;
	unsigned int total_trans;
	unsigned long state;
	ktime_t last_time;
	ktime_t *time_in_state;
	unsigned int *trans_table;
};

static void update_time_in_state(struct cooling_dev_stats *stats)
{
	ktime_t now = ktime_get(), delta;

	delta = ktime_sub(now, stats->last_time);
	stats->time_in_state[stats->state] =
		ktime_add(stats->time_in_state[stats->state], delta);
	stats->last_time = now;
}

void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev,
					 unsigned long new_state)
{
	struct cooling_dev_stats *stats = cdev->stats;

	lockdep_assert_held(&cdev->lock);

	if (!stats)
		return;

	spin_lock(&stats->lock);

	if (stats->state == new_state)
		goto unlock;

	update_time_in_state(stats);
	stats->trans_table[stats->state * (cdev->max_state + 1) + new_state]++;
	stats->state = new_state;
	stats->total_trans++;

unlock:
	spin_unlock(&stats->lock);
}

static ssize_t total_trans_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct thermal_cooling_device *cdev = to_cooling_device(dev);
	struct cooling_dev_stats *stats;
	int ret;

	guard(cooling_dev)(cdev);

	stats = cdev->stats;
	if (!stats)
		return 0;

	spin_lock(&stats->lock);
	ret = sysfs_emit(buf, "%u\n", stats->total_trans);
	spin_unlock(&stats->lock);

	return ret;
}

static ssize_t
time_in_state_ms_show(struct device *dev, struct device_attribute *attr,
		      char *buf)
{
	struct thermal_cooling_device *cdev = to_cooling_device(dev);
	struct cooling_dev_stats *stats;
	ssize_t len = 0;
	int i;

	guard(cooling_dev)(cdev);

	stats = cdev->stats;
	if (!stats)
		return 0;

	spin_lock(&stats->lock);

	update_time_in_state(stats);

	for (i = 0; i <= cdev->max_state; i++) {
		len += sysfs_emit_at(buf, len, "state%u\t%llu\n", i,
				     ktime_to_ms(stats->time_in_state[i]));
	}
	spin_unlock(&stats->lock);

	return len;
}

Annotation

Implementation Notes