drivers/powercap/powercap_sys.c

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

File Facts

System
Linux kernel
Corpus path
drivers/powercap/powercap_sys.c
Extension
.c
Size
18997 bytes
Lines
685
Domain
Driver Families
Bucket
drivers/powercap
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 powercap_constraint_attr {
	struct device_attribute power_limit_attr;
	struct device_attribute time_window_attr;
	struct device_attribute max_power_attr;
	struct device_attribute min_power_attr;
	struct device_attribute max_time_window_attr;
	struct device_attribute min_time_window_attr;
	struct device_attribute name_attr;
};

static struct powercap_constraint_attr
				constraint_attrs[MAX_CONSTRAINTS_PER_ZONE];

/* A list of powercap control_types */
static LIST_HEAD(powercap_cntrl_list);
/* Mutex to protect list of powercap control_types */
static DEFINE_MUTEX(powercap_cntrl_list_lock);

#define POWERCAP_CONSTRAINT_NAME_LEN	30 /* Some limit to avoid overflow */
static ssize_t show_constraint_name(struct device *dev,
				struct device_attribute *dev_attr,
				char *buf)
{
	const char *name;
	struct powercap_zone *power_zone = to_powercap_zone(dev);
	int id;
	ssize_t len = -ENODATA;
	struct powercap_zone_constraint *pconst;

	if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1)
		return -EINVAL;
	if (id >= power_zone->const_id_cnt)
		return -EINVAL;
	pconst = &power_zone->constraints[id];

	if (pconst && pconst->ops && pconst->ops->get_name) {
		name = pconst->ops->get_name(power_zone, id);
		if (name) {
			len = sysfs_emit(buf, "%.*s\n",
					 POWERCAP_CONSTRAINT_NAME_LEN - 1, name);
		}
	}

	return len;
}

static int create_constraint_attribute(int id, const char *name,
				int mode,
				struct device_attribute *dev_attr,
				ssize_t (*show)(struct device *,
					struct device_attribute *, char *),
				ssize_t (*store)(struct device *,
					struct device_attribute *,
				const char *, size_t)
				)
{

	dev_attr->attr.name = kasprintf(GFP_KERNEL, "constraint_%d_%s",
								id, name);
	if (!dev_attr->attr.name)
		return -ENOMEM;
	dev_attr->attr.mode = mode;
	dev_attr->show = show;
	dev_attr->store = store;

	return 0;
}

static void free_constraint_attributes(void)
{
	int i;

	for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) {
		kfree(constraint_attrs[i].power_limit_attr.attr.name);
		kfree(constraint_attrs[i].time_window_attr.attr.name);
		kfree(constraint_attrs[i].name_attr.attr.name);
		kfree(constraint_attrs[i].max_power_attr.attr.name);
		kfree(constraint_attrs[i].min_power_attr.attr.name);
		kfree(constraint_attrs[i].max_time_window_attr.attr.name);
		kfree(constraint_attrs[i].min_time_window_attr.attr.name);
	}
}

static int seed_constraint_attributes(void)
{
	int i;
	int ret;

	for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) {
		ret = create_constraint_attribute(i, "power_limit_uw",

Annotation

Implementation Notes