kern_cpu.c (227309) | kern_cpu.c (232793) |
---|---|
1/*- 2 * Copyright (c) 2004-2007 Nate Lawson (SDG) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004-2007 Nate Lawson (SDG) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/kern/kern_cpu.c 227309 2011-11-07 15:43:11Z ed $"); | 28__FBSDID("$FreeBSD: head/sys/kern/kern_cpu.c 232793 2012-03-10 18:56:16Z mav $"); |
29 30#include <sys/param.h> 31#include <sys/bus.h> 32#include <sys/cpu.h> 33#include <sys/eventhandler.h> 34#include <sys/kernel.h> 35#include <sys/lock.h> 36#include <sys/malloc.h> --- 270 unchanged lines hidden (view full) --- 307 if (level->total_set.freq < cf_lowest_freq) { 308 CF_DEBUG("rejecting freq %d, less than %d limit\n", 309 level->total_set.freq, cf_lowest_freq); 310 error = EINVAL; 311 goto out; 312 } 313 314 /* If already at this level, just return. */ | 29 30#include <sys/param.h> 31#include <sys/bus.h> 32#include <sys/cpu.h> 33#include <sys/eventhandler.h> 34#include <sys/kernel.h> 35#include <sys/lock.h> 36#include <sys/malloc.h> --- 270 unchanged lines hidden (view full) --- 307 if (level->total_set.freq < cf_lowest_freq) { 308 CF_DEBUG("rejecting freq %d, less than %d limit\n", 309 level->total_set.freq, cf_lowest_freq); 310 error = EINVAL; 311 goto out; 312 } 313 314 /* If already at this level, just return. */ |
315 if (CPUFREQ_CMP(sc->curr_level.total_set.freq, level->total_set.freq)) { | 315 if (sc->curr_level.total_set.freq == level->total_set.freq) { |
316 CF_DEBUG("skipping freq %d, same as current level %d\n", 317 level->total_set.freq, sc->curr_level.total_set.freq); 318 goto skip; 319 } 320 321 /* First, set the absolute frequency via its driver. */ 322 set = &level->abs_set; 323 if (set->dev) { --- 142 unchanged lines hidden (view full) --- 466 */ 467 CF_MTX_LOCK(&sc->lock); 468 for (n = 0; n < numdevs && curr_set->freq == CPUFREQ_VAL_UNKNOWN; n++) { 469 if (!device_is_attached(devs[n])) 470 continue; 471 if (CPUFREQ_DRV_GET(devs[n], &set) != 0) 472 continue; 473 for (i = 0; i < count; i++) { | 316 CF_DEBUG("skipping freq %d, same as current level %d\n", 317 level->total_set.freq, sc->curr_level.total_set.freq); 318 goto skip; 319 } 320 321 /* First, set the absolute frequency via its driver. */ 322 set = &level->abs_set; 323 if (set->dev) { --- 142 unchanged lines hidden (view full) --- 466 */ 467 CF_MTX_LOCK(&sc->lock); 468 for (n = 0; n < numdevs && curr_set->freq == CPUFREQ_VAL_UNKNOWN; n++) { 469 if (!device_is_attached(devs[n])) 470 continue; 471 if (CPUFREQ_DRV_GET(devs[n], &set) != 0) 472 continue; 473 for (i = 0; i < count; i++) { |
474 if (CPUFREQ_CMP(set.freq, levels[i].total_set.freq)) { | 474 if (set.freq == levels[i].total_set.freq) { |
475 sc->curr_level = levels[i]; 476 break; 477 } 478 } 479 } 480 free(devs, M_TEMP); 481 if (curr_set->freq != CPUFREQ_VAL_UNKNOWN) { 482 CF_DEBUG("get matched freq %d from drivers\n", curr_set->freq); --- 139 unchanged lines hidden (view full) --- 622 *count = sc->all_count; 623 error = E2BIG; 624 goto out; 625 } 626 627 /* Finally, output the list of levels. */ 628 i = 0; 629 TAILQ_FOREACH(lev, &sc->all_levels, link) { | 475 sc->curr_level = levels[i]; 476 break; 477 } 478 } 479 } 480 free(devs, M_TEMP); 481 if (curr_set->freq != CPUFREQ_VAL_UNKNOWN) { 482 CF_DEBUG("get matched freq %d from drivers\n", curr_set->freq); --- 139 unchanged lines hidden (view full) --- 622 *count = sc->all_count; 623 error = E2BIG; 624 goto out; 625 } 626 627 /* Finally, output the list of levels. */ 628 i = 0; 629 TAILQ_FOREACH(lev, &sc->all_levels, link) { |
630 /* 631 * Skip levels that are too close in frequency to the 632 * previous levels. Some systems report bogus duplicate 633 * settings (i.e., for acpi_perf). 634 */ 635 if (i > 0 && CPUFREQ_CMP(lev->total_set.freq, 636 levels[i - 1].total_set.freq)) { 637 sc->all_count--; 638 continue; 639 } | |
640 641 /* Skip levels that have a frequency that is too low. */ 642 if (lev->total_set.freq < cf_lowest_freq) { 643 sc->all_count--; 644 continue; 645 } 646 647 levels[i] = *lev; --- 217 unchanged lines hidden (view full) --- 865 return (fill); 866} 867 868static int 869cpufreq_curr_sysctl(SYSCTL_HANDLER_ARGS) 870{ 871 struct cpufreq_softc *sc; 872 struct cf_level *levels; | 630 631 /* Skip levels that have a frequency that is too low. */ 632 if (lev->total_set.freq < cf_lowest_freq) { 633 sc->all_count--; 634 continue; 635 } 636 637 levels[i] = *lev; --- 217 unchanged lines hidden (view full) --- 855 return (fill); 856} 857 858static int 859cpufreq_curr_sysctl(SYSCTL_HANDLER_ARGS) 860{ 861 struct cpufreq_softc *sc; 862 struct cf_level *levels; |
873 int count, devcount, error, freq, i, n; | 863 int best, count, diff, bdiff, devcount, error, freq, i, n; |
874 device_t *devs; 875 876 devs = NULL; 877 sc = oidp->oid_arg1; 878 levels = sc->levels_buf; 879 880 error = CPUFREQ_GET(sc->dev, &levels[0]); 881 if (error) --- 15 unchanged lines hidden (view full) --- 897 count = CF_MAX_LEVELS; 898 error = CPUFREQ_LEVELS(devs[n], levels, &count); 899 if (error) { 900 if (error == E2BIG) 901 printf( 902 "cpufreq: need to increase CF_MAX_LEVELS\n"); 903 break; 904 } | 864 device_t *devs; 865 866 devs = NULL; 867 sc = oidp->oid_arg1; 868 levels = sc->levels_buf; 869 870 error = CPUFREQ_GET(sc->dev, &levels[0]); 871 if (error) --- 15 unchanged lines hidden (view full) --- 887 count = CF_MAX_LEVELS; 888 error = CPUFREQ_LEVELS(devs[n], levels, &count); 889 if (error) { 890 if (error == E2BIG) 891 printf( 892 "cpufreq: need to increase CF_MAX_LEVELS\n"); 893 break; 894 } |
895 best = 0; 896 bdiff = 1 << 30; |
|
905 for (i = 0; i < count; i++) { | 897 for (i = 0; i < count; i++) { |
906 if (CPUFREQ_CMP(levels[i].total_set.freq, freq)) { 907 error = CPUFREQ_SET(devs[n], &levels[i], 908 CPUFREQ_PRIO_USER); 909 break; | 898 diff = abs(levels[i].total_set.freq - freq); 899 if (diff < bdiff) { 900 bdiff = diff; 901 best = i; |
910 } 911 } | 902 } 903 } |
912 if (i == count) { 913 error = EINVAL; 914 break; 915 } | 904 error = CPUFREQ_SET(devs[n], &levels[best], CPUFREQ_PRIO_USER); |
916 } 917 918out: 919 if (devs) 920 free(devs, M_TEMP); 921 return (error); 922} 923 --- 151 unchanged lines hidden --- | 905 } 906 907out: 908 if (devs) 909 free(devs, M_TEMP); 910 return (error); 911} 912 --- 151 unchanged lines hidden --- |