misc: tegra-profiler: send all frequencies
Igor Nabirushkin [Tue, 28 Apr 2015 05:58:51 +0000 (09:58 +0400)]
Send CPU, EMC and GPU frequencies at the start of profiling.
It is needed so that initial frequencies are also displayed
in the profiler GUI.

Bug 1635012

Change-Id: I2e850c846b110da8aa4331ac700a20930da6841b
Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/730895
Reviewed-by: Dmitry Antipov <dantipov@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>

drivers/misc/tegra-profiler/power_clk.c
drivers/misc/tegra-profiler/version.h

index fc31ecc..7af0753 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/misc/tegra-profiler/power_clk.c
  *
- * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2013-2015, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -51,9 +51,7 @@ struct power_clk_source {
        int nr;
        struct power_clk_data data[POWER_CLK_MAX_VALUES];
 
-       unsigned long long counter;
        atomic_t active;
-
        struct mutex lock;
 };
 
@@ -185,10 +183,8 @@ static void check_source(struct power_clk_source *s)
 {
        mutex_lock(&s->lock);
 
-       if (!is_data_changed(s)) {
-               mutex_unlock(&s->lock);
-               return;
-       }
+       if (!is_data_changed(s))
+               goto out_unlock;
 
        pr_debug("cpu: %lu/%lu/%lu/%lu\n",
                 power_ctx.cpu.data[0].value,
@@ -200,6 +196,10 @@ static void check_source(struct power_clk_source *s)
        mutex_unlock(&s->lock);
 
        make_sample();
+       return;
+
+out_unlock:
+       mutex_unlock(&s->lock);
 }
 
 static void
@@ -246,10 +246,9 @@ read_source(struct power_clk_source *s, int cpu)
 
        default:
                pr_err_once("error: invalid power_clk type\n");
-               return;
+               break;
        }
 
-       s->counter++;
        mutex_unlock(&s->lock);
 }
 
@@ -280,18 +279,17 @@ read_cpufreq(struct power_clk_source *s, struct cpufreq_freqs *freq)
 
        mutex_lock(&s->lock);
 
-       if (!atomic_read(&s->active)) {
-               mutex_unlock(&s->lock);
-               return;
-       }
+       if (!atomic_read(&s->active))
+               goto out_unlock;
 
        cpu = freq->cpu;
        cpufreq = freq->new;
 
-       if (cpu >= POWER_CLK_MAX_VALUES) {
+       pr_debug("cpu: %d, cpufreq: %d\n", cpu, cpufreq);
+
+       if (cpu >= s->nr) {
                pr_err_once("error: cpu id: %d\n", cpu);
-               mutex_unlock(&s->lock);
-               return;
+               goto out_unlock;
        }
 
        s->data[cpu].value = cpufreq;
@@ -300,8 +298,11 @@ read_cpufreq(struct power_clk_source *s, struct cpufreq_freqs *freq)
                 cpu, freq->old, cpufreq);
 
        mutex_unlock(&s->lock);
-
        check_source(s);
+       return;
+
+out_unlock:
+       mutex_unlock(&s->lock);
 }
 
 static int
@@ -314,6 +315,8 @@ cpufreq_notifier_call(struct notifier_block *nb,
        if (!atomic_read(&s->active))
                return 0;
 
+       pr_debug("action: %lu\n", action);
+
        if (action == CPUFREQ_POSTCHANGE ||
            action == CPUFREQ_RESUMECHANGE) {
                freq = hcpu;
@@ -332,7 +335,6 @@ static void reset_data(struct power_clk_source *s)
                s->data[i].value = 0;
                s->data[i].prev = 0;
        }
-       atomic_set(s, 0);
        mutex_unlock(&s->lock);
 }
 
@@ -344,8 +346,9 @@ static void init_source(struct power_clk_source *s,
        s->type = type;
        s->nb.notifier_call = notifier;
        s->nr = min_t(int, nr_values, POWER_CLK_MAX_VALUES);
-
+       atomic_set(&s->active, 0);
        mutex_init(&s->lock);
+
        reset_data(s);
 }
 
@@ -369,6 +372,22 @@ static void power_clk_timer(unsigned long data)
        add_timer(timer);
 }
 
+static void
+read_all_sources_work_func(struct work_struct *work)
+{
+       int cpu_id;
+
+       for_each_possible_cpu(cpu_id)
+               read_source(&power_ctx.cpu, cpu_id);
+
+       read_source(&power_ctx.gpu, -1);
+       read_source(&power_ctx.emc, -1);
+
+       check_clks();
+}
+
+static DECLARE_WORK(read_all_sources_work, read_all_sources_work_func);
+
 int quadd_power_clk_start(void)
 {
        struct power_clk_source *s;
@@ -443,6 +462,8 @@ int quadd_power_clk_start(void)
                add_timer(timer);
        }
 
+       schedule_work(&read_all_sources_work);
+
        return 0;
 }
 
@@ -478,9 +499,9 @@ void quadd_power_clk_stop(void)
        mutex_unlock(&s->lock);
 
        s = &power_ctx.cpu;
-       mutex_unlock(&s->lock);
-       atomic_set(&s->active, 0);
        mutex_lock(&s->lock);
+       atomic_set(&s->active, 0);
+       mutex_unlock(&s->lock);
 
        pr_info("power_clk: stop\n");
 }
index b26eb4e..53e1e06 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __QUADD_VERSION_H
 #define __QUADD_VERSION_H
 
-#define QUADD_MODULE_VERSION           "1.100"
+#define QUADD_MODULE_VERSION           "1.101"
 #define QUADD_MODULE_BRANCH            "Dev"
 
 #endif /* __QUADD_VERSION_H */