drivers/cpuidle/sysfs.c

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

File Facts

System
Linux kernel
Corpus path
drivers/cpuidle/sysfs.c
Extension
.c
Size
19621 bytes
Lines
748
Domain
Driver Families
Bucket
drivers/cpuidle
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 cpuidle_attr {
	struct attribute attr;
	ssize_t (*show)(struct cpuidle_device *, char *);
	ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
};

#define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)

struct cpuidle_device_kobj {
	struct cpuidle_device *dev;
	struct completion kobj_unregister;
	struct kobject kobj;
};

static inline struct cpuidle_device *to_cpuidle_device(struct kobject *kobj)
{
	struct cpuidle_device_kobj *kdev =
		container_of(kobj, struct cpuidle_device_kobj, kobj);

	return kdev->dev;
}

static ssize_t cpuidle_show(struct kobject *kobj, struct attribute *attr,
			    char *buf)
{
	int ret = -EIO;
	struct cpuidle_device *dev = to_cpuidle_device(kobj);
	struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);

	if (cattr->show) {
		mutex_lock(&cpuidle_lock);
		ret = cattr->show(dev, buf);
		mutex_unlock(&cpuidle_lock);
	}
	return ret;
}

static ssize_t cpuidle_store(struct kobject *kobj, struct attribute *attr,
			     const char *buf, size_t count)
{
	int ret = -EIO;
	struct cpuidle_device *dev = to_cpuidle_device(kobj);
	struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);

	if (cattr->store) {
		mutex_lock(&cpuidle_lock);
		ret = cattr->store(dev, buf, count);
		mutex_unlock(&cpuidle_lock);
	}
	return ret;
}

static const struct sysfs_ops cpuidle_sysfs_ops = {
	.show = cpuidle_show,
	.store = cpuidle_store,
};

static void cpuidle_sysfs_release(struct kobject *kobj)
{
	struct cpuidle_device_kobj *kdev =
		container_of(kobj, struct cpuidle_device_kobj, kobj);

	complete(&kdev->kobj_unregister);
}

static const struct kobj_type ktype_cpuidle = {
	.sysfs_ops = &cpuidle_sysfs_ops,
	.release = cpuidle_sysfs_release,
};

struct cpuidle_state_attr {
	struct attribute attr;
	ssize_t (*show)(struct cpuidle_state *, \
					struct cpuidle_state_usage *, char *);
	ssize_t (*store)(struct cpuidle_state *, \
			struct cpuidle_state_usage *, const char *, size_t);
};

#define define_one_state_ro(_name, show) \
static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)

#define define_one_state_rw(_name, show, store) \
static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store)

#define define_show_state_function(_name) \
static ssize_t show_state_##_name(struct cpuidle_state *state, \
			 struct cpuidle_state_usage *state_usage, char *buf) \
{ \
	return sysfs_emit(buf, "%u\n", state->_name);\
}

Annotation

Implementation Notes