static void enable_callback(struct cpuquiet_attribute *attr)
{
+ int disabled = -1;
+
mutex_lock(tegra3_cpu_lock);
if (!enable && cpq_state != TEGRA_CPQ_DISABLED) {
+ disabled = 1;
cpq_state = TEGRA_CPQ_DISABLED;
- mutex_unlock(tegra3_cpu_lock);
- cancel_delayed_work_sync(&cpuquiet_work);
- pr_info("Tegra cpuquiet clusterswitch disabled\n");
- cpuquiet_device_busy();
- mutex_lock(tegra3_cpu_lock);
} else if (enable && cpq_state == TEGRA_CPQ_DISABLED) {
+ disabled = 0;
cpq_state = TEGRA_CPQ_IDLE;
- pr_info("Tegra cpuquiet clusterswitch enabled\n");
tegra_cpu_set_speed_cap(NULL);
- cpuquiet_device_free();
}
mutex_unlock(tegra3_cpu_lock);
+
+ if (disabled == -1)
+ return;
+
+ if (disabled == 1) {
+ cancel_delayed_work_sync(&cpuquiet_work);
+ pr_info("Tegra cpuquiet clusterswitch disabled\n");
+ cpuquiet_device_busy();
+ } else if (!disabled) {
+ pr_info("Tegra cpuquiet clusterswitch enabled\n");
+ cpuquiet_device_free();
+ }
}
CPQ_BASIC_ATTRIBUTE(no_lp, 0644, bool);
return err;
}
+static void runnables_device_busy(void)
+{
+ if (runnables_state != DISABLED) {
+ runnables_state = DISABLED;
+ cancel_delayed_work_sync(&runnables_work);
+ }
+}
+
+static void runnables_device_free(void)
+{
+ if (runnables_state == DISABLED) {
+ runnables_state = IDLE;
+ runnables_work_func(NULL);
+ }
+}
+
static void runnables_stop(void)
{
runnables_state = DISABLED;
struct cpuquiet_governor runnables_governor = {
.name = "runnable",
.start = runnables_start,
+ .device_free_notification = runnables_device_free,
+ .device_busy_notification = runnables_device_busy,
.stop = runnables_stop,
.owner = THIS_MODULE,
};