root/drivers/macintosh/windfarm_pm72.c

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

DEFINITIONS

This source file includes following definitions.
  1. cpu_max_all_fans
  2. cpu_check_overtemp
  3. read_one_cpu_vals
  4. cpu_fans_tick_split
  5. cpu_fans_tick_combined
  6. cpu_setup_pid
  7. backside_fan_tick
  8. backside_setup_pid
  9. drives_fan_tick
  10. drives_setup_pid
  11. set_fail_state
  12. pm72_tick
  13. pm72_new_control
  14. pm72_new_sensor
  15. pm72_wf_notify
  16. wf_pm72_probe
  17. wf_pm72_remove
  18. wf_pm72_init
  19. wf_pm72_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Windfarm PowerMac thermal control.
   4  * Control loops for PowerMac7,2 and 7,3
   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 #include <asm/prom.h>
  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 */
  48 static struct wf_sensor *sens_cpu_temp[NR_CHIPS];
  49 static struct wf_sensor *sens_cpu_volts[NR_CHIPS];
  50 static struct wf_sensor *sens_cpu_amps[NR_CHIPS];
  51 static struct wf_sensor *backside_temp;
  52 static struct wf_sensor *drives_temp;
  53 
  54 static struct wf_control *cpu_front_fans[NR_CHIPS];
  55 static struct wf_control *cpu_rear_fans[NR_CHIPS];
  56 static struct wf_control *cpu_pumps[NR_CHIPS];
  57 static struct wf_control *backside_fan;
  58 static struct wf_control *drives_fan;
  59 static struct wf_control *slots_fan;
  60 static struct wf_control *cpufreq_clamp;
  61 
  62 /* We keep a temperature history for average calculation of 180s */
  63 #define CPU_TEMP_HIST_SIZE      180
  64 
  65 /* Fixed speed for slot fan */
  66 #define SLOTS_FAN_DEFAULT_PWM   40
  67 
  68 /* Scale value for CPU intake fans */
  69 #define CPU_INTAKE_SCALE        0x0000f852
  70 
  71 /* PID loop state */
  72 static const struct mpu_data *cpu_mpu_data[NR_CHIPS];
  73 static struct wf_cpu_pid_state cpu_pid[NR_CHIPS];
  74 static bool cpu_pid_combined;
  75 static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
  76 static int cpu_thist_pt;
  77 static s64 cpu_thist_total;
  78 static s32 cpu_all_tmax = 100 << 16;
  79 static struct wf_pid_state backside_pid;
  80 static int backside_tick;
  81 static struct wf_pid_state drives_pid;
  82 static int drives_tick;
  83 
  84 static int nr_chips;
  85 static bool have_all_controls;
  86 static bool have_all_sensors;
  87 static bool started;
  88 
  89 static int failure_state;
  90 #define FAILURE_SENSOR          1
  91 #define FAILURE_FAN             2
  92 #define FAILURE_PERM            4
  93 #define FAILURE_LOW_OVERTEMP    8
  94 #define FAILURE_HIGH_OVERTEMP   16
  95 
  96 /* Overtemp values */
  97 #define LOW_OVER_AVERAGE        0
  98 #define LOW_OVER_IMMEDIATE      (10 << 16)
  99 #define LOW_OVER_CLEAR          ((-10) << 16)
 100 #define HIGH_OVER_IMMEDIATE     (14 << 16)
 101 #define HIGH_OVER_AVERAGE       (10 << 16)
 102 #define HIGH_OVER_IMMEDIATE     (14 << 16)
 103 
 104 
 105 static void cpu_max_all_fans(void)
 106 {
 107         int i;
 108 
 109         /* We max all CPU fans in case of a sensor error. We also do the
 110          * cpufreq clamping now, even if it's supposedly done later by the
 111          * generic code anyway, we do it earlier here to react faster
 112          */
 113         if (cpufreq_clamp)
 114                 wf_control_set_max(cpufreq_clamp);
 115         for (i = 0; i < nr_chips; i++) {
 116                 if (cpu_front_fans[i])
 117                         wf_control_set_max(cpu_front_fans[i]);
 118                 if (cpu_rear_fans[i])
 119                         wf_control_set_max(cpu_rear_fans[i]);
 120                 if (cpu_pumps[i])
 121                         wf_control_set_max(cpu_pumps[i]);
 122         }
 123 }
 124 
 125 static int cpu_check_overtemp(s32 temp)
 126 {
 127         int new_state = 0;
 128         s32 t_avg, t_old;
 129         static bool first = true;
 130 
 131         /* First check for immediate overtemps */
 132         if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
 133                 new_state |= FAILURE_LOW_OVERTEMP;
 134                 if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
 135                         printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
 136                                " temperature !\n");
 137         }
 138         if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
 139                 new_state |= FAILURE_HIGH_OVERTEMP;
 140                 if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
 141                         printk(KERN_ERR "windfarm: Critical overtemp due to"
 142                                " immediate CPU temperature !\n");
 143         }
 144 
 145         /*
 146          * The first time around, initialize the array with the first
 147          * temperature reading
 148          */
 149         if (first) {
 150                 int i;
 151 
 152                 cpu_thist_total = 0;
 153                 for (i = 0; i < CPU_TEMP_HIST_SIZE; i++) {
 154                         cpu_thist[i] = temp;
 155                         cpu_thist_total += temp;
 156                 }
 157                 first = false;
 158         }
 159 
 160         /*
 161          * We calculate a history of max temperatures and use that for the
 162          * overtemp management
 163          */
 164         t_old = cpu_thist[cpu_thist_pt];
 165         cpu_thist[cpu_thist_pt] = temp;
 166         cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
 167         cpu_thist_total -= t_old;
 168         cpu_thist_total += temp;
 169         t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
 170 
 171         DBG_LOTS("  t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
 172                  FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
 173 
 174         /* Now check for average overtemps */
 175         if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
 176                 new_state |= FAILURE_LOW_OVERTEMP;
 177                 if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
 178                         printk(KERN_ERR "windfarm: Overtemp due to average CPU"
 179                                " temperature !\n");
 180         }
 181         if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
 182                 new_state |= FAILURE_HIGH_OVERTEMP;
 183                 if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
 184                         printk(KERN_ERR "windfarm: Critical overtemp due to"
 185                                " average CPU temperature !\n");
 186         }
 187 
 188         /* Now handle overtemp conditions. We don't currently use the windfarm
 189          * overtemp handling core as it's not fully suited to the needs of those
 190          * new machine. This will be fixed later.
 191          */
 192         if (new_state) {
 193                 /* High overtemp -> immediate shutdown */
 194                 if (new_state & FAILURE_HIGH_OVERTEMP)
 195                         machine_power_off();
 196                 if ((failure_state & new_state) != new_state)
 197                         cpu_max_all_fans();
 198                 failure_state |= new_state;
 199         } else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
 200                    (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
 201                 printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
 202                 failure_state &= ~FAILURE_LOW_OVERTEMP;
 203         }
 204 
 205         return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
 206 }
 207 
 208 static int read_one_cpu_vals(int cpu, s32 *temp, s32 *power)
 209 {
 210         s32 dtemp, volts, amps;
 211         int rc;
 212 
 213         /* Get diode temperature */
 214         rc = wf_sensor_get(sens_cpu_temp[cpu], &dtemp);
 215         if (rc) {
 216                 DBG("  CPU%d: temp reading error !\n", cpu);
 217                 return -EIO;
 218         }
 219         DBG_LOTS("  CPU%d: temp   = %d.%03d\n", cpu, FIX32TOPRINT((dtemp)));
 220         *temp = dtemp;
 221 
 222         /* Get voltage */
 223         rc = wf_sensor_get(sens_cpu_volts[cpu], &volts);
 224         if (rc) {
 225                 DBG("  CPU%d, volts reading error !\n", cpu);
 226                 return -EIO;
 227         }
 228         DBG_LOTS("  CPU%d: volts  = %d.%03d\n", cpu, FIX32TOPRINT((volts)));
 229 
 230         /* Get current */
 231         rc = wf_sensor_get(sens_cpu_amps[cpu], &amps);
 232         if (rc) {
 233                 DBG("  CPU%d, current reading error !\n", cpu);
 234                 return -EIO;
 235         }
 236         DBG_LOTS("  CPU%d: amps   = %d.%03d\n", cpu, FIX32TOPRINT((amps)));
 237 
 238         /* Calculate power */
 239 
 240         /* Scale voltage and current raw sensor values according to fixed scales
 241          * obtained in Darwin and calculate power from I and V
 242          */
 243         *power = (((u64)volts) * ((u64)amps)) >> 16;
 244 
 245         DBG_LOTS("  CPU%d: power  = %d.%03d\n", cpu, FIX32TOPRINT((*power)));
 246 
 247         return 0;
 248 
 249 }
 250 
 251 static void cpu_fans_tick_split(void)
 252 {
 253         int err, cpu;
 254         s32 intake, temp, power, t_max = 0;
 255 
 256         DBG_LOTS("* cpu fans_tick_split()\n");
 257 
 258         for (cpu = 0; cpu < nr_chips; ++cpu) {
 259                 struct wf_cpu_pid_state *sp = &cpu_pid[cpu];
 260 
 261                 /* Read current speed */
 262                 wf_control_get(cpu_rear_fans[cpu], &sp->target);
 263 
 264                 DBG_LOTS("  CPU%d: cur_target = %d RPM\n", cpu, sp->target);
 265 
 266                 err = read_one_cpu_vals(cpu, &temp, &power);
 267                 if (err) {
 268                         failure_state |= FAILURE_SENSOR;
 269                         cpu_max_all_fans();
 270                         return;
 271                 }
 272 
 273                 /* Keep track of highest temp */
 274                 t_max = max(t_max, temp);
 275 
 276                 /* Handle possible overtemps */
 277                 if (cpu_check_overtemp(t_max))
 278                         return;
 279 
 280                 /* Run PID */
 281                 wf_cpu_pid_run(sp, power, temp);
 282 
 283                 DBG_LOTS("  CPU%d: target = %d RPM\n", cpu, sp->target);
 284 
 285                 /* Apply result directly to exhaust fan */
 286                 err = wf_control_set(cpu_rear_fans[cpu], sp->target);
 287                 if (err) {
 288                         pr_warning("wf_pm72: Fan %s reports error %d\n",
 289                                cpu_rear_fans[cpu]->name, err);
 290                         failure_state |= FAILURE_FAN;
 291                         break;
 292                 }
 293 
 294                 /* Scale result for intake fan */
 295                 intake = (sp->target * CPU_INTAKE_SCALE) >> 16;
 296                 DBG_LOTS("  CPU%d: intake = %d RPM\n", cpu, intake);
 297                 err = wf_control_set(cpu_front_fans[cpu], intake);
 298                 if (err) {
 299                         pr_warning("wf_pm72: Fan %s reports error %d\n",
 300                                cpu_front_fans[cpu]->name, err);
 301                         failure_state |= FAILURE_FAN;
 302                         break;
 303                 }
 304         }
 305 }
 306 
 307 static void cpu_fans_tick_combined(void)
 308 {
 309         s32 temp0, power0, temp1, power1, t_max = 0;
 310         s32 temp, power, intake, pump;
 311         struct wf_control *pump0, *pump1;
 312         struct wf_cpu_pid_state *sp = &cpu_pid[0];
 313         int err, cpu;
 314 
 315         DBG_LOTS("* cpu fans_tick_combined()\n");
 316 
 317         /* Read current speed from cpu 0 */
 318         wf_control_get(cpu_rear_fans[0], &sp->target);
 319 
 320         DBG_LOTS("  CPUs: cur_target = %d RPM\n", sp->target);
 321 
 322         /* Read values for both CPUs */
 323         err = read_one_cpu_vals(0, &temp0, &power0);
 324         if (err) {
 325                 failure_state |= FAILURE_SENSOR;
 326                 cpu_max_all_fans();
 327                 return;
 328         }
 329         err = read_one_cpu_vals(1, &temp1, &power1);
 330         if (err) {
 331                 failure_state |= FAILURE_SENSOR;
 332                 cpu_max_all_fans();
 333                 return;
 334         }
 335 
 336         /* Keep track of highest temp */
 337         t_max = max(t_max, max(temp0, temp1));
 338 
 339         /* Handle possible overtemps */
 340         if (cpu_check_overtemp(t_max))
 341                 return;
 342 
 343         /* Use the max temp & power of both */
 344         temp = max(temp0, temp1);
 345         power = max(power0, power1);
 346 
 347         /* Run PID */
 348         wf_cpu_pid_run(sp, power, temp);
 349 
 350         /* Scale result for intake fan */
 351         intake = (sp->target * CPU_INTAKE_SCALE) >> 16;
 352 
 353         /* Same deal with pump speed */
 354         pump0 = cpu_pumps[0];
 355         pump1 = cpu_pumps[1];
 356         if (!pump0) {
 357                 pump0 = pump1;
 358                 pump1 = NULL;
 359         }
 360         pump = (sp->target * wf_control_get_max(pump0)) /
 361                 cpu_mpu_data[0]->rmaxn_exhaust_fan;
 362 
 363         DBG_LOTS("  CPUs: target = %d RPM\n", sp->target);
 364         DBG_LOTS("  CPUs: intake = %d RPM\n", intake);
 365         DBG_LOTS("  CPUs: pump   = %d RPM\n", pump);
 366 
 367         for (cpu = 0; cpu < nr_chips; cpu++) {
 368                 err = wf_control_set(cpu_rear_fans[cpu], sp->target);
 369                 if (err) {
 370                         pr_warning("wf_pm72: Fan %s reports error %d\n",
 371                                    cpu_rear_fans[cpu]->name, err);
 372                         failure_state |= FAILURE_FAN;
 373                 }
 374                 err = wf_control_set(cpu_front_fans[cpu], intake);
 375                 if (err) {
 376                         pr_warning("wf_pm72: Fan %s reports error %d\n",
 377                                    cpu_front_fans[cpu]->name, err);
 378                         failure_state |= FAILURE_FAN;
 379                 }
 380                 err = 0;
 381                 if (cpu_pumps[cpu])
 382                         err = wf_control_set(cpu_pumps[cpu], pump);
 383                 if (err) {
 384                         pr_warning("wf_pm72: Pump %s reports error %d\n",
 385                                    cpu_pumps[cpu]->name, err);
 386                         failure_state |= FAILURE_FAN;
 387                 }
 388         }
 389 }
 390 
 391 /* Implementation... */
 392 static int cpu_setup_pid(int cpu)
 393 {
 394         struct wf_cpu_pid_param pid;
 395         const struct mpu_data *mpu = cpu_mpu_data[cpu];
 396         s32 tmax, ttarget, ptarget;
 397         int fmin, fmax, hsize;
 398 
 399         /* Get PID params from the appropriate MPU EEPROM */
 400         tmax = mpu->tmax << 16;
 401         ttarget = mpu->ttarget << 16;
 402         ptarget = ((s32)(mpu->pmaxh - mpu->padjmax)) << 16;
 403 
 404         DBG("wf_72: CPU%d ttarget = %d.%03d, tmax = %d.%03d\n",
 405             cpu, FIX32TOPRINT(ttarget), FIX32TOPRINT(tmax));
 406 
 407         /* We keep a global tmax for overtemp calculations */
 408         if (tmax < cpu_all_tmax)
 409                 cpu_all_tmax = tmax;
 410 
 411         /* Set PID min/max by using the rear fan min/max */
 412         fmin = wf_control_get_min(cpu_rear_fans[cpu]);
 413         fmax = wf_control_get_max(cpu_rear_fans[cpu]);
 414         DBG("wf_72: CPU%d max RPM range = [%d..%d]\n", cpu, fmin, fmax);
 415 
 416         /* History size */
 417         hsize = min_t(int, mpu->tguardband, WF_PID_MAX_HISTORY);
 418         DBG("wf_72: CPU%d history size = %d\n", cpu, hsize);
 419 
 420         /* Initialize PID loop */
 421         pid.interval    = 1;    /* seconds */
 422         pid.history_len = hsize;
 423         pid.gd          = mpu->pid_gd;
 424         pid.gp          = mpu->pid_gp;
 425         pid.gr          = mpu->pid_gr;
 426         pid.tmax        = tmax;
 427         pid.ttarget     = ttarget;
 428         pid.pmaxadj     = ptarget;
 429         pid.min         = fmin;
 430         pid.max         = fmax;
 431 
 432         wf_cpu_pid_init(&cpu_pid[cpu], &pid);
 433         cpu_pid[cpu].target = 1000;
 434 
 435         return 0;
 436 }
 437 
 438 /* Backside/U3 fan */
 439 static struct wf_pid_param backside_u3_param = {
 440         .interval       = 5,
 441         .history_len    = 2,
 442         .gd             = 40 << 20,
 443         .gp             = 5 << 20,
 444         .gr             = 0,
 445         .itarget        = 65 << 16,
 446         .additive       = 1,
 447         .min            = 20,
 448         .max            = 100,
 449 };
 450 
 451 static struct wf_pid_param backside_u3h_param = {
 452         .interval       = 5,
 453         .history_len    = 2,
 454         .gd             = 20 << 20,
 455         .gp             = 5 << 20,
 456         .gr             = 0,
 457         .itarget        = 75 << 16,
 458         .additive       = 1,
 459         .min            = 20,
 460         .max            = 100,
 461 };
 462 
 463 static void backside_fan_tick(void)
 464 {
 465         s32 temp;
 466         int speed;
 467         int err;
 468 
 469         if (!backside_fan || !backside_temp || !backside_tick)
 470                 return;
 471         if (--backside_tick > 0)
 472                 return;
 473         backside_tick = backside_pid.param.interval;
 474 
 475         DBG_LOTS("* backside fans tick\n");
 476 
 477         /* Update fan speed from actual fans */
 478         err = wf_control_get(backside_fan, &speed);
 479         if (!err)
 480                 backside_pid.target = speed;
 481 
 482         err = wf_sensor_get(backside_temp, &temp);
 483         if (err) {
 484                 printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
 485                        err);
 486                 failure_state |= FAILURE_SENSOR;
 487                 wf_control_set_max(backside_fan);
 488                 return;
 489         }
 490         speed = wf_pid_run(&backside_pid, temp);
 491 
 492         DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
 493                  FIX32TOPRINT(temp), speed);
 494 
 495         err = wf_control_set(backside_fan, speed);
 496         if (err) {
 497                 printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
 498                 failure_state |= FAILURE_FAN;
 499         }
 500 }
 501 
 502 static void backside_setup_pid(void)
 503 {
 504         /* first time initialize things */
 505         s32 fmin = wf_control_get_min(backside_fan);
 506         s32 fmax = wf_control_get_max(backside_fan);
 507         struct wf_pid_param param;
 508         struct device_node *u3;
 509         int u3h = 1; /* conservative by default */
 510 
 511         u3 = of_find_node_by_path("/u3@0,f8000000");
 512         if (u3 != NULL) {
 513                 const u32 *vers = of_get_property(u3, "device-rev", NULL);
 514                 if (vers)
 515                         if (((*vers) & 0x3f) < 0x34)
 516                                 u3h = 0;
 517                 of_node_put(u3);
 518         }
 519 
 520         param = u3h ? backside_u3h_param : backside_u3_param;
 521 
 522         param.min = max(param.min, fmin);
 523         param.max = min(param.max, fmax);
 524         wf_pid_init(&backside_pid, &param);
 525         backside_tick = 1;
 526 
 527         pr_info("wf_pm72: Backside control loop started.\n");
 528 }
 529 
 530 /* Drive bay fan */
 531 static const struct wf_pid_param drives_param = {
 532         .interval       = 5,
 533         .history_len    = 2,
 534         .gd             = 30 << 20,
 535         .gp             = 5 << 20,
 536         .gr             = 0,
 537         .itarget        = 40 << 16,
 538         .additive       = 1,
 539         .min            = 300,
 540         .max            = 4000,
 541 };
 542 
 543 static void drives_fan_tick(void)
 544 {
 545         s32 temp;
 546         int speed;
 547         int err;
 548 
 549         if (!drives_fan || !drives_temp || !drives_tick)
 550                 return;
 551         if (--drives_tick > 0)
 552                 return;
 553         drives_tick = drives_pid.param.interval;
 554 
 555         DBG_LOTS("* drives fans tick\n");
 556 
 557         /* Update fan speed from actual fans */
 558         err = wf_control_get(drives_fan, &speed);
 559         if (!err)
 560                 drives_pid.target = speed;
 561 
 562         err = wf_sensor_get(drives_temp, &temp);
 563         if (err) {
 564                 pr_warning("wf_pm72: drive bay temp sensor error %d\n", err);
 565                 failure_state |= FAILURE_SENSOR;
 566                 wf_control_set_max(drives_fan);
 567                 return;
 568         }
 569         speed = wf_pid_run(&drives_pid, temp);
 570 
 571         DBG_LOTS("drives PID temp=%d.%.3d speed=%d\n",
 572                  FIX32TOPRINT(temp), speed);
 573 
 574         err = wf_control_set(drives_fan, speed);
 575         if (err) {
 576                 printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
 577                 failure_state |= FAILURE_FAN;
 578         }
 579 }
 580 
 581 static void drives_setup_pid(void)
 582 {
 583         /* first time initialize things */
 584         s32 fmin = wf_control_get_min(drives_fan);
 585         s32 fmax = wf_control_get_max(drives_fan);
 586         struct wf_pid_param param = drives_param;
 587 
 588         param.min = max(param.min, fmin);
 589         param.max = min(param.max, fmax);
 590         wf_pid_init(&drives_pid, &param);
 591         drives_tick = 1;
 592 
 593         pr_info("wf_pm72: Drive bay control loop started.\n");
 594 }
 595 
 596 static void set_fail_state(void)
 597 {
 598         cpu_max_all_fans();
 599 
 600         if (backside_fan)
 601                 wf_control_set_max(backside_fan);
 602         if (slots_fan)
 603                 wf_control_set_max(slots_fan);
 604         if (drives_fan)
 605                 wf_control_set_max(drives_fan);
 606 }
 607 
 608 static void pm72_tick(void)
 609 {
 610         int i, last_failure;
 611 
 612         if (!started) {
 613                 started = true;
 614                 printk(KERN_INFO "windfarm: CPUs control loops started.\n");
 615                 for (i = 0; i < nr_chips; ++i) {
 616                         if (cpu_setup_pid(i) < 0) {
 617                                 failure_state = FAILURE_PERM;
 618                                 set_fail_state();
 619                                 break;
 620                         }
 621                 }
 622                 DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
 623 
 624                 backside_setup_pid();
 625                 drives_setup_pid();
 626 
 627                 /*
 628                  * We don't have the right stuff to drive the PCI fan
 629                  * so we fix it to a default value
 630                  */
 631                 wf_control_set(slots_fan, SLOTS_FAN_DEFAULT_PWM);
 632 
 633 #ifdef HACKED_OVERTEMP
 634                 cpu_all_tmax = 60 << 16;
 635 #endif
 636         }
 637 
 638         /* Permanent failure, bail out */
 639         if (failure_state & FAILURE_PERM)
 640                 return;
 641 
 642         /*
 643          * Clear all failure bits except low overtemp which will be eventually
 644          * cleared by the control loop itself
 645          */
 646         last_failure = failure_state;
 647         failure_state &= FAILURE_LOW_OVERTEMP;
 648         if (cpu_pid_combined)
 649                 cpu_fans_tick_combined();
 650         else
 651                 cpu_fans_tick_split();
 652         backside_fan_tick();
 653         drives_fan_tick();
 654 
 655         DBG_LOTS("  last_failure: 0x%x, failure_state: %x\n",
 656                  last_failure, failure_state);
 657 
 658         /* Check for failures. Any failure causes cpufreq clamping */
 659         if (failure_state && last_failure == 0 && cpufreq_clamp)
 660                 wf_control_set_max(cpufreq_clamp);
 661         if (failure_state == 0 && last_failure && cpufreq_clamp)
 662                 wf_control_set_min(cpufreq_clamp);
 663 
 664         /* That's it for now, we might want to deal with other failures
 665          * differently in the future though
 666          */
 667 }
 668 
 669 static void pm72_new_control(struct wf_control *ct)
 670 {
 671         bool all_controls;
 672         bool had_pump = cpu_pumps[0] || cpu_pumps[1];
 673 
 674         if (!strcmp(ct->name, "cpu-front-fan-0"))
 675                 cpu_front_fans[0] = ct;
 676         else if (!strcmp(ct->name, "cpu-front-fan-1"))
 677                 cpu_front_fans[1] = ct;
 678         else if (!strcmp(ct->name, "cpu-rear-fan-0"))
 679                 cpu_rear_fans[0] = ct;
 680         else if (!strcmp(ct->name, "cpu-rear-fan-1"))
 681                 cpu_rear_fans[1] = ct;
 682         else if (!strcmp(ct->name, "cpu-pump-0"))
 683                 cpu_pumps[0] = ct;
 684         else if (!strcmp(ct->name, "cpu-pump-1"))
 685                 cpu_pumps[1] = ct;
 686         else if (!strcmp(ct->name, "backside-fan"))
 687                 backside_fan = ct;
 688         else if (!strcmp(ct->name, "slots-fan"))
 689                 slots_fan = ct;
 690         else if (!strcmp(ct->name, "drive-bay-fan"))
 691                 drives_fan = ct;
 692         else if (!strcmp(ct->name, "cpufreq-clamp"))
 693                 cpufreq_clamp = ct;
 694 
 695         all_controls =
 696                 cpu_front_fans[0] &&
 697                 cpu_rear_fans[0] &&
 698                 backside_fan &&
 699                 slots_fan &&
 700                 drives_fan;
 701         if (nr_chips > 1)
 702                 all_controls &=
 703                         cpu_front_fans[1] &&
 704                         cpu_rear_fans[1];
 705         have_all_controls = all_controls;
 706 
 707         if ((cpu_pumps[0] || cpu_pumps[1]) && !had_pump) {
 708                 pr_info("wf_pm72: Liquid cooling pump(s) detected,"
 709                         " using new algorithm !\n");
 710                 cpu_pid_combined = true;
 711         }
 712 }
 713 
 714 
 715 static void pm72_new_sensor(struct wf_sensor *sr)
 716 {
 717         bool all_sensors;
 718 
 719         if (!strcmp(sr->name, "cpu-diode-temp-0"))
 720                 sens_cpu_temp[0] = sr;
 721         else if (!strcmp(sr->name, "cpu-diode-temp-1"))
 722                 sens_cpu_temp[1] = sr;
 723         else if (!strcmp(sr->name, "cpu-voltage-0"))
 724                 sens_cpu_volts[0] = sr;
 725         else if (!strcmp(sr->name, "cpu-voltage-1"))
 726                 sens_cpu_volts[1] = sr;
 727         else if (!strcmp(sr->name, "cpu-current-0"))
 728                 sens_cpu_amps[0] = sr;
 729         else if (!strcmp(sr->name, "cpu-current-1"))
 730                 sens_cpu_amps[1] = sr;
 731         else if (!strcmp(sr->name, "backside-temp"))
 732                 backside_temp = sr;
 733         else if (!strcmp(sr->name, "hd-temp"))
 734                 drives_temp = sr;
 735 
 736         all_sensors =
 737                 sens_cpu_temp[0] &&
 738                 sens_cpu_volts[0] &&
 739                 sens_cpu_amps[0] &&
 740                 backside_temp &&
 741                 drives_temp;
 742         if (nr_chips > 1)
 743                 all_sensors &=
 744                         sens_cpu_temp[1] &&
 745                         sens_cpu_volts[1] &&
 746                         sens_cpu_amps[1];
 747 
 748         have_all_sensors = all_sensors;
 749 }
 750 
 751 static int pm72_wf_notify(struct notifier_block *self,
 752                           unsigned long event, void *data)
 753 {
 754         switch (event) {
 755         case WF_EVENT_NEW_SENSOR:
 756                 pm72_new_sensor(data);
 757                 break;
 758         case WF_EVENT_NEW_CONTROL:
 759                 pm72_new_control(data);
 760                 break;
 761         case WF_EVENT_TICK:
 762                 if (have_all_controls && have_all_sensors)
 763                         pm72_tick();
 764         }
 765         return 0;
 766 }
 767 
 768 static struct notifier_block pm72_events = {
 769         .notifier_call = pm72_wf_notify,
 770 };
 771 
 772 static int wf_pm72_probe(struct platform_device *dev)
 773 {
 774         wf_register_client(&pm72_events);
 775         return 0;
 776 }
 777 
 778 static int wf_pm72_remove(struct platform_device *dev)
 779 {
 780         wf_unregister_client(&pm72_events);
 781 
 782         /* should release all sensors and controls */
 783         return 0;
 784 }
 785 
 786 static struct platform_driver wf_pm72_driver = {
 787         .probe  = wf_pm72_probe,
 788         .remove = wf_pm72_remove,
 789         .driver = {
 790                 .name = "windfarm",
 791         },
 792 };
 793 
 794 static int __init wf_pm72_init(void)
 795 {
 796         struct device_node *cpu;
 797         int i;
 798 
 799         if (!of_machine_is_compatible("PowerMac7,2") &&
 800             !of_machine_is_compatible("PowerMac7,3"))
 801                 return -ENODEV;
 802 
 803         /* Count the number of CPU cores */
 804         nr_chips = 0;
 805         for_each_node_by_type(cpu, "cpu")
 806                 ++nr_chips;
 807         if (nr_chips > NR_CHIPS)
 808                 nr_chips = NR_CHIPS;
 809 
 810         pr_info("windfarm: Initializing for desktop G5 with %d chips\n",
 811                 nr_chips);
 812 
 813         /* Get MPU data for each CPU */
 814         for (i = 0; i < nr_chips; i++) {
 815                 cpu_mpu_data[i] = wf_get_mpu(i);
 816                 if (!cpu_mpu_data[i]) {
 817                         pr_err("wf_pm72: Failed to find MPU data for CPU %d\n", i);
 818                         return -ENXIO;
 819                 }
 820         }
 821 
 822 #ifdef MODULE
 823         request_module("windfarm_fcu_controls");
 824         request_module("windfarm_lm75_sensor");
 825         request_module("windfarm_ad7417_sensor");
 826         request_module("windfarm_max6690_sensor");
 827         request_module("windfarm_cpufreq_clamp");
 828 #endif /* MODULE */
 829 
 830         platform_driver_register(&wf_pm72_driver);
 831         return 0;
 832 }
 833 
 834 static void __exit wf_pm72_exit(void)
 835 {
 836         platform_driver_unregister(&wf_pm72_driver);
 837 }
 838 
 839 module_init(wf_pm72_init);
 840 module_exit(wf_pm72_exit);
 841 
 842 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 843 MODULE_DESCRIPTION("Thermal control for AGP PowerMac G5s");
 844 MODULE_LICENSE("GPL");
 845 MODULE_ALIAS("platform:windfarm");

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