root/drivers/macintosh/windfarm_pm112.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. create_cpu_loop
  2. cpu_max_all_fans
  3. cpu_check_overtemp
  4. cpu_fans_tick
  5. backside_fan_tick
  6. drive_bay_fan_tick
  7. slots_fan_tick
  8. set_fail_state
  9. pm112_tick
  10. pm112_new_control
  11. pm112_new_sensor
  12. pm112_wf_notify
  13. wf_pm112_probe
  14. wf_pm112_remove
  15. wf_pm112_init
  16. wf_pm112_exit

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

/* [<][>][^][v][top][bottom][index][help] */