Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Windfarm PowerMac thermal control.
0004  * Control loops for machines with SMU and PPC970MP processors.
0005  *
0006  * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
0007  * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
0008  */
0009 #include <linux/types.h>
0010 #include <linux/errno.h>
0011 #include <linux/kernel.h>
0012 #include <linux/device.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/reboot.h>
0015 #include <linux/of.h>
0016 #include <linux/slab.h>
0017 
0018 #include <asm/smu.h>
0019 
0020 #include "windfarm.h"
0021 #include "windfarm_pid.h"
0022 
0023 #define VERSION "0.2"
0024 
0025 #define DEBUG
0026 #undef LOTSA_DEBUG
0027 
0028 #ifdef DEBUG
0029 #define DBG(args...)    printk(args)
0030 #else
0031 #define DBG(args...)    do { } while(0)
0032 #endif
0033 
0034 #ifdef LOTSA_DEBUG
0035 #define DBG_LOTS(args...)   printk(args)
0036 #else
0037 #define DBG_LOTS(args...)   do { } while(0)
0038 #endif
0039 
0040 /* define this to force CPU overtemp to 60 degree, useful for testing
0041  * the overtemp code
0042  */
0043 #undef HACKED_OVERTEMP
0044 
0045 /* We currently only handle 2 chips, 4 cores... */
0046 #define NR_CHIPS    2
0047 #define NR_CORES    4
0048 #define NR_CPU_FANS 3 * NR_CHIPS
0049 
0050 /* Controls and sensors */
0051 static struct wf_sensor *sens_cpu_temp[NR_CORES];
0052 static struct wf_sensor *sens_cpu_power[NR_CORES];
0053 static struct wf_sensor *hd_temp;
0054 static struct wf_sensor *slots_power;
0055 static struct wf_sensor *u4_temp;
0056 
0057 static struct wf_control *cpu_fans[NR_CPU_FANS];
0058 static char *cpu_fan_names[NR_CPU_FANS] = {
0059     "cpu-rear-fan-0",
0060     "cpu-rear-fan-1",
0061     "cpu-front-fan-0",
0062     "cpu-front-fan-1",
0063     "cpu-pump-0",
0064     "cpu-pump-1",
0065 };
0066 static struct wf_control *cpufreq_clamp;
0067 
0068 /* Second pump isn't required (and isn't actually present) */
0069 #define CPU_FANS_REQD       (NR_CPU_FANS - 2)
0070 #define FIRST_PUMP      4
0071 #define LAST_PUMP       5
0072 
0073 /* We keep a temperature history for average calculation of 180s */
0074 #define CPU_TEMP_HIST_SIZE  180
0075 
0076 /* Scale factor for fan speed, *100 */
0077 static int cpu_fan_scale[NR_CPU_FANS] = {
0078     100,
0079     100,
0080     97,     /* inlet fans run at 97% of exhaust fan */
0081     97,
0082     100,        /* updated later */
0083     100,        /* updated later */
0084 };
0085 
0086 static struct wf_control *backside_fan;
0087 static struct wf_control *slots_fan;
0088 static struct wf_control *drive_bay_fan;
0089 
0090 /* PID loop state */
0091 static struct wf_cpu_pid_state cpu_pid[NR_CORES];
0092 static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
0093 static int cpu_thist_pt;
0094 static s64 cpu_thist_total;
0095 static s32 cpu_all_tmax = 100 << 16;
0096 static int cpu_last_target;
0097 static struct wf_pid_state backside_pid;
0098 static int backside_tick;
0099 static struct wf_pid_state slots_pid;
0100 static bool slots_started;
0101 static struct wf_pid_state drive_bay_pid;
0102 static int drive_bay_tick;
0103 
0104 static int nr_cores;
0105 static int have_all_controls;
0106 static int have_all_sensors;
0107 static bool started;
0108 
0109 static int failure_state;
0110 #define FAILURE_SENSOR      1
0111 #define FAILURE_FAN     2
0112 #define FAILURE_PERM        4
0113 #define FAILURE_LOW_OVERTEMP    8
0114 #define FAILURE_HIGH_OVERTEMP   16
0115 
0116 /* Overtemp values */
0117 #define LOW_OVER_AVERAGE    0
0118 #define LOW_OVER_IMMEDIATE  (10 << 16)
0119 #define LOW_OVER_CLEAR      ((-10) << 16)
0120 #define HIGH_OVER_IMMEDIATE (14 << 16)
0121 #define HIGH_OVER_AVERAGE   (10 << 16)
0122 #define HIGH_OVER_IMMEDIATE (14 << 16)
0123 
0124 
0125 /* Implementation... */
0126 static int create_cpu_loop(int cpu)
0127 {
0128     int chip = cpu / 2;
0129     int core = cpu & 1;
0130     struct smu_sdbp_header *hdr;
0131     struct smu_sdbp_cpupiddata *piddata;
0132     struct wf_cpu_pid_param pid;
0133     struct wf_control *main_fan = cpu_fans[0];
0134     s32 tmax;
0135     int fmin;
0136 
0137     /* Get FVT params to get Tmax; if not found, assume default */
0138     hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
0139     if (hdr) {
0140         struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1];
0141         tmax = fvt->maxtemp << 16;
0142     } else
0143         tmax = 95 << 16;    /* default to 95 degrees C */
0144 
0145     /* We keep a global tmax for overtemp calculations */
0146     if (tmax < cpu_all_tmax)
0147         cpu_all_tmax = tmax;
0148 
0149     kfree(hdr);
0150 
0151     /* Get PID params from the appropriate SAT */
0152     hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
0153     if (hdr == NULL) {
0154         printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
0155         return -EINVAL;
0156     }
0157     piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
0158 
0159     /*
0160      * Darwin has a minimum fan speed of 1000 rpm for the 4-way and
0161      * 515 for the 2-way.  That appears to be overkill, so for now,
0162      * impose a minimum of 750 or 515.
0163      */
0164     fmin = (nr_cores > 2) ? 750 : 515;
0165 
0166     /* Initialize PID loop */
0167     pid.interval = 1;   /* seconds */
0168     pid.history_len = piddata->history_len;
0169     pid.gd = piddata->gd;
0170     pid.gp = piddata->gp;
0171     pid.gr = piddata->gr / piddata->history_len;
0172     pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8);
0173     pid.ttarget = tmax - (piddata->target_temp_delta << 16);
0174     pid.tmax = tmax;
0175     pid.min = main_fan->ops->get_min(main_fan);
0176     pid.max = main_fan->ops->get_max(main_fan);
0177     if (pid.min < fmin)
0178         pid.min = fmin;
0179 
0180     wf_cpu_pid_init(&cpu_pid[cpu], &pid);
0181 
0182     kfree(hdr);
0183 
0184     return 0;
0185 }
0186 
0187 static void cpu_max_all_fans(void)
0188 {
0189     int i;
0190 
0191     /* We max all CPU fans in case of a sensor error. We also do the
0192      * cpufreq clamping now, even if it's supposedly done later by the
0193      * generic code anyway, we do it earlier here to react faster
0194      */
0195     if (cpufreq_clamp)
0196         wf_control_set_max(cpufreq_clamp);
0197     for (i = 0; i < NR_CPU_FANS; ++i)
0198         if (cpu_fans[i])
0199             wf_control_set_max(cpu_fans[i]);
0200 }
0201 
0202 static int cpu_check_overtemp(s32 temp)
0203 {
0204     int new_state = 0;
0205     s32 t_avg, t_old;
0206 
0207     /* First check for immediate overtemps */
0208     if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
0209         new_state |= FAILURE_LOW_OVERTEMP;
0210         if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
0211             printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
0212                    " temperature !\n");
0213     }
0214     if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
0215         new_state |= FAILURE_HIGH_OVERTEMP;
0216         if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
0217             printk(KERN_ERR "windfarm: Critical overtemp due to"
0218                    " immediate CPU temperature !\n");
0219     }
0220 
0221     /* We calculate a history of max temperatures and use that for the
0222      * overtemp management
0223      */
0224     t_old = cpu_thist[cpu_thist_pt];
0225     cpu_thist[cpu_thist_pt] = temp;
0226     cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
0227     cpu_thist_total -= t_old;
0228     cpu_thist_total += temp;
0229     t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
0230 
0231     DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
0232          FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
0233 
0234     /* Now check for average overtemps */
0235     if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
0236         new_state |= FAILURE_LOW_OVERTEMP;
0237         if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
0238             printk(KERN_ERR "windfarm: Overtemp due to average CPU"
0239                    " temperature !\n");
0240     }
0241     if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
0242         new_state |= FAILURE_HIGH_OVERTEMP;
0243         if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
0244             printk(KERN_ERR "windfarm: Critical overtemp due to"
0245                    " average CPU temperature !\n");
0246     }
0247 
0248     /* Now handle overtemp conditions. We don't currently use the windfarm
0249      * overtemp handling core as it's not fully suited to the needs of those
0250      * new machine. This will be fixed later.
0251      */
0252     if (new_state) {
0253         /* High overtemp -> immediate shutdown */
0254         if (new_state & FAILURE_HIGH_OVERTEMP)
0255             machine_power_off();
0256         if ((failure_state & new_state) != new_state)
0257             cpu_max_all_fans();
0258         failure_state |= new_state;
0259     } else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
0260            (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
0261         printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
0262         failure_state &= ~FAILURE_LOW_OVERTEMP;
0263     }
0264 
0265     return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
0266 }
0267 
0268 static void cpu_fans_tick(void)
0269 {
0270     int err, cpu;
0271     s32 greatest_delta = 0;
0272     s32 temp, power, t_max = 0;
0273     int i, t, target = 0;
0274     struct wf_sensor *sr;
0275     struct wf_control *ct;
0276     struct wf_cpu_pid_state *sp;
0277 
0278     DBG_LOTS(KERN_DEBUG);
0279     for (cpu = 0; cpu < nr_cores; ++cpu) {
0280         /* Get CPU core temperature */
0281         sr = sens_cpu_temp[cpu];
0282         err = sr->ops->get_value(sr, &temp);
0283         if (err) {
0284             DBG("\n");
0285             printk(KERN_WARNING "windfarm: CPU %d temperature "
0286                    "sensor error %d\n", cpu, err);
0287             failure_state |= FAILURE_SENSOR;
0288             cpu_max_all_fans();
0289             return;
0290         }
0291 
0292         /* Keep track of highest temp */
0293         t_max = max(t_max, temp);
0294 
0295         /* Get CPU power */
0296         sr = sens_cpu_power[cpu];
0297         err = sr->ops->get_value(sr, &power);
0298         if (err) {
0299             DBG("\n");
0300             printk(KERN_WARNING "windfarm: CPU %d power "
0301                    "sensor error %d\n", cpu, err);
0302             failure_state |= FAILURE_SENSOR;
0303             cpu_max_all_fans();
0304             return;
0305         }
0306 
0307         /* Run PID */
0308         sp = &cpu_pid[cpu];
0309         t = wf_cpu_pid_run(sp, power, temp);
0310 
0311         if (cpu == 0 || sp->last_delta > greatest_delta) {
0312             greatest_delta = sp->last_delta;
0313             target = t;
0314         }
0315         DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ",
0316             cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp));
0317     }
0318     DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max));
0319 
0320     /* Darwin limits decrease to 20 per iteration */
0321     if (target < (cpu_last_target - 20))
0322         target = cpu_last_target - 20;
0323     cpu_last_target = target;
0324     for (cpu = 0; cpu < nr_cores; ++cpu)
0325         cpu_pid[cpu].target = target;
0326 
0327     /* Handle possible overtemps */
0328     if (cpu_check_overtemp(t_max))
0329         return;
0330 
0331     /* Set fans */
0332     for (i = 0; i < NR_CPU_FANS; ++i) {
0333         ct = cpu_fans[i];
0334         if (ct == NULL)
0335             continue;
0336         err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100);
0337         if (err) {
0338             printk(KERN_WARNING "windfarm: fan %s reports "
0339                    "error %d\n", ct->name, err);
0340             failure_state |= FAILURE_FAN;
0341             break;
0342         }
0343     }
0344 }
0345 
0346 /* Backside/U4 fan */
0347 static struct wf_pid_param backside_param = {
0348     .interval   = 5,
0349     .history_len    = 2,
0350     .gd     = 48 << 20,
0351     .gp     = 5 << 20,
0352     .gr     = 0,
0353     .itarget    = 64 << 16,
0354     .additive   = 1,
0355 };
0356 
0357 static void backside_fan_tick(void)
0358 {
0359     s32 temp;
0360     int speed;
0361     int err;
0362 
0363     if (!backside_fan || !u4_temp)
0364         return;
0365     if (!backside_tick) {
0366         /* first time; initialize things */
0367         printk(KERN_INFO "windfarm: Backside control loop started.\n");
0368         backside_param.min = backside_fan->ops->get_min(backside_fan);
0369         backside_param.max = backside_fan->ops->get_max(backside_fan);
0370         wf_pid_init(&backside_pid, &backside_param);
0371         backside_tick = 1;
0372     }
0373     if (--backside_tick > 0)
0374         return;
0375     backside_tick = backside_pid.param.interval;
0376 
0377     err = u4_temp->ops->get_value(u4_temp, &temp);
0378     if (err) {
0379         printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
0380                err);
0381         failure_state |= FAILURE_SENSOR;
0382         wf_control_set_max(backside_fan);
0383         return;
0384     }
0385     speed = wf_pid_run(&backside_pid, temp);
0386     DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
0387          FIX32TOPRINT(temp), speed);
0388 
0389     err = backside_fan->ops->set_value(backside_fan, speed);
0390     if (err) {
0391         printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
0392         failure_state |= FAILURE_FAN;
0393     }
0394 }
0395 
0396 /* Drive bay fan */
0397 static struct wf_pid_param drive_bay_prm = {
0398     .interval   = 5,
0399     .history_len    = 2,
0400     .gd     = 30 << 20,
0401     .gp     = 5 << 20,
0402     .gr     = 0,
0403     .itarget    = 40 << 16,
0404     .additive   = 1,
0405 };
0406 
0407 static void drive_bay_fan_tick(void)
0408 {
0409     s32 temp;
0410     int speed;
0411     int err;
0412 
0413     if (!drive_bay_fan || !hd_temp)
0414         return;
0415     if (!drive_bay_tick) {
0416         /* first time; initialize things */
0417         printk(KERN_INFO "windfarm: Drive bay control loop started.\n");
0418         drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
0419         drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
0420         wf_pid_init(&drive_bay_pid, &drive_bay_prm);
0421         drive_bay_tick = 1;
0422     }
0423     if (--drive_bay_tick > 0)
0424         return;
0425     drive_bay_tick = drive_bay_pid.param.interval;
0426 
0427     err = hd_temp->ops->get_value(hd_temp, &temp);
0428     if (err) {
0429         printk(KERN_WARNING "windfarm: drive bay temp sensor "
0430                "error %d\n", err);
0431         failure_state |= FAILURE_SENSOR;
0432         wf_control_set_max(drive_bay_fan);
0433         return;
0434     }
0435     speed = wf_pid_run(&drive_bay_pid, temp);
0436     DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n",
0437          FIX32TOPRINT(temp), speed);
0438 
0439     err = drive_bay_fan->ops->set_value(drive_bay_fan, speed);
0440     if (err) {
0441         printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
0442         failure_state |= FAILURE_FAN;
0443     }
0444 }
0445 
0446 /* PCI slots area fan */
0447 /* This makes the fan speed proportional to the power consumed */
0448 static struct wf_pid_param slots_param = {
0449     .interval   = 1,
0450     .history_len    = 2,
0451     .gd     = 0,
0452     .gp     = 0,
0453     .gr     = 0x1277952,
0454     .itarget    = 0,
0455     .min        = 1560,
0456     .max        = 3510,
0457 };
0458 
0459 static void slots_fan_tick(void)
0460 {
0461     s32 power;
0462     int speed;
0463     int err;
0464 
0465     if (!slots_fan || !slots_power)
0466         return;
0467     if (!slots_started) {
0468         /* first time; initialize things */
0469         printk(KERN_INFO "windfarm: Slots control loop started.\n");
0470         wf_pid_init(&slots_pid, &slots_param);
0471         slots_started = true;
0472     }
0473 
0474     err = slots_power->ops->get_value(slots_power, &power);
0475     if (err) {
0476         printk(KERN_WARNING "windfarm: slots power sensor error %d\n",
0477                err);
0478         failure_state |= FAILURE_SENSOR;
0479         wf_control_set_max(slots_fan);
0480         return;
0481     }
0482     speed = wf_pid_run(&slots_pid, power);
0483     DBG_LOTS("slots PID power=%d.%.3d speed=%d\n",
0484          FIX32TOPRINT(power), speed);
0485 
0486     err = slots_fan->ops->set_value(slots_fan, speed);
0487     if (err) {
0488         printk(KERN_WARNING "windfarm: slots fan error %d\n", err);
0489         failure_state |= FAILURE_FAN;
0490     }
0491 }
0492 
0493 static void set_fail_state(void)
0494 {
0495     int i;
0496 
0497     if (cpufreq_clamp)
0498         wf_control_set_max(cpufreq_clamp);
0499     for (i = 0; i < NR_CPU_FANS; ++i)
0500         if (cpu_fans[i])
0501             wf_control_set_max(cpu_fans[i]);
0502     if (backside_fan)
0503         wf_control_set_max(backside_fan);
0504     if (slots_fan)
0505         wf_control_set_max(slots_fan);
0506     if (drive_bay_fan)
0507         wf_control_set_max(drive_bay_fan);
0508 }
0509 
0510 static void pm112_tick(void)
0511 {
0512     int i, last_failure;
0513 
0514     if (!started) {
0515         started = true;
0516         printk(KERN_INFO "windfarm: CPUs control loops started.\n");
0517         for (i = 0; i < nr_cores; ++i) {
0518             if (create_cpu_loop(i) < 0) {
0519                 failure_state = FAILURE_PERM;
0520                 set_fail_state();
0521                 break;
0522             }
0523         }
0524         DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
0525 
0526 #ifdef HACKED_OVERTEMP
0527         cpu_all_tmax = 60 << 16;
0528 #endif
0529     }
0530 
0531     /* Permanent failure, bail out */
0532     if (failure_state & FAILURE_PERM)
0533         return;
0534     /* Clear all failure bits except low overtemp which will be eventually
0535      * cleared by the control loop itself
0536      */
0537     last_failure = failure_state;
0538     failure_state &= FAILURE_LOW_OVERTEMP;
0539     cpu_fans_tick();
0540     backside_fan_tick();
0541     slots_fan_tick();
0542     drive_bay_fan_tick();
0543 
0544     DBG_LOTS("last_failure: 0x%x, failure_state: %x\n",
0545          last_failure, failure_state);
0546 
0547     /* Check for failures. Any failure causes cpufreq clamping */
0548     if (failure_state && last_failure == 0 && cpufreq_clamp)
0549         wf_control_set_max(cpufreq_clamp);
0550     if (failure_state == 0 && last_failure && cpufreq_clamp)
0551         wf_control_set_min(cpufreq_clamp);
0552 
0553     /* That's it for now, we might want to deal with other failures
0554      * differently in the future though
0555      */
0556 }
0557 
0558 static void pm112_new_control(struct wf_control *ct)
0559 {
0560     int i, max_exhaust;
0561 
0562     if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
0563         if (wf_get_control(ct) == 0)
0564             cpufreq_clamp = ct;
0565     }
0566 
0567     for (i = 0; i < NR_CPU_FANS; ++i) {
0568         if (!strcmp(ct->name, cpu_fan_names[i])) {
0569             if (cpu_fans[i] == NULL && wf_get_control(ct) == 0)
0570                 cpu_fans[i] = ct;
0571             break;
0572         }
0573     }
0574     if (i >= NR_CPU_FANS) {
0575         /* not a CPU fan, try the others */
0576         if (!strcmp(ct->name, "backside-fan")) {
0577             if (backside_fan == NULL && wf_get_control(ct) == 0)
0578                 backside_fan = ct;
0579         } else if (!strcmp(ct->name, "slots-fan")) {
0580             if (slots_fan == NULL && wf_get_control(ct) == 0)
0581                 slots_fan = ct;
0582         } else if (!strcmp(ct->name, "drive-bay-fan")) {
0583             if (drive_bay_fan == NULL && wf_get_control(ct) == 0)
0584                 drive_bay_fan = ct;
0585         }
0586         return;
0587     }
0588 
0589     for (i = 0; i < CPU_FANS_REQD; ++i)
0590         if (cpu_fans[i] == NULL)
0591             return;
0592 
0593     /* work out pump scaling factors */
0594     max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]);
0595     for (i = FIRST_PUMP; i <= LAST_PUMP; ++i)
0596         if ((ct = cpu_fans[i]) != NULL)
0597             cpu_fan_scale[i] =
0598                 ct->ops->get_max(ct) * 100 / max_exhaust;
0599 
0600     have_all_controls = 1;
0601 }
0602 
0603 static void pm112_new_sensor(struct wf_sensor *sr)
0604 {
0605     unsigned int i;
0606 
0607     if (!strncmp(sr->name, "cpu-temp-", 9)) {
0608         i = sr->name[9] - '0';
0609         if (sr->name[10] == 0 && i < NR_CORES &&
0610             sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0)
0611             sens_cpu_temp[i] = sr;
0612 
0613     } else if (!strncmp(sr->name, "cpu-power-", 10)) {
0614         i = sr->name[10] - '0';
0615         if (sr->name[11] == 0 && i < NR_CORES &&
0616             sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0)
0617             sens_cpu_power[i] = sr;
0618     } else if (!strcmp(sr->name, "hd-temp")) {
0619         if (hd_temp == NULL && wf_get_sensor(sr) == 0)
0620             hd_temp = sr;
0621     } else if (!strcmp(sr->name, "slots-power")) {
0622         if (slots_power == NULL && wf_get_sensor(sr) == 0)
0623             slots_power = sr;
0624     } else if (!strcmp(sr->name, "backside-temp")) {
0625         if (u4_temp == NULL && wf_get_sensor(sr) == 0)
0626             u4_temp = sr;
0627     } else
0628         return;
0629 
0630     /* check if we have all the sensors we need */
0631     for (i = 0; i < nr_cores; ++i)
0632         if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL)
0633             return;
0634 
0635     have_all_sensors = 1;
0636 }
0637 
0638 static int pm112_wf_notify(struct notifier_block *self,
0639                unsigned long event, void *data)
0640 {
0641     switch (event) {
0642     case WF_EVENT_NEW_SENSOR:
0643         pm112_new_sensor(data);
0644         break;
0645     case WF_EVENT_NEW_CONTROL:
0646         pm112_new_control(data);
0647         break;
0648     case WF_EVENT_TICK:
0649         if (have_all_controls && have_all_sensors)
0650             pm112_tick();
0651     }
0652     return 0;
0653 }
0654 
0655 static struct notifier_block pm112_events = {
0656     .notifier_call = pm112_wf_notify,
0657 };
0658 
0659 static int wf_pm112_probe(struct platform_device *dev)
0660 {
0661     wf_register_client(&pm112_events);
0662     return 0;
0663 }
0664 
0665 static int wf_pm112_remove(struct platform_device *dev)
0666 {
0667     wf_unregister_client(&pm112_events);
0668     /* should release all sensors and controls */
0669     return 0;
0670 }
0671 
0672 static struct platform_driver wf_pm112_driver = {
0673     .probe = wf_pm112_probe,
0674     .remove = wf_pm112_remove,
0675     .driver = {
0676         .name = "windfarm",
0677     },
0678 };
0679 
0680 static int __init wf_pm112_init(void)
0681 {
0682     struct device_node *cpu;
0683 
0684     if (!of_machine_is_compatible("PowerMac11,2"))
0685         return -ENODEV;
0686 
0687     /* Count the number of CPU cores */
0688     nr_cores = 0;
0689     for_each_node_by_type(cpu, "cpu")
0690         ++nr_cores;
0691 
0692     printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
0693 
0694 #ifdef MODULE
0695     request_module("windfarm_smu_controls");
0696     request_module("windfarm_smu_sensors");
0697     request_module("windfarm_smu_sat");
0698     request_module("windfarm_lm75_sensor");
0699     request_module("windfarm_max6690_sensor");
0700     request_module("windfarm_cpufreq_clamp");
0701 
0702 #endif /* MODULE */
0703 
0704     platform_driver_register(&wf_pm112_driver);
0705     return 0;
0706 }
0707 
0708 static void __exit wf_pm112_exit(void)
0709 {
0710     platform_driver_unregister(&wf_pm112_driver);
0711 }
0712 
0713 module_init(wf_pm112_init);
0714 module_exit(wf_pm112_exit);
0715 
0716 MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
0717 MODULE_DESCRIPTION("Thermal control for PowerMac11,2");
0718 MODULE_LICENSE("GPL");
0719 MODULE_ALIAS("platform:windfarm");