linux/drivers/macintosh/windfarm_pm72.c
<<
>>
Prefs
   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 */
  48static struct wf_sensor *sens_cpu_temp[NR_CHIPS];
  49static struct wf_sensor *sens_cpu_volts[NR_CHIPS];
  50static struct wf_sensor *sens_cpu_amps[NR_CHIPS];
  51static struct wf_sensor *backside_temp;
  52static struct wf_sensor *drives_temp;
  53
  54static struct wf_control *cpu_front_fans[NR_CHIPS];
  55static struct wf_control *cpu_rear_fans[NR_CHIPS];
  56static struct wf_control *cpu_pumps[NR_CHIPS];
  57static struct wf_control *backside_fan;
  58static struct wf_control *drives_fan;
  59static struct wf_control *slots_fan;
  60static 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 */
  72static const struct mpu_data *cpu_mpu_data[NR_CHIPS];
  73static struct wf_cpu_pid_state cpu_pid[NR_CHIPS];
  74static bool cpu_pid_combined;
  75static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
  76static int cpu_thist_pt;
  77static s64 cpu_thist_total;
  78static s32 cpu_all_tmax = 100 << 16;
  79static struct wf_pid_state backside_pid;
  80static int backside_tick;
  81static struct wf_pid_state drives_pid;
  82static int drives_tick;
  83
  84static int nr_chips;
  85static bool have_all_controls;
  86static bool have_all_sensors;
  87static bool started;
  88
  89static 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
 105static 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
 125static 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
 208static 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
 251static 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_warn("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_warn("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
 307static 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_warn("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_warn("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_warn("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... */
 392static 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 */
 439static 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
 451static 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
 463static 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
 502static 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 */
 531static 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
 543static 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_warn("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
 581static 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
 596static 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
 608static 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
 669static 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
 715static 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
 751static 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
 768static struct notifier_block pm72_events = {
 769        .notifier_call = pm72_wf_notify,
 770};
 771
 772static int wf_pm72_probe(struct platform_device *dev)
 773{
 774        wf_register_client(&pm72_events);
 775        return 0;
 776}
 777
 778static 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
 786static struct platform_driver wf_pm72_driver = {
 787        .probe  = wf_pm72_probe,
 788        .remove = wf_pm72_remove,
 789        .driver = {
 790                .name = "windfarm",
 791        },
 792};
 793
 794static 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
 834static void __exit wf_pm72_exit(void)
 835{
 836        platform_driver_unregister(&wf_pm72_driver);
 837}
 838
 839module_init(wf_pm72_init);
 840module_exit(wf_pm72_exit);
 841
 842MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 843MODULE_DESCRIPTION("Thermal control for AGP PowerMac G5s");
 844MODULE_LICENSE("GPL");
 845MODULE_ALIAS("platform:windfarm");
 846