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_pm112.c (18460B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Windfarm PowerMac thermal control.
      4 * Control loops for machines with SMU and PPC970MP processors.
      5 *
      6 * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
      7 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
      8 */
      9#include <linux/types.h>
     10#include <linux/errno.h>
     11#include <linux/kernel.h>
     12#include <linux/device.h>
     13#include <linux/platform_device.h>
     14#include <linux/reboot.h>
     15#include <linux/of.h>
     16#include <linux/slab.h>
     17
     18#include <asm/smu.h>
     19
     20#include "windfarm.h"
     21#include "windfarm_pid.h"
     22
     23#define VERSION "0.2"
     24
     25#define DEBUG
     26#undef LOTSA_DEBUG
     27
     28#ifdef DEBUG
     29#define DBG(args...)	printk(args)
     30#else
     31#define DBG(args...)	do { } while(0)
     32#endif
     33
     34#ifdef LOTSA_DEBUG
     35#define DBG_LOTS(args...)	printk(args)
     36#else
     37#define DBG_LOTS(args...)	do { } while(0)
     38#endif
     39
     40/* define this to force CPU overtemp to 60 degree, useful for testing
     41 * the overtemp code
     42 */
     43#undef HACKED_OVERTEMP
     44
     45/* We currently only handle 2 chips, 4 cores... */
     46#define NR_CHIPS	2
     47#define NR_CORES	4
     48#define NR_CPU_FANS	3 * NR_CHIPS
     49
     50/* Controls and sensors */
     51static struct wf_sensor *sens_cpu_temp[NR_CORES];
     52static struct wf_sensor *sens_cpu_power[NR_CORES];
     53static struct wf_sensor *hd_temp;
     54static struct wf_sensor *slots_power;
     55static struct wf_sensor *u4_temp;
     56
     57static struct wf_control *cpu_fans[NR_CPU_FANS];
     58static char *cpu_fan_names[NR_CPU_FANS] = {
     59	"cpu-rear-fan-0",
     60	"cpu-rear-fan-1",
     61	"cpu-front-fan-0",
     62	"cpu-front-fan-1",
     63	"cpu-pump-0",
     64	"cpu-pump-1",
     65};
     66static struct wf_control *cpufreq_clamp;
     67
     68/* Second pump isn't required (and isn't actually present) */
     69#define CPU_FANS_REQD		(NR_CPU_FANS - 2)
     70#define FIRST_PUMP		4
     71#define LAST_PUMP		5
     72
     73/* We keep a temperature history for average calculation of 180s */
     74#define CPU_TEMP_HIST_SIZE	180
     75
     76/* Scale factor for fan speed, *100 */
     77static int cpu_fan_scale[NR_CPU_FANS] = {
     78	100,
     79	100,
     80	97,		/* inlet fans run at 97% of exhaust fan */
     81	97,
     82	100,		/* updated later */
     83	100,		/* updated later */
     84};
     85
     86static struct wf_control *backside_fan;
     87static struct wf_control *slots_fan;
     88static struct wf_control *drive_bay_fan;
     89
     90/* PID loop state */
     91static struct wf_cpu_pid_state cpu_pid[NR_CORES];
     92static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
     93static int cpu_thist_pt;
     94static s64 cpu_thist_total;
     95static s32 cpu_all_tmax = 100 << 16;
     96static int cpu_last_target;
     97static struct wf_pid_state backside_pid;
     98static int backside_tick;
     99static struct wf_pid_state slots_pid;
    100static bool slots_started;
    101static struct wf_pid_state drive_bay_pid;
    102static int drive_bay_tick;
    103
    104static int nr_cores;
    105static int have_all_controls;
    106static int have_all_sensors;
    107static bool started;
    108
    109static int failure_state;
    110#define FAILURE_SENSOR		1
    111#define FAILURE_FAN		2
    112#define FAILURE_PERM		4
    113#define FAILURE_LOW_OVERTEMP	8
    114#define FAILURE_HIGH_OVERTEMP	16
    115
    116/* Overtemp values */
    117#define LOW_OVER_AVERAGE	0
    118#define LOW_OVER_IMMEDIATE	(10 << 16)
    119#define LOW_OVER_CLEAR		((-10) << 16)
    120#define HIGH_OVER_IMMEDIATE	(14 << 16)
    121#define HIGH_OVER_AVERAGE	(10 << 16)
    122#define HIGH_OVER_IMMEDIATE	(14 << 16)
    123
    124
    125/* Implementation... */
    126static int create_cpu_loop(int cpu)
    127{
    128	int chip = cpu / 2;
    129	int core = cpu & 1;
    130	struct smu_sdbp_header *hdr;
    131	struct smu_sdbp_cpupiddata *piddata;
    132	struct wf_cpu_pid_param pid;
    133	struct wf_control *main_fan = cpu_fans[0];
    134	s32 tmax;
    135	int fmin;
    136
    137	/* Get FVT params to get Tmax; if not found, assume default */
    138	hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
    139	if (hdr) {
    140		struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1];
    141		tmax = fvt->maxtemp << 16;
    142	} else
    143		tmax = 95 << 16;	/* default to 95 degrees C */
    144
    145	/* We keep a global tmax for overtemp calculations */
    146	if (tmax < cpu_all_tmax)
    147		cpu_all_tmax = tmax;
    148
    149	kfree(hdr);
    150
    151	/* Get PID params from the appropriate SAT */
    152	hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
    153	if (hdr == NULL) {
    154		printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
    155		return -EINVAL;
    156	}
    157	piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
    158
    159	/*
    160	 * Darwin has a minimum fan speed of 1000 rpm for the 4-way and
    161	 * 515 for the 2-way.  That appears to be overkill, so for now,
    162	 * impose a minimum of 750 or 515.
    163	 */
    164	fmin = (nr_cores > 2) ? 750 : 515;
    165
    166	/* Initialize PID loop */
    167	pid.interval = 1;	/* seconds */
    168	pid.history_len = piddata->history_len;
    169	pid.gd = piddata->gd;
    170	pid.gp = piddata->gp;
    171	pid.gr = piddata->gr / piddata->history_len;
    172	pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8);
    173	pid.ttarget = tmax - (piddata->target_temp_delta << 16);
    174	pid.tmax = tmax;
    175	pid.min = main_fan->ops->get_min(main_fan);
    176	pid.max = main_fan->ops->get_max(main_fan);
    177	if (pid.min < fmin)
    178		pid.min = fmin;
    179
    180	wf_cpu_pid_init(&cpu_pid[cpu], &pid);
    181
    182	kfree(hdr);
    183
    184	return 0;
    185}
    186
    187static void cpu_max_all_fans(void)
    188{
    189	int i;
    190
    191	/* We max all CPU fans in case of a sensor error. We also do the
    192	 * cpufreq clamping now, even if it's supposedly done later by the
    193	 * generic code anyway, we do it earlier here to react faster
    194	 */
    195	if (cpufreq_clamp)
    196		wf_control_set_max(cpufreq_clamp);
    197	for (i = 0; i < NR_CPU_FANS; ++i)
    198		if (cpu_fans[i])
    199			wf_control_set_max(cpu_fans[i]);
    200}
    201
    202static int cpu_check_overtemp(s32 temp)
    203{
    204	int new_state = 0;
    205	s32 t_avg, t_old;
    206
    207	/* First check for immediate overtemps */
    208	if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
    209		new_state |= FAILURE_LOW_OVERTEMP;
    210		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
    211			printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
    212			       " temperature !\n");
    213	}
    214	if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
    215		new_state |= FAILURE_HIGH_OVERTEMP;
    216		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
    217			printk(KERN_ERR "windfarm: Critical overtemp due to"
    218			       " immediate CPU temperature !\n");
    219	}
    220
    221	/* We calculate a history of max temperatures and use that for the
    222	 * overtemp management
    223	 */
    224	t_old = cpu_thist[cpu_thist_pt];
    225	cpu_thist[cpu_thist_pt] = temp;
    226	cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
    227	cpu_thist_total -= t_old;
    228	cpu_thist_total += temp;
    229	t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
    230
    231	DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
    232		 FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
    233
    234	/* Now check for average overtemps */
    235	if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
    236		new_state |= FAILURE_LOW_OVERTEMP;
    237		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
    238			printk(KERN_ERR "windfarm: Overtemp due to average CPU"
    239			       " temperature !\n");
    240	}
    241	if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
    242		new_state |= FAILURE_HIGH_OVERTEMP;
    243		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
    244			printk(KERN_ERR "windfarm: Critical overtemp due to"
    245			       " average CPU temperature !\n");
    246	}
    247
    248	/* Now handle overtemp conditions. We don't currently use the windfarm
    249	 * overtemp handling core as it's not fully suited to the needs of those
    250	 * new machine. This will be fixed later.
    251	 */
    252	if (new_state) {
    253		/* High overtemp -> immediate shutdown */
    254		if (new_state & FAILURE_HIGH_OVERTEMP)
    255			machine_power_off();
    256		if ((failure_state & new_state) != new_state)
    257			cpu_max_all_fans();
    258		failure_state |= new_state;
    259	} else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
    260		   (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
    261		printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
    262		failure_state &= ~FAILURE_LOW_OVERTEMP;
    263	}
    264
    265	return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
    266}
    267
    268static void cpu_fans_tick(void)
    269{
    270	int err, cpu;
    271	s32 greatest_delta = 0;
    272	s32 temp, power, t_max = 0;
    273	int i, t, target = 0;
    274	struct wf_sensor *sr;
    275	struct wf_control *ct;
    276	struct wf_cpu_pid_state *sp;
    277
    278	DBG_LOTS(KERN_DEBUG);
    279	for (cpu = 0; cpu < nr_cores; ++cpu) {
    280		/* Get CPU core temperature */
    281		sr = sens_cpu_temp[cpu];
    282		err = sr->ops->get_value(sr, &temp);
    283		if (err) {
    284			DBG("\n");
    285			printk(KERN_WARNING "windfarm: CPU %d temperature "
    286			       "sensor error %d\n", cpu, err);
    287			failure_state |= FAILURE_SENSOR;
    288			cpu_max_all_fans();
    289			return;
    290		}
    291
    292		/* Keep track of highest temp */
    293		t_max = max(t_max, temp);
    294
    295		/* Get CPU power */
    296		sr = sens_cpu_power[cpu];
    297		err = sr->ops->get_value(sr, &power);
    298		if (err) {
    299			DBG("\n");
    300			printk(KERN_WARNING "windfarm: CPU %d power "
    301			       "sensor error %d\n", cpu, err);
    302			failure_state |= FAILURE_SENSOR;
    303			cpu_max_all_fans();
    304			return;
    305		}
    306
    307		/* Run PID */
    308		sp = &cpu_pid[cpu];
    309		t = wf_cpu_pid_run(sp, power, temp);
    310
    311		if (cpu == 0 || sp->last_delta > greatest_delta) {
    312			greatest_delta = sp->last_delta;
    313			target = t;
    314		}
    315		DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ",
    316		    cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp));
    317	}
    318	DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max));
    319
    320	/* Darwin limits decrease to 20 per iteration */
    321	if (target < (cpu_last_target - 20))
    322		target = cpu_last_target - 20;
    323	cpu_last_target = target;
    324	for (cpu = 0; cpu < nr_cores; ++cpu)
    325		cpu_pid[cpu].target = target;
    326
    327	/* Handle possible overtemps */
    328	if (cpu_check_overtemp(t_max))
    329		return;
    330
    331	/* Set fans */
    332	for (i = 0; i < NR_CPU_FANS; ++i) {
    333		ct = cpu_fans[i];
    334		if (ct == NULL)
    335			continue;
    336		err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100);
    337		if (err) {
    338			printk(KERN_WARNING "windfarm: fan %s reports "
    339			       "error %d\n", ct->name, err);
    340			failure_state |= FAILURE_FAN;
    341			break;
    342		}
    343	}
    344}
    345
    346/* Backside/U4 fan */
    347static struct wf_pid_param backside_param = {
    348	.interval	= 5,
    349	.history_len	= 2,
    350	.gd		= 48 << 20,
    351	.gp		= 5 << 20,
    352	.gr		= 0,
    353	.itarget	= 64 << 16,
    354	.additive	= 1,
    355};
    356
    357static void backside_fan_tick(void)
    358{
    359	s32 temp;
    360	int speed;
    361	int err;
    362
    363	if (!backside_fan || !u4_temp)
    364		return;
    365	if (!backside_tick) {
    366		/* first time; initialize things */
    367		printk(KERN_INFO "windfarm: Backside control loop started.\n");
    368		backside_param.min = backside_fan->ops->get_min(backside_fan);
    369		backside_param.max = backside_fan->ops->get_max(backside_fan);
    370		wf_pid_init(&backside_pid, &backside_param);
    371		backside_tick = 1;
    372	}
    373	if (--backside_tick > 0)
    374		return;
    375	backside_tick = backside_pid.param.interval;
    376
    377	err = u4_temp->ops->get_value(u4_temp, &temp);
    378	if (err) {
    379		printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
    380		       err);
    381		failure_state |= FAILURE_SENSOR;
    382		wf_control_set_max(backside_fan);
    383		return;
    384	}
    385	speed = wf_pid_run(&backside_pid, temp);
    386	DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
    387		 FIX32TOPRINT(temp), speed);
    388
    389	err = backside_fan->ops->set_value(backside_fan, speed);
    390	if (err) {
    391		printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
    392		failure_state |= FAILURE_FAN;
    393	}
    394}
    395
    396/* Drive bay fan */
    397static struct wf_pid_param drive_bay_prm = {
    398	.interval	= 5,
    399	.history_len	= 2,
    400	.gd		= 30 << 20,
    401	.gp		= 5 << 20,
    402	.gr		= 0,
    403	.itarget	= 40 << 16,
    404	.additive	= 1,
    405};
    406
    407static void drive_bay_fan_tick(void)
    408{
    409	s32 temp;
    410	int speed;
    411	int err;
    412
    413	if (!drive_bay_fan || !hd_temp)
    414		return;
    415	if (!drive_bay_tick) {
    416		/* first time; initialize things */
    417		printk(KERN_INFO "windfarm: Drive bay control loop started.\n");
    418		drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
    419		drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
    420		wf_pid_init(&drive_bay_pid, &drive_bay_prm);
    421		drive_bay_tick = 1;
    422	}
    423	if (--drive_bay_tick > 0)
    424		return;
    425	drive_bay_tick = drive_bay_pid.param.interval;
    426
    427	err = hd_temp->ops->get_value(hd_temp, &temp);
    428	if (err) {
    429		printk(KERN_WARNING "windfarm: drive bay temp sensor "
    430		       "error %d\n", err);
    431		failure_state |= FAILURE_SENSOR;
    432		wf_control_set_max(drive_bay_fan);
    433		return;
    434	}
    435	speed = wf_pid_run(&drive_bay_pid, temp);
    436	DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n",
    437		 FIX32TOPRINT(temp), speed);
    438
    439	err = drive_bay_fan->ops->set_value(drive_bay_fan, speed);
    440	if (err) {
    441		printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
    442		failure_state |= FAILURE_FAN;
    443	}
    444}
    445
    446/* PCI slots area fan */
    447/* This makes the fan speed proportional to the power consumed */
    448static struct wf_pid_param slots_param = {
    449	.interval	= 1,
    450	.history_len	= 2,
    451	.gd		= 0,
    452	.gp		= 0,
    453	.gr		= 0x1277952,
    454	.itarget	= 0,
    455	.min		= 1560,
    456	.max		= 3510,
    457};
    458
    459static void slots_fan_tick(void)
    460{
    461	s32 power;
    462	int speed;
    463	int err;
    464
    465	if (!slots_fan || !slots_power)
    466		return;
    467	if (!slots_started) {
    468		/* first time; initialize things */
    469		printk(KERN_INFO "windfarm: Slots control loop started.\n");
    470		wf_pid_init(&slots_pid, &slots_param);
    471		slots_started = true;
    472	}
    473
    474	err = slots_power->ops->get_value(slots_power, &power);
    475	if (err) {
    476		printk(KERN_WARNING "windfarm: slots power sensor error %d\n",
    477		       err);
    478		failure_state |= FAILURE_SENSOR;
    479		wf_control_set_max(slots_fan);
    480		return;
    481	}
    482	speed = wf_pid_run(&slots_pid, power);
    483	DBG_LOTS("slots PID power=%d.%.3d speed=%d\n",
    484		 FIX32TOPRINT(power), speed);
    485
    486	err = slots_fan->ops->set_value(slots_fan, speed);
    487	if (err) {
    488		printk(KERN_WARNING "windfarm: slots fan error %d\n", err);
    489		failure_state |= FAILURE_FAN;
    490	}
    491}
    492
    493static void set_fail_state(void)
    494{
    495	int i;
    496
    497	if (cpufreq_clamp)
    498		wf_control_set_max(cpufreq_clamp);
    499	for (i = 0; i < NR_CPU_FANS; ++i)
    500		if (cpu_fans[i])
    501			wf_control_set_max(cpu_fans[i]);
    502	if (backside_fan)
    503		wf_control_set_max(backside_fan);
    504	if (slots_fan)
    505		wf_control_set_max(slots_fan);
    506	if (drive_bay_fan)
    507		wf_control_set_max(drive_bay_fan);
    508}
    509
    510static void pm112_tick(void)
    511{
    512	int i, last_failure;
    513
    514	if (!started) {
    515		started = true;
    516		printk(KERN_INFO "windfarm: CPUs control loops started.\n");
    517		for (i = 0; i < nr_cores; ++i) {
    518			if (create_cpu_loop(i) < 0) {
    519				failure_state = FAILURE_PERM;
    520				set_fail_state();
    521				break;
    522			}
    523		}
    524		DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
    525
    526#ifdef HACKED_OVERTEMP
    527		cpu_all_tmax = 60 << 16;
    528#endif
    529	}
    530
    531	/* Permanent failure, bail out */
    532	if (failure_state & FAILURE_PERM)
    533		return;
    534	/* Clear all failure bits except low overtemp which will be eventually
    535	 * cleared by the control loop itself
    536	 */
    537	last_failure = failure_state;
    538	failure_state &= FAILURE_LOW_OVERTEMP;
    539	cpu_fans_tick();
    540	backside_fan_tick();
    541	slots_fan_tick();
    542	drive_bay_fan_tick();
    543
    544	DBG_LOTS("last_failure: 0x%x, failure_state: %x\n",
    545		 last_failure, failure_state);
    546
    547	/* Check for failures. Any failure causes cpufreq clamping */
    548	if (failure_state && last_failure == 0 && cpufreq_clamp)
    549		wf_control_set_max(cpufreq_clamp);
    550	if (failure_state == 0 && last_failure && cpufreq_clamp)
    551		wf_control_set_min(cpufreq_clamp);
    552
    553	/* That's it for now, we might want to deal with other failures
    554	 * differently in the future though
    555	 */
    556}
    557
    558static void pm112_new_control(struct wf_control *ct)
    559{
    560	int i, max_exhaust;
    561
    562	if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
    563		if (wf_get_control(ct) == 0)
    564			cpufreq_clamp = ct;
    565	}
    566
    567	for (i = 0; i < NR_CPU_FANS; ++i) {
    568		if (!strcmp(ct->name, cpu_fan_names[i])) {
    569			if (cpu_fans[i] == NULL && wf_get_control(ct) == 0)
    570				cpu_fans[i] = ct;
    571			break;
    572		}
    573	}
    574	if (i >= NR_CPU_FANS) {
    575		/* not a CPU fan, try the others */
    576		if (!strcmp(ct->name, "backside-fan")) {
    577			if (backside_fan == NULL && wf_get_control(ct) == 0)
    578				backside_fan = ct;
    579		} else if (!strcmp(ct->name, "slots-fan")) {
    580			if (slots_fan == NULL && wf_get_control(ct) == 0)
    581				slots_fan = ct;
    582		} else if (!strcmp(ct->name, "drive-bay-fan")) {
    583			if (drive_bay_fan == NULL && wf_get_control(ct) == 0)
    584				drive_bay_fan = ct;
    585		}
    586		return;
    587	}
    588
    589	for (i = 0; i < CPU_FANS_REQD; ++i)
    590		if (cpu_fans[i] == NULL)
    591			return;
    592
    593	/* work out pump scaling factors */
    594	max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]);
    595	for (i = FIRST_PUMP; i <= LAST_PUMP; ++i)
    596		if ((ct = cpu_fans[i]) != NULL)
    597			cpu_fan_scale[i] =
    598				ct->ops->get_max(ct) * 100 / max_exhaust;
    599
    600	have_all_controls = 1;
    601}
    602
    603static void pm112_new_sensor(struct wf_sensor *sr)
    604{
    605	unsigned int i;
    606
    607	if (!strncmp(sr->name, "cpu-temp-", 9)) {
    608		i = sr->name[9] - '0';
    609		if (sr->name[10] == 0 && i < NR_CORES &&
    610		    sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0)
    611			sens_cpu_temp[i] = sr;
    612
    613	} else if (!strncmp(sr->name, "cpu-power-", 10)) {
    614		i = sr->name[10] - '0';
    615		if (sr->name[11] == 0 && i < NR_CORES &&
    616		    sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0)
    617			sens_cpu_power[i] = sr;
    618	} else if (!strcmp(sr->name, "hd-temp")) {
    619		if (hd_temp == NULL && wf_get_sensor(sr) == 0)
    620			hd_temp = sr;
    621	} else if (!strcmp(sr->name, "slots-power")) {
    622		if (slots_power == NULL && wf_get_sensor(sr) == 0)
    623			slots_power = sr;
    624	} else if (!strcmp(sr->name, "backside-temp")) {
    625		if (u4_temp == NULL && wf_get_sensor(sr) == 0)
    626			u4_temp = sr;
    627	} else
    628		return;
    629
    630	/* check if we have all the sensors we need */
    631	for (i = 0; i < nr_cores; ++i)
    632		if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL)
    633			return;
    634
    635	have_all_sensors = 1;
    636}
    637
    638static int pm112_wf_notify(struct notifier_block *self,
    639			   unsigned long event, void *data)
    640{
    641	switch (event) {
    642	case WF_EVENT_NEW_SENSOR:
    643		pm112_new_sensor(data);
    644		break;
    645	case WF_EVENT_NEW_CONTROL:
    646		pm112_new_control(data);
    647		break;
    648	case WF_EVENT_TICK:
    649		if (have_all_controls && have_all_sensors)
    650			pm112_tick();
    651	}
    652	return 0;
    653}
    654
    655static struct notifier_block pm112_events = {
    656	.notifier_call = pm112_wf_notify,
    657};
    658
    659static int wf_pm112_probe(struct platform_device *dev)
    660{
    661	wf_register_client(&pm112_events);
    662	return 0;
    663}
    664
    665static int wf_pm112_remove(struct platform_device *dev)
    666{
    667	wf_unregister_client(&pm112_events);
    668	/* should release all sensors and controls */
    669	return 0;
    670}
    671
    672static struct platform_driver wf_pm112_driver = {
    673	.probe = wf_pm112_probe,
    674	.remove = wf_pm112_remove,
    675	.driver = {
    676		.name = "windfarm",
    677	},
    678};
    679
    680static int __init wf_pm112_init(void)
    681{
    682	struct device_node *cpu;
    683
    684	if (!of_machine_is_compatible("PowerMac11,2"))
    685		return -ENODEV;
    686
    687	/* Count the number of CPU cores */
    688	nr_cores = 0;
    689	for_each_node_by_type(cpu, "cpu")
    690		++nr_cores;
    691
    692	printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
    693
    694#ifdef MODULE
    695	request_module("windfarm_smu_controls");
    696	request_module("windfarm_smu_sensors");
    697	request_module("windfarm_smu_sat");
    698	request_module("windfarm_lm75_sensor");
    699	request_module("windfarm_max6690_sensor");
    700	request_module("windfarm_cpufreq_clamp");
    701
    702#endif /* MODULE */
    703
    704	platform_driver_register(&wf_pm112_driver);
    705	return 0;
    706}
    707
    708static void __exit wf_pm112_exit(void)
    709{
    710	platform_driver_unregister(&wf_pm112_driver);
    711}
    712
    713module_init(wf_pm112_init);
    714module_exit(wf_pm112_exit);
    715
    716MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
    717MODULE_DESCRIPTION("Thermal control for PowerMac11,2");
    718MODULE_LICENSE("GPL");
    719MODULE_ALIAS("platform:windfarm");