Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * sysfs.c - sysfs support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * (C) 2006-2007 Shaohua Li <shaohua.li@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * This code is licenced under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/cpuidle.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/kobject.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "cpuidle.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static ssize_t show_available_governors(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 					struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 					char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	ssize_t i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	struct cpuidle_governor *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	mutex_lock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		if (i >= (ssize_t) (PAGE_SIZE - (CPUIDLE_NAME_LEN + 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		i += scnprintf(&buf[i], CPUIDLE_NAME_LEN + 1, "%s ", tmp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	i+= sprintf(&buf[i], "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	mutex_unlock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static ssize_t show_current_driver(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 				   struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 				   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct cpuidle_driver *drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	spin_lock(&cpuidle_driver_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	drv = cpuidle_get_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		ret = sprintf(buf, "%s\n", drv->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		ret = sprintf(buf, "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	spin_unlock(&cpuidle_driver_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static ssize_t show_current_governor(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 				     struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				     char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	mutex_lock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if (cpuidle_curr_governor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		ret = sprintf(buf, "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	mutex_unlock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static ssize_t store_current_governor(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 				      struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				      const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	char gov_name[CPUIDLE_NAME_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct cpuidle_governor *gov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	ret = sscanf(buf, "%" __stringify(CPUIDLE_NAME_LEN) "s", gov_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	mutex_lock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	list_for_each_entry(gov, &cpuidle_governors, governor_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (!strncmp(gov->name, gov_name, CPUIDLE_NAME_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			ret = cpuidle_switch_governor(gov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	mutex_unlock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static DEVICE_ATTR(available_governors, 0444, show_available_governors, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static DEVICE_ATTR(current_driver, 0444, show_current_driver, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static DEVICE_ATTR(current_governor, 0644, show_current_governor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 				   store_current_governor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static DEVICE_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static struct attribute *cpuidle_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	&dev_attr_available_governors.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	&dev_attr_current_driver.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	&dev_attr_current_governor.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	&dev_attr_current_governor_ro.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static struct attribute_group cpuidle_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	.attrs = cpuidle_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	.name = "cpuidle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * cpuidle_add_interface - add CPU global sysfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * @dev: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int cpuidle_add_interface(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return sysfs_create_group(&dev->kobj, &cpuidle_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * cpuidle_remove_interface - remove CPU global sysfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * @dev: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) void cpuidle_remove_interface(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	sysfs_remove_group(&dev->kobj, &cpuidle_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct cpuidle_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ssize_t (*show)(struct cpuidle_device *, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct cpuidle_device_kobj {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	struct cpuidle_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct completion kobj_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct kobject kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static inline struct cpuidle_device *to_cpuidle_device(struct kobject *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	struct cpuidle_device_kobj *kdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		container_of(kobj, struct cpuidle_device_kobj, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	return kdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static ssize_t cpuidle_show(struct kobject *kobj, struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			    char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	int ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct cpuidle_device *dev = to_cpuidle_device(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (cattr->show) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		mutex_lock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		ret = cattr->show(dev, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		mutex_unlock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static ssize_t cpuidle_store(struct kobject *kobj, struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			     const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	int ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct cpuidle_device *dev = to_cpuidle_device(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (cattr->store) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		mutex_lock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		ret = cattr->store(dev, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		mutex_unlock(&cpuidle_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static const struct sysfs_ops cpuidle_sysfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	.show = cpuidle_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	.store = cpuidle_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void cpuidle_sysfs_release(struct kobject *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	struct cpuidle_device_kobj *kdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		container_of(kobj, struct cpuidle_device_kobj, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	complete(&kdev->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static struct kobj_type ktype_cpuidle = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	.sysfs_ops = &cpuidle_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	.release = cpuidle_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct cpuidle_state_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	struct attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	ssize_t (*show)(struct cpuidle_state *, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 					struct cpuidle_state_usage *, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	ssize_t (*store)(struct cpuidle_state *, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			struct cpuidle_state_usage *, const char *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define define_one_state_ro(_name, show) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define define_one_state_rw(_name, show, store) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define define_show_state_function(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static ssize_t show_state_##_name(struct cpuidle_state *state, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			 struct cpuidle_state_usage *state_usage, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	return sprintf(buf, "%u\n", state->_name);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define define_show_state_ull_function(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static ssize_t show_state_##_name(struct cpuidle_state *state, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 				  struct cpuidle_state_usage *state_usage, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				  char *buf)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	return sprintf(buf, "%llu\n", state_usage->_name);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define define_show_state_str_function(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static ssize_t show_state_##_name(struct cpuidle_state *state, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 				  struct cpuidle_state_usage *state_usage, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				  char *buf)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (state->_name[0] == '\0')\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		return sprintf(buf, "<null>\n");\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	return sprintf(buf, "%s\n", state->_name);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define define_show_state_time_function(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static ssize_t show_state_##_name(struct cpuidle_state *state, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				  struct cpuidle_state_usage *state_usage, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				  char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	return sprintf(buf, "%llu\n", ktime_to_us(state->_name##_ns)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) define_show_state_time_function(exit_latency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) define_show_state_time_function(target_residency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) define_show_state_function(power_usage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) define_show_state_ull_function(usage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) define_show_state_ull_function(rejected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) define_show_state_str_function(name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) define_show_state_str_function(desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) define_show_state_ull_function(above)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) define_show_state_ull_function(below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static ssize_t show_state_time(struct cpuidle_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			       struct cpuidle_state_usage *state_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			       char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	return sprintf(buf, "%llu\n", ktime_to_us(state_usage->time_ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static ssize_t show_state_disable(struct cpuidle_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				  struct cpuidle_state_usage *state_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				  char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return sprintf(buf, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		       state_usage->disable & CPUIDLE_STATE_DISABLED_BY_USER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static ssize_t store_state_disable(struct cpuidle_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 				   struct cpuidle_state_usage *state_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 				   const char *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	err = kstrtouint(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		state_usage->disable |= CPUIDLE_STATE_DISABLED_BY_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		state_usage->disable &= ~CPUIDLE_STATE_DISABLED_BY_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static ssize_t show_state_default_status(struct cpuidle_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 					  struct cpuidle_state_usage *state_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 					  char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		       state->flags & CPUIDLE_FLAG_OFF ? "disabled" : "enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) define_one_state_ro(name, show_state_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) define_one_state_ro(desc, show_state_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) define_one_state_ro(latency, show_state_exit_latency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) define_one_state_ro(residency, show_state_target_residency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) define_one_state_ro(power, show_state_power_usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) define_one_state_ro(usage, show_state_usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) define_one_state_ro(rejected, show_state_rejected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) define_one_state_ro(time, show_state_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) define_one_state_rw(disable, show_state_disable, store_state_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) define_one_state_ro(above, show_state_above);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) define_one_state_ro(below, show_state_below);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) define_one_state_ro(default_status, show_state_default_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static struct attribute *cpuidle_state_default_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	&attr_name.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	&attr_desc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	&attr_latency.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	&attr_residency.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	&attr_power.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	&attr_usage.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	&attr_rejected.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	&attr_time.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	&attr_disable.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	&attr_above.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	&attr_below.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	&attr_default_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct cpuidle_state_kobj {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	struct cpuidle_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	struct cpuidle_state_usage *state_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	struct completion kobj_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	struct kobject kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	struct cpuidle_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #ifdef CONFIG_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #define define_show_state_s2idle_ull_function(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static ssize_t show_state_s2idle_##_name(struct cpuidle_state *state, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 					 struct cpuidle_state_usage *state_usage, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 					 char *buf)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	return sprintf(buf, "%llu\n", state_usage->s2idle_##_name);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) define_show_state_s2idle_ull_function(usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) define_show_state_s2idle_ull_function(time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #define define_one_state_s2idle_ro(_name, show) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static struct cpuidle_state_attr attr_s2idle_##_name = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	__ATTR(_name, 0444, show, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) define_one_state_s2idle_ro(usage, show_state_s2idle_usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) define_one_state_s2idle_ro(time, show_state_s2idle_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static struct attribute *cpuidle_state_s2idle_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	&attr_s2idle_usage.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	&attr_s2idle_time.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static const struct attribute_group cpuidle_state_s2idle_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	.name	= "s2idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	.attrs	= cpuidle_state_s2idle_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (!kobj->state->enter_s2idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	ret = sysfs_create_group(&kobj->kobj, &cpuidle_state_s2idle_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		pr_debug("%s: sysfs attribute group not created\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	if (kobj->state->enter_s2idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		sysfs_remove_group(&kobj->kobj, &cpuidle_state_s2idle_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static inline void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static inline void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) #endif /* CONFIG_SUSPEND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) #define kobj_to_state(k) (kobj_to_state_obj(k)->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #define kobj_to_device(k) (kobj_to_state_obj(k)->device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static ssize_t cpuidle_state_show(struct kobject *kobj, struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				  char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	int ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	struct cpuidle_state *state = kobj_to_state(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	if (cattr->show)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		ret = cattr->show(state, state_usage, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static ssize_t cpuidle_state_store(struct kobject *kobj, struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 				   const char *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	int ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	struct cpuidle_state *state = kobj_to_state(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	struct cpuidle_device *dev = kobj_to_device(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (cattr->store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		ret = cattr->store(state, state_usage, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	/* reset poll time cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	dev->poll_limit_ns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static const struct sysfs_ops cpuidle_state_sysfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	.show = cpuidle_state_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	.store = cpuidle_state_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static void cpuidle_state_sysfs_release(struct kobject *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	complete(&state_obj->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static struct kobj_type ktype_state_cpuidle = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	.sysfs_ops = &cpuidle_state_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	.default_attrs = cpuidle_state_default_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	.release = cpuidle_state_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	cpuidle_remove_s2idle_attr_group(device->kobjs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	kobject_put(&device->kobjs[i]->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	wait_for_completion(&device->kobjs[i]->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	kfree(device->kobjs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	device->kobjs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)  * cpuidle_add_state_sysfs - adds cpuidle states sysfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)  * @device: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int cpuidle_add_state_sysfs(struct cpuidle_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	int i, ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct cpuidle_state_kobj *kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	struct cpuidle_device_kobj *kdev = device->kobj_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	/* state statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	for (i = 0; i < drv->state_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (!kobj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			goto error_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		kobj->state = &drv->states[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		kobj->state_usage = &device->states_usage[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		kobj->device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		init_completion(&kobj->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 					   &kdev->kobj, "state%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			kobject_put(&kobj->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			kfree(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			goto error_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		cpuidle_add_s2idle_attr_group(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		kobject_uevent(&kobj->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		device->kobjs[i] = kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) error_state:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	for (i = i - 1; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		cpuidle_free_state_kobj(device, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)  * cpuidle_remove_driver_sysfs - removes the cpuidle states sysfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)  * @device: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	for (i = 0; i < drv->state_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		cpuidle_free_state_kobj(device, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #define kobj_to_driver_kobj(k) container_of(k, struct cpuidle_driver_kobj, kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #define attr_to_driver_attr(a) container_of(a, struct cpuidle_driver_attr, attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) #define define_one_driver_ro(_name, show)                       \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	static struct cpuidle_driver_attr attr_driver_##_name = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		__ATTR(_name, 0444, show, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct cpuidle_driver_kobj {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	struct cpuidle_driver *drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	struct completion kobj_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	struct kobject kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct cpuidle_driver_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	struct attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	ssize_t (*show)(struct cpuidle_driver *, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	ssize_t (*store)(struct cpuidle_driver *, const char *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static ssize_t show_driver_name(struct cpuidle_driver *drv, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	spin_lock(&cpuidle_driver_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	ret = sprintf(buf, "%s\n", drv ? drv->name : "none");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	spin_unlock(&cpuidle_driver_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static void cpuidle_driver_sysfs_release(struct kobject *kobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	complete(&driver_kobj->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 				   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	int ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	if (dattr->show)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		ret = dattr->show(driver_kobj->drv, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static ssize_t cpuidle_driver_store(struct kobject *kobj, struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 				    const char *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	int ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	if (dattr->store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		ret = dattr->store(driver_kobj->drv, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) define_one_driver_ro(name, show_driver_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static const struct sysfs_ops cpuidle_driver_sysfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	.show = cpuidle_driver_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	.store = cpuidle_driver_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static struct attribute *cpuidle_driver_default_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	&attr_driver_name.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static struct kobj_type ktype_driver_cpuidle = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	.sysfs_ops = &cpuidle_driver_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	.default_attrs = cpuidle_driver_default_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	.release = cpuidle_driver_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)  * cpuidle_add_driver_sysfs - adds the driver name sysfs attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)  * @dev: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	struct cpuidle_driver_kobj *kdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	struct cpuidle_device_kobj *kdev = dev->kobj_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	kdrv = kzalloc(sizeof(*kdrv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	if (!kdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	kdrv->drv = drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	init_completion(&kdrv->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 				   &kdev->kobj, "driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		kobject_put(&kdrv->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		kfree(kdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	kobject_uevent(&kdrv->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	dev->kobj_driver = kdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)  * cpuidle_remove_driver_sysfs - removes the driver name sysfs attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)  * @dev: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	struct cpuidle_driver_kobj *kdrv = dev->kobj_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	kobject_put(&kdrv->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	wait_for_completion(&kdrv->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	kfree(kdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static inline int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static inline void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  * cpuidle_add_device_sysfs - adds device specific sysfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  * @device: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int cpuidle_add_device_sysfs(struct cpuidle_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	ret = cpuidle_add_state_sysfs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	ret = cpuidle_add_driver_sysfs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		cpuidle_remove_state_sysfs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)  * cpuidle_remove_device_sysfs : removes device specific sysfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)  * @device : the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) void cpuidle_remove_device_sysfs(struct cpuidle_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	cpuidle_remove_driver_sysfs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	cpuidle_remove_state_sysfs(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)  * cpuidle_add_sysfs - creates a sysfs instance for the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)  * @dev: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int cpuidle_add_sysfs(struct cpuidle_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	struct cpuidle_device_kobj *kdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	 * Return if cpu_device is not setup for this CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	 * This could happen if the arch did not set up cpu_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	 * since this CPU is not in cpu_present mask and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	 * driver did not send a correct CPU mask during registration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	 * Without this check we would end up passing bogus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	 * value for &cpu_dev->kobj in kobject_init_and_add()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	if (!cpu_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (!kdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	kdev->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	init_completion(&kdev->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 				   "cpuidle");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		kobject_put(&kdev->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		kfree(kdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	dev->kobj_dev = kdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	kobject_uevent(&kdev->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)  * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)  * @dev: the target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) void cpuidle_remove_sysfs(struct cpuidle_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	struct cpuidle_device_kobj *kdev = dev->kobj_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	kobject_put(&kdev->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	wait_for_completion(&kdev->kobj_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	kfree(kdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }