-obj-$(CONFIG_CPUQUIET_FRAMEWORK) += cpuquiet.o driver.o sysfs.o governor.o governors/
+obj-$(CONFIG_CPUQUIET_FRAMEWORK) += cpuquiet.o driver.o sysfs.o cpuquiet_attribute.o governor.o governors/
--- /dev/null
+/*
+ * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/cpuquiet.h>
+
+ssize_t show_int_attribute(struct cpuquiet_attribute *cattr, char *buf)
+{
+ return sprintf(buf, "%d\n", *((int *)cattr->param));
+}
+
+ssize_t store_int_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count)
+{
+ int err, val;
+
+ err = kstrtoint(buf, 0, &val);
+ if (err < 0)
+ return err;
+
+ *((int *)(cattr->param)) = val;
+
+ if (cattr->store_callback)
+ cattr->store_callback(cattr);
+
+ return count;
+}
+
+ssize_t show_bool_attribute(struct cpuquiet_attribute *cattr, char *buf)
+{
+ return sprintf(buf, "%d\n", *((bool *)cattr->param));
+}
+
+ssize_t store_bool_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count)
+{
+ int err, val;
+
+ err = kstrtoint(buf, 0, &val);
+ if (err < 0)
+ return err;
+
+ if (val < 0 || val > 1)
+ return -EINVAL;
+
+ *((bool *)(cattr->param)) = val;
+
+ if (cattr->store_callback)
+ cattr->store_callback(cattr);
+
+ return count;
+}
+
+ssize_t show_uint_attribute(struct cpuquiet_attribute *cattr, char *buf)
+{
+ return sprintf(buf, "%u\n", *((unsigned int *)cattr->param));
+}
+
+ssize_t store_uint_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned int val;
+
+ err = kstrtouint(buf, 0, &val);
+ if (err < 0)
+ return err;
+
+ *((unsigned int *)(cattr->param)) = val;
+
+ if (cattr->store_callback)
+ cattr->store_callback(cattr);
+
+ return count;
+}
+
+ssize_t store_ulong_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count)
+{
+ int err;
+ unsigned long val;
+
+ err = kstrtoul(buf, 0, &val);
+ if (err < 0)
+ return err;
+
+ *((unsigned long *)(cattr->param)) = val;
+
+ if (cattr->store_callback)
+ cattr->store_callback(cattr);
+
+ return count;
+}
+
+ssize_t show_ulong_attribute(struct cpuquiet_attribute *cattr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", *((unsigned long *)cattr->param));
+}
+
+ssize_t cpuquiet_auto_sysfs_store(struct kobject *kobj,
+ struct attribute *attr, const char *buf, size_t count)
+{
+ struct cpuquiet_attribute *cattr =
+ container_of(attr, struct cpuquiet_attribute, attr);
+
+ if (cattr->store)
+ return cattr->store(cattr, buf, count);
+
+ return -EINVAL;
+}
+
+ssize_t cpuquiet_auto_sysfs_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct cpuquiet_attribute *cattr =
+ container_of(attr, struct cpuquiet_attribute, attr);
+
+ return cattr->show(cattr, buf);
+}
static struct timer_list load_timer;
static bool load_timer_active;
-struct balanced_attribute {
- struct attribute attr;
- ssize_t (*show)(struct balanced_attribute *attr, char *buf);
- ssize_t (*store)(struct balanced_attribute *attr, const char *buf,
- size_t count);
- unsigned long *param;
-};
-
-#define BALANCED_ATTRIBUTE(_name, _mode) \
- static struct balanced_attribute _name ## _attr = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
- .show = show_attribute, \
- .store = store_attribute, \
- .param = &_name, \
-}
/* configurable parameters */
-static unsigned long balance_level = 60;
-static unsigned long idle_bottom_freq;
-static unsigned long idle_top_freq;
+static unsigned int balance_level = 60;
+static unsigned int idle_bottom_freq;
+static unsigned int idle_top_freq;
static unsigned long up_delay;
static unsigned long down_delay;
static unsigned long last_change_time;
-static unsigned long load_sample_rate = 20; // msec
+static unsigned int load_sample_rate = 20; /* msec */
static struct workqueue_struct *balanced_wq;
static struct delayed_work balanced_work;
static BALANCED_STATE balanced_state;
.notifier_call = balanced_cpufreq_transition,
};
-static ssize_t show_attribute(struct balanced_attribute *battr, char *buf)
-{
- return sprintf(buf, "%lu\n", *(battr->param));
-}
-
-static ssize_t store_attribute(struct balanced_attribute *battr,
- const char *buf, size_t count)
+static void delay_callback(struct cpuquiet_attribute *attr)
{
- int err;
unsigned long val;
- err = strict_strtoul(buf, 0, &val);
- if (err < 0)
- return err;
-
- *(battr->param) = val;
-
- return count;
-}
-
-static ssize_t balanced_sysfs_store(struct kobject *kobj,
- struct attribute *attr, const char *buf, size_t count)
-{
- struct balanced_attribute *battr =
- container_of(attr, struct balanced_attribute, attr);
-
- if (battr->store)
- return battr->store(battr, buf, count);
-
- return -EINVAL;
-}
-
-static ssize_t balanced_sysfs_show(struct kobject *kobj,
- struct attribute *attr, char *buf)
-{
- struct balanced_attribute *battr =
- container_of(attr, struct balanced_attribute, attr);
-
- return battr->show(battr, buf);
+ if (attr) {
+ val = (*((unsigned long *)(attr->param)));
+ (*((unsigned long *)(attr->param))) = msecs_to_jiffies(val);
+ }
}
-BALANCED_ATTRIBUTE(balance_level, 0644);
-BALANCED_ATTRIBUTE(idle_bottom_freq, 0644);
-BALANCED_ATTRIBUTE(idle_top_freq, 0644);
-BALANCED_ATTRIBUTE(up_delay, 0644);
-BALANCED_ATTRIBUTE(down_delay, 0644);
-BALANCED_ATTRIBUTE(load_sample_rate, 0644);
+CPQ_BASIC_ATTRIBUTE(balance_level, 0644, uint);
+CPQ_BASIC_ATTRIBUTE(idle_bottom_freq, 0644, uint);
+CPQ_BASIC_ATTRIBUTE(idle_top_freq, 0644, uint);
+CPQ_BASIC_ATTRIBUTE(load_sample_rate, 0644, uint);
+CPQ_ATTRIBUTE(up_delay, 0644, ulong, delay_callback);
+CPQ_ATTRIBUTE(down_delay, 0644, ulong, delay_callback);
static struct attribute *balanced_attributes[] = {
&balance_level_attr.attr,
};
static const struct sysfs_ops balanced_sysfs_ops = {
- .show = balanced_sysfs_show,
- .store = balanced_sysfs_store,
+ .show = cpuquiet_auto_sysfs_show,
+ .store = cpuquiet_auto_sysfs_store,
};
static struct kobj_type ktype_balanced = {
static void balanced_stop(void)
{
-
/*
first unregister the notifiers. This ensures the governor state
can't be modified by a cpufreq transition
down_delay = msecs_to_jiffies(500);
table = cpufreq_frequency_get_table(0);
- for (count = 0; table[count].frequency != CPUFREQ_TABLE_END; count++)
- ;
+ for (count = 0; table[count].frequency != CPUFREQ_TABLE_END; count++);
idle_top_freq = table[(count / 2) - 1].frequency;
idle_bottom_freq = table[(count / 2) - 2].frequency;
int cpuquiet_kobject_init(struct kobject *kobj, struct kobj_type *type,
char *name);
extern unsigned int nr_cluster_ids;
+
+/* Sysfs support */
+struct cpuquiet_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct cpuquiet_attribute *attr, char *buf);
+ ssize_t (*store)(struct cpuquiet_attribute *attr, const char *buf,
+ size_t count);
+ /* Optional. Called after store is called */
+ void (*store_callback)(struct cpuquiet_attribute *attr);
+ void *param;
+};
+
+#define CPQ_ATTRIBUTE(_name, _mode, _type, _callback) \
+ static struct cpuquiet_attribute _name ## _attr = { \
+ .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .show = show_ ## _type ## _attribute, \
+ .store = store_ ## _type ## _attribute, \
+ .store_callback = _callback, \
+ .param = &_name, \
+}
+
+#define CPQ_BASIC_ATTRIBUTE(_name, _mode, _type) \
+ CPQ_ATTRIBUTE(_name, _mode, _type, NULL)
+
+#define CPQ_ATTRIBUTE_CUSTOM(_name, _mode, _show, _store) \
+ static struct cpuquiet_attribute _name ## _attr = { \
+ .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .show = _show, \
+ .store = _store \
+ .store_callback = NULL, \
+ .param = &_name, \
+}
+
+
+extern ssize_t show_int_attribute(struct cpuquiet_attribute *cattr, char *buf);
+extern ssize_t store_int_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count);
+extern ssize_t show_bool_attribute(struct cpuquiet_attribute *cattr, char *buf);
+extern ssize_t store_bool_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count);
+extern ssize_t store_uint_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count);
+extern ssize_t show_uint_attribute(struct cpuquiet_attribute *cattr, char *buf);
+extern ssize_t store_ulong_attribute(struct cpuquiet_attribute *cattr,
+ const char *buf, size_t count);
+extern ssize_t show_ulong_attribute(struct cpuquiet_attribute *cattr,
+ char *buf);
+extern ssize_t cpuquiet_auto_sysfs_show(struct kobject *kobj,
+ struct attribute *attr, char *buf);
+extern ssize_t cpuquiet_auto_sysfs_store(struct kobject *kobj,
+ struct attribute *attr, const char *buf,
+ size_t count);
#endif