/*
- * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2013 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
#include "cpuquiet.h"
+static struct cpuquiet_driver *cpuquiet_curr_driver;
+
+#ifdef CONFIG_CPUQUIET_STATS
struct cpuquiet_cpu_stat {
cputime64_t time_up_total;
u64 last_update;
struct kobject cpu_kobject;
};
+struct cpuquiet_cpu_stat *stats;
+
struct cpu_attribute {
struct attribute attr;
enum { up_down_count, time_up_total } type;
};
-static struct cpuquiet_driver *cpuquiet_curr_driver;
-struct cpuquiet_cpu_stat *stats;
-
#define CPU_ATTRIBUTE(_name) \
static struct cpu_attribute _name ## _attr = { \
.attr = {.name = __stringify(_name), .mode = 0444 }, \
bool was_up = stat->up_down_count & 0x1;
if (was_up)
- stat->time_up_total = cputime64_add(stat->time_up_total,
- cputime64_sub(cur_jiffies, stat->last_update));
+ stat->time_up_total += cur_jiffies - stat->last_update;
if (was_up != up)
stat->up_down_count++;
stat->last_update = cur_jiffies;
}
-int cpuquiet_quiesence_cpu(unsigned int cpunumber)
-{
- int err = -EPERM;
-
- if (cpuquiet_curr_driver && cpuquiet_curr_driver->quiesence_cpu)
- err = cpuquiet_curr_driver->quiesence_cpu(cpunumber);
-
- stats_update(stats + cpunumber, 0);
-
- return err;
-}
-EXPORT_SYMBOL(cpuquiet_quiesence_cpu);
-
-int cpuquiet_wake_cpu(unsigned int cpunumber)
-{
- int err = -EPERM;
-
- if (cpuquiet_curr_driver && cpuquiet_curr_driver->wake_cpu)
- err = cpuquiet_curr_driver->wake_cpu(cpunumber);
-
- stats_update(stats + cpunumber, 1);
-
- return err;
-}
-EXPORT_SYMBOL(cpuquiet_wake_cpu);
-
static ssize_t stats_sysfs_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
.sysfs_ops = &stats_sysfs_ops,
.default_attrs = cpu_attributes,
};
+#endif
+
+int cpuquiet_quiesence_cpu(unsigned int cpunumber, bool sync)
+{
+ int err = -EPERM;
+
+ if (cpuquiet_curr_driver && cpuquiet_curr_driver->quiesence_cpu)
+ err = cpuquiet_curr_driver->quiesence_cpu(cpunumber, sync);
+
+#ifdef CONFIG_CPUQUIET_STATS
+ if (!err)
+ stats_update(stats + cpunumber, 0);
+#endif
+
+ return err;
+}
+EXPORT_SYMBOL(cpuquiet_quiesence_cpu);
+
+int cpuquiet_wake_cpu(unsigned int cpunumber, bool sync)
+{
+ int err = -EPERM;
+
+ if (cpuquiet_curr_driver && cpuquiet_curr_driver->wake_cpu)
+ err = cpuquiet_curr_driver->wake_cpu(cpunumber, sync);
+
+#ifdef CONFIG_CPUQUIET_STATS
+ if (!err)
+ stats_update(stats + cpunumber, 1);
+#endif
+
+ return err;
+}
+EXPORT_SYMBOL(cpuquiet_wake_cpu);
int cpuquiet_register_driver(struct cpuquiet_driver *drv)
{
int err = -EBUSY;
unsigned int cpu;
- struct sys_device *sys_dev;
- u64 cur_jiffies;
+ struct device *dev;
if (!drv)
return -EINVAL;
+#ifdef CONFIG_CPUQUIET_STATS
stats = kzalloc(nr_cpu_ids * sizeof(*stats), GFP_KERNEL);
if (!stats)
return -ENOMEM;
+#endif
for_each_possible_cpu(cpu) {
- cur_jiffies = get_jiffies_64();
+#ifdef CONFIG_CPUQUIET_STATS
+ u64 cur_jiffies = get_jiffies_64();
stats[cpu].last_update = cur_jiffies;
if (cpu_online(cpu))
stats[cpu].up_down_count = 1;
- sys_dev = get_cpu_sysdev(cpu);
- if (sys_dev) {
- cpuquiet_add_dev(sys_dev, cpu);
+#endif
+ dev = get_cpu_device(cpu);
+ if (dev) {
+ cpuquiet_add_dev(dev, cpu);
+#ifdef CONFIG_CPUQUIET_STATS
cpuquiet_cpu_kobject_init(&stats[cpu].cpu_kobject,
&ktype_cpu_stats, "stats", cpu);
+#endif
}
}
return;
}
- /* stop current governor first */
- cpuquiet_switch_governor(NULL);
-
mutex_lock(&cpuquiet_lock);
+
+ /* Stop current governor first */
+ cpuquiet_switch_governor(NULL);
cpuquiet_curr_driver = NULL;
for_each_possible_cpu(cpu) {
+#ifdef CONFIG_CPUQUIET_STATS
kobject_put(&stats[cpu].cpu_kobject);
+#endif
cpuquiet_remove_dev(cpu);
}