drivers/devfreq/devfreq.c

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

File Facts

System
Linux kernel
Corpus path
drivers/devfreq/devfreq.c
Extension
.c
Size
58911 bytes
Lines
2301
Domain
Driver Families
Bucket
drivers/devfreq
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

* device_add and dev_pm_qos_add_request
	 */
	if (!dev_pm_qos_request_active(&df->user_min_freq_req))
		return -EAGAIN;

	ret = sscanf(buf, "%lu", &value);
	if (ret != 1)
		return -EINVAL;

	/* Round down to kHz for PM QoS */
	ret = dev_pm_qos_update_request(&df->user_min_freq_req,
					value / HZ_PER_KHZ);
	if (ret < 0)
		return ret;

	return count;
}

static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long min_freq, max_freq;

	mutex_lock(&df->lock);
	devfreq_get_freq_range(df, &min_freq, &max_freq);
	mutex_unlock(&df->lock);

	return sprintf(buf, "%lu\n", min_freq);
}
static DEVICE_ATTR_RW(min_freq);

static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long value;
	int ret;

	/*
	 * Protect against theoretical sysfs writes between
	 * device_add and dev_pm_qos_add_request
	 */
	if (!dev_pm_qos_request_active(&df->user_max_freq_req))
		return -EINVAL;

	ret = sscanf(buf, "%lu", &value);
	if (ret != 1)
		return -EINVAL;

	/*
	 * PM QoS frequencies are in kHz so we need to convert. Convert by
	 * rounding upwards so that the acceptable interval never shrinks.
	 *
	 * For example if the user writes "666666666" to sysfs this value will
	 * be converted to 666667 kHz and back to 666667000 Hz before an OPP
	 * lookup, this ensures that an OPP of 666666666Hz is still accepted.
	 *
	 * A value of zero means "no limit".
	 */
	if (value)
		value = DIV_ROUND_UP(value, HZ_PER_KHZ);
	else
		value = PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;

	ret = dev_pm_qos_update_request(&df->user_max_freq_req, value);
	if (ret < 0)
		return ret;

	return count;
}

static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned long min_freq, max_freq;

	mutex_lock(&df->lock);
	devfreq_get_freq_range(df, &min_freq, &max_freq);
	mutex_unlock(&df->lock);

	return sprintf(buf, "%lu\n", max_freq);
}
static DEVICE_ATTR_RW(max_freq);

static ssize_t available_frequencies_show(struct device *d,
					  struct device_attribute *attr,
					  char *buf)
{

Annotation

Implementation Notes