2 * Copyright (c) 2012-2013 NVIDIA CORPORATION. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include <linux/kernel.h>
20 #include <linux/sysfs.h>
21 #include <linux/slab.h>
22 #include <linux/cpuquiet.h>
31 struct cpuquiet_sysfs_attr {
32 struct attribute attr;
33 ssize_t (*show)(char *);
34 ssize_t (*store)(const char *, size_t count);
37 static struct kobject *cpuquiet_global_kobject;
38 struct cpuquiet_dev *cpuquiet_cpu_devices[CONFIG_NR_CPUS];
40 static ssize_t show_current_governor(char *buf)
44 mutex_lock(&cpuquiet_lock);
46 if (cpuquiet_curr_governor)
47 ret = sprintf(buf, "%s\n", cpuquiet_curr_governor->name);
49 ret = sprintf(buf, "none\n");
51 mutex_unlock(&cpuquiet_lock);
57 static ssize_t store_current_governor(const char *buf, size_t count)
59 char name[CPUQUIET_NAME_LEN];
60 struct cpuquiet_governor *gov;
61 int len = count, ret = -EINVAL;
63 if (!len || len >= sizeof(name))
66 memcpy(name, buf, count);
68 if (name[len - 1] == '\n')
71 mutex_lock(&cpuquiet_lock);
72 gov = cpuquiet_find_governor(name);
75 ret = cpuquiet_switch_governor(gov);
76 mutex_unlock(&cpuquiet_lock);
84 static ssize_t available_governors_show(char *buf)
87 struct cpuquiet_governor *gov;
89 mutex_lock(&cpuquiet_lock);
90 if (!list_empty(&cpuquiet_governors)) {
91 list_for_each_entry(gov, &cpuquiet_governors, governor_list) {
92 len = sprintf(buf, "%s ", gov->name);
99 ret = sprintf(buf, "none\n");
101 mutex_unlock(&cpuquiet_lock);
106 struct cpuquiet_sysfs_attr attr_current_governor = __ATTR(current_governor,
107 0644, show_current_governor, store_current_governor);
108 struct cpuquiet_sysfs_attr attr_governors = __ATTR_RO(available_governors);
111 static struct attribute *cpuquiet_default_attrs[] = {
112 &attr_current_governor.attr,
113 &attr_governors.attr,
117 static ssize_t cpuquiet_sysfs_show(struct kobject *kobj,
118 struct attribute *attr, char *buf)
120 struct cpuquiet_sysfs_attr *cattr =
121 container_of(attr, struct cpuquiet_sysfs_attr, attr);
123 return cattr->show(buf);
126 static ssize_t cpuquiet_sysfs_store(struct kobject *kobj,
127 struct attribute *attr, const char *buf, size_t count)
129 struct cpuquiet_sysfs_attr *cattr =
130 container_of(attr, struct cpuquiet_sysfs_attr, attr);
133 return cattr->store(buf, count);
138 static const struct sysfs_ops cpuquiet_sysfs_ops = {
139 .show = cpuquiet_sysfs_show,
140 .store = cpuquiet_sysfs_store,
143 static struct kobj_type ktype_cpuquiet_sysfs = {
144 .sysfs_ops = &cpuquiet_sysfs_ops,
145 .default_attrs = cpuquiet_default_attrs,
148 int cpuquiet_add_group(struct attribute_group *attrs)
150 return sysfs_create_group(cpuquiet_global_kobject, attrs);
153 void cpuquiet_remove_group(struct attribute_group *attrs)
155 sysfs_remove_group(cpuquiet_global_kobject, attrs);
158 int cpuquiet_kobject_init(struct kobject *kobj, struct kobj_type *type,
163 err = kobject_init_and_add(kobj, type, cpuquiet_global_kobject, name);
165 kobject_uevent(kobj, KOBJ_ADD);
170 int cpuquiet_cpu_kobject_init(struct kobject *kobj, struct kobj_type *type,
175 err = kobject_init_and_add(kobj, type, &cpuquiet_cpu_devices[cpu]->kobj,
178 kobject_uevent(kobj, KOBJ_ADD);
183 int cpuquiet_add_interface(struct device *dev)
187 cpuquiet_global_kobject = kzalloc(sizeof(*cpuquiet_global_kobject),
189 if (!cpuquiet_global_kobject)
192 err = kobject_init_and_add(cpuquiet_global_kobject,
193 &ktype_cpuquiet_sysfs, &dev->kobj, "cpuquiet");
195 kobject_uevent(cpuquiet_global_kobject, KOBJ_ADD);
201 struct cpuquiet_attr {
202 struct attribute attr;
203 ssize_t (*show)(unsigned int, char *);
204 ssize_t (*store)(unsigned int, const char *, size_t count);
208 static ssize_t cpuquiet_state_show(struct kobject *kobj,
209 struct attribute *attr, char *buf)
211 struct cpuquiet_attr *cattr = container_of(attr,
212 struct cpuquiet_attr, attr);
213 struct cpuquiet_dev *dev = container_of(kobj,
214 struct cpuquiet_dev, kobj);
216 return cattr->show(dev->cpu, buf);
219 static ssize_t cpuquiet_state_store(struct kobject *kobj,
220 struct attribute *attr, const char *buf, size_t count)
222 struct cpuquiet_attr *cattr = container_of(attr,
223 struct cpuquiet_attr, attr);
224 struct cpuquiet_dev *dev = container_of(kobj,
225 struct cpuquiet_dev, kobj);
228 return cattr->store(dev->cpu, buf, count);
233 static ssize_t show_active(unsigned int cpu, char *buf)
235 return sprintf(buf, "%u\n", cpu_online(cpu));
238 static ssize_t store_active(unsigned int cpu, const char *value, size_t count)
243 if (!cpuquiet_curr_governor->store_active)
246 ret = sscanf(value, "%u", &active);
250 cpuquiet_curr_governor->store_active(cpu, active);
255 struct cpuquiet_attr attr_active = __ATTR(active, 0644, show_active,
258 static struct attribute *cpuquiet_default_cpu_attrs[] = {
263 static const struct sysfs_ops cpuquiet_cpu_sysfs_ops = {
264 .show = cpuquiet_state_show,
265 .store = cpuquiet_state_store,
268 static struct kobj_type ktype_cpuquiet = {
269 .sysfs_ops = &cpuquiet_cpu_sysfs_ops,
270 .default_attrs = cpuquiet_default_cpu_attrs,
273 void cpuquiet_add_dev(struct device *device, unsigned int cpu)
275 struct cpuquiet_dev *dev;
278 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
280 cpuquiet_cpu_devices[cpu] = dev;
281 err = kobject_init_and_add(&dev->kobj, &ktype_cpuquiet,
282 &device->kobj, "cpuquiet");
284 kobject_uevent(&dev->kobj, KOBJ_ADD);
287 void cpuquiet_remove_dev(unsigned int cpu)
289 if (cpu < CONFIG_NR_CPUS && cpuquiet_cpu_devices[cpu])
290 kobject_put(&cpuquiet_cpu_devices[cpu]->kobj);