static ssize_t show_overall_time_in_state(struct kobject *kobj, struct attribute *attr, char *buf) { ssize_t len = 0; int i; unsigned long long cputime = 0; struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, 1); if (stat) cpufreq_stats_update(1); else stat = per_cpu(cpufreq_stats_table, 0); if (!stat) return 0; for (i = 0; i < stat->state_num; i++) { cputime = cputime64_to_clock_t(cpu0_time_in_state[i]); len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], cputime); } for (i = 0; i < stat->state_num; i++) { cputime = cputime64_to_clock_t(cpu1_time_in_state[i]); len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], cputime); } #ifdef CONFIG_QUAD_CORES_SOC_STAT for (i = 0; i < stat->state_num; i++) { cputime = cputime64_to_clock_t(cpu2_time_in_state[i]); len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], cputime); } for (i = 0; i < stat->state_num; i++) { cputime = cputime64_to_clock_t(cpu3_time_in_state[i]); len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], cputime); } #endif return len; }
static int cpufreq_stat_notifier_trans(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; struct cpufreq_stats *stat; int old_index, new_index; if (val != CPUFREQ_POSTCHANGE) return 0; stat = per_cpu(cpufreq_stats_table, freq->cpu); if (!stat) return 0; old_index = stat->last_index; new_index = freq_table_get_index(stat, freq->new); /* We can't do stat->time_in_state[-1]= .. */ if (old_index == -1 || new_index == -1) return 0; cpufreq_stats_update(freq->cpu); if (old_index == new_index) return 0; spin_lock(&cpufreq_stats_lock); stat->last_index = new_index; #ifdef CONFIG_CPU_FREQ_STAT_DETAILS stat->trans_table[old_index * stat->max_state + new_index]++; #endif stat->total_trans++; spin_unlock(&cpufreq_stats_lock); return 0; }
static ssize_t show_bL_all_time_in_state(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { ssize_t len = 0; unsigned int cpu = 0; int i; struct cpufreq_stats *stat; stat = per_cpu(cpufreq_stats_table, cpu); if (!stat) return 0; cpufreq_stats_update(stat->cpu); for (i = 0; i < stat->state_num; i++) { len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], (unsigned long long) cputime64_to_clock_t(stat->time_in_state[i])); } if (!bL_freq_table) { pr_info("%s: bL_freq_table is null!\n", __func__); return len; } for (i = 0; i < bL_freq_table->table_size; i++) { len += sprintf(buf + len, "%u %llu\n", bL_freq_table->freq_table[i], (unsigned long long) cputime64_to_clock_t(bL_freq_table->time_in_state[i])); } return len; }
static int cpufreq_stat_notifier_trans(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; struct cpufreq_stats *stat; int old_index, new_index; if (val != CPUFREQ_POSTCHANGE) return 0; cpufreq_stats_update(freq->cpu); spin_lock(&cpufreq_stats_lock); stat = per_cpu(cpufreq_stats_table, freq->cpu); if (!stat) { spin_unlock(&cpufreq_stats_lock); return 0; } old_index = stat->last_index; new_index = freq_table_get_index(stat, freq->new); if (old_index == -1 || new_index == -1) { spin_unlock(&cpufreq_stats_lock); return 0; } if (old_index == new_index) { spin_unlock(&cpufreq_stats_lock); return 0; } stat->last_index = new_index; #ifdef CONFIG_CPU_FREQ_STAT_DETAILS stat->trans_table[old_index * stat->max_state + new_index]++; #endif stat->total_trans++; #ifdef CONFIG_ARCH_APQ8064 if (freq->cpu == 1) cpu1_total_trans++; if (freq->cpu == 2) cpu2_total_trans++; if (freq->cpu == 3) cpu3_total_trans++; #elif defined(CONFIG_ARCH_MSM8960) if (freq->cpu == 1) cpu1_total_trans++; #endif spin_unlock(&cpufreq_stats_lock); return 0; }
/* should be called late in the CPU removal sequence so that the stats * memory is still available in case someone tries to use it. */ static void cpufreq_stats_free_table(unsigned int cpu) { struct cpufreq_stats *stat = NULL; spin_lock(&cpufreq_stats_lock); stat = per_cpu(cpufreq_stats_table, cpu); per_cpu(cpufreq_stats_table, cpu) = NULL; spin_unlock(&cpufreq_stats_lock); if (stat) { cpufreq_stats_update(cpu); kfree(stat->time_in_state); kfree(stat); } }
static int cpufreq_stat_notifier_trans(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; struct cpufreq_stats *stat; int old_index, new_index; if (val != CPUFREQ_POSTCHANGE) return 0; stat = per_cpu(cpufreq_stats_table, freq->cpu); if (!stat) return 0; old_index = stat->last_index; new_index = freq_table_get_index(stat, freq->new); #if defined (CONFIG_MACH_SAMSUNG_P5) if(cpufreq_stats_update(freq->cpu) < 0) return 0; #else cpufreq_stats_update(freq->cpu); #endif if (old_index == new_index) return 0; spin_lock(&cpufreq_stats_lock); stat->last_index = new_index; #ifdef CONFIG_CPU_FREQ_STAT_DETAILS if (old_index >= 0 && new_index >= 0) stat->trans_table[old_index * stat->max_state + new_index]++; #endif stat->total_trans++; spin_unlock(&cpufreq_stats_lock); return 0; }
static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) { ssize_t len = 0; int i; struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); if (!stat) return 0; cpufreq_stats_update(stat->cpu); for (i = 0; i < stat->state_num; i++) { len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], (unsigned long long) cputime64_to_clock_t(stat->time_in_state[i])); } return len; }
/* should be called late in the CPU removal sequence so that the stats * memory is still available in case someone tries to use it. */ static void cpufreq_stats_free_table(unsigned int cpu) { struct cpufreq_stats *stat = NULL; spin_lock(&cpufreq_stats_lock); stat = per_cpu(cpufreq_stats_table, cpu); per_cpu(cpufreq_stats_table, cpu) = NULL; spin_unlock(&cpufreq_stats_lock); if (stat) { #if defined(CONFIG_ARCH_APQ8064) || defined(CONFIG_ARCH_MSM8960) cpufreq_stats_update(cpu); #endif kfree(stat->time_in_state); kfree(stat); } }
static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) { ssize_t len = 0; int i, j; struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu]; if (!stat) return 0; cpufreq_stats_update(stat->cpu); len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); len += snprintf(buf + len, PAGE_SIZE - len, " : "); for (i = 0; i < stat->state_num; i++) { if (len >= PAGE_SIZE) break; len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", stat->freq_table[i]); } if (len >= PAGE_SIZE) return PAGE_SIZE; len += snprintf(buf + len, PAGE_SIZE - len, "\n"); for (i = 0; i < stat->state_num; i++) { if (len >= PAGE_SIZE) break; len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", stat->freq_table[i]); for (j = 0; j < stat->state_num; j++) { if (len >= PAGE_SIZE) break; len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", stat->trans_table[i*stat->max_state+j]); } if (len >= PAGE_SIZE) break; len += snprintf(buf + len, PAGE_SIZE - len, "\n"); } if (len >= PAGE_SIZE) return PAGE_SIZE; return len; }
static ssize_t show_all_time_in_state(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { ssize_t len = 0; unsigned int i, cpu, freq, index; struct all_cpufreq_stats *all_stat; struct cpufreq_policy *policy; len += scnprintf(buf + len, PAGE_SIZE - len, "freq\t\t"); for_each_possible_cpu(cpu) { len += scnprintf(buf + len, PAGE_SIZE - len, "cpu%d\t\t", cpu); if (cpu_online(cpu)) cpufreq_stats_update(cpu); } if (!all_freq_table) goto out; for (i = 0; i < all_freq_table->table_size; i++) { freq = all_freq_table->freq_table[i]; len += scnprintf(buf + len, PAGE_SIZE - len, "\n%u\t\t", freq); for_each_possible_cpu(cpu) { policy = cpufreq_cpu_get(cpu); if (policy == NULL) continue; all_stat = per_cpu(all_cpufreq_stats, policy->cpu); index = get_index_all_cpufreq_stat(all_stat, freq); if (index != -1) { len += scnprintf(buf + len, PAGE_SIZE - len, "%llu\t\t", (unsigned long long) cputime64_to_clock_t(all_stat->time_in_state[index])); } else { len += scnprintf(buf + len, PAGE_SIZE - len, "N/A\t\t"); } cpufreq_cpu_put(policy); } } out: len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); return len; }