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