cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

windfarm_rm31.c (17978B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Windfarm PowerMac thermal control.
      4 * Control loops for RackMack3,1 (Xserve G5)
      5 *
      6 * Copyright (C) 2012 Benjamin Herrenschmidt, IBM Corp.
      7 */
      8#include <linux/types.h>
      9#include <linux/errno.h>
     10#include <linux/kernel.h>
     11#include <linux/device.h>
     12#include <linux/platform_device.h>
     13#include <linux/reboot.h>
     14
     15#include <asm/smu.h>
     16
     17#include "windfarm.h"
     18#include "windfarm_pid.h"
     19#include "windfarm_mpu.h"
     20
     21#define VERSION "1.0"
     22
     23#undef DEBUG
     24#undef LOTSA_DEBUG
     25
     26#ifdef DEBUG
     27#define DBG(args...)	printk(args)
     28#else
     29#define DBG(args...)	do { } while(0)
     30#endif
     31
     32#ifdef LOTSA_DEBUG
     33#define DBG_LOTS(args...)	printk(args)
     34#else
     35#define DBG_LOTS(args...)	do { } while(0)
     36#endif
     37
     38/* define this to force CPU overtemp to 60 degree, useful for testing
     39 * the overtemp code
     40 */
     41#undef HACKED_OVERTEMP
     42
     43/* We currently only handle 2 chips */
     44#define NR_CHIPS	2
     45#define NR_CPU_FANS	3 * NR_CHIPS
     46
     47/* Controls and sensors */
     48static struct wf_sensor *sens_cpu_temp[NR_CHIPS];
     49static struct wf_sensor *sens_cpu_volts[NR_CHIPS];
     50static struct wf_sensor *sens_cpu_amps[NR_CHIPS];
     51static struct wf_sensor *backside_temp;
     52static struct wf_sensor *slots_temp;
     53static struct wf_sensor *dimms_temp;
     54
     55static struct wf_control *cpu_fans[NR_CHIPS][3];
     56static struct wf_control *backside_fan;
     57static struct wf_control *slots_fan;
     58static struct wf_control *cpufreq_clamp;
     59
     60/* We keep a temperature history for average calculation of 180s */
     61#define CPU_TEMP_HIST_SIZE	180
     62
     63/* PID loop state */
     64static const struct mpu_data *cpu_mpu_data[NR_CHIPS];
     65static struct wf_cpu_pid_state cpu_pid[NR_CHIPS];
     66static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
     67static int cpu_thist_pt;
     68static s64 cpu_thist_total;
     69static s32 cpu_all_tmax = 100 << 16;
     70static struct wf_pid_state backside_pid;
     71static int backside_tick;
     72static struct wf_pid_state slots_pid;
     73static int slots_tick;
     74static int slots_speed;
     75static struct wf_pid_state dimms_pid;
     76static int dimms_output_clamp;
     77
     78static int nr_chips;
     79static bool have_all_controls;
     80static bool have_all_sensors;
     81static bool started;
     82
     83static int failure_state;
     84#define FAILURE_SENSOR		1
     85#define FAILURE_FAN		2
     86#define FAILURE_PERM		4
     87#define FAILURE_LOW_OVERTEMP	8
     88#define FAILURE_HIGH_OVERTEMP	16
     89
     90/* Overtemp values */
     91#define LOW_OVER_AVERAGE	0
     92#define LOW_OVER_IMMEDIATE	(10 << 16)
     93#define LOW_OVER_CLEAR		((-10) << 16)
     94#define HIGH_OVER_IMMEDIATE	(14 << 16)
     95#define HIGH_OVER_AVERAGE	(10 << 16)
     96#define HIGH_OVER_IMMEDIATE	(14 << 16)
     97
     98
     99static void cpu_max_all_fans(void)
    100{
    101	int i;
    102
    103	/* We max all CPU fans in case of a sensor error. We also do the
    104	 * cpufreq clamping now, even if it's supposedly done later by the
    105	 * generic code anyway, we do it earlier here to react faster
    106	 */
    107	if (cpufreq_clamp)
    108		wf_control_set_max(cpufreq_clamp);
    109	for (i = 0; i < nr_chips; i++) {
    110		if (cpu_fans[i][0])
    111			wf_control_set_max(cpu_fans[i][0]);
    112		if (cpu_fans[i][1])
    113			wf_control_set_max(cpu_fans[i][1]);
    114		if (cpu_fans[i][2])
    115			wf_control_set_max(cpu_fans[i][2]);
    116	}
    117}
    118
    119static int cpu_check_overtemp(s32 temp)
    120{
    121	int new_state = 0;
    122	s32 t_avg, t_old;
    123	static bool first = true;
    124
    125	/* First check for immediate overtemps */
    126	if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
    127		new_state |= FAILURE_LOW_OVERTEMP;
    128		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
    129			printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
    130			       " temperature !\n");
    131	}
    132	if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
    133		new_state |= FAILURE_HIGH_OVERTEMP;
    134		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
    135			printk(KERN_ERR "windfarm: Critical overtemp due to"
    136			       " immediate CPU temperature !\n");
    137	}
    138
    139	/*
    140	 * The first time around, initialize the array with the first
    141	 * temperature reading
    142	 */
    143	if (first) {
    144		int i;
    145
    146		cpu_thist_total = 0;
    147		for (i = 0; i < CPU_TEMP_HIST_SIZE; i++) {
    148			cpu_thist[i] = temp;
    149			cpu_thist_total += temp;
    150		}
    151		first = false;
    152	}
    153
    154	/*
    155	 * We calculate a history of max temperatures and use that for the
    156	 * overtemp management
    157	 */
    158	t_old = cpu_thist[cpu_thist_pt];
    159	cpu_thist[cpu_thist_pt] = temp;
    160	cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
    161	cpu_thist_total -= t_old;
    162	cpu_thist_total += temp;
    163	t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
    164
    165	DBG_LOTS("  t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
    166		 FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
    167
    168	/* Now check for average overtemps */
    169	if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
    170		new_state |= FAILURE_LOW_OVERTEMP;
    171		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
    172			printk(KERN_ERR "windfarm: Overtemp due to average CPU"
    173			       " temperature !\n");
    174	}
    175	if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
    176		new_state |= FAILURE_HIGH_OVERTEMP;
    177		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
    178			printk(KERN_ERR "windfarm: Critical overtemp due to"
    179			       " average CPU temperature !\n");
    180	}
    181
    182	/* Now handle overtemp conditions. We don't currently use the windfarm
    183	 * overtemp handling core as it's not fully suited to the needs of those
    184	 * new machine. This will be fixed later.
    185	 */
    186	if (new_state) {
    187		/* High overtemp -> immediate shutdown */
    188		if (new_state & FAILURE_HIGH_OVERTEMP)
    189			machine_power_off();
    190		if ((failure_state & new_state) != new_state)
    191			cpu_max_all_fans();
    192		failure_state |= new_state;
    193	} else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
    194		   (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
    195		printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
    196		failure_state &= ~FAILURE_LOW_OVERTEMP;
    197	}
    198
    199	return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
    200}
    201
    202static int read_one_cpu_vals(int cpu, s32 *temp, s32 *power)
    203{
    204	s32 dtemp, volts, amps;
    205	int rc;
    206
    207	/* Get diode temperature */
    208	rc = wf_sensor_get(sens_cpu_temp[cpu], &dtemp);
    209	if (rc) {
    210		DBG("  CPU%d: temp reading error !\n", cpu);
    211		return -EIO;
    212	}
    213	DBG_LOTS("  CPU%d: temp   = %d.%03d\n", cpu, FIX32TOPRINT((dtemp)));
    214	*temp = dtemp;
    215
    216	/* Get voltage */
    217	rc = wf_sensor_get(sens_cpu_volts[cpu], &volts);
    218	if (rc) {
    219		DBG("  CPU%d, volts reading error !\n", cpu);
    220		return -EIO;
    221	}
    222	DBG_LOTS("  CPU%d: volts  = %d.%03d\n", cpu, FIX32TOPRINT((volts)));
    223
    224	/* Get current */
    225	rc = wf_sensor_get(sens_cpu_amps[cpu], &amps);
    226	if (rc) {
    227		DBG("  CPU%d, current reading error !\n", cpu);
    228		return -EIO;
    229	}
    230	DBG_LOTS("  CPU%d: amps   = %d.%03d\n", cpu, FIX32TOPRINT((amps)));
    231
    232	/* Calculate power */
    233
    234	/* Scale voltage and current raw sensor values according to fixed scales
    235	 * obtained in Darwin and calculate power from I and V
    236	 */
    237	*power = (((u64)volts) * ((u64)amps)) >> 16;
    238
    239	DBG_LOTS("  CPU%d: power  = %d.%03d\n", cpu, FIX32TOPRINT((*power)));
    240
    241	return 0;
    242
    243}
    244
    245static void cpu_fans_tick(void)
    246{
    247	int err, cpu, i;
    248	s32 speed, temp, power, t_max = 0;
    249
    250	DBG_LOTS("* cpu fans_tick_split()\n");
    251
    252	for (cpu = 0; cpu < nr_chips; ++cpu) {
    253		struct wf_cpu_pid_state *sp = &cpu_pid[cpu];
    254
    255		/* Read current speed */
    256		wf_control_get(cpu_fans[cpu][0], &sp->target);
    257
    258		err = read_one_cpu_vals(cpu, &temp, &power);
    259		if (err) {
    260			failure_state |= FAILURE_SENSOR;
    261			cpu_max_all_fans();
    262			return;
    263		}
    264
    265		/* Keep track of highest temp */
    266		t_max = max(t_max, temp);
    267
    268		/* Handle possible overtemps */
    269		if (cpu_check_overtemp(t_max))
    270			return;
    271
    272		/* Run PID */
    273		wf_cpu_pid_run(sp, power, temp);
    274
    275		DBG_LOTS("  CPU%d: target = %d RPM\n", cpu, sp->target);
    276
    277		/* Apply DIMMs clamp */
    278		speed = max(sp->target, dimms_output_clamp);
    279
    280		/* Apply result to all cpu fans */
    281		for (i = 0; i < 3; i++) {
    282			err = wf_control_set(cpu_fans[cpu][i], speed);
    283			if (err) {
    284				pr_warn("wf_rm31: Fan %s reports error %d\n",
    285					cpu_fans[cpu][i]->name, err);
    286				failure_state |= FAILURE_FAN;
    287			}
    288		}
    289	}
    290}
    291
    292/* Implementation... */
    293static int cpu_setup_pid(int cpu)
    294{
    295	struct wf_cpu_pid_param pid;
    296	const struct mpu_data *mpu = cpu_mpu_data[cpu];
    297	s32 tmax, ttarget, ptarget;
    298	int fmin, fmax, hsize;
    299
    300	/* Get PID params from the appropriate MPU EEPROM */
    301	tmax = mpu->tmax << 16;
    302	ttarget = mpu->ttarget << 16;
    303	ptarget = ((s32)(mpu->pmaxh - mpu->padjmax)) << 16;
    304
    305	DBG("wf_72: CPU%d ttarget = %d.%03d, tmax = %d.%03d\n",
    306	    cpu, FIX32TOPRINT(ttarget), FIX32TOPRINT(tmax));
    307
    308	/* We keep a global tmax for overtemp calculations */
    309	if (tmax < cpu_all_tmax)
    310		cpu_all_tmax = tmax;
    311
    312	/* Set PID min/max by using the rear fan min/max */
    313	fmin = wf_control_get_min(cpu_fans[cpu][0]);
    314	fmax = wf_control_get_max(cpu_fans[cpu][0]);
    315	DBG("wf_72: CPU%d max RPM range = [%d..%d]\n", cpu, fmin, fmax);
    316
    317	/* History size */
    318	hsize = min_t(int, mpu->tguardband, WF_PID_MAX_HISTORY);
    319	DBG("wf_72: CPU%d history size = %d\n", cpu, hsize);
    320
    321	/* Initialize PID loop */
    322	pid.interval	= 1;	/* seconds */
    323	pid.history_len = hsize;
    324	pid.gd		= mpu->pid_gd;
    325	pid.gp		= mpu->pid_gp;
    326	pid.gr		= mpu->pid_gr;
    327	pid.tmax	= tmax;
    328	pid.ttarget	= ttarget;
    329	pid.pmaxadj	= ptarget;
    330	pid.min		= fmin;
    331	pid.max		= fmax;
    332
    333	wf_cpu_pid_init(&cpu_pid[cpu], &pid);
    334	cpu_pid[cpu].target = 4000;
    335	
    336	return 0;
    337}
    338
    339/* Backside/U3 fan */
    340static const struct wf_pid_param backside_param = {
    341	.interval	= 1,
    342	.history_len	= 2,
    343	.gd		= 0x00500000,
    344	.gp		= 0x0004cccc,
    345	.gr		= 0,
    346	.itarget	= 70 << 16,
    347	.additive	= 0,
    348	.min		= 20,
    349	.max		= 100,
    350};
    351
    352/* DIMMs temperature (clamp the backside fan) */
    353static const struct wf_pid_param dimms_param = {
    354	.interval	= 1,
    355	.history_len	= 20,
    356	.gd		= 0,
    357	.gp		= 0,
    358	.gr		= 0x06553600,
    359	.itarget	= 50 << 16,
    360	.additive	= 0,
    361	.min		= 4000,
    362	.max		= 14000,
    363};
    364
    365static void backside_fan_tick(void)
    366{
    367	s32 temp, dtemp;
    368	int speed, dspeed, fan_min;
    369	int err;
    370
    371	if (!backside_fan || !backside_temp || !dimms_temp || !backside_tick)
    372		return;
    373	if (--backside_tick > 0)
    374		return;
    375	backside_tick = backside_pid.param.interval;
    376
    377	DBG_LOTS("* backside fans tick\n");
    378
    379	/* Update fan speed from actual fans */
    380	err = wf_control_get(backside_fan, &speed);
    381	if (!err)
    382		backside_pid.target = speed;
    383
    384	err = wf_sensor_get(backside_temp, &temp);
    385	if (err) {
    386		printk(KERN_WARNING "windfarm: U3 temp sensor error %d\n",
    387		       err);
    388		failure_state |= FAILURE_SENSOR;
    389		wf_control_set_max(backside_fan);
    390		return;
    391	}
    392	speed = wf_pid_run(&backside_pid, temp);
    393
    394	DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
    395		 FIX32TOPRINT(temp), speed);
    396
    397	err = wf_sensor_get(dimms_temp, &dtemp);
    398	if (err) {
    399		printk(KERN_WARNING "windfarm: DIMMs temp sensor error %d\n",
    400		       err);
    401		failure_state |= FAILURE_SENSOR;
    402		wf_control_set_max(backside_fan);
    403		return;
    404	}
    405	dspeed = wf_pid_run(&dimms_pid, dtemp);
    406	dimms_output_clamp = dspeed;
    407
    408	fan_min = (dspeed * 100) / 14000;
    409	fan_min = max(fan_min, backside_param.min);
    410	speed = max(speed, fan_min);
    411
    412	err = wf_control_set(backside_fan, speed);
    413	if (err) {
    414		printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
    415		failure_state |= FAILURE_FAN;
    416	}
    417}
    418
    419static void backside_setup_pid(void)
    420{
    421	/* first time initialize things */
    422	s32 fmin = wf_control_get_min(backside_fan);
    423	s32 fmax = wf_control_get_max(backside_fan);
    424	struct wf_pid_param param;
    425
    426	param = backside_param;
    427	param.min = max(param.min, fmin);
    428	param.max = min(param.max, fmax);
    429	wf_pid_init(&backside_pid, &param);
    430
    431	param = dimms_param;
    432	wf_pid_init(&dimms_pid, &param);
    433
    434	backside_tick = 1;
    435
    436	pr_info("wf_rm31: Backside control loop started.\n");
    437}
    438
    439/* Slots fan */
    440static const struct wf_pid_param slots_param = {
    441	.interval	= 1,
    442	.history_len	= 20,
    443	.gd		= 0,
    444	.gp		= 0,
    445	.gr		= 0x00100000,
    446	.itarget	= 3200000,
    447	.additive	= 0,
    448	.min		= 20,
    449	.max		= 100,
    450};
    451
    452static void slots_fan_tick(void)
    453{
    454	s32 temp;
    455	int speed;
    456	int err;
    457
    458	if (!slots_fan || !slots_temp || !slots_tick)
    459		return;
    460	if (--slots_tick > 0)
    461		return;
    462	slots_tick = slots_pid.param.interval;
    463
    464	DBG_LOTS("* slots fans tick\n");
    465
    466	err = wf_sensor_get(slots_temp, &temp);
    467	if (err) {
    468		pr_warn("wf_rm31: slots temp sensor error %d\n", err);
    469		failure_state |= FAILURE_SENSOR;
    470		wf_control_set_max(slots_fan);
    471		return;
    472	}
    473	speed = wf_pid_run(&slots_pid, temp);
    474
    475	DBG_LOTS("slots PID temp=%d.%.3d speed=%d\n",
    476		 FIX32TOPRINT(temp), speed);
    477
    478	slots_speed = speed;
    479	err = wf_control_set(slots_fan, speed);
    480	if (err) {
    481		printk(KERN_WARNING "windfarm: slots bay fan error %d\n", err);
    482		failure_state |= FAILURE_FAN;
    483	}
    484}
    485
    486static void slots_setup_pid(void)
    487{
    488	/* first time initialize things */
    489	s32 fmin = wf_control_get_min(slots_fan);
    490	s32 fmax = wf_control_get_max(slots_fan);
    491	struct wf_pid_param param = slots_param;
    492
    493	param.min = max(param.min, fmin);
    494	param.max = min(param.max, fmax);
    495	wf_pid_init(&slots_pid, &param);
    496	slots_tick = 1;
    497
    498	pr_info("wf_rm31: Slots control loop started.\n");
    499}
    500
    501static void set_fail_state(void)
    502{
    503	cpu_max_all_fans();
    504
    505	if (backside_fan)
    506		wf_control_set_max(backside_fan);
    507	if (slots_fan)
    508		wf_control_set_max(slots_fan);
    509}
    510
    511static void rm31_tick(void)
    512{
    513	int i, last_failure;
    514
    515	if (!started) {
    516		started = true;
    517		printk(KERN_INFO "windfarm: CPUs control loops started.\n");
    518		for (i = 0; i < nr_chips; ++i) {
    519			if (cpu_setup_pid(i) < 0) {
    520				failure_state = FAILURE_PERM;
    521				set_fail_state();
    522				break;
    523			}
    524		}
    525		DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
    526
    527		backside_setup_pid();
    528		slots_setup_pid();
    529
    530#ifdef HACKED_OVERTEMP
    531		cpu_all_tmax = 60 << 16;
    532#endif
    533	}
    534
    535	/* Permanent failure, bail out */
    536	if (failure_state & FAILURE_PERM)
    537		return;
    538
    539	/*
    540	 * Clear all failure bits except low overtemp which will be eventually
    541	 * cleared by the control loop itself
    542	 */
    543	last_failure = failure_state;
    544	failure_state &= FAILURE_LOW_OVERTEMP;
    545	backside_fan_tick();
    546	slots_fan_tick();
    547
    548	/* We do CPUs last because they can be clamped high by
    549	 * DIMM temperature
    550	 */
    551	cpu_fans_tick();
    552
    553	DBG_LOTS("  last_failure: 0x%x, failure_state: %x\n",
    554		 last_failure, failure_state);
    555
    556	/* Check for failures. Any failure causes cpufreq clamping */
    557	if (failure_state && last_failure == 0 && cpufreq_clamp)
    558		wf_control_set_max(cpufreq_clamp);
    559	if (failure_state == 0 && last_failure && cpufreq_clamp)
    560		wf_control_set_min(cpufreq_clamp);
    561
    562	/* That's it for now, we might want to deal with other failures
    563	 * differently in the future though
    564	 */
    565}
    566
    567static void rm31_new_control(struct wf_control *ct)
    568{
    569	bool all_controls;
    570
    571	if (!strcmp(ct->name, "cpu-fan-a-0"))
    572		cpu_fans[0][0] = ct;
    573	else if (!strcmp(ct->name, "cpu-fan-b-0"))
    574		cpu_fans[0][1] = ct;
    575	else if (!strcmp(ct->name, "cpu-fan-c-0"))
    576		cpu_fans[0][2] = ct;
    577	else if (!strcmp(ct->name, "cpu-fan-a-1"))
    578		cpu_fans[1][0] = ct;
    579	else if (!strcmp(ct->name, "cpu-fan-b-1"))
    580		cpu_fans[1][1] = ct;
    581	else if (!strcmp(ct->name, "cpu-fan-c-1"))
    582		cpu_fans[1][2] = ct;
    583	else if (!strcmp(ct->name, "backside-fan"))
    584		backside_fan = ct;
    585	else if (!strcmp(ct->name, "slots-fan"))
    586		slots_fan = ct;
    587	else if (!strcmp(ct->name, "cpufreq-clamp"))
    588		cpufreq_clamp = ct;
    589
    590	all_controls =
    591		cpu_fans[0][0] &&
    592		cpu_fans[0][1] &&
    593		cpu_fans[0][2] &&
    594		backside_fan &&
    595		slots_fan;
    596	if (nr_chips > 1)
    597		all_controls &=
    598			cpu_fans[1][0] &&
    599			cpu_fans[1][1] &&
    600			cpu_fans[1][2];
    601	have_all_controls = all_controls;
    602}
    603
    604
    605static void rm31_new_sensor(struct wf_sensor *sr)
    606{
    607	bool all_sensors;
    608
    609	if (!strcmp(sr->name, "cpu-diode-temp-0"))
    610		sens_cpu_temp[0] = sr;
    611	else if (!strcmp(sr->name, "cpu-diode-temp-1"))
    612		sens_cpu_temp[1] = sr;
    613	else if (!strcmp(sr->name, "cpu-voltage-0"))
    614		sens_cpu_volts[0] = sr;
    615	else if (!strcmp(sr->name, "cpu-voltage-1"))
    616		sens_cpu_volts[1] = sr;
    617	else if (!strcmp(sr->name, "cpu-current-0"))
    618		sens_cpu_amps[0] = sr;
    619	else if (!strcmp(sr->name, "cpu-current-1"))
    620		sens_cpu_amps[1] = sr;
    621	else if (!strcmp(sr->name, "backside-temp"))
    622		backside_temp = sr;
    623	else if (!strcmp(sr->name, "slots-temp"))
    624		slots_temp = sr;
    625	else if (!strcmp(sr->name, "dimms-temp"))
    626		dimms_temp = sr;
    627
    628	all_sensors =
    629		sens_cpu_temp[0] &&
    630		sens_cpu_volts[0] &&
    631		sens_cpu_amps[0] &&
    632		backside_temp &&
    633		slots_temp &&
    634		dimms_temp;
    635	if (nr_chips > 1)
    636		all_sensors &=
    637			sens_cpu_temp[1] &&
    638			sens_cpu_volts[1] &&
    639			sens_cpu_amps[1];
    640
    641	have_all_sensors = all_sensors;
    642}
    643
    644static int rm31_wf_notify(struct notifier_block *self,
    645			  unsigned long event, void *data)
    646{
    647	switch (event) {
    648	case WF_EVENT_NEW_SENSOR:
    649		rm31_new_sensor(data);
    650		break;
    651	case WF_EVENT_NEW_CONTROL:
    652		rm31_new_control(data);
    653		break;
    654	case WF_EVENT_TICK:
    655		if (have_all_controls && have_all_sensors)
    656			rm31_tick();
    657	}
    658	return 0;
    659}
    660
    661static struct notifier_block rm31_events = {
    662	.notifier_call = rm31_wf_notify,
    663};
    664
    665static int wf_rm31_probe(struct platform_device *dev)
    666{
    667	wf_register_client(&rm31_events);
    668	return 0;
    669}
    670
    671static int wf_rm31_remove(struct platform_device *dev)
    672{
    673	wf_unregister_client(&rm31_events);
    674
    675	/* should release all sensors and controls */
    676	return 0;
    677}
    678
    679static struct platform_driver wf_rm31_driver = {
    680	.probe	= wf_rm31_probe,
    681	.remove	= wf_rm31_remove,
    682	.driver	= {
    683		.name = "windfarm",
    684	},
    685};
    686
    687static int __init wf_rm31_init(void)
    688{
    689	struct device_node *cpu;
    690	int i;
    691
    692	if (!of_machine_is_compatible("RackMac3,1"))
    693		return -ENODEV;
    694
    695	/* Count the number of CPU cores */
    696	nr_chips = 0;
    697	for_each_node_by_type(cpu, "cpu")
    698		++nr_chips;
    699	if (nr_chips > NR_CHIPS)
    700		nr_chips = NR_CHIPS;
    701
    702	pr_info("windfarm: Initializing for desktop G5 with %d chips\n",
    703		nr_chips);
    704
    705	/* Get MPU data for each CPU */
    706	for (i = 0; i < nr_chips; i++) {
    707		cpu_mpu_data[i] = wf_get_mpu(i);
    708		if (!cpu_mpu_data[i]) {
    709			pr_err("wf_rm31: Failed to find MPU data for CPU %d\n", i);
    710			return -ENXIO;
    711		}
    712	}
    713
    714#ifdef MODULE
    715	request_module("windfarm_fcu_controls");
    716	request_module("windfarm_lm75_sensor");
    717	request_module("windfarm_lm87_sensor");
    718	request_module("windfarm_ad7417_sensor");
    719	request_module("windfarm_max6690_sensor");
    720	request_module("windfarm_cpufreq_clamp");
    721#endif /* MODULE */
    722
    723	platform_driver_register(&wf_rm31_driver);
    724	return 0;
    725}
    726
    727static void __exit wf_rm31_exit(void)
    728{
    729	platform_driver_unregister(&wf_rm31_driver);
    730}
    731
    732module_init(wf_rm31_init);
    733module_exit(wf_rm31_exit);
    734
    735MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
    736MODULE_DESCRIPTION("Thermal control for Xserve G5");
    737MODULE_LICENSE("GPL");
    738MODULE_ALIAS("platform:windfarm");