|  | /* | 
|  | *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de> | 
|  | * | 
|  | *  Licensed under the terms of the GNU GPL License version 2. | 
|  | */ | 
|  |  | 
|  |  | 
|  | #include <unistd.h> | 
|  | #include <stdio.h> | 
|  | #include <errno.h> | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  |  | 
|  | #include <getopt.h> | 
|  |  | 
|  | #include "cpufreq.h" | 
|  | #include "helpers/helpers.h" | 
|  | #include "helpers/bitmask.h" | 
|  |  | 
|  | #define LINE_LEN 10 | 
|  |  | 
|  | static unsigned int count_cpus(void) | 
|  | { | 
|  | FILE *fp; | 
|  | char value[LINE_LEN]; | 
|  | unsigned int ret = 0; | 
|  | unsigned int cpunr = 0; | 
|  |  | 
|  | fp = fopen("/proc/stat", "r"); | 
|  | if (!fp) { | 
|  | printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno)); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | while (!feof(fp)) { | 
|  | if (!fgets(value, LINE_LEN, fp)) | 
|  | continue; | 
|  | value[LINE_LEN - 1] = '\0'; | 
|  | if (strlen(value) < (LINE_LEN - 2)) | 
|  | continue; | 
|  | if (strstr(value, "cpu ")) | 
|  | continue; | 
|  | if (sscanf(value, "cpu%d ", &cpunr) != 1) | 
|  | continue; | 
|  | if (cpunr > ret) | 
|  | ret = cpunr; | 
|  | } | 
|  | fclose(fp); | 
|  |  | 
|  | /* cpu count starts from 0, on error return 1 (UP) */ | 
|  | return ret + 1; | 
|  | } | 
|  |  | 
|  |  | 
|  | static void proc_cpufreq_output(void) | 
|  | { | 
|  | unsigned int cpu, nr_cpus; | 
|  | struct cpufreq_policy *policy; | 
|  | unsigned int min_pctg = 0; | 
|  | unsigned int max_pctg = 0; | 
|  | unsigned long min, max; | 
|  |  | 
|  | printf(_("          minimum CPU frequency  -  maximum CPU frequency  -  governor\n")); | 
|  |  | 
|  | nr_cpus = count_cpus(); | 
|  | for (cpu = 0; cpu < nr_cpus; cpu++) { | 
|  | policy = cpufreq_get_policy(cpu); | 
|  | if (!policy) | 
|  | continue; | 
|  |  | 
|  | if (cpufreq_get_hardware_limits(cpu, &min, &max)) { | 
|  | max = 0; | 
|  | } else { | 
|  | min_pctg = (policy->min * 100) / max; | 
|  | max_pctg = (policy->max * 100) / max; | 
|  | } | 
|  | printf("CPU%3d    %9lu kHz (%3d %%)  -  %9lu kHz (%3d %%)  -  %s\n", | 
|  | cpu , policy->min, max ? min_pctg : 0, policy->max, | 
|  | max ? max_pctg : 0, policy->governor); | 
|  |  | 
|  | cpufreq_put_policy(policy); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void print_speed(unsigned long speed) | 
|  | { | 
|  | unsigned long tmp; | 
|  |  | 
|  | if (speed > 1000000) { | 
|  | tmp = speed % 10000; | 
|  | if (tmp >= 5000) | 
|  | speed += 10000; | 
|  | printf("%u.%02u GHz", ((unsigned int) speed/1000000), | 
|  | ((unsigned int) (speed%1000000)/10000)); | 
|  | } else if (speed > 100000) { | 
|  | tmp = speed % 1000; | 
|  | if (tmp >= 500) | 
|  | speed += 1000; | 
|  | printf("%u MHz", ((unsigned int) speed / 1000)); | 
|  | } else if (speed > 1000) { | 
|  | tmp = speed % 100; | 
|  | if (tmp >= 50) | 
|  | speed += 100; | 
|  | printf("%u.%01u MHz", ((unsigned int) speed/1000), | 
|  | ((unsigned int) (speed%1000)/100)); | 
|  | } else | 
|  | printf("%lu kHz", speed); | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | static void print_duration(unsigned long duration) | 
|  | { | 
|  | unsigned long tmp; | 
|  |  | 
|  | if (duration > 1000000) { | 
|  | tmp = duration % 10000; | 
|  | if (tmp >= 5000) | 
|  | duration += 10000; | 
|  | printf("%u.%02u ms", ((unsigned int) duration/1000000), | 
|  | ((unsigned int) (duration%1000000)/10000)); | 
|  | } else if (duration > 100000) { | 
|  | tmp = duration % 1000; | 
|  | if (tmp >= 500) | 
|  | duration += 1000; | 
|  | printf("%u us", ((unsigned int) duration / 1000)); | 
|  | } else if (duration > 1000) { | 
|  | tmp = duration % 100; | 
|  | if (tmp >= 50) | 
|  | duration += 100; | 
|  | printf("%u.%01u us", ((unsigned int) duration/1000), | 
|  | ((unsigned int) (duration%1000)/100)); | 
|  | } else | 
|  | printf("%lu ns", duration); | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | /* --boost / -b */ | 
|  |  | 
|  | static int get_boost_mode(unsigned int cpu) | 
|  | { | 
|  | int support, active, b_states = 0, ret, pstate_no, i; | 
|  | /* ToDo: Make this more global */ | 
|  | unsigned long pstates[MAX_HW_PSTATES] = {0,}; | 
|  |  | 
|  | if (cpupower_cpu_info.vendor != X86_VENDOR_AMD && | 
|  | cpupower_cpu_info.vendor != X86_VENDOR_INTEL) | 
|  | return 0; | 
|  |  | 
|  | ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states); | 
|  | if (ret) { | 
|  | printf(_("Error while evaluating Boost Capabilities" | 
|  | " on CPU %d -- are you root?\n"), cpu); | 
|  | return ret; | 
|  | } | 
|  | /* P state changes via MSR are identified via cpuid 80000007 | 
|  | on Intel and AMD, but we assume boost capable machines can do that | 
|  | if (cpuid_eax(0x80000000) >= 0x80000007 | 
|  | && (cpuid_edx(0x80000007) & (1 << 7))) | 
|  | */ | 
|  |  | 
|  | printf(_("  boost state support:\n")); | 
|  |  | 
|  | printf(_("    Supported: %s\n"), support ? _("yes") : _("no")); | 
|  | printf(_("    Active: %s\n"), active ? _("yes") : _("no")); | 
|  |  | 
|  | if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && | 
|  | cpupower_cpu_info.family >= 0x10) { | 
|  | ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states, | 
|  | pstates, &pstate_no); | 
|  | if (ret) | 
|  | return ret; | 
|  |  | 
|  | printf(_("    Boost States: %d\n"), b_states); | 
|  | printf(_("    Total States: %d\n"), pstate_no); | 
|  | for (i = 0; i < pstate_no; i++) { | 
|  | if (i < b_states) | 
|  | printf(_("    Pstate-Pb%d: %luMHz (boost state)" | 
|  | "\n"), i, pstates[i]); | 
|  | else | 
|  | printf(_("    Pstate-P%d:  %luMHz\n"), | 
|  | i - b_states, pstates[i]); | 
|  | } | 
|  | } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) { | 
|  | double bclk; | 
|  | unsigned long long intel_turbo_ratio = 0; | 
|  | unsigned int ratio; | 
|  |  | 
|  | /* Any way to autodetect this ? */ | 
|  | if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB) | 
|  | bclk = 100.00; | 
|  | else | 
|  | bclk = 133.33; | 
|  | intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu); | 
|  | dprint ("    Ratio: 0x%llx - bclk: %f\n", | 
|  | intel_turbo_ratio, bclk); | 
|  |  | 
|  | ratio = (intel_turbo_ratio >> 24) & 0xFF; | 
|  | if (ratio) | 
|  | printf(_("    %.0f MHz max turbo 4 active cores\n"), | 
|  | ratio * bclk); | 
|  |  | 
|  | ratio = (intel_turbo_ratio >> 16) & 0xFF; | 
|  | if (ratio) | 
|  | printf(_("    %.0f MHz max turbo 3 active cores\n"), | 
|  | ratio * bclk); | 
|  |  | 
|  | ratio = (intel_turbo_ratio >> 8) & 0xFF; | 
|  | if (ratio) | 
|  | printf(_("    %.0f MHz max turbo 2 active cores\n"), | 
|  | ratio * bclk); | 
|  |  | 
|  | ratio = (intel_turbo_ratio >> 0) & 0xFF; | 
|  | if (ratio) | 
|  | printf(_("    %.0f MHz max turbo 1 active cores\n"), | 
|  | ratio * bclk); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void debug_output_one(unsigned int cpu) | 
|  | { | 
|  | char *driver; | 
|  | struct cpufreq_affected_cpus *cpus; | 
|  | struct cpufreq_available_frequencies *freqs; | 
|  | unsigned long min, max, freq_kernel, freq_hardware; | 
|  | unsigned long total_trans, latency; | 
|  | unsigned long long total_time; | 
|  | struct cpufreq_policy *policy; | 
|  | struct cpufreq_available_governors *governors; | 
|  | struct cpufreq_stats *stats; | 
|  |  | 
|  | if (cpufreq_cpu_exists(cpu)) | 
|  | return; | 
|  |  | 
|  | freq_kernel = cpufreq_get_freq_kernel(cpu); | 
|  | freq_hardware = cpufreq_get_freq_hardware(cpu); | 
|  |  | 
|  | driver = cpufreq_get_driver(cpu); | 
|  | if (!driver) { | 
|  | printf(_("  no or unknown cpufreq driver is active on this CPU\n")); | 
|  | } else { | 
|  | printf(_("  driver: %s\n"), driver); | 
|  | cpufreq_put_driver(driver); | 
|  | } | 
|  |  | 
|  | cpus = cpufreq_get_related_cpus(cpu); | 
|  | if (cpus) { | 
|  | printf(_("  CPUs which run at the same hardware frequency: ")); | 
|  | while (cpus->next) { | 
|  | printf("%d ", cpus->cpu); | 
|  | cpus = cpus->next; | 
|  | } | 
|  | printf("%d\n", cpus->cpu); | 
|  | cpufreq_put_related_cpus(cpus); | 
|  | } | 
|  |  | 
|  | cpus = cpufreq_get_affected_cpus(cpu); | 
|  | if (cpus) { | 
|  | printf(_("  CPUs which need to have their frequency coordinated by software: ")); | 
|  | while (cpus->next) { | 
|  | printf("%d ", cpus->cpu); | 
|  | cpus = cpus->next; | 
|  | } | 
|  | printf("%d\n", cpus->cpu); | 
|  | cpufreq_put_affected_cpus(cpus); | 
|  | } | 
|  |  | 
|  | latency = cpufreq_get_transition_latency(cpu); | 
|  | if (latency) { | 
|  | printf(_("  maximum transition latency: ")); | 
|  | print_duration(latency); | 
|  | printf(".\n"); | 
|  | } | 
|  |  | 
|  | if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) { | 
|  | printf(_("  hardware limits: ")); | 
|  | print_speed(min); | 
|  | printf(" - "); | 
|  | print_speed(max); | 
|  | printf("\n"); | 
|  | } | 
|  |  | 
|  | freqs = cpufreq_get_available_frequencies(cpu); | 
|  | if (freqs) { | 
|  | printf(_("  available frequency steps: ")); | 
|  | while (freqs->next) { | 
|  | print_speed(freqs->frequency); | 
|  | printf(", "); | 
|  | freqs = freqs->next; | 
|  | } | 
|  | print_speed(freqs->frequency); | 
|  | printf("\n"); | 
|  | cpufreq_put_available_frequencies(freqs); | 
|  | } | 
|  |  | 
|  | governors = cpufreq_get_available_governors(cpu); | 
|  | if (governors) { | 
|  | printf(_("  available cpufreq governors: ")); | 
|  | while (governors->next) { | 
|  | printf("%s, ", governors->governor); | 
|  | governors = governors->next; | 
|  | } | 
|  | printf("%s\n", governors->governor); | 
|  | cpufreq_put_available_governors(governors); | 
|  | } | 
|  |  | 
|  | policy = cpufreq_get_policy(cpu); | 
|  | if (policy) { | 
|  | printf(_("  current policy: frequency should be within ")); | 
|  | print_speed(policy->min); | 
|  | printf(_(" and ")); | 
|  | print_speed(policy->max); | 
|  |  | 
|  | printf(".\n                  "); | 
|  | printf(_("The governor \"%s\" may" | 
|  | " decide which speed to use\n                  within this range.\n"), | 
|  | policy->governor); | 
|  | cpufreq_put_policy(policy); | 
|  | } | 
|  |  | 
|  | if (freq_kernel || freq_hardware) { | 
|  | printf(_("  current CPU frequency is ")); | 
|  | if (freq_hardware) { | 
|  | print_speed(freq_hardware); | 
|  | printf(_(" (asserted by call to hardware)")); | 
|  | } else | 
|  | print_speed(freq_kernel); | 
|  | printf(".\n"); | 
|  | } | 
|  | stats = cpufreq_get_stats(cpu, &total_time); | 
|  | if (stats) { | 
|  | printf(_("  cpufreq stats: ")); | 
|  | while (stats) { | 
|  | print_speed(stats->frequency); | 
|  | printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time); | 
|  | stats = stats->next; | 
|  | if (stats) | 
|  | printf(", "); | 
|  | } | 
|  | cpufreq_put_stats(stats); | 
|  | total_trans = cpufreq_get_transitions(cpu); | 
|  | if (total_trans) | 
|  | printf("  (%lu)\n", total_trans); | 
|  | else | 
|  | printf("\n"); | 
|  | } | 
|  | get_boost_mode(cpu); | 
|  |  | 
|  | } | 
|  |  | 
|  | /* --freq / -f */ | 
|  |  | 
|  | static int get_freq_kernel(unsigned int cpu, unsigned int human) | 
|  | { | 
|  | unsigned long freq = cpufreq_get_freq_kernel(cpu); | 
|  | if (!freq) | 
|  | return -EINVAL; | 
|  | if (human) { | 
|  | print_speed(freq); | 
|  | printf("\n"); | 
|  | } else | 
|  | printf("%lu\n", freq); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* --hwfreq / -w */ | 
|  |  | 
|  | static int get_freq_hardware(unsigned int cpu, unsigned int human) | 
|  | { | 
|  | unsigned long freq = cpufreq_get_freq_hardware(cpu); | 
|  | if (!freq) | 
|  | return -EINVAL; | 
|  | if (human) { | 
|  | print_speed(freq); | 
|  | printf("\n"); | 
|  | } else | 
|  | printf("%lu\n", freq); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --hwlimits / -l */ | 
|  |  | 
|  | static int get_hardware_limits(unsigned int cpu) | 
|  | { | 
|  | unsigned long min, max; | 
|  | if (cpufreq_get_hardware_limits(cpu, &min, &max)) | 
|  | return -EINVAL; | 
|  | printf("%lu %lu\n", min, max); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --driver / -d */ | 
|  |  | 
|  | static int get_driver(unsigned int cpu) | 
|  | { | 
|  | char *driver = cpufreq_get_driver(cpu); | 
|  | if (!driver) | 
|  | return -EINVAL; | 
|  | printf("%s\n", driver); | 
|  | cpufreq_put_driver(driver); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --policy / -p */ | 
|  |  | 
|  | static int get_policy(unsigned int cpu) | 
|  | { | 
|  | struct cpufreq_policy *policy = cpufreq_get_policy(cpu); | 
|  | if (!policy) | 
|  | return -EINVAL; | 
|  | printf("%lu %lu %s\n", policy->min, policy->max, policy->governor); | 
|  | cpufreq_put_policy(policy); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --governors / -g */ | 
|  |  | 
|  | static int get_available_governors(unsigned int cpu) | 
|  | { | 
|  | struct cpufreq_available_governors *governors = | 
|  | cpufreq_get_available_governors(cpu); | 
|  | if (!governors) | 
|  | return -EINVAL; | 
|  |  | 
|  | while (governors->next) { | 
|  | printf("%s ", governors->governor); | 
|  | governors = governors->next; | 
|  | } | 
|  | printf("%s\n", governors->governor); | 
|  | cpufreq_put_available_governors(governors); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* --affected-cpus  / -a */ | 
|  |  | 
|  | static int get_affected_cpus(unsigned int cpu) | 
|  | { | 
|  | struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu); | 
|  | if (!cpus) | 
|  | return -EINVAL; | 
|  |  | 
|  | while (cpus->next) { | 
|  | printf("%d ", cpus->cpu); | 
|  | cpus = cpus->next; | 
|  | } | 
|  | printf("%d\n", cpus->cpu); | 
|  | cpufreq_put_affected_cpus(cpus); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --related-cpus  / -r */ | 
|  |  | 
|  | static int get_related_cpus(unsigned int cpu) | 
|  | { | 
|  | struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu); | 
|  | if (!cpus) | 
|  | return -EINVAL; | 
|  |  | 
|  | while (cpus->next) { | 
|  | printf("%d ", cpus->cpu); | 
|  | cpus = cpus->next; | 
|  | } | 
|  | printf("%d\n", cpus->cpu); | 
|  | cpufreq_put_related_cpus(cpus); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --stats / -s */ | 
|  |  | 
|  | static int get_freq_stats(unsigned int cpu, unsigned int human) | 
|  | { | 
|  | unsigned long total_trans = cpufreq_get_transitions(cpu); | 
|  | unsigned long long total_time; | 
|  | struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time); | 
|  | while (stats) { | 
|  | if (human) { | 
|  | print_speed(stats->frequency); | 
|  | printf(":%.2f%%", | 
|  | (100.0 * stats->time_in_state) / total_time); | 
|  | } else | 
|  | printf("%lu:%llu", | 
|  | stats->frequency, stats->time_in_state); | 
|  | stats = stats->next; | 
|  | if (stats) | 
|  | printf(", "); | 
|  | } | 
|  | cpufreq_put_stats(stats); | 
|  | if (total_trans) | 
|  | printf("  (%lu)\n", total_trans); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* --latency / -y */ | 
|  |  | 
|  | static int get_latency(unsigned int cpu, unsigned int human) | 
|  | { | 
|  | unsigned long latency = cpufreq_get_transition_latency(cpu); | 
|  | if (!latency) | 
|  | return -EINVAL; | 
|  |  | 
|  | if (human) { | 
|  | print_duration(latency); | 
|  | printf("\n"); | 
|  | } else | 
|  | printf("%lu\n", latency); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static struct option info_opts[] = { | 
|  | { .name = "debug",	.has_arg = no_argument,		.flag = NULL,	.val = 'e'}, | 
|  | { .name = "boost",	.has_arg = no_argument,		.flag = NULL,	.val = 'b'}, | 
|  | { .name = "freq",	.has_arg = no_argument,		.flag = NULL,	.val = 'f'}, | 
|  | { .name = "hwfreq",	.has_arg = no_argument,		.flag = NULL,	.val = 'w'}, | 
|  | { .name = "hwlimits",	.has_arg = no_argument,		.flag = NULL,	.val = 'l'}, | 
|  | { .name = "driver",	.has_arg = no_argument,		.flag = NULL,	.val = 'd'}, | 
|  | { .name = "policy",	.has_arg = no_argument,		.flag = NULL,	.val = 'p'}, | 
|  | { .name = "governors",	.has_arg = no_argument,		.flag = NULL,	.val = 'g'}, | 
|  | { .name = "related-cpus", .has_arg = no_argument,	.flag = NULL,	.val = 'r'}, | 
|  | { .name = "affected-cpus",.has_arg = no_argument,	.flag = NULL,	.val = 'a'}, | 
|  | { .name = "stats",	.has_arg = no_argument,		.flag = NULL,	.val = 's'}, | 
|  | { .name = "latency",	.has_arg = no_argument,		.flag = NULL,	.val = 'y'}, | 
|  | { .name = "proc",	.has_arg = no_argument,		.flag = NULL,	.val = 'o'}, | 
|  | { .name = "human",	.has_arg = no_argument,		.flag = NULL,	.val = 'm'}, | 
|  | { }, | 
|  | }; | 
|  |  | 
|  | int cmd_freq_info(int argc, char **argv) | 
|  | { | 
|  | extern char *optarg; | 
|  | extern int optind, opterr, optopt; | 
|  | int ret = 0, cont = 1; | 
|  | unsigned int cpu = 0; | 
|  | unsigned int human = 0; | 
|  | int output_param = 0; | 
|  |  | 
|  | do { | 
|  | ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL); | 
|  | switch (ret) { | 
|  | case '?': | 
|  | output_param = '?'; | 
|  | cont = 0; | 
|  | break; | 
|  | case -1: | 
|  | cont = 0; | 
|  | break; | 
|  | case 'b': | 
|  | case 'o': | 
|  | case 'a': | 
|  | case 'r': | 
|  | case 'g': | 
|  | case 'p': | 
|  | case 'd': | 
|  | case 'l': | 
|  | case 'w': | 
|  | case 'f': | 
|  | case 'e': | 
|  | case 's': | 
|  | case 'y': | 
|  | if (output_param) { | 
|  | output_param = -1; | 
|  | cont = 0; | 
|  | break; | 
|  | } | 
|  | output_param = ret; | 
|  | break; | 
|  | case 'm': | 
|  | if (human) { | 
|  | output_param = -1; | 
|  | cont = 0; | 
|  | break; | 
|  | } | 
|  | human = 1; | 
|  | break; | 
|  | default: | 
|  | fprintf(stderr, "invalid or unknown argument\n"); | 
|  | return EXIT_FAILURE; | 
|  | } | 
|  | } while (cont); | 
|  |  | 
|  | switch (output_param) { | 
|  | case 'o': | 
|  | if (!bitmask_isallclear(cpus_chosen)) { | 
|  | printf(_("The argument passed to this tool can't be " | 
|  | "combined with passing a --cpu argument\n")); | 
|  | return -EINVAL; | 
|  | } | 
|  | break; | 
|  | case 0: | 
|  | output_param = 'e'; | 
|  | } | 
|  |  | 
|  | ret = 0; | 
|  |  | 
|  | /* Default is: show output of CPU 0 only */ | 
|  | if (bitmask_isallclear(cpus_chosen)) | 
|  | bitmask_setbit(cpus_chosen, 0); | 
|  |  | 
|  | switch (output_param) { | 
|  | case -1: | 
|  | printf(_("You can't specify more than one --cpu parameter and/or\n" | 
|  | "more than one output-specific argument\n")); | 
|  | return -EINVAL; | 
|  | case '?': | 
|  | printf(_("invalid or unknown argument\n")); | 
|  | return -EINVAL; | 
|  | case 'o': | 
|  | proc_cpufreq_output(); | 
|  | return EXIT_SUCCESS; | 
|  | } | 
|  |  | 
|  | for (cpu = bitmask_first(cpus_chosen); | 
|  | cpu <= bitmask_last(cpus_chosen); cpu++) { | 
|  |  | 
|  | if (!bitmask_isbitset(cpus_chosen, cpu)) | 
|  | continue; | 
|  | if (cpufreq_cpu_exists(cpu)) { | 
|  | printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu); | 
|  | continue; | 
|  | } | 
|  | printf(_("analyzing CPU %d:\n"), cpu); | 
|  |  | 
|  | switch (output_param) { | 
|  | case 'b': | 
|  | get_boost_mode(cpu); | 
|  | break; | 
|  | case 'e': | 
|  | debug_output_one(cpu); | 
|  | break; | 
|  | case 'a': | 
|  | ret = get_affected_cpus(cpu); | 
|  | break; | 
|  | case 'r': | 
|  | ret = get_related_cpus(cpu); | 
|  | break; | 
|  | case 'g': | 
|  | ret = get_available_governors(cpu); | 
|  | break; | 
|  | case 'p': | 
|  | ret = get_policy(cpu); | 
|  | break; | 
|  | case 'd': | 
|  | ret = get_driver(cpu); | 
|  | break; | 
|  | case 'l': | 
|  | ret = get_hardware_limits(cpu); | 
|  | break; | 
|  | case 'w': | 
|  | ret = get_freq_hardware(cpu, human); | 
|  | break; | 
|  | case 'f': | 
|  | ret = get_freq_kernel(cpu, human); | 
|  | break; | 
|  | case 's': | 
|  | ret = get_freq_stats(cpu, human); | 
|  | break; | 
|  | case 'y': | 
|  | ret = get_latency(cpu, human); | 
|  | break; | 
|  | } | 
|  | if (ret) | 
|  | return ret; | 
|  | } | 
|  | return ret; | 
|  | } |