diff options
author | njl <njl@FreeBSD.org> | 2007-03-26 18:03:29 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2007-03-26 18:03:29 +0000 |
commit | 4933ca0aa02fff68e3e30186b454ed25d7d926fb (patch) | |
tree | 38a5baa5f3b7261150b7178ed80307e7f2bd65c9 /sys/sys/cpu.h | |
parent | 3cb53690e0c2c81ed3b336133bf003c7b3173abf (diff) | |
download | FreeBSD-src-4933ca0aa02fff68e3e30186b454ed25d7d926fb.zip FreeBSD-src-4933ca0aa02fff68e3e30186b454ed25d7d926fb.tar.gz |
Add an interface for drivers to be notified of changes to CPU frequency.
cpufreq_pre_change is called before the change, giving each driver a chance
to revoke the change. cpufreq_post_change provides the results of the
change (success or failure). cpufreq_levels_changed gives the unit number
of the cpufreq device whose number of available levels has changed. Hook
in all the drivers I could find that needed it.
* TSC: update TSC frequency value. When the available levels change, take the
highest possible level and notify the timecounter set_cputicker() of that
freq. This gets rid of the "calcru: runtime went backwards" messages.
* identcpu: updates the sysctl hw.clockrate value
* Profiling: if profiling is active when the clock changes, let the user
know the results may be inaccurate.
Reviewed by: bde, phk
MFC after: 1 month
Diffstat (limited to 'sys/sys/cpu.h')
-rw-r--r-- | sys/sys/cpu.h | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/sys/sys/cpu.h b/sys/sys/cpu.h index e2337ab..d282d30 100644 --- a/sys/sys/cpu.h +++ b/sys/sys/cpu.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Nate Lawson (SDG) + * Copyright (c) 2005-2007 Nate Lawson (SDG) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +29,8 @@ #ifndef _SYS_CPU_H_ #define _SYS_CPU_H_ +#include <sys/eventhandler.h> + /* * CPU device support. */ @@ -118,6 +120,36 @@ TAILQ_HEAD(cf_level_lst, cf_level); int cpufreq_register(device_t dev); int cpufreq_unregister(device_t dev); +/* + * Notify the cpufreq core that the number of or values for settings have + * changed. + */ +int cpufreq_settings_changed(device_t dev); + +/* + * Eventhandlers that are called before and after a change in frequency. + * The new level and the result of the change (0 is success) is passed in. + * If the driver wishes to revoke the change from cpufreq_pre_change, it + * stores a non-zero error code in the result parameter and the change will + * not be made. If the post-change eventhandler gets a non-zero result, + * no change was made and the previous level remains in effect. If a change + * is revoked, the post-change eventhandler is still called with the error + * value supplied by the revoking driver. This gives listeners who cached + * some data in preparation for a level change a chance to clean up. + */ +typedef void (*cpufreq_pre_notify_fn)(void *, const struct cf_level *, int *); +typedef void (*cpufreq_post_notify_fn)(void *, const struct cf_level *, int); +EVENTHANDLER_DECLARE(cpufreq_pre_change, cpufreq_pre_notify_fn); +EVENTHANDLER_DECLARE(cpufreq_post_change, cpufreq_post_notify_fn); + +/* + * Eventhandler called when the available list of levels changed. + * The unit number of the device (i.e. "cpufreq0") whose levels changed + * is provided so the listener can retrieve the new list of levels. + */ +typedef void (*cpufreq_levels_notify_fn)(void *, int); +EVENTHANDLER_DECLARE(cpufreq_levels_changed, cpufreq_levels_notify_fn); + /* Allow values to be +/- a bit since sometimes we have to estimate. */ #define CPUFREQ_CMP(x, y) (abs((x) - (y)) < 25) |