mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Benjamin Herrenschmidt](/assets/img/avatar_default.png)
This patch adds a windfarm module, windfarm_pm112, for the dual core G5s (both 2 and 4 core models), keeping the machine from getting into vacuum-cleaner mode ;) For proper credits, the patch was initially written by Paul Mackerras, and slightly reworked by me to add overtemp handling among others. The patch also removes the sysfs attributes from windfarm_pm81 and windfarm_pm91 and instead adds code to the windfarm core to automagically expose attributes for sensor & controls. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
85 lines
2.7 KiB
C
85 lines
2.7 KiB
C
/*
|
|
* Windfarm PowerMac thermal control. Generic PID helpers
|
|
*
|
|
* (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
|
|
* <benh@kernel.crashing.org>
|
|
*
|
|
* Released under the term of the GNU GPL v2.
|
|
*
|
|
* This is a pair of generic PID helpers that can be used by
|
|
* control loops. One is the basic PID implementation, the
|
|
* other one is more specifically tailored to the loops used
|
|
* for CPU control with 2 input sample types (temp and power)
|
|
*/
|
|
|
|
/*
|
|
* *** Simple PID ***
|
|
*/
|
|
|
|
#define WF_PID_MAX_HISTORY 32
|
|
|
|
/* This parameter array is passed to the PID algorithm. Currently,
|
|
* we don't support changing parameters on the fly as it's not needed
|
|
* but could be implemented (with necessary adjustment of the history
|
|
* buffer
|
|
*/
|
|
struct wf_pid_param {
|
|
int interval; /* Interval between samples in seconds */
|
|
int history_len; /* Size of history buffer */
|
|
int additive; /* 1: target relative to previous value */
|
|
s32 gd, gp, gr; /* PID gains */
|
|
s32 itarget; /* PID input target */
|
|
s32 min,max; /* min and max target values */
|
|
};
|
|
|
|
struct wf_pid_state {
|
|
int first; /* first run of the loop */
|
|
int index; /* index of current sample */
|
|
s32 target; /* current target value */
|
|
s32 samples[WF_PID_MAX_HISTORY]; /* samples history buffer */
|
|
s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
|
|
|
|
struct wf_pid_param param;
|
|
};
|
|
|
|
extern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param);
|
|
extern s32 wf_pid_run(struct wf_pid_state *st, s32 sample);
|
|
|
|
|
|
/*
|
|
* *** CPU PID ***
|
|
*/
|
|
|
|
#define WF_CPU_PID_MAX_HISTORY 32
|
|
|
|
/* This parameter array is passed to the CPU PID algorithm. Currently,
|
|
* we don't support changing parameters on the fly as it's not needed
|
|
* but could be implemented (with necessary adjustment of the history
|
|
* buffer
|
|
*/
|
|
struct wf_cpu_pid_param {
|
|
int interval; /* Interval between samples in seconds */
|
|
int history_len; /* Size of history buffer */
|
|
s32 gd, gp, gr; /* PID gains */
|
|
s32 pmaxadj; /* PID max power adjust */
|
|
s32 ttarget; /* PID input target */
|
|
s32 tmax; /* PID input max */
|
|
s32 min,max; /* min and max target values */
|
|
};
|
|
|
|
struct wf_cpu_pid_state {
|
|
int first; /* first run of the loop */
|
|
int index; /* index of current power */
|
|
int tindex; /* index of current temp */
|
|
s32 target; /* current target value */
|
|
s32 last_delta; /* last Tactual - Ttarget */
|
|
s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */
|
|
s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
|
|
s32 temps[2]; /* temp. history buffer */
|
|
|
|
struct wf_cpu_pid_param param;
|
|
};
|
|
|
|
extern void wf_cpu_pid_init(struct wf_cpu_pid_state *st,
|
|
struct wf_cpu_pid_param *param);
|
|
extern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp);
|