windfarm_pm112.c 18 KB

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