aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/macintosh
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/Kconfig23
-rw-r--r--drivers/macintosh/Makefile14
-rw-r--r--drivers/macintosh/adb.c4
-rw-r--r--drivers/macintosh/ams/ams-core.c4
-rw-r--r--drivers/macintosh/ams/ams-i2c.c2
-rw-r--r--drivers/macintosh/ams/ams-input.c4
-rw-r--r--drivers/macintosh/macio-adb.c1
-rw-r--r--drivers/macintosh/macio_asic.c8
-rw-r--r--drivers/macintosh/mediabay.c13
-rw-r--r--drivers/macintosh/rack-meter.c26
-rw-r--r--drivers/macintosh/smu.c11
-rw-r--r--drivers/macintosh/therm_adt746x.c483
-rw-r--r--drivers/macintosh/therm_pm72.c1
-rw-r--r--drivers/macintosh/therm_windtunnel.c1
-rw-r--r--drivers/macintosh/via-cuda.c1
-rw-r--r--drivers/macintosh/via-macii.c3
-rw-r--r--drivers/macintosh/via-maciisi.c4
-rw-r--r--drivers/macintosh/via-pmu.c1
-rw-r--r--drivers/macintosh/via-pmu68k.c1
-rw-r--r--drivers/macintosh/windfarm.h51
-rw-r--r--drivers/macintosh/windfarm_ad7417_sensor.c347
-rw-r--r--drivers/macintosh/windfarm_core.c23
-rw-r--r--drivers/macintosh/windfarm_cpufreq_clamp.c6
-rw-r--r--drivers/macintosh/windfarm_fcu_controls.c600
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c150
-rw-r--r--drivers/macintosh/windfarm_lm87_sensor.c201
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c122
-rw-r--r--drivers/macintosh/windfarm_mpu.h105
-rw-r--r--drivers/macintosh/windfarm_pm112.c4
-rw-r--r--drivers/macintosh/windfarm_pm121.c5
-rw-r--r--drivers/macintosh/windfarm_pm72.c847
-rw-r--r--drivers/macintosh/windfarm_pm81.c30
-rw-r--r--drivers/macintosh/windfarm_pm91.c38
-rw-r--r--drivers/macintosh/windfarm_rm31.c740
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c2
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c143
-rw-r--r--drivers/macintosh/windfarm_smu_sensors.c1
37 files changed, 701 insertions, 3319 deletions
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index a555da64224..fa51af11c6f 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -204,14 +204,11 @@ config THERM_ADT746X
204 better fan behaviour by default, and some manual control. 204 better fan behaviour by default, and some manual control.
205 205
206config THERM_PM72 206config THERM_PM72
207 tristate "Support for thermal management on PowerMac G5 (AGP)" 207 tristate "Support for thermal management on PowerMac G5"
208 depends on I2C && I2C_POWERMAC && PPC_PMAC64 208 depends on I2C && I2C_POWERMAC && PPC_PMAC64
209 default n
210 help 209 help
211 This driver provides thermostat and fan control for the desktop 210 This driver provides thermostat and fan control for the desktop
212 G5 machines. 211 G5 machines.
213
214 This is deprecated, use windfarm instead.
215 212
216config WINDFARM 213config WINDFARM
217 tristate "New PowerMac thermal control infrastructure" 214 tristate "New PowerMac thermal control infrastructure"
@@ -224,22 +221,6 @@ config WINDFARM_PM81
224 help 221 help
225 This driver provides thermal control for the iMacG5 222 This driver provides thermal control for the iMacG5
226 223
227config WINDFARM_PM72
228 tristate "Support for thermal management on PowerMac G5 (AGP)"
229 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && ADB_PMU
230 select I2C_POWERMAC
231 help
232 This driver provides thermal control for the PowerMac G5
233 "AGP" variants (PowerMac 7,2 and 7,3)
234
235config WINDFARM_RM31
236 tristate "Support for thermal management on Xserve G5"
237 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && ADB_PMU
238 select I2C_POWERMAC
239 help
240 This driver provides thermal control for the Xserve G5
241 (RackMac3,1)
242
243config WINDFARM_PM91 224config WINDFARM_PM91
244 tristate "Support for thermal management on PowerMac9,1" 225 tristate "Support for thermal management on PowerMac9,1"
245 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU 226 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 6753b65f8ed..6652a6ebb6f 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -29,20 +29,6 @@ obj-$(CONFIG_THERM_PM72) += therm_pm72.o
29obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o 29obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o
30obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o 30obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o
31obj-$(CONFIG_WINDFARM) += windfarm_core.o 31obj-$(CONFIG_WINDFARM) += windfarm_core.o
32obj-$(CONFIG_WINDFARM_PM72) += windfarm_fcu_controls.o \
33 windfarm_ad7417_sensor.o \
34 windfarm_lm75_sensor.o \
35 windfarm_max6690_sensor.o \
36 windfarm_pid.o \
37 windfarm_cpufreq_clamp.o \
38 windfarm_pm72.o
39obj-$(CONFIG_WINDFARM_RM31) += windfarm_fcu_controls.o \
40 windfarm_ad7417_sensor.o \
41 windfarm_lm75_sensor.o \
42 windfarm_lm87_sensor.o \
43 windfarm_pid.o \
44 windfarm_cpufreq_clamp.o \
45 windfarm_rm31.o
46obj-$(CONFIG_WINDFARM_PM81) += windfarm_smu_controls.o \ 32obj-$(CONFIG_WINDFARM_PM81) += windfarm_smu_controls.o \
47 windfarm_smu_sensors.o \ 33 windfarm_smu_sensors.o \
48 windfarm_lm75_sensor.o windfarm_pid.o \ 34 windfarm_lm75_sensor.o windfarm_pid.o \
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index b026896206c..75049e76519 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -710,7 +710,7 @@ static ssize_t adb_read(struct file *file, char __user *buf,
710 req = NULL; 710 req = NULL;
711 spin_lock_irqsave(&state->lock, flags); 711 spin_lock_irqsave(&state->lock, flags);
712 add_wait_queue(&state->wait_queue, &wait); 712 add_wait_queue(&state->wait_queue, &wait);
713 set_current_state(TASK_INTERRUPTIBLE); 713 current->state = TASK_INTERRUPTIBLE;
714 714
715 for (;;) { 715 for (;;) {
716 req = state->completed; 716 req = state->completed;
@@ -734,7 +734,7 @@ static ssize_t adb_read(struct file *file, char __user *buf,
734 spin_lock_irqsave(&state->lock, flags); 734 spin_lock_irqsave(&state->lock, flags);
735 } 735 }
736 736
737 set_current_state(TASK_RUNNING); 737 current->state = TASK_RUNNING;
738 remove_wait_queue(&state->wait_queue, &wait); 738 remove_wait_queue(&state->wait_queue, &wait);
739 spin_unlock_irqrestore(&state->lock, flags); 739 spin_unlock_irqrestore(&state->lock, flags);
740 740
diff --git a/drivers/macintosh/ams/ams-core.c b/drivers/macintosh/ams/ams-core.c
index 36a4fdddd64..399beb1638d 100644
--- a/drivers/macintosh/ams/ams-core.c
+++ b/drivers/macintosh/ams/ams-core.c
@@ -31,7 +31,7 @@
31/* There is only one motion sensor per machine */ 31/* There is only one motion sensor per machine */
32struct ams ams_info; 32struct ams ams_info;
33 33
34static bool verbose; 34static unsigned int verbose;
35module_param(verbose, bool, 0644); 35module_param(verbose, bool, 0644);
36MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output"); 36MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
37 37
@@ -226,7 +226,7 @@ void ams_sensor_detach(void)
226 * We do this after ams_info.exit(), because an interrupt might 226 * We do this after ams_info.exit(), because an interrupt might
227 * have arrived before disabling them. 227 * have arrived before disabling them.
228 */ 228 */
229 flush_work(&ams_info.worker); 229 flush_work_sync(&ams_info.worker);
230 230
231 /* Remove device */ 231 /* Remove device */
232 of_device_unregister(ams_info.of_dev); 232 of_device_unregister(ams_info.of_dev);
diff --git a/drivers/macintosh/ams/ams-i2c.c b/drivers/macintosh/ams/ams-i2c.c
index 978eda8d667..abeecd27b48 100644
--- a/drivers/macintosh/ams/ams-i2c.c
+++ b/drivers/macintosh/ams/ams-i2c.c
@@ -65,7 +65,7 @@ static int ams_i2c_probe(struct i2c_client *client,
65static int ams_i2c_remove(struct i2c_client *client); 65static int ams_i2c_remove(struct i2c_client *client);
66 66
67static const struct i2c_device_id ams_id[] = { 67static const struct i2c_device_id ams_id[] = {
68 { "MAC,accelerometer_1", 0 }, 68 { "ams", 0 },
69 { } 69 { }
70}; 70};
71MODULE_DEVICE_TABLE(i2c, ams_id); 71MODULE_DEVICE_TABLE(i2c, ams_id);
diff --git a/drivers/macintosh/ams/ams-input.c b/drivers/macintosh/ams/ams-input.c
index b27e530a87a..8a712392cd3 100644
--- a/drivers/macintosh/ams/ams-input.c
+++ b/drivers/macintosh/ams/ams-input.c
@@ -19,11 +19,11 @@
19 19
20#include "ams.h" 20#include "ams.h"
21 21
22static bool joystick; 22static unsigned int joystick;
23module_param(joystick, bool, S_IRUGO); 23module_param(joystick, bool, S_IRUGO);
24MODULE_PARM_DESC(joystick, "Enable the input class device on module load"); 24MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
25 25
26static bool invert; 26static unsigned int invert;
27module_param(invert, bool, S_IWUSR | S_IRUGO); 27module_param(invert, bool, S_IWUSR | S_IRUGO);
28MODULE_PARM_DESC(invert, "Invert input data on X and Y axis"); 28MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
29 29
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
index 87de8d9bcfa..b6ef8f59076 100644
--- a/drivers/macintosh/macio-adb.c
+++ b/drivers/macintosh/macio-adb.c
@@ -14,6 +14,7 @@
14#include <asm/pgtable.h> 14#include <asm/pgtable.h>
15#include <asm/hydra.h> 15#include <asm/hydra.h>
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/system.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/ioport.h> 19#include <linux/ioport.h>
19 20
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index ac5c8793986..4daf9e5a773 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -137,7 +137,7 @@ extern struct device_attribute macio_dev_attrs[];
137struct bus_type macio_bus_type = { 137struct bus_type macio_bus_type = {
138 .name = "macio", 138 .name = "macio",
139 .match = macio_bus_match, 139 .match = macio_bus_match,
140 .uevent = of_device_uevent_modalias, 140 .uevent = of_device_uevent,
141 .probe = macio_device_probe, 141 .probe = macio_device_probe,
142 .remove = macio_device_remove, 142 .remove = macio_device_remove,
143 .shutdown = macio_device_shutdown, 143 .shutdown = macio_device_shutdown,
@@ -679,7 +679,7 @@ void macio_release_resources(struct macio_dev *dev)
679 679
680#ifdef CONFIG_PCI 680#ifdef CONFIG_PCI
681 681
682static int macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 682static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
683{ 683{
684 struct device_node* np; 684 struct device_node* np;
685 struct macio_chip* chip; 685 struct macio_chip* chip;
@@ -739,7 +739,7 @@ static int macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
739 return 0; 739 return 0;
740} 740}
741 741
742static void macio_pci_remove(struct pci_dev* pdev) 742static void __devexit macio_pci_remove(struct pci_dev* pdev)
743{ 743{
744 panic("removing of macio-asic not supported !\n"); 744 panic("removing of macio-asic not supported !\n");
745} 745}
@@ -748,7 +748,7 @@ static void macio_pci_remove(struct pci_dev* pdev)
748 * MacIO is matched against any Apple ID, it's probe() function 748 * MacIO is matched against any Apple ID, it's probe() function
749 * will then decide wether it applies or not 749 * will then decide wether it applies or not
750 */ 750 */
751static const struct pci_device_id pci_ids[] = { { 751static const struct pci_device_id __devinitdata pci_ids [] = { {
752 .vendor = PCI_VENDOR_ID_APPLE, 752 .vendor = PCI_VENDOR_ID_APPLE,
753 .device = PCI_ANY_ID, 753 .device = PCI_ANY_ID,
754 .subvendor = PCI_ANY_ID, 754 .subvendor = PCI_ANY_ID,
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index d98e566a8f5..2fd435bc542 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -63,7 +63,7 @@ struct media_bay_info {
63 int value_count; 63 int value_count;
64 int timer; 64 int timer;
65 struct macio_dev *mdev; 65 struct macio_dev *mdev;
66 const struct mb_ops* ops; 66 struct mb_ops* ops;
67 int index; 67 int index;
68 int cached_gpio; 68 int cached_gpio;
69 int sleeping; 69 int sleeping;
@@ -356,7 +356,7 @@ static void poll_media_bay(struct media_bay_info* bay)
356 static char *mb_content_types[] = { 356 static char *mb_content_types[] = {
357 "a floppy drive", 357 "a floppy drive",
358 "a floppy drive", 358 "a floppy drive",
359 "an unsupported audio device", 359 "an unsuported audio device",
360 "an ATA device", 360 "an ATA device",
361 "an unsupported PCI device", 361 "an unsupported PCI device",
362 "an unknown device", 362 "an unknown device",
@@ -556,8 +556,7 @@ static int media_bay_task(void *x)
556 return 0; 556 return 0;
557} 557}
558 558
559static int media_bay_attach(struct macio_dev *mdev, 559static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
560 const struct of_device_id *match)
561{ 560{
562 struct media_bay_info* bay; 561 struct media_bay_info* bay;
563 u32 __iomem *regbase; 562 u32 __iomem *regbase;
@@ -670,7 +669,7 @@ static int media_bay_resume(struct macio_dev *mdev)
670 669
671/* Definitions of "ops" structures. 670/* Definitions of "ops" structures.
672 */ 671 */
673static const struct mb_ops ohare_mb_ops = { 672static struct mb_ops ohare_mb_ops = {
674 .name = "Ohare", 673 .name = "Ohare",
675 .content = ohare_mb_content, 674 .content = ohare_mb_content,
676 .power = ohare_mb_power, 675 .power = ohare_mb_power,
@@ -679,7 +678,7 @@ static const struct mb_ops ohare_mb_ops = {
679 .un_reset_ide = ohare_mb_un_reset_ide, 678 .un_reset_ide = ohare_mb_un_reset_ide,
680}; 679};
681 680
682static const struct mb_ops heathrow_mb_ops = { 681static struct mb_ops heathrow_mb_ops = {
683 .name = "Heathrow", 682 .name = "Heathrow",
684 .content = heathrow_mb_content, 683 .content = heathrow_mb_content,
685 .power = heathrow_mb_power, 684 .power = heathrow_mb_power,
@@ -688,7 +687,7 @@ static const struct mb_ops heathrow_mb_ops = {
688 .un_reset_ide = heathrow_mb_un_reset_ide, 687 .un_reset_ide = heathrow_mb_un_reset_ide,
689}; 688};
690 689
691static const struct mb_ops keylargo_mb_ops = { 690static struct mb_ops keylargo_mb_ops = {
692 .name = "KeyLargo", 691 .name = "KeyLargo",
693 .init = keylargo_mb_init, 692 .init = keylargo_mb_init,
694 .content = keylargo_mb_content, 693 .content = keylargo_mb_content,
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
index cad0e19b47a..2637c139777 100644
--- a/drivers/macintosh/rack-meter.c
+++ b/drivers/macintosh/rack-meter.c
@@ -81,13 +81,13 @@ static int rackmeter_ignore_nice;
81 */ 81 */
82static inline cputime64_t get_cpu_idle_time(unsigned int cpu) 82static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
83{ 83{
84 u64 retval; 84 cputime64_t retval;
85 85
86 retval = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE] + 86 retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
87 kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; 87 kstat_cpu(cpu).cpustat.iowait);
88 88
89 if (rackmeter_ignore_nice) 89 if (rackmeter_ignore_nice)
90 retval += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE]; 90 retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
91 91
92 return retval; 92 return retval;
93} 93}
@@ -220,11 +220,13 @@ static void rackmeter_do_timer(struct work_struct *work)
220 int i, offset, load, cumm, pause; 220 int i, offset, load, cumm, pause;
221 221
222 cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); 222 cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
223 total_ticks = (unsigned int) (cur_jiffies - rcpu->prev_wall); 223 total_ticks = (unsigned int)cputime64_sub(cur_jiffies,
224 rcpu->prev_wall);
224 rcpu->prev_wall = cur_jiffies; 225 rcpu->prev_wall = cur_jiffies;
225 226
226 total_idle_ticks = get_cpu_idle_time(cpu); 227 total_idle_ticks = get_cpu_idle_time(cpu);
227 idle_ticks = (unsigned int) (total_idle_ticks - rcpu->prev_idle); 228 idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks,
229 rcpu->prev_idle);
228 rcpu->prev_idle = total_idle_ticks; 230 rcpu->prev_idle = total_idle_ticks;
229 231
230 /* We do a very dumb calculation to update the LEDs for now, 232 /* We do a very dumb calculation to update the LEDs for now,
@@ -253,7 +255,7 @@ static void rackmeter_do_timer(struct work_struct *work)
253 msecs_to_jiffies(CPU_SAMPLING_RATE)); 255 msecs_to_jiffies(CPU_SAMPLING_RATE));
254} 256}
255 257
256static void rackmeter_init_cpu_sniffer(struct rackmeter *rm) 258static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)
257{ 259{
258 unsigned int cpu; 260 unsigned int cpu;
259 261
@@ -287,7 +289,7 @@ static void rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
287 cancel_delayed_work_sync(&rm->cpu[1].sniffer); 289 cancel_delayed_work_sync(&rm->cpu[1].sniffer);
288} 290}
289 291
290static int rackmeter_setup(struct rackmeter *rm) 292static int __devinit rackmeter_setup(struct rackmeter *rm)
291{ 293{
292 pr_debug("rackmeter: setting up i2s..\n"); 294 pr_debug("rackmeter: setting up i2s..\n");
293 rackmeter_setup_i2s(rm); 295 rackmeter_setup_i2s(rm);
@@ -362,8 +364,8 @@ static irqreturn_t rackmeter_irq(int irq, void *arg)
362 return IRQ_HANDLED; 364 return IRQ_HANDLED;
363} 365}
364 366
365static int rackmeter_probe(struct macio_dev* mdev, 367static int __devinit rackmeter_probe(struct macio_dev* mdev,
366 const struct of_device_id *match) 368 const struct of_device_id *match)
367{ 369{
368 struct device_node *i2s = NULL, *np = NULL; 370 struct device_node *i2s = NULL, *np = NULL;
369 struct rackmeter *rm = NULL; 371 struct rackmeter *rm = NULL;
@@ -521,7 +523,7 @@ static int rackmeter_probe(struct macio_dev* mdev,
521 return rc; 523 return rc;
522} 524}
523 525
524static int rackmeter_remove(struct macio_dev* mdev) 526static int __devexit rackmeter_remove(struct macio_dev* mdev)
525{ 527{
526 struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev); 528 struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
527 529
@@ -588,7 +590,7 @@ static struct macio_driver rackmeter_driver = {
588 .of_match_table = rackmeter_match, 590 .of_match_table = rackmeter_match,
589 }, 591 },
590 .probe = rackmeter_probe, 592 .probe = rackmeter_probe,
591 .remove = rackmeter_remove, 593 .remove = __devexit_p(rackmeter_remove),
592 .shutdown = rackmeter_shutdown, 594 .shutdown = rackmeter_shutdown,
593}; 595};
594 596
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 9c6b9641486..116a49ce74b 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -32,6 +32,7 @@
32#include <linux/completion.h> 32#include <linux/completion.h>
33#include <linux/miscdevice.h> 33#include <linux/miscdevice.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/sysdev.h>
35#include <linux/poll.h> 36#include <linux/poll.h>
36#include <linux/mutex.h> 37#include <linux/mutex.h>
37#include <linux/of_device.h> 38#include <linux/of_device.h>
@@ -45,6 +46,7 @@
45#include <asm/pmac_feature.h> 46#include <asm/pmac_feature.h>
46#include <asm/smu.h> 47#include <asm/smu.h>
47#include <asm/sections.h> 48#include <asm/sections.h>
49#include <asm/abs_addr.h>
48#include <asm/uaccess.h> 50#include <asm/uaccess.h>
49 51
50#define VERSION "0.7" 52#define VERSION "0.7"
@@ -501,7 +503,7 @@ int __init smu_init (void)
501 * 32 bits value safely 503 * 32 bits value safely
502 */ 504 */
503 smu->cmd_buf_abs = (u32)smu_cmdbuf_abs; 505 smu->cmd_buf_abs = (u32)smu_cmdbuf_abs;
504 smu->cmd_buf = __va(smu_cmdbuf_abs); 506 smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs);
505 507
506 smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); 508 smu->db_node = of_find_node_by_name(NULL, "smu-doorbell");
507 if (smu->db_node == NULL) { 509 if (smu->db_node == NULL) {
@@ -565,7 +567,7 @@ fail_msg_node:
565fail_db_node: 567fail_db_node:
566 of_node_put(smu->db_node); 568 of_node_put(smu->db_node);
567fail_bootmem: 569fail_bootmem:
568 free_bootmem(__pa(smu), sizeof(struct smu_device)); 570 free_bootmem((unsigned long)smu, sizeof(struct smu_device));
569 smu = NULL; 571 smu = NULL;
570fail_np: 572fail_np:
571 of_node_put(np); 573 of_node_put(np);
@@ -679,6 +681,9 @@ static struct platform_driver smu_of_platform_driver =
679static int __init smu_init_sysfs(void) 681static int __init smu_init_sysfs(void)
680{ 682{
681 /* 683 /*
684 * Due to sysfs bogosity, a sysdev is not a real device, so
685 * we should in fact create both if we want sysdev semantics
686 * for power management.
682 * For now, we don't power manage machines with an SMU chip, 687 * For now, we don't power manage machines with an SMU chip,
683 * I'm a bit too far from figuring out how that works with those 688 * I'm a bit too far from figuring out how that works with those
684 * new chipsets, but that will come back and bite us 689 * new chipsets, but that will come back and bite us
@@ -997,7 +1002,7 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id)
997 "%02x !\n", id, hdr->id); 1002 "%02x !\n", id, hdr->id);
998 goto failure; 1003 goto failure;
999 } 1004 }
1000 if (of_add_property(smu->of_node, prop)) { 1005 if (prom_add_property(smu->of_node, prop)) {
1001 printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x " 1006 printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x "
1002 "property !\n", id); 1007 "property !\n", id);
1003 goto failure; 1008 goto failure;
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index f433521a6f9..02367308ff2 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -29,6 +29,7 @@
29#include <asm/prom.h> 29#include <asm/prom.h>
30#include <asm/machdep.h> 30#include <asm/machdep.h>
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/system.h>
32#include <asm/sections.h> 33#include <asm/sections.h>
33 34
34#undef DEBUG 35#undef DEBUG
@@ -47,11 +48,11 @@ static u8 FAN_SPD_SET[2] = {0x30, 0x31};
47 48
48static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ 49static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */
49static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ 50static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */
50static const char *sensor_location[3] = { "?", "?", "?" }; 51static const char *sensor_location[3];
51 52
52static int limit_adjust; 53static int limit_adjust;
53static int fan_speed = -1; 54static int fan_speed = -1;
54static bool verbose; 55static int verbose;
55 56
56MODULE_AUTHOR("Colin Leroy <colin@colino.net>"); 57MODULE_AUTHOR("Colin Leroy <colin@colino.net>");
57MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and " 58MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and "
@@ -79,16 +80,18 @@ struct thermostat {
79 int last_speed[2]; 80 int last_speed[2];
80 int last_var[2]; 81 int last_var[2];
81 int pwm_inv[2]; 82 int pwm_inv[2];
82 struct task_struct *thread;
83 struct platform_device *pdev;
84 enum {
85 ADT7460,
86 ADT7467
87 } type;
88}; 83};
89 84
85static enum {ADT7460, ADT7467} therm_type;
86static int therm_bus, therm_address;
87static struct platform_device * of_dev;
88static struct thermostat* thermostat;
89static struct task_struct *thread_therm = NULL;
90
90static void write_both_fan_speed(struct thermostat *th, int speed); 91static void write_both_fan_speed(struct thermostat *th, int speed);
91static void write_fan_speed(struct thermostat *th, int speed, int fan); 92static void write_fan_speed(struct thermostat *th, int speed, int fan);
93static void thermostat_create_files(void);
94static void thermostat_remove_files(void);
92 95
93static int 96static int
94write_reg(struct thermostat* th, int reg, u8 data) 97write_reg(struct thermostat* th, int reg, u8 data)
@@ -124,6 +127,66 @@ read_reg(struct thermostat* th, int reg)
124 return data; 127 return data;
125} 128}
126 129
130static struct i2c_driver thermostat_driver;
131
132static int
133attach_thermostat(struct i2c_adapter *adapter)
134{
135 unsigned long bus_no;
136 struct i2c_board_info info;
137 struct i2c_client *client;
138
139 if (strncmp(adapter->name, "uni-n", 5))
140 return -ENODEV;
141 bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
142 if (bus_no != therm_bus)
143 return -ENODEV;
144
145 memset(&info, 0, sizeof(struct i2c_board_info));
146 strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE);
147 info.addr = therm_address;
148 client = i2c_new_device(adapter, &info);
149 if (!client)
150 return -ENODEV;
151
152 /*
153 * Let i2c-core delete that device on driver removal.
154 * This is safe because i2c-core holds the core_lock mutex for us.
155 */
156 list_add_tail(&client->detected, &thermostat_driver.clients);
157 return 0;
158}
159
160static int
161remove_thermostat(struct i2c_client *client)
162{
163 struct thermostat *th = i2c_get_clientdata(client);
164 int i;
165
166 thermostat_remove_files();
167
168 if (thread_therm != NULL) {
169 kthread_stop(thread_therm);
170 }
171
172 printk(KERN_INFO "adt746x: Putting max temperatures back from "
173 "%d, %d, %d to %d, %d, %d\n",
174 th->limits[0], th->limits[1], th->limits[2],
175 th->initial_limits[0], th->initial_limits[1],
176 th->initial_limits[2]);
177
178 for (i = 0; i < 3; i++)
179 write_reg(th, LIMIT_REG[i], th->initial_limits[i]);
180
181 write_both_fan_speed(th, -1);
182
183 thermostat = NULL;
184
185 kfree(th);
186
187 return 0;
188}
189
127static int read_fan_speed(struct thermostat *th, u8 addr) 190static int read_fan_speed(struct thermostat *th, u8 addr)
128{ 191{
129 u8 tmp[2]; 192 u8 tmp[2];
@@ -141,7 +204,7 @@ static int read_fan_speed(struct thermostat *th, u8 addr)
141static void write_both_fan_speed(struct thermostat *th, int speed) 204static void write_both_fan_speed(struct thermostat *th, int speed)
142{ 205{
143 write_fan_speed(th, speed, 0); 206 write_fan_speed(th, speed, 0);
144 if (th->type == ADT7460) 207 if (therm_type == ADT7460)
145 write_fan_speed(th, speed, 1); 208 write_fan_speed(th, speed, 1);
146} 209}
147 210
@@ -154,7 +217,7 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
154 else if (speed < -1) 217 else if (speed < -1)
155 speed = 0; 218 speed = 0;
156 219
157 if (th->type == ADT7467 && fan == 1) 220 if (therm_type == ADT7467 && fan == 1)
158 return; 221 return;
159 222
160 if (th->last_speed[fan] != speed) { 223 if (th->last_speed[fan] != speed) {
@@ -177,7 +240,7 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
177 write_reg(th, FAN_SPD_SET[fan], speed); 240 write_reg(th, FAN_SPD_SET[fan], speed);
178 } else { 241 } else {
179 /* back to automatic */ 242 /* back to automatic */
180 if(th->type == ADT7460) { 243 if(therm_type == ADT7460) {
181 manual = read_reg(th, 244 manual = read_reg(th,
182 MANUAL_MODE[fan]) & (~MANUAL_MASK); 245 MANUAL_MODE[fan]) & (~MANUAL_MASK);
183 manual &= ~INVERT_MASK; 246 manual &= ~INVERT_MASK;
@@ -231,7 +294,7 @@ static void update_fans_speed (struct thermostat *th)
231 /* we don't care about local sensor, so we start at sensor 1 */ 294 /* we don't care about local sensor, so we start at sensor 1 */
232 for (i = 1; i < 3; i++) { 295 for (i = 1; i < 3; i++) {
233 int started = 0; 296 int started = 0;
234 int fan_number = (th->type == ADT7460 && i == 2); 297 int fan_number = (therm_type == ADT7460 && i == 2);
235 int var = th->temps[i] - th->limits[i]; 298 int var = th->temps[i] - th->limits[i];
236 299
237 if (var > -1) { 300 if (var > -1) {
@@ -308,22 +371,116 @@ static int monitor_task(void *arg)
308 371
309static void set_limit(struct thermostat *th, int i) 372static void set_limit(struct thermostat *th, int i)
310{ 373{
311 /* Set sensor1 limit higher to avoid powerdowns */ 374 /* Set sensor1 limit higher to avoid powerdowns */
312 th->limits[i] = default_limits_chip[i] + limit_adjust; 375 th->limits[i] = default_limits_chip[i] + limit_adjust;
313 write_reg(th, LIMIT_REG[i], th->limits[i]); 376 write_reg(th, LIMIT_REG[i], th->limits[i]);
314 377
315 /* set our limits to normal */ 378 /* set our limits to normal */
316 th->limits[i] = default_limits_local[i] + limit_adjust; 379 th->limits[i] = default_limits_local[i] + limit_adjust;
317} 380}
318 381
319#define BUILD_SHOW_FUNC_INT(name, data) \ 382static int probe_thermostat(struct i2c_client *client,
320static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 383 const struct i2c_device_id *id)
321{ \ 384{
322 struct thermostat *th = dev_get_drvdata(dev); \ 385 struct thermostat* th;
323 return sprintf(buf, "%d\n", data); \ 386 int rc;
387 int i;
388
389 if (thermostat)
390 return 0;
391
392 th = kzalloc(sizeof(struct thermostat), GFP_KERNEL);
393 if (!th)
394 return -ENOMEM;
395
396 i2c_set_clientdata(client, th);
397 th->clt = client;
398
399 rc = read_reg(th, CONFIG_REG);
400 if (rc < 0) {
401 dev_err(&client->dev, "Thermostat failed to read config!\n");
402 kfree(th);
403 return -ENODEV;
404 }
405
406 /* force manual control to start the fan quieter */
407 if (fan_speed == -1)
408 fan_speed = 64;
409
410 if(therm_type == ADT7460) {
411 printk(KERN_INFO "adt746x: ADT7460 initializing\n");
412 /* The 7460 needs to be started explicitly */
413 write_reg(th, CONFIG_REG, 1);
414 } else
415 printk(KERN_INFO "adt746x: ADT7467 initializing\n");
416
417 for (i = 0; i < 3; i++) {
418 th->initial_limits[i] = read_reg(th, LIMIT_REG[i]);
419 set_limit(th, i);
420 }
421
422 printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d"
423 " to %d, %d, %d\n",
424 th->initial_limits[0], th->initial_limits[1],
425 th->initial_limits[2], th->limits[0], th->limits[1],
426 th->limits[2]);
427
428 thermostat = th;
429
430 /* record invert bit status because fw can corrupt it after suspend */
431 th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
432 th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
433
434 /* be sure to really write fan speed the first time */
435 th->last_speed[0] = -2;
436 th->last_speed[1] = -2;
437 th->last_var[0] = -80;
438 th->last_var[1] = -80;
439
440 if (fan_speed != -1) {
441 /* manual mode, stop fans */
442 write_both_fan_speed(th, 0);
443 } else {
444 /* automatic mode */
445 write_both_fan_speed(th, -1);
446 }
447
448 thread_therm = kthread_run(monitor_task, th, "kfand");
449
450 if (thread_therm == ERR_PTR(-ENOMEM)) {
451 printk(KERN_INFO "adt746x: Kthread creation failed\n");
452 thread_therm = NULL;
453 return -ENOMEM;
454 }
455
456 thermostat_create_files();
457
458 return 0;
324} 459}
325 460
326#define BUILD_SHOW_FUNC_INT_LITE(name, data) \ 461static const struct i2c_device_id therm_adt746x_id[] = {
462 { "therm_adt746x", 0 },
463 { }
464};
465
466static struct i2c_driver thermostat_driver = {
467 .driver = {
468 .name = "therm_adt746x",
469 },
470 .attach_adapter = attach_thermostat,
471 .probe = probe_thermostat,
472 .remove = remove_thermostat,
473 .id_table = therm_adt746x_id,
474};
475
476/*
477 * Now, unfortunately, sysfs doesn't give us a nice void * we could
478 * pass around to the attribute functions, so we don't really have
479 * choice but implement a bunch of them...
480 *
481 * FIXME, it does now...
482 */
483#define BUILD_SHOW_FUNC_INT(name, data) \
327static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 484static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
328{ \ 485{ \
329 return sprintf(buf, "%d\n", data); \ 486 return sprintf(buf, "%d\n", data); \
@@ -338,24 +495,22 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch
338#define BUILD_SHOW_FUNC_FAN(name, data) \ 495#define BUILD_SHOW_FUNC_FAN(name, data) \
339static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 496static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
340{ \ 497{ \
341 struct thermostat *th = dev_get_drvdata(dev); \
342 return sprintf(buf, "%d (%d rpm)\n", \ 498 return sprintf(buf, "%d (%d rpm)\n", \
343 th->last_speed[data], \ 499 thermostat->last_speed[data], \
344 read_fan_speed(th, FAN_SPEED[data]) \ 500 read_fan_speed(thermostat, FAN_SPEED[data]) \
345 ); \ 501 ); \
346} 502}
347 503
348#define BUILD_STORE_FUNC_DEG(name, data) \ 504#define BUILD_STORE_FUNC_DEG(name, data) \
349static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \ 505static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
350{ \ 506{ \
351 struct thermostat *th = dev_get_drvdata(dev); \
352 int val; \ 507 int val; \
353 int i; \ 508 int i; \
354 val = simple_strtol(buf, NULL, 10); \ 509 val = simple_strtol(buf, NULL, 10); \
355 printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \ 510 printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \
356 limit_adjust = val; \ 511 limit_adjust = val; \
357 for (i=0; i < 3; i++) \ 512 for (i=0; i < 3; i++) \
358 set_limit(th, i); \ 513 set_limit(thermostat, i); \
359 return n; \ 514 return n; \
360} 515}
361 516
@@ -371,21 +526,20 @@ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, c
371 return n; \ 526 return n; \
372} 527}
373 528
374BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(th, TEMP_REG[1]))) 529BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(thermostat, TEMP_REG[1])))
375BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(th, TEMP_REG[2]))) 530BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(thermostat, TEMP_REG[2])))
376BUILD_SHOW_FUNC_INT(sensor1_limit, th->limits[1]) 531BUILD_SHOW_FUNC_INT(sensor1_limit, thermostat->limits[1])
377BUILD_SHOW_FUNC_INT(sensor2_limit, th->limits[2]) 532BUILD_SHOW_FUNC_INT(sensor2_limit, thermostat->limits[2])
378BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1]) 533BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1])
379BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2]) 534BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2])
380 535
381BUILD_SHOW_FUNC_INT_LITE(specified_fan_speed, fan_speed) 536BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed)
382BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed)
383
384BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0) 537BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0)
385BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1) 538BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1)
386 539
387BUILD_SHOW_FUNC_INT_LITE(limit_adjust, limit_adjust) 540BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed)
388BUILD_STORE_FUNC_DEG(limit_adjust, th) 541BUILD_SHOW_FUNC_INT(limit_adjust, limit_adjust)
542BUILD_STORE_FUNC_DEG(limit_adjust, thermostat)
389 543
390static DEVICE_ATTR(sensor1_temperature, S_IRUGO, 544static DEVICE_ATTR(sensor1_temperature, S_IRUGO,
391 show_sensor1_temperature,NULL); 545 show_sensor1_temperature,NULL);
@@ -411,77 +565,53 @@ static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO,
411static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 565static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
412 show_limit_adjust, store_limit_adjust); 566 show_limit_adjust, store_limit_adjust);
413 567
414static void thermostat_create_files(struct thermostat *th) 568
569static int __init
570thermostat_init(void)
415{ 571{
416 struct device_node *np = th->clt->dev.of_node; 572 struct device_node* np;
417 struct device *dev; 573 const u32 *prop;
418 int err; 574 int i = 0, offset = 0;
419 575
420 /* To maintain ABI compatibility with userspace, create 576 np = of_find_node_by_name(NULL, "fan");
421 * the old style platform driver and attach the attributes 577 if (!np)
422 * to it here 578 return -ENODEV;
423 */ 579 if (of_device_is_compatible(np, "adt7460"))
424 th->pdev = of_platform_device_create(np, "temperatures", NULL); 580 therm_type = ADT7460;
425 if (!th->pdev) 581 else if (of_device_is_compatible(np, "adt7467"))
426 return; 582 therm_type = ADT7467;
427 dev = &th->pdev->dev; 583 else {
428 dev_set_drvdata(dev, th); 584 of_node_put(np);
429 err = device_create_file(dev, &dev_attr_sensor1_temperature); 585 return -ENODEV;
430 err |= device_create_file(dev, &dev_attr_sensor2_temperature); 586 }
431 err |= device_create_file(dev, &dev_attr_sensor1_limit);
432 err |= device_create_file(dev, &dev_attr_sensor2_limit);
433 err |= device_create_file(dev, &dev_attr_sensor1_location);
434 err |= device_create_file(dev, &dev_attr_sensor2_location);
435 err |= device_create_file(dev, &dev_attr_limit_adjust);
436 err |= device_create_file(dev, &dev_attr_specified_fan_speed);
437 err |= device_create_file(dev, &dev_attr_sensor1_fan_speed);
438 if(th->type == ADT7460)
439 err |= device_create_file(dev, &dev_attr_sensor2_fan_speed);
440 if (err)
441 printk(KERN_WARNING
442 "Failed to create temperature attribute file(s).\n");
443}
444 587
445static void thermostat_remove_files(struct thermostat *th) 588 prop = of_get_property(np, "hwsensor-params-version", NULL);
446{ 589 printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop,
447 struct device *dev; 590 (*prop == 1)?"":"un");
591 if (*prop != 1) {
592 of_node_put(np);
593 return -ENODEV;
594 }
448 595
449 if (!th->pdev) 596 prop = of_get_property(np, "reg", NULL);
450 return; 597 if (!prop) {
451 dev = &th->pdev->dev; 598 of_node_put(np);
452 device_remove_file(dev, &dev_attr_sensor1_temperature); 599 return -ENODEV;
453 device_remove_file(dev, &dev_attr_sensor2_temperature); 600 }
454 device_remove_file(dev, &dev_attr_sensor1_limit);
455 device_remove_file(dev, &dev_attr_sensor2_limit);
456 device_remove_file(dev, &dev_attr_sensor1_location);
457 device_remove_file(dev, &dev_attr_sensor2_location);
458 device_remove_file(dev, &dev_attr_limit_adjust);
459 device_remove_file(dev, &dev_attr_specified_fan_speed);
460 device_remove_file(dev, &dev_attr_sensor1_fan_speed);
461 if (th->type == ADT7460)
462 device_remove_file(dev, &dev_attr_sensor2_fan_speed);
463 of_device_unregister(th->pdev);
464 601
465} 602 /* look for bus either by path or using "reg" */
603 if (strstr(np->full_name, "/i2c-bus@") != NULL) {
604 const char *tmp_bus = (strstr(np->full_name, "/i2c-bus@") + 9);
605 therm_bus = tmp_bus[0]-'0';
606 } else {
607 therm_bus = ((*prop) >> 8) & 0x0f;
608 }
466 609
467static int probe_thermostat(struct i2c_client *client, 610 therm_address = ((*prop) & 0xff) >> 1;
468 const struct i2c_device_id *id)
469{
470 struct device_node *np = client->dev.of_node;
471 struct thermostat* th;
472 const __be32 *prop;
473 int i, rc, vers, offset = 0;
474 611
475 if (!np) 612 printk(KERN_INFO "adt746x: Thermostat bus: %d, address: 0x%02x, "
476 return -ENXIO; 613 "limit_adjust: %d, fan_speed: %d\n",
477 prop = of_get_property(np, "hwsensor-params-version", NULL); 614 therm_bus, therm_address, limit_adjust, fan_speed);
478 if (!prop)
479 return -ENXIO;
480 vers = be32_to_cpup(prop);
481 printk(KERN_INFO "adt746x: version %d (%ssupported)\n",
482 vers, vers == 1 ? "" : "un");
483 if (vers != 1)
484 return -ENXIO;
485 615
486 if (of_get_property(np, "hwsensor-location", NULL)) { 616 if (of_get_property(np, "hwsensor-location", NULL)) {
487 for (i = 0; i < 3; i++) { 617 for (i = 0; i < 3; i++) {
@@ -494,129 +624,72 @@ static int probe_thermostat(struct i2c_client *client,
494 printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]); 624 printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]);
495 offset += strlen(sensor_location[i]) + 1; 625 offset += strlen(sensor_location[i]) + 1;
496 } 626 }
627 } else {
628 sensor_location[0] = "?";
629 sensor_location[1] = "?";
630 sensor_location[2] = "?";
497 } 631 }
498 632
499 th = kzalloc(sizeof(struct thermostat), GFP_KERNEL); 633 of_dev = of_platform_device_create(np, "temperatures", NULL);
500 if (!th) 634 of_node_put(np);
501 return -ENOMEM;
502
503 i2c_set_clientdata(client, th);
504 th->clt = client;
505 th->type = id->driver_data;
506 635
507 rc = read_reg(th, CONFIG_REG); 636 if (of_dev == NULL) {
508 if (rc < 0) { 637 printk(KERN_ERR "Can't register temperatures device !\n");
509 dev_err(&client->dev, "Thermostat failed to read config!\n");
510 kfree(th);
511 return -ENODEV; 638 return -ENODEV;
512 } 639 }
513 640
514 /* force manual control to start the fan quieter */ 641#ifndef CONFIG_I2C_POWERMAC
515 if (fan_speed == -1) 642 request_module("i2c-powermac");
516 fan_speed = 64; 643#endif
517
518 if (th->type == ADT7460) {
519 printk(KERN_INFO "adt746x: ADT7460 initializing\n");
520 /* The 7460 needs to be started explicitly */
521 write_reg(th, CONFIG_REG, 1);
522 } else
523 printk(KERN_INFO "adt746x: ADT7467 initializing\n");
524
525 for (i = 0; i < 3; i++) {
526 th->initial_limits[i] = read_reg(th, LIMIT_REG[i]);
527 set_limit(th, i);
528 }
529
530 printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d"
531 " to %d, %d, %d\n",
532 th->initial_limits[0], th->initial_limits[1],
533 th->initial_limits[2], th->limits[0], th->limits[1],
534 th->limits[2]);
535
536 /* record invert bit status because fw can corrupt it after suspend */
537 th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
538 th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
539
540 /* be sure to really write fan speed the first time */
541 th->last_speed[0] = -2;
542 th->last_speed[1] = -2;
543 th->last_var[0] = -80;
544 th->last_var[1] = -80;
545
546 if (fan_speed != -1) {
547 /* manual mode, stop fans */
548 write_both_fan_speed(th, 0);
549 } else {
550 /* automatic mode */
551 write_both_fan_speed(th, -1);
552 }
553
554 th->thread = kthread_run(monitor_task, th, "kfand");
555 if (th->thread == ERR_PTR(-ENOMEM)) {
556 printk(KERN_INFO "adt746x: Kthread creation failed\n");
557 th->thread = NULL;
558 return -ENOMEM;
559 }
560
561 thermostat_create_files(th);
562 644
563 return 0; 645 return i2c_add_driver(&thermostat_driver);
564} 646}
565 647
566static int remove_thermostat(struct i2c_client *client) 648static void thermostat_create_files(void)
567{ 649{
568 struct thermostat *th = i2c_get_clientdata(client); 650 int err;
569 int i;
570
571 thermostat_remove_files(th);
572
573 if (th->thread != NULL)
574 kthread_stop(th->thread);
575
576 printk(KERN_INFO "adt746x: Putting max temperatures back from "
577 "%d, %d, %d to %d, %d, %d\n",
578 th->limits[0], th->limits[1], th->limits[2],
579 th->initial_limits[0], th->initial_limits[1],
580 th->initial_limits[2]);
581
582 for (i = 0; i < 3; i++)
583 write_reg(th, LIMIT_REG[i], th->initial_limits[i]);
584
585 write_both_fan_speed(th, -1);
586
587 kfree(th);
588 651
589 return 0; 652 err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
653 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
654 err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
655 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
656 err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
657 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
658 err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
659 err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
660 err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
661 if(therm_type == ADT7460)
662 err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
663 if (err)
664 printk(KERN_WARNING
665 "Failed to create temperature attribute file(s).\n");
590} 666}
591 667
592static const struct i2c_device_id therm_adt746x_id[] = { 668static void thermostat_remove_files(void)
593 { "MAC,adt7460", ADT7460 },
594 { "MAC,adt7467", ADT7467 },
595 { }
596};
597MODULE_DEVICE_TABLE(i2c, therm_adt746x_id);
598
599static struct i2c_driver thermostat_driver = {
600 .driver = {
601 .name = "therm_adt746x",
602 },
603 .probe = probe_thermostat,
604 .remove = remove_thermostat,
605 .id_table = therm_adt746x_id,
606};
607
608static int __init thermostat_init(void)
609{ 669{
610#ifndef CONFIG_I2C_POWERMAC 670 if (of_dev) {
611 request_module("i2c-powermac"); 671 device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature);
612#endif 672 device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature);
673 device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit);
674 device_remove_file(&of_dev->dev, &dev_attr_sensor2_limit);
675 device_remove_file(&of_dev->dev, &dev_attr_sensor1_location);
676 device_remove_file(&of_dev->dev, &dev_attr_sensor2_location);
677 device_remove_file(&of_dev->dev, &dev_attr_limit_adjust);
678 device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed);
679 device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
680
681 if(therm_type == ADT7460)
682 device_remove_file(&of_dev->dev,
683 &dev_attr_sensor2_fan_speed);
613 684
614 return i2c_add_driver(&thermostat_driver); 685 }
615} 686}
616 687
617static void __exit thermostat_exit(void) 688static void __exit
689thermostat_exit(void)
618{ 690{
619 i2c_del_driver(&thermostat_driver); 691 i2c_del_driver(&thermostat_driver);
692 of_device_unregister(of_dev);
620} 693}
621 694
622module_init(thermostat_init); 695module_init(thermostat_init);
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 97cfc5ac9fd..0ff92c20800 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -127,6 +127,7 @@
127#include <asm/prom.h> 127#include <asm/prom.h>
128#include <asm/machdep.h> 128#include <asm/machdep.h>
129#include <asm/io.h> 129#include <asm/io.h>
130#include <asm/system.h>
130#include <asm/sections.h> 131#include <asm/sections.h>
131#include <asm/macio.h> 132#include <asm/macio.h>
132 133
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 3b4a157714b..46c4e95f10d 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -41,6 +41,7 @@
41#include <asm/prom.h> 41#include <asm/prom.h>
42#include <asm/machdep.h> 42#include <asm/machdep.h>
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/system.h>
44#include <asm/sections.h> 45#include <asm/sections.h>
45#include <asm/macio.h> 46#include <asm/macio.h>
46 47
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 86511c570dd..971bc9582a5 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -26,6 +26,7 @@
26#include <asm/mac_via.h> 26#include <asm/mac_via.h>
27#endif 27#endif
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/system.h>
29#include <linux/init.h> 30#include <linux/init.h>
30 31
31static volatile unsigned char __iomem *via; 32static volatile unsigned char __iomem *via;
diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 3725f088f17..817f37a875c 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -34,6 +34,7 @@
34#include <asm/macintosh.h> 34#include <asm/macintosh.h>
35#include <asm/macints.h> 35#include <asm/macints.h>
36#include <asm/mac_via.h> 36#include <asm/mac_via.h>
37#include <asm/system.h>
37 38
38static volatile unsigned char *via; 39static volatile unsigned char *via;
39 40
@@ -158,7 +159,7 @@ int macii_init(void)
158 err = macii_init_via(); 159 err = macii_init_via();
159 if (err) goto out; 160 if (err) goto out;
160 161
161 err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB", 162 err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB",
162 macii_interrupt); 163 macii_interrupt);
163 if (err) goto out; 164 if (err) goto out;
164 165
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
index 34d02a91b29..9ab5b0c34f0 100644
--- a/drivers/macintosh/via-maciisi.c
+++ b/drivers/macintosh/via-maciisi.c
@@ -122,8 +122,8 @@ maciisi_init(void)
122 return err; 122 return err;
123 } 123 }
124 124
125 if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB", 125 if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST,
126 maciisi_interrupt)) { 126 "ADB", maciisi_interrupt)) {
127 printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB); 127 printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
128 return -EAGAIN; 128 return -EAGAIN;
129 } 129 }
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 22b8ce4191c..6cccd60c594 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -50,6 +50,7 @@
50#include <asm/machdep.h> 50#include <asm/machdep.h>
51#include <asm/io.h> 51#include <asm/io.h>
52#include <asm/pgtable.h> 52#include <asm/pgtable.h>
53#include <asm/system.h>
53#include <asm/sections.h> 54#include <asm/sections.h>
54#include <asm/irq.h> 55#include <asm/irq.h>
55#include <asm/pmac_feature.h> 56#include <asm/pmac_feature.h>
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index a00ee41f057..aeb30d07d5a 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -37,6 +37,7 @@
37#include <asm/mac_via.h> 37#include <asm/mac_via.h>
38 38
39#include <asm/pgtable.h> 39#include <asm/pgtable.h>
40#include <asm/system.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42 43
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h
index 028cdac2d33..7a2482cc26a 100644
--- a/drivers/macintosh/windfarm.h
+++ b/drivers/macintosh/windfarm.h
@@ -17,7 +17,7 @@
17#include <linux/device.h> 17#include <linux/device.h>
18 18
19/* Display a 16.16 fixed point value */ 19/* Display a 16.16 fixed point value */
20#define FIX32TOPRINT(f) (((s32)(f)) >> 16),(((((s32)(f)) & 0xffff) * 1000) >> 16) 20#define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
21 21
22/* 22/*
23 * Control objects 23 * Control objects
@@ -35,13 +35,12 @@ struct wf_control_ops {
35}; 35};
36 36
37struct wf_control { 37struct wf_control {
38 struct list_head link; 38 struct list_head link;
39 const struct wf_control_ops *ops; 39 struct wf_control_ops *ops;
40 const char *name; 40 char *name;
41 int type; 41 int type;
42 struct kref ref; 42 struct kref ref;
43 struct device_attribute attr; 43 struct device_attribute attr;
44 void *priv;
45}; 44};
46 45
47#define WF_CONTROL_TYPE_GENERIC 0 46#define WF_CONTROL_TYPE_GENERIC 0
@@ -73,26 +72,6 @@ static inline int wf_control_set_min(struct wf_control *ct)
73 return ct->ops->set_value(ct, vmin); 72 return ct->ops->set_value(ct, vmin);
74} 73}
75 74
76static inline int wf_control_set(struct wf_control *ct, s32 val)
77{
78 return ct->ops->set_value(ct, val);
79}
80
81static inline int wf_control_get(struct wf_control *ct, s32 *val)
82{
83 return ct->ops->get_value(ct, val);
84}
85
86static inline s32 wf_control_get_min(struct wf_control *ct)
87{
88 return ct->ops->get_min(ct);
89}
90
91static inline s32 wf_control_get_max(struct wf_control *ct)
92{
93 return ct->ops->get_max(ct);
94}
95
96/* 75/*
97 * Sensor objects 76 * Sensor objects
98 */ 77 */
@@ -106,12 +85,11 @@ struct wf_sensor_ops {
106}; 85};
107 86
108struct wf_sensor { 87struct wf_sensor {
109 struct list_head link; 88 struct list_head link;
110 const struct wf_sensor_ops *ops; 89 struct wf_sensor_ops *ops;
111 const char *name; 90 char *name;
112 struct kref ref; 91 struct kref ref;
113 struct device_attribute attr; 92 struct device_attribute attr;
114 void *priv;
115}; 93};
116 94
117/* Same lifetime rules as controls */ 95/* Same lifetime rules as controls */
@@ -121,11 +99,6 @@ extern struct wf_sensor * wf_find_sensor(const char *name);
121extern int wf_get_sensor(struct wf_sensor *sr); 99extern int wf_get_sensor(struct wf_sensor *sr);
122extern void wf_put_sensor(struct wf_sensor *sr); 100extern void wf_put_sensor(struct wf_sensor *sr);
123 101
124static inline int wf_sensor_get(struct wf_sensor *sr, s32 *val)
125{
126 return sr->ops->get_value(sr, val);
127}
128
129/* For use by clients. Note that we are a bit racy here since 102/* For use by clients. Note that we are a bit racy here since
130 * notifier_block doesn't have a module owner field. I may fix 103 * notifier_block doesn't have a module owner field. I may fix
131 * it one day ... 104 * it one day ...
diff --git a/drivers/macintosh/windfarm_ad7417_sensor.c b/drivers/macintosh/windfarm_ad7417_sensor.c
deleted file mode 100644
index 7c28b71246c..00000000000
--- a/drivers/macintosh/windfarm_ad7417_sensor.c
+++ /dev/null
@@ -1,347 +0,0 @@
1/*
2 * Windfarm PowerMac thermal control. AD7417 sensors
3 *
4 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp.
5 *
6 * Released under the term of the GNU GPL v2.
7 */
8
9#include <linux/types.h>
10#include <linux/errno.h>
11#include <linux/kernel.h>
12#include <linux/delay.h>
13#include <linux/slab.h>
14#include <linux/init.h>
15#include <linux/wait.h>
16#include <linux/i2c.h>
17#include <asm/prom.h>
18#include <asm/machdep.h>
19#include <asm/io.h>
20#include <asm/sections.h>
21
22#include "windfarm.h"
23#include "windfarm_mpu.h"
24
25#define VERSION "1.0"
26
27struct wf_ad7417_priv {
28 struct kref ref;
29 struct i2c_client *i2c;
30 u8 config;
31 u8 cpu;
32 const struct mpu_data *mpu;
33 struct wf_sensor sensors[5];
34 struct mutex lock;
35};
36
37static int wf_ad7417_temp_get(struct wf_sensor *sr, s32 *value)
38{
39 struct wf_ad7417_priv *pv = sr->priv;
40 u8 buf[2];
41 s16 raw;
42 int rc;
43
44 *value = 0;
45 mutex_lock(&pv->lock);
46
47 /* Read temp register */
48 buf[0] = 0;
49 rc = i2c_master_send(pv->i2c, buf, 1);
50 if (rc < 0)
51 goto error;
52 rc = i2c_master_recv(pv->i2c, buf, 2);
53 if (rc < 0)
54 goto error;
55
56 /* Read a a 16-bit signed value */
57 raw = be16_to_cpup((__le16 *)buf);
58
59 /* Convert 8.8-bit to 16.16 fixed point */
60 *value = ((s32)raw) << 8;
61
62 mutex_unlock(&pv->lock);
63 return 0;
64
65error:
66 mutex_unlock(&pv->lock);
67 return -1;
68}
69
70/*
71 * Scaling factors for the AD7417 ADC converters (except
72 * for the CPU diode which is obtained from the EEPROM).
73 * Those values are obtained from the property list of
74 * the darwin driver
75 */
76#define ADC_12V_CURRENT_SCALE 0x0320 /* _AD2 */
77#define ADC_CPU_VOLTAGE_SCALE 0x00a0 /* _AD3 */
78#define ADC_CPU_CURRENT_SCALE 0x1f40 /* _AD4 */
79
80static void wf_ad7417_adc_convert(struct wf_ad7417_priv *pv,
81 int chan, s32 raw, s32 *value)
82{
83 switch(chan) {
84 case 1: /* Diode */
85 *value = (raw * (s32)pv->mpu->mdiode +
86 ((s32)pv->mpu->bdiode << 12)) >> 2;
87 break;
88 case 2: /* 12v current */
89 *value = raw * ADC_12V_CURRENT_SCALE;
90 break;
91 case 3: /* core voltage */
92 *value = raw * ADC_CPU_VOLTAGE_SCALE;
93 break;
94 case 4: /* core current */
95 *value = raw * ADC_CPU_CURRENT_SCALE;
96 break;
97 }
98}
99
100static int wf_ad7417_adc_get(struct wf_sensor *sr, s32 *value)
101{
102 struct wf_ad7417_priv *pv = sr->priv;
103 int chan = sr - pv->sensors;
104 int i, rc;
105 u8 buf[2];
106 u16 raw;
107
108 *value = 0;
109 mutex_lock(&pv->lock);
110 for (i = 0; i < 10; i++) {
111 /* Set channel */
112 buf[0] = 1;
113 buf[1] = (pv->config & 0x1f) | (chan << 5);
114 rc = i2c_master_send(pv->i2c, buf, 2);
115 if (rc < 0)
116 goto error;
117
118 /* Wait for conversion */
119 msleep(1);
120
121 /* Switch to data register */
122 buf[0] = 4;
123 rc = i2c_master_send(pv->i2c, buf, 1);
124 if (rc < 0)
125 goto error;
126
127 /* Read result */
128 rc = i2c_master_recv(pv->i2c, buf, 2);
129 if (rc < 0)
130 goto error;
131
132 /* Read a a 16-bit signed value */
133 raw = be16_to_cpup((__le16 *)buf) >> 6;
134 wf_ad7417_adc_convert(pv, chan, raw, value);
135
136 dev_vdbg(&pv->i2c->dev, "ADC chan %d [%s]"
137 " raw value: 0x%x, conv to: 0x%08x\n",
138 chan, sr->name, raw, *value);
139
140 mutex_unlock(&pv->lock);
141 return 0;
142
143 error:
144 dev_dbg(&pv->i2c->dev,
145 "Error reading ADC, try %d...\n", i);
146 if (i < 9)
147 msleep(10);
148 }
149 mutex_unlock(&pv->lock);
150 return -1;
151}
152
153static void wf_ad7417_release(struct kref *ref)
154{
155 struct wf_ad7417_priv *pv = container_of(ref,
156 struct wf_ad7417_priv, ref);
157 kfree(pv);
158}
159
160static void wf_ad7417_sensor_release(struct wf_sensor *sr)
161{
162 struct wf_ad7417_priv *pv = sr->priv;
163
164 kfree(sr->name);
165 kref_put(&pv->ref, wf_ad7417_release);
166}
167
168static const struct wf_sensor_ops wf_ad7417_temp_ops = {
169 .get_value = wf_ad7417_temp_get,
170 .release = wf_ad7417_sensor_release,
171 .owner = THIS_MODULE,
172};
173
174static const struct wf_sensor_ops wf_ad7417_adc_ops = {
175 .get_value = wf_ad7417_adc_get,
176 .release = wf_ad7417_sensor_release,
177 .owner = THIS_MODULE,
178};
179
180static void wf_ad7417_add_sensor(struct wf_ad7417_priv *pv,
181 int index, const char *name,
182 const struct wf_sensor_ops *ops)
183{
184 pv->sensors[index].name = kasprintf(GFP_KERNEL, "%s-%d", name, pv->cpu);
185 pv->sensors[index].priv = pv;
186 pv->sensors[index].ops = ops;
187 if (!wf_register_sensor(&pv->sensors[index]))
188 kref_get(&pv->ref);
189}
190
191static void wf_ad7417_init_chip(struct wf_ad7417_priv *pv)
192{
193 int rc;
194 u8 buf[2];
195 u8 config = 0;
196
197 /*
198 * Read ADC the configuration register and cache it. We
199 * also make sure Config2 contains proper values, I've seen
200 * cases where we got stale grabage in there, thus preventing
201 * proper reading of conv. values
202 */
203
204 /* Clear Config2 */
205 buf[0] = 5;
206 buf[1] = 0;
207 i2c_master_send(pv->i2c, buf, 2);
208
209 /* Read & cache Config1 */
210 buf[0] = 1;
211 rc = i2c_master_send(pv->i2c, buf, 1);
212 if (rc > 0) {
213 rc = i2c_master_recv(pv->i2c, buf, 1);
214 if (rc > 0) {
215 config = buf[0];
216
217 dev_dbg(&pv->i2c->dev, "ADC config reg: %02x\n",
218 config);
219
220 /* Disable shutdown mode */
221 config &= 0xfe;
222 buf[0] = 1;
223 buf[1] = config;
224 rc = i2c_master_send(pv->i2c, buf, 2);
225 }
226 }
227 if (rc <= 0)
228 dev_err(&pv->i2c->dev, "Error reading ADC config\n");
229
230 pv->config = config;
231}
232
233static int wf_ad7417_probe(struct i2c_client *client,
234 const struct i2c_device_id *id)
235{
236 struct wf_ad7417_priv *pv;
237 const struct mpu_data *mpu;
238 const char *loc;
239 int cpu_nr;
240
241 loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL);
242 if (!loc) {
243 dev_warn(&client->dev, "Missing hwsensor-location property!\n");
244 return -ENXIO;
245 }
246
247 /*
248 * Identify which CPU we belong to by looking at the first entry
249 * in the hwsensor-location list
250 */
251 if (!strncmp(loc, "CPU A", 5))
252 cpu_nr = 0;
253 else if (!strncmp(loc, "CPU B", 5))
254 cpu_nr = 1;
255 else {
256 pr_err("wf_ad7417: Can't identify location %s\n", loc);
257 return -ENXIO;
258 }
259 mpu = wf_get_mpu(cpu_nr);
260 if (!mpu) {
261 dev_err(&client->dev, "Failed to retrieve MPU data\n");
262 return -ENXIO;
263 }
264
265 pv = kzalloc(sizeof(struct wf_ad7417_priv), GFP_KERNEL);
266 if (pv == NULL)
267 return -ENODEV;
268
269 kref_init(&pv->ref);
270 mutex_init(&pv->lock);
271 pv->i2c = client;
272 pv->cpu = cpu_nr;
273 pv->mpu = mpu;
274 dev_set_drvdata(&client->dev, pv);
275
276 /* Initialize the chip */
277 wf_ad7417_init_chip(pv);
278
279 /*
280 * We cannot rely on Apple device-tree giving us child
281 * node with the names of the individual sensors so we
282 * just hard code what we know about them
283 */
284 wf_ad7417_add_sensor(pv, 0, "cpu-amb-temp", &wf_ad7417_temp_ops);
285 wf_ad7417_add_sensor(pv, 1, "cpu-diode-temp", &wf_ad7417_adc_ops);
286 wf_ad7417_add_sensor(pv, 2, "cpu-12v-current", &wf_ad7417_adc_ops);
287 wf_ad7417_add_sensor(pv, 3, "cpu-voltage", &wf_ad7417_adc_ops);
288 wf_ad7417_add_sensor(pv, 4, "cpu-current", &wf_ad7417_adc_ops);
289
290 return 0;
291}
292
293static int wf_ad7417_remove(struct i2c_client *client)
294{
295 struct wf_ad7417_priv *pv = dev_get_drvdata(&client->dev);
296 int i;
297
298 /* Mark client detached */
299 pv->i2c = NULL;
300
301 /* Release sensor */
302 for (i = 0; i < 5; i++)
303 wf_unregister_sensor(&pv->sensors[i]);
304
305 kref_put(&pv->ref, wf_ad7417_release);
306
307 return 0;
308}
309
310static const struct i2c_device_id wf_ad7417_id[] = {
311 { "MAC,ad7417", 0 },
312 { }
313};
314MODULE_DEVICE_TABLE(i2c, wf_ad7417_id);
315
316static struct i2c_driver wf_ad7417_driver = {
317 .driver = {
318 .name = "wf_ad7417",
319 },
320 .probe = wf_ad7417_probe,
321 .remove = wf_ad7417_remove,
322 .id_table = wf_ad7417_id,
323};
324
325static int wf_ad7417_init(void)
326{
327 /* This is only supported on these machines */
328 if (!of_machine_is_compatible("PowerMac7,2") &&
329 !of_machine_is_compatible("PowerMac7,3") &&
330 !of_machine_is_compatible("RackMac3,1"))
331 return -ENODEV;
332
333 return i2c_add_driver(&wf_ad7417_driver);
334}
335
336static void wf_ad7417_exit(void)
337{
338 i2c_del_driver(&wf_ad7417_driver);
339}
340
341module_init(wf_ad7417_init);
342module_exit(wf_ad7417_exit);
343
344MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
345MODULE_DESCRIPTION("ad7417 sensor driver for PowerMacs");
346MODULE_LICENSE("GPL");
347
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 3ee198b6584..ce8897933a8 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -164,27 +164,13 @@ static ssize_t wf_show_control(struct device *dev,
164 struct device_attribute *attr, char *buf) 164 struct device_attribute *attr, char *buf)
165{ 165{
166 struct wf_control *ctrl = container_of(attr, struct wf_control, attr); 166 struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
167 const char *typestr;
168 s32 val = 0; 167 s32 val = 0;
169 int err; 168 int err;
170 169
171 err = ctrl->ops->get_value(ctrl, &val); 170 err = ctrl->ops->get_value(ctrl, &val);
172 if (err < 0) { 171 if (err < 0)
173 if (err == -EFAULT)
174 return sprintf(buf, "<HW FAULT>\n");
175 return err; 172 return err;
176 } 173 return sprintf(buf, "%d\n", val);
177 switch(ctrl->type) {
178 case WF_CONTROL_RPM_FAN:
179 typestr = " RPM";
180 break;
181 case WF_CONTROL_PWM_FAN:
182 typestr = " %";
183 break;
184 default:
185 typestr = "";
186 }
187 return sprintf(buf, "%d%s\n", val, typestr);
188} 174}
189 175
190/* This is really only for debugging... */ 176/* This is really only for debugging... */
@@ -484,6 +470,11 @@ static int __init windfarm_core_init(void)
484{ 470{
485 DBG("wf: core loaded\n"); 471 DBG("wf: core loaded\n");
486 472
473 /* Don't register on old machines that use therm_pm72 for now */
474 if (of_machine_is_compatible("PowerMac7,2") ||
475 of_machine_is_compatible("PowerMac7,3") ||
476 of_machine_is_compatible("RackMac3,1"))
477 return -ENODEV;
487 platform_device_register(&wf_platform_device); 478 platform_device_register(&wf_platform_device);
488 return 0; 479 return 0;
489} 480}
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c
index 72d1fdfe02a..1a77a7c97d0 100644
--- a/drivers/macintosh/windfarm_cpufreq_clamp.c
+++ b/drivers/macintosh/windfarm_cpufreq_clamp.c
@@ -75,6 +75,12 @@ static int __init wf_cpufreq_clamp_init(void)
75{ 75{
76 struct wf_control *clamp; 76 struct wf_control *clamp;
77 77
78 /* Don't register on old machines that use therm_pm72 for now */
79 if (of_machine_is_compatible("PowerMac7,2") ||
80 of_machine_is_compatible("PowerMac7,3") ||
81 of_machine_is_compatible("RackMac3,1"))
82 return -ENODEV;
83
78 clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); 84 clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
79 if (clamp == NULL) 85 if (clamp == NULL)
80 return -ENOMEM; 86 return -ENOMEM;
diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c
deleted file mode 100644
index 0226b796a21..00000000000
--- a/drivers/macintosh/windfarm_fcu_controls.c
+++ /dev/null
@@ -1,600 +0,0 @@
1/*
2 * Windfarm PowerMac thermal control. FCU fan control
3 *
4 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp.
5 *
6 * Released under the term of the GNU GPL v2.
7 */
8#undef DEBUG
9
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/wait.h>
17#include <linux/i2c.h>
18#include <asm/prom.h>
19#include <asm/machdep.h>
20#include <asm/io.h>
21#include <asm/sections.h>
22
23#include "windfarm.h"
24#include "windfarm_mpu.h"
25
26#define VERSION "1.0"
27
28#ifdef DEBUG
29#define DBG(args...) printk(args)
30#else
31#define DBG(args...) do { } while(0)
32#endif
33
34/*
35 * This option is "weird" :) Basically, if you define this to 1
36 * the control loop for the RPMs fans (not PWMs) will apply the
37 * correction factor obtained from the PID to the actual RPM
38 * speed read from the FCU.
39 *
40 * If you define the below constant to 0, then it will be
41 * applied to the setpoint RPM speed, that is basically the
42 * speed we proviously "asked" for.
43 *
44 * I'm using 0 for now which is what therm_pm72 used to do and
45 * what Darwin -apparently- does based on observed behaviour.
46 */
47#define RPM_PID_USE_ACTUAL_SPEED 0
48
49/* Default min/max for pumps */
50#define CPU_PUMP_OUTPUT_MAX 3200
51#define CPU_PUMP_OUTPUT_MIN 1250
52
53#define FCU_FAN_RPM 0
54#define FCU_FAN_PWM 1
55
56struct wf_fcu_priv {
57 struct kref ref;
58 struct i2c_client *i2c;
59 struct mutex lock;
60 struct list_head fan_list;
61 int rpm_shift;
62};
63
64struct wf_fcu_fan {
65 struct list_head link;
66 int id;
67 s32 min, max, target;
68 struct wf_fcu_priv *fcu_priv;
69 struct wf_control ctrl;
70};
71
72static void wf_fcu_release(struct kref *ref)
73{
74 struct wf_fcu_priv *pv = container_of(ref, struct wf_fcu_priv, ref);
75
76 kfree(pv);
77}
78
79static void wf_fcu_fan_release(struct wf_control *ct)
80{
81 struct wf_fcu_fan *fan = ct->priv;
82
83 kref_put(&fan->fcu_priv->ref, wf_fcu_release);
84 kfree(fan);
85}
86
87static int wf_fcu_read_reg(struct wf_fcu_priv *pv, int reg,
88 unsigned char *buf, int nb)
89{
90 int tries, nr, nw;
91
92 mutex_lock(&pv->lock);
93
94 buf[0] = reg;
95 tries = 0;
96 for (;;) {
97 nw = i2c_master_send(pv->i2c, buf, 1);
98 if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
99 break;
100 msleep(10);
101 ++tries;
102 }
103 if (nw <= 0) {
104 pr_err("Failure writing address to FCU: %d", nw);
105 nr = nw;
106 goto bail;
107 }
108 tries = 0;
109 for (;;) {
110 nr = i2c_master_recv(pv->i2c, buf, nb);
111 if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100)
112 break;
113 msleep(10);
114 ++tries;
115 }
116 if (nr <= 0)
117 pr_err("wf_fcu: Failure reading data from FCU: %d", nw);
118 bail:
119 mutex_unlock(&pv->lock);
120 return nr;
121}
122
123static int wf_fcu_write_reg(struct wf_fcu_priv *pv, int reg,
124 const unsigned char *ptr, int nb)
125{
126 int tries, nw;
127 unsigned char buf[16];
128
129 buf[0] = reg;
130 memcpy(buf+1, ptr, nb);
131 ++nb;
132 tries = 0;
133 for (;;) {
134 nw = i2c_master_send(pv->i2c, buf, nb);
135 if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
136 break;
137 msleep(10);
138 ++tries;
139 }
140 if (nw < 0)
141 pr_err("wf_fcu: Failure writing to FCU: %d", nw);
142 return nw;
143}
144
145static int wf_fcu_fan_set_rpm(struct wf_control *ct, s32 value)
146{
147 struct wf_fcu_fan *fan = ct->priv;
148 struct wf_fcu_priv *pv = fan->fcu_priv;
149 int rc, shift = pv->rpm_shift;
150 unsigned char buf[2];
151
152 if (value < fan->min)
153 value = fan->min;
154 if (value > fan->max)
155 value = fan->max;
156
157 fan->target = value;
158
159 buf[0] = value >> (8 - shift);
160 buf[1] = value << shift;
161 rc = wf_fcu_write_reg(pv, 0x10 + (fan->id * 2), buf, 2);
162 if (rc < 0)
163 return -EIO;
164 return 0;
165}
166
167static int wf_fcu_fan_get_rpm(struct wf_control *ct, s32 *value)
168{
169 struct wf_fcu_fan *fan = ct->priv;
170 struct wf_fcu_priv *pv = fan->fcu_priv;
171 int rc, reg_base, shift = pv->rpm_shift;
172 unsigned char failure;
173 unsigned char active;
174 unsigned char buf[2];
175
176 rc = wf_fcu_read_reg(pv, 0xb, &failure, 1);
177 if (rc != 1)
178 return -EIO;
179 if ((failure & (1 << fan->id)) != 0)
180 return -EFAULT;
181 rc = wf_fcu_read_reg(pv, 0xd, &active, 1);
182 if (rc != 1)
183 return -EIO;
184 if ((active & (1 << fan->id)) == 0)
185 return -ENXIO;
186
187 /* Programmed value or real current speed */
188#if RPM_PID_USE_ACTUAL_SPEED
189 reg_base = 0x11;
190#else
191 reg_base = 0x10;
192#endif
193 rc = wf_fcu_read_reg(pv, reg_base + (fan->id * 2), buf, 2);
194 if (rc != 2)
195 return -EIO;
196
197 *value = (buf[0] << (8 - shift)) | buf[1] >> shift;
198
199 return 0;
200}
201
202static int wf_fcu_fan_set_pwm(struct wf_control *ct, s32 value)
203{
204 struct wf_fcu_fan *fan = ct->priv;
205 struct wf_fcu_priv *pv = fan->fcu_priv;
206 unsigned char buf[2];
207 int rc;
208
209 if (value < fan->min)
210 value = fan->min;
211 if (value > fan->max)
212 value = fan->max;
213
214 fan->target = value;
215
216 value = (value * 2559) / 1000;
217 buf[0] = value;
218 rc = wf_fcu_write_reg(pv, 0x30 + (fan->id * 2), buf, 1);
219 if (rc < 0)
220 return -EIO;
221 return 0;
222}
223
224static int wf_fcu_fan_get_pwm(struct wf_control *ct, s32 *value)
225{
226 struct wf_fcu_fan *fan = ct->priv;
227 struct wf_fcu_priv *pv = fan->fcu_priv;
228 unsigned char failure;
229 unsigned char active;
230 unsigned char buf[2];
231 int rc;
232
233 rc = wf_fcu_read_reg(pv, 0x2b, &failure, 1);
234 if (rc != 1)
235 return -EIO;
236 if ((failure & (1 << fan->id)) != 0)
237 return -EFAULT;
238 rc = wf_fcu_read_reg(pv, 0x2d, &active, 1);
239 if (rc != 1)
240 return -EIO;
241 if ((active & (1 << fan->id)) == 0)
242 return -ENXIO;
243
244 rc = wf_fcu_read_reg(pv, 0x30 + (fan->id * 2), buf, 1);
245 if (rc != 1)
246 return -EIO;
247
248 *value = (((s32)buf[0]) * 1000) / 2559;
249
250 return 0;
251}
252
253static s32 wf_fcu_fan_min(struct wf_control *ct)
254{
255 struct wf_fcu_fan *fan = ct->priv;
256
257 return fan->min;
258}
259
260static s32 wf_fcu_fan_max(struct wf_control *ct)
261{
262 struct wf_fcu_fan *fan = ct->priv;
263
264 return fan->max;
265}
266
267static const struct wf_control_ops wf_fcu_fan_rpm_ops = {
268 .set_value = wf_fcu_fan_set_rpm,
269 .get_value = wf_fcu_fan_get_rpm,
270 .get_min = wf_fcu_fan_min,
271 .get_max = wf_fcu_fan_max,
272 .release = wf_fcu_fan_release,
273 .owner = THIS_MODULE,
274};
275
276static const struct wf_control_ops wf_fcu_fan_pwm_ops = {
277 .set_value = wf_fcu_fan_set_pwm,
278 .get_value = wf_fcu_fan_get_pwm,
279 .get_min = wf_fcu_fan_min,
280 .get_max = wf_fcu_fan_max,
281 .release = wf_fcu_fan_release,
282 .owner = THIS_MODULE,
283};
284
285static void wf_fcu_get_pump_minmax(struct wf_fcu_fan *fan)
286{
287 const struct mpu_data *mpu = wf_get_mpu(0);
288 u16 pump_min = 0, pump_max = 0xffff;
289 u16 tmp[4];
290
291 /* Try to fetch pumps min/max infos from eeprom */
292 if (mpu) {
293 memcpy(&tmp, mpu->processor_part_num, 8);
294 if (tmp[0] != 0xffff && tmp[1] != 0xffff) {
295 pump_min = max(pump_min, tmp[0]);
296 pump_max = min(pump_max, tmp[1]);
297 }
298 if (tmp[2] != 0xffff && tmp[3] != 0xffff) {
299 pump_min = max(pump_min, tmp[2]);
300 pump_max = min(pump_max, tmp[3]);
301 }
302 }
303
304 /* Double check the values, this _IS_ needed as the EEPROM on
305 * some dual 2.5Ghz G5s seem, at least, to have both min & max
306 * same to the same value ... (grrrr)
307 */
308 if (pump_min == pump_max || pump_min == 0 || pump_max == 0xffff) {
309 pump_min = CPU_PUMP_OUTPUT_MIN;
310 pump_max = CPU_PUMP_OUTPUT_MAX;
311 }
312
313 fan->min = pump_min;
314 fan->max = pump_max;
315
316 DBG("wf_fcu: pump min/max for %s set to: [%d..%d] RPM\n",
317 fan->ctrl.name, pump_min, pump_max);
318}
319
320static void wf_fcu_get_rpmfan_minmax(struct wf_fcu_fan *fan)
321{
322 struct wf_fcu_priv *pv = fan->fcu_priv;
323 const struct mpu_data *mpu0 = wf_get_mpu(0);
324 const struct mpu_data *mpu1 = wf_get_mpu(1);
325
326 /* Default */
327 fan->min = 2400 >> pv->rpm_shift;
328 fan->max = 56000 >> pv->rpm_shift;
329
330 /* CPU fans have min/max in MPU */
331 if (mpu0 && !strcmp(fan->ctrl.name, "cpu-front-fan-0")) {
332 fan->min = max(fan->min, (s32)mpu0->rminn_intake_fan);
333 fan->max = min(fan->max, (s32)mpu0->rmaxn_intake_fan);
334 goto bail;
335 }
336 if (mpu1 && !strcmp(fan->ctrl.name, "cpu-front-fan-1")) {
337 fan->min = max(fan->min, (s32)mpu1->rminn_intake_fan);
338 fan->max = min(fan->max, (s32)mpu1->rmaxn_intake_fan);
339 goto bail;
340 }
341 if (mpu0 && !strcmp(fan->ctrl.name, "cpu-rear-fan-0")) {
342 fan->min = max(fan->min, (s32)mpu0->rminn_exhaust_fan);
343 fan->max = min(fan->max, (s32)mpu0->rmaxn_exhaust_fan);
344 goto bail;
345 }
346 if (mpu1 && !strcmp(fan->ctrl.name, "cpu-rear-fan-1")) {
347 fan->min = max(fan->min, (s32)mpu1->rminn_exhaust_fan);
348 fan->max = min(fan->max, (s32)mpu1->rmaxn_exhaust_fan);
349 goto bail;
350 }
351 /* Rackmac variants, we just use mpu0 intake */
352 if (!strncmp(fan->ctrl.name, "cpu-fan", 7)) {
353 fan->min = max(fan->min, (s32)mpu0->rminn_intake_fan);
354 fan->max = min(fan->max, (s32)mpu0->rmaxn_intake_fan);
355 goto bail;
356 }
357 bail:
358 DBG("wf_fcu: fan min/max for %s set to: [%d..%d] RPM\n",
359 fan->ctrl.name, fan->min, fan->max);
360}
361
362static void wf_fcu_add_fan(struct wf_fcu_priv *pv, const char *name,
363 int type, int id)
364{
365 struct wf_fcu_fan *fan;
366
367 fan = kzalloc(sizeof(*fan), GFP_KERNEL);
368 if (!fan)
369 return;
370 fan->fcu_priv = pv;
371 fan->id = id;
372 fan->ctrl.name = name;
373 fan->ctrl.priv = fan;
374
375 /* min/max is oddball but the code comes from
376 * therm_pm72 which seems to work so ...
377 */
378 if (type == FCU_FAN_RPM) {
379 if (!strncmp(name, "cpu-pump", strlen("cpu-pump")))
380 wf_fcu_get_pump_minmax(fan);
381 else
382 wf_fcu_get_rpmfan_minmax(fan);
383 fan->ctrl.type = WF_CONTROL_RPM_FAN;
384 fan->ctrl.ops = &wf_fcu_fan_rpm_ops;
385 } else {
386 fan->min = 10;
387 fan->max = 100;
388 fan->ctrl.type = WF_CONTROL_PWM_FAN;
389 fan->ctrl.ops = &wf_fcu_fan_pwm_ops;
390 }
391
392 if (wf_register_control(&fan->ctrl)) {
393 pr_err("wf_fcu: Failed to register fan %s\n", name);
394 kfree(fan);
395 return;
396 }
397 list_add(&fan->link, &pv->fan_list);
398 kref_get(&pv->ref);
399}
400
401static void wf_fcu_lookup_fans(struct wf_fcu_priv *pv)
402{
403 /* Translation of device-tree location properties to
404 * windfarm fan names
405 */
406 static const struct {
407 const char *dt_name; /* Device-tree name */
408 const char *ct_name; /* Control name */
409 } loc_trans[] = {
410 { "BACKSIDE", "backside-fan", },
411 { "SYS CTRLR FAN", "backside-fan", },
412 { "DRIVE BAY", "drive-bay-fan", },
413 { "SLOT", "slots-fan", },
414 { "PCI FAN", "slots-fan", },
415 { "CPU A INTAKE", "cpu-front-fan-0", },
416 { "CPU A EXHAUST", "cpu-rear-fan-0", },
417 { "CPU B INTAKE", "cpu-front-fan-1", },
418 { "CPU B EXHAUST", "cpu-rear-fan-1", },
419 { "CPU A PUMP", "cpu-pump-0", },
420 { "CPU B PUMP", "cpu-pump-1", },
421 { "CPU A 1", "cpu-fan-a-0", },
422 { "CPU A 2", "cpu-fan-b-0", },
423 { "CPU A 3", "cpu-fan-c-0", },
424 { "CPU B 1", "cpu-fan-a-1", },
425 { "CPU B 2", "cpu-fan-b-1", },
426 { "CPU B 3", "cpu-fan-c-1", },
427 };
428 struct device_node *np = NULL, *fcu = pv->i2c->dev.of_node;
429 int i;
430
431 DBG("Looking up FCU controls in device-tree...\n");
432
433 while ((np = of_get_next_child(fcu, np)) != NULL) {
434 int id, type = -1;
435 const char *loc;
436 const char *name;
437 const u32 *reg;
438
439 DBG(" control: %s, type: %s\n", np->name, np->type);
440
441 /* Detect control type */
442 if (!strcmp(np->type, "fan-rpm-control") ||
443 !strcmp(np->type, "fan-rpm"))
444 type = FCU_FAN_RPM;
445 if (!strcmp(np->type, "fan-pwm-control") ||
446 !strcmp(np->type, "fan-pwm"))
447 type = FCU_FAN_PWM;
448 /* Only care about fans for now */
449 if (type == -1)
450 continue;
451
452 /* Lookup for a matching location */
453 loc = of_get_property(np, "location", NULL);
454 reg = of_get_property(np, "reg", NULL);
455 if (loc == NULL || reg == NULL)
456 continue;
457 DBG(" matching location: %s, reg: 0x%08x\n", loc, *reg);
458
459 for (i = 0; i < ARRAY_SIZE(loc_trans); i++) {
460 if (strncmp(loc, loc_trans[i].dt_name,
461 strlen(loc_trans[i].dt_name)))
462 continue;
463 name = loc_trans[i].ct_name;
464
465 DBG(" location match, name: %s\n", name);
466
467 if (type == FCU_FAN_RPM)
468 id = ((*reg) - 0x10) / 2;
469 else
470 id = ((*reg) - 0x30) / 2;
471 if (id > 7) {
472 pr_warning("wf_fcu: Can't parse "
473 "fan ID in device-tree for %s\n",
474 np->full_name);
475 break;
476 }
477 wf_fcu_add_fan(pv, name, type, id);
478 break;
479 }
480 }
481}
482
483static void wf_fcu_default_fans(struct wf_fcu_priv *pv)
484{
485 /* We only support the default fans for PowerMac7,2 */
486 if (!of_machine_is_compatible("PowerMac7,2"))
487 return;
488
489 wf_fcu_add_fan(pv, "backside-fan", FCU_FAN_PWM, 1);
490 wf_fcu_add_fan(pv, "drive-bay-fan", FCU_FAN_RPM, 2);
491 wf_fcu_add_fan(pv, "slots-fan", FCU_FAN_PWM, 2);
492 wf_fcu_add_fan(pv, "cpu-front-fan-0", FCU_FAN_RPM, 3);
493 wf_fcu_add_fan(pv, "cpu-rear-fan-0", FCU_FAN_RPM, 4);
494 wf_fcu_add_fan(pv, "cpu-front-fan-1", FCU_FAN_RPM, 5);
495 wf_fcu_add_fan(pv, "cpu-rear-fan-1", FCU_FAN_RPM, 6);
496}
497
498static int wf_fcu_init_chip(struct wf_fcu_priv *pv)
499{
500 unsigned char buf = 0xff;
501 int rc;
502
503 rc = wf_fcu_write_reg(pv, 0xe, &buf, 1);
504 if (rc < 0)
505 return -EIO;
506 rc = wf_fcu_write_reg(pv, 0x2e, &buf, 1);
507 if (rc < 0)
508 return -EIO;
509 rc = wf_fcu_read_reg(pv, 0, &buf, 1);
510 if (rc < 0)
511 return -EIO;
512 pv->rpm_shift = (buf == 1) ? 2 : 3;
513
514 pr_debug("wf_fcu: FCU Initialized, RPM fan shift is %d\n",
515 pv->rpm_shift);
516
517 return 0;
518}
519
520static int wf_fcu_probe(struct i2c_client *client,
521 const struct i2c_device_id *id)
522{
523 struct wf_fcu_priv *pv;
524
525 pv = kzalloc(sizeof(*pv), GFP_KERNEL);
526 if (!pv)
527 return -ENOMEM;
528
529 kref_init(&pv->ref);
530 mutex_init(&pv->lock);
531 INIT_LIST_HEAD(&pv->fan_list);
532 pv->i2c = client;
533
534 /*
535 * First we must start the FCU which will query the
536 * shift value to apply to RPMs
537 */
538 if (wf_fcu_init_chip(pv)) {
539 pr_err("wf_fcu: Initialization failed !\n");
540 kfree(pv);
541 return -ENXIO;
542 }
543
544 /* First lookup fans in the device-tree */
545 wf_fcu_lookup_fans(pv);
546
547 /*
548 * Older machines don't have the device-tree entries
549 * we are looking for, just hard code the list
550 */
551 if (list_empty(&pv->fan_list))
552 wf_fcu_default_fans(pv);
553
554 /* Still no fans ? FAIL */
555 if (list_empty(&pv->fan_list)) {
556 pr_err("wf_fcu: Failed to find fans for your machine\n");
557 kfree(pv);
558 return -ENODEV;
559 }
560
561 dev_set_drvdata(&client->dev, pv);
562
563 return 0;
564}
565
566static int wf_fcu_remove(struct i2c_client *client)
567{
568 struct wf_fcu_priv *pv = dev_get_drvdata(&client->dev);
569 struct wf_fcu_fan *fan;
570
571 while (!list_empty(&pv->fan_list)) {
572 fan = list_first_entry(&pv->fan_list, struct wf_fcu_fan, link);
573 list_del(&fan->link);
574 wf_unregister_control(&fan->ctrl);
575 }
576 kref_put(&pv->ref, wf_fcu_release);
577 return 0;
578}
579
580static const struct i2c_device_id wf_fcu_id[] = {
581 { "MAC,fcu", 0 },
582 { }
583};
584MODULE_DEVICE_TABLE(i2c, wf_fcu_id);
585
586static struct i2c_driver wf_fcu_driver = {
587 .driver = {
588 .name = "wf_fcu",
589 },
590 .probe = wf_fcu_probe,
591 .remove = wf_fcu_remove,
592 .id_table = wf_fcu_id,
593};
594
595module_i2c_driver(wf_fcu_driver);
596
597MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
598MODULE_DESCRIPTION("FCU control objects for PowerMacs thermal control");
599MODULE_LICENSE("GPL");
600
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 9ef32b3df91..647c6add219 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -18,12 +18,13 @@
18#include <asm/prom.h> 18#include <asm/prom.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/system.h>
21#include <asm/sections.h> 22#include <asm/sections.h>
22#include <asm/pmac_low_i2c.h> 23#include <asm/pmac_low_i2c.h>
23 24
24#include "windfarm.h" 25#include "windfarm.h"
25 26
26#define VERSION "1.0" 27#define VERSION "0.2"
27 28
28#undef DEBUG 29#undef DEBUG
29 30
@@ -36,8 +37,8 @@
36struct wf_lm75_sensor { 37struct wf_lm75_sensor {
37 int ds1775 : 1; 38 int ds1775 : 1;
38 int inited : 1; 39 int inited : 1;
39 struct i2c_client *i2c; 40 struct i2c_client *i2c;
40 struct wf_sensor sens; 41 struct wf_sensor sens;
41}; 42};
42#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) 43#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
43 44
@@ -90,19 +91,40 @@ static struct wf_sensor_ops wf_lm75_ops = {
90 91
91static int wf_lm75_probe(struct i2c_client *client, 92static int wf_lm75_probe(struct i2c_client *client,
92 const struct i2c_device_id *id) 93 const struct i2c_device_id *id)
93{ 94{
94 struct wf_lm75_sensor *lm; 95 struct wf_lm75_sensor *lm;
95 int rc, ds1775 = id->driver_data; 96 int rc;
96 const char *name, *loc;
97 97
98 DBG("wf_lm75: creating %s device at address 0x%02x\n", 98 lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
99 ds1775 ? "ds1775" : "lm75", client->addr); 99 if (lm == NULL)
100 return -ENODEV;
100 101
101 loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL); 102 lm->inited = 0;
102 if (!loc) { 103 lm->ds1775 = id->driver_data;
103 dev_warn(&client->dev, "Missing hwsensor-location property!\n"); 104 lm->i2c = client;
104 return -ENXIO; 105 lm->sens.name = client->dev.platform_data;
105 } 106 lm->sens.ops = &wf_lm75_ops;
107 i2c_set_clientdata(client, lm);
108
109 rc = wf_register_sensor(&lm->sens);
110 if (rc)
111 kfree(lm);
112
113 return rc;
114}
115
116static struct i2c_driver wf_lm75_driver;
117
118static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
119 u8 addr, int ds1775,
120 const char *loc)
121{
122 struct i2c_board_info info;
123 struct i2c_client *client;
124 char *name;
125
126 DBG("wf_lm75: creating %s device at address 0x%02x\n",
127 ds1775 ? "ds1775" : "lm75", addr);
106 128
107 /* Usual rant about sensor names not beeing very consistent in 129 /* Usual rant about sensor names not beeing very consistent in
108 * the device-tree, oh well ... 130 * the device-tree, oh well ...
@@ -116,31 +138,68 @@ static int wf_lm75_probe(struct i2c_client *client,
116 name = "optical-drive-temp"; 138 name = "optical-drive-temp";
117 else if (!strcmp(loc, "HD Temp")) 139 else if (!strcmp(loc, "HD Temp"))
118 name = "hard-drive-temp"; 140 name = "hard-drive-temp";
119 else if (!strcmp(loc, "PCI SLOTS"))
120 name = "slots-temp";
121 else if (!strcmp(loc, "CPU A INLET"))
122 name = "cpu-inlet-temp-0";
123 else if (!strcmp(loc, "CPU B INLET"))
124 name = "cpu-inlet-temp-1";
125 else 141 else
126 return -ENXIO; 142 goto fail;
127 143
144 memset(&info, 0, sizeof(struct i2c_board_info));
145 info.addr = (addr >> 1) & 0x7f;
146 info.platform_data = name;
147 strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE);
148
149 client = i2c_new_device(adapter, &info);
150 if (client == NULL) {
151 printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
152 ds1775 ? "ds1775" : "lm75", name);
153 goto fail;
154 }
128 155
129 lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); 156 /*
130 if (lm == NULL) 157 * Let i2c-core delete that device on driver removal.
158 * This is safe because i2c-core holds the core_lock mutex for us.
159 */
160 list_add_tail(&client->detected, &wf_lm75_driver.clients);
161 return client;
162 fail:
163 return NULL;
164}
165
166static int wf_lm75_attach(struct i2c_adapter *adapter)
167{
168 struct device_node *busnode, *dev;
169 struct pmac_i2c_bus *bus;
170
171 DBG("wf_lm75: adapter %s detected\n", adapter->name);
172
173 bus = pmac_i2c_adapter_to_bus(adapter);
174 if (bus == NULL)
131 return -ENODEV; 175 return -ENODEV;
176 busnode = pmac_i2c_get_bus_node(bus);
132 177
133 lm->inited = 0; 178 DBG("wf_lm75: bus found, looking for device...\n");
134 lm->ds1775 = ds1775;
135 lm->i2c = client;
136 lm->sens.name = (char *)name; /* XXX fix constness in structure */
137 lm->sens.ops = &wf_lm75_ops;
138 i2c_set_clientdata(client, lm);
139 179
140 rc = wf_register_sensor(&lm->sens); 180 /* Now look for lm75(s) in there */
141 if (rc) 181 for (dev = NULL;
142 kfree(lm); 182 (dev = of_get_next_child(busnode, dev)) != NULL;) {
143 return rc; 183 const char *loc =
184 of_get_property(dev, "hwsensor-location", NULL);
185 u8 addr;
186
187 /* We must re-match the adapter in order to properly check
188 * the channel on multibus setups
189 */
190 if (!pmac_i2c_match_adapter(dev, adapter))
191 continue;
192 addr = pmac_i2c_get_dev_addr(dev);
193 if (loc == NULL || addr == 0)
194 continue;
195 /* real lm75 */
196 if (of_device_is_compatible(dev, "lm75"))
197 wf_lm75_create(adapter, addr, 0, loc);
198 /* ds1775 (compatible, better resolution */
199 else if (of_device_is_compatible(dev, "ds1775"))
200 wf_lm75_create(adapter, addr, 1, loc);
201 }
202 return 0;
144} 203}
145 204
146static int wf_lm75_remove(struct i2c_client *client) 205static int wf_lm75_remove(struct i2c_client *client)
@@ -159,22 +218,39 @@ static int wf_lm75_remove(struct i2c_client *client)
159} 218}
160 219
161static const struct i2c_device_id wf_lm75_id[] = { 220static const struct i2c_device_id wf_lm75_id[] = {
162 { "MAC,lm75", 0 }, 221 { "wf_lm75", 0 },
163 { "MAC,ds1775", 1 }, 222 { "wf_ds1775", 1 },
164 { } 223 { }
165}; 224};
166MODULE_DEVICE_TABLE(i2c, wf_lm75_id);
167 225
168static struct i2c_driver wf_lm75_driver = { 226static struct i2c_driver wf_lm75_driver = {
169 .driver = { 227 .driver = {
170 .name = "wf_lm75", 228 .name = "wf_lm75",
171 }, 229 },
230 .attach_adapter = wf_lm75_attach,
172 .probe = wf_lm75_probe, 231 .probe = wf_lm75_probe,
173 .remove = wf_lm75_remove, 232 .remove = wf_lm75_remove,
174 .id_table = wf_lm75_id, 233 .id_table = wf_lm75_id,
175}; 234};
176 235
177module_i2c_driver(wf_lm75_driver); 236static int __init wf_lm75_sensor_init(void)
237{
238 /* Don't register on old machines that use therm_pm72 for now */
239 if (of_machine_is_compatible("PowerMac7,2") ||
240 of_machine_is_compatible("PowerMac7,3") ||
241 of_machine_is_compatible("RackMac3,1"))
242 return -ENODEV;
243 return i2c_add_driver(&wf_lm75_driver);
244}
245
246static void __exit wf_lm75_sensor_exit(void)
247{
248 i2c_del_driver(&wf_lm75_driver);
249}
250
251
252module_init(wf_lm75_sensor_init);
253module_exit(wf_lm75_sensor_exit);
178 254
179MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); 255MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
180MODULE_DESCRIPTION("LM75 sensor objects for PowerMacs thermal control"); 256MODULE_DESCRIPTION("LM75 sensor objects for PowerMacs thermal control");
diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c
deleted file mode 100644
index c071aab79dd..00000000000
--- a/drivers/macintosh/windfarm_lm87_sensor.c
+++ /dev/null
@@ -1,201 +0,0 @@
1/*
2 * Windfarm PowerMac thermal control. LM87 sensor
3 *
4 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp.
5 *
6 * Released under the term of the GNU GPL v2.
7 *
8 */
9
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/wait.h>
17#include <linux/i2c.h>
18#include <asm/prom.h>
19#include <asm/machdep.h>
20#include <asm/io.h>
21#include <asm/sections.h>
22#include <asm/pmac_low_i2c.h>
23
24#include "windfarm.h"
25
26#define VERSION "1.0"
27
28#undef DEBUG
29
30#ifdef DEBUG
31#define DBG(args...) printk(args)
32#else
33#define DBG(args...) do { } while(0)
34#endif
35
36struct wf_lm87_sensor {
37 struct i2c_client *i2c;
38 struct wf_sensor sens;
39};
40#define wf_to_lm87(c) container_of(c, struct wf_lm87_sensor, sens)
41
42
43static int wf_lm87_read_reg(struct i2c_client *chip, int reg)
44{
45 int rc, tries = 0;
46 u8 buf;
47
48 for (;;) {
49 /* Set address */
50 buf = (u8)reg;
51 rc = i2c_master_send(chip, &buf, 1);
52 if (rc <= 0)
53 goto error;
54 rc = i2c_master_recv(chip, &buf, 1);
55 if (rc <= 0)
56 goto error;
57 return (int)buf;
58 error:
59 DBG("wf_lm87: Error reading LM87, retrying...\n");
60 if (++tries > 10) {
61 printk(KERN_ERR "wf_lm87: Error reading LM87 !\n");
62 return -EIO;
63 }
64 msleep(10);
65 }
66}
67
68static int wf_lm87_get(struct wf_sensor *sr, s32 *value)
69{
70 struct wf_lm87_sensor *lm = sr->priv;
71 s32 temp;
72
73 if (lm->i2c == NULL)
74 return -ENODEV;
75
76#define LM87_INT_TEMP 0x27
77
78 /* Read temperature register */
79 temp = wf_lm87_read_reg(lm->i2c, LM87_INT_TEMP);
80 if (temp < 0)
81 return temp;
82 *value = temp << 16;
83
84 return 0;
85}
86
87static void wf_lm87_release(struct wf_sensor *sr)
88{
89 struct wf_lm87_sensor *lm = wf_to_lm87(sr);
90
91 kfree(lm);
92}
93
94static struct wf_sensor_ops wf_lm87_ops = {
95 .get_value = wf_lm87_get,
96 .release = wf_lm87_release,
97 .owner = THIS_MODULE,
98};
99
100static int wf_lm87_probe(struct i2c_client *client,
101 const struct i2c_device_id *id)
102{
103 struct wf_lm87_sensor *lm;
104 const char *name = NULL, *loc;
105 struct device_node *np = NULL;
106 int rc;
107
108 /*
109 * The lm87 contains a whole pile of sensors, additionally,
110 * the Xserve G5 has several lm87's. However, for now we only
111 * care about the internal temperature sensor
112 */
113 while ((np = of_get_next_child(client->dev.of_node, np)) != NULL) {
114 if (strcmp(np->name, "int-temp"))
115 continue;
116 loc = of_get_property(np, "location", NULL);
117 if (!loc)
118 continue;
119 if (strstr(loc, "DIMM"))
120 name = "dimms-temp";
121 else if (strstr(loc, "Processors"))
122 name = "between-cpus-temp";
123 if (name) {
124 of_node_put(np);
125 break;
126 }
127 }
128 if (!name) {
129 pr_warning("wf_lm87: Unsupported sensor %s\n",
130 client->dev.of_node->full_name);
131 return -ENODEV;
132 }
133
134 lm = kzalloc(sizeof(struct wf_lm87_sensor), GFP_KERNEL);
135 if (lm == NULL)
136 return -ENODEV;
137
138 lm->i2c = client;
139 lm->sens.name = name;
140 lm->sens.ops = &wf_lm87_ops;
141 lm->sens.priv = lm;
142 i2c_set_clientdata(client, lm);
143
144 rc = wf_register_sensor(&lm->sens);
145 if (rc)
146 kfree(lm);
147 return rc;
148}
149
150static int wf_lm87_remove(struct i2c_client *client)
151{
152 struct wf_lm87_sensor *lm = i2c_get_clientdata(client);
153
154 DBG("wf_lm87: i2c detatch called for %s\n", lm->sens.name);
155
156 /* Mark client detached */
157 lm->i2c = NULL;
158
159 /* release sensor */
160 wf_unregister_sensor(&lm->sens);
161
162 return 0;
163}
164
165static const struct i2c_device_id wf_lm87_id[] = {
166 { "MAC,lm87cimt", 0 },
167 { }
168};
169MODULE_DEVICE_TABLE(i2c, wf_lm87_id);
170
171static struct i2c_driver wf_lm87_driver = {
172 .driver = {
173 .name = "wf_lm87",
174 },
175 .probe = wf_lm87_probe,
176 .remove = wf_lm87_remove,
177 .id_table = wf_lm87_id,
178};
179
180static int __init wf_lm87_sensor_init(void)
181{
182 /* We only support this on the Xserve */
183 if (!of_machine_is_compatible("RackMac3,1"))
184 return -ENODEV;
185
186 return i2c_add_driver(&wf_lm87_driver);
187}
188
189static void __exit wf_lm87_sensor_exit(void)
190{
191 i2c_del_driver(&wf_lm87_driver);
192}
193
194
195module_init(wf_lm87_sensor_init);
196module_exit(wf_lm87_sensor_exit);
197
198MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
199MODULE_DESCRIPTION("LM87 sensor objects for PowerMacs thermal control");
200MODULE_LICENSE("GPL");
201
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index 945a25b2f31..8204113268f 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -16,7 +16,7 @@
16 16
17#include "windfarm.h" 17#include "windfarm.h"
18 18
19#define VERSION "1.0" 19#define VERSION "0.2"
20 20
21/* This currently only exports the external temperature sensor, 21/* This currently only exports the external temperature sensor,
22 since that's all the control loops need. */ 22 since that's all the control loops need. */
@@ -64,29 +64,9 @@ static struct wf_sensor_ops wf_max6690_ops = {
64static int wf_max6690_probe(struct i2c_client *client, 64static int wf_max6690_probe(struct i2c_client *client,
65 const struct i2c_device_id *id) 65 const struct i2c_device_id *id)
66{ 66{
67 const char *name, *loc;
68 struct wf_6690_sensor *max; 67 struct wf_6690_sensor *max;
69 int rc; 68 int rc;
70 69
71 loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL);
72 if (!loc) {
73 dev_warn(&client->dev, "Missing hwsensor-location property!\n");
74 return -ENXIO;
75 }
76
77 /*
78 * We only expose the external temperature register for
79 * now as this is all we need for our control loops
80 */
81 if (!strcmp(loc, "BACKSIDE") || !strcmp(loc, "SYS CTRLR AMBIENT"))
82 name = "backside-temp";
83 else if (!strcmp(loc, "NB Ambient"))
84 name = "north-bridge-temp";
85 else if (!strcmp(loc, "GPU Ambient"))
86 name = "gpu-temp";
87 else
88 return -ENXIO;
89
90 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); 70 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
91 if (max == NULL) { 71 if (max == NULL) {
92 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: " 72 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
@@ -95,16 +75,90 @@ static int wf_max6690_probe(struct i2c_client *client,
95 } 75 }
96 76
97 max->i2c = client; 77 max->i2c = client;
98 max->sens.name = (char *)name; /* XXX fix constness in structure */ 78 max->sens.name = client->dev.platform_data;
99 max->sens.ops = &wf_max6690_ops; 79 max->sens.ops = &wf_max6690_ops;
100 i2c_set_clientdata(client, max); 80 i2c_set_clientdata(client, max);
101 81
102 rc = wf_register_sensor(&max->sens); 82 rc = wf_register_sensor(&max->sens);
103 if (rc) 83 if (rc) {
104 kfree(max); 84 kfree(max);
85 }
86
105 return rc; 87 return rc;
106} 88}
107 89
90static struct i2c_driver wf_max6690_driver;
91
92static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
93 u8 addr, const char *loc)
94{
95 struct i2c_board_info info;
96 struct i2c_client *client;
97 char *name;
98
99 if (!strcmp(loc, "BACKSIDE"))
100 name = "backside-temp";
101 else if (!strcmp(loc, "NB Ambient"))
102 name = "north-bridge-temp";
103 else if (!strcmp(loc, "GPU Ambient"))
104 name = "gpu-temp";
105 else
106 goto fail;
107
108 memset(&info, 0, sizeof(struct i2c_board_info));
109 info.addr = addr >> 1;
110 info.platform_data = name;
111 strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE);
112
113 client = i2c_new_device(adapter, &info);
114 if (client == NULL) {
115 printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
116 goto fail;
117 }
118
119 /*
120 * Let i2c-core delete that device on driver removal.
121 * This is safe because i2c-core holds the core_lock mutex for us.
122 */
123 list_add_tail(&client->detected, &wf_max6690_driver.clients);
124 return client;
125
126 fail:
127 return NULL;
128}
129
130static int wf_max6690_attach(struct i2c_adapter *adapter)
131{
132 struct device_node *busnode, *dev = NULL;
133 struct pmac_i2c_bus *bus;
134 const char *loc;
135
136 bus = pmac_i2c_adapter_to_bus(adapter);
137 if (bus == NULL)
138 return -ENODEV;
139 busnode = pmac_i2c_get_bus_node(bus);
140
141 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
142 u8 addr;
143
144 /* We must re-match the adapter in order to properly check
145 * the channel on multibus setups
146 */
147 if (!pmac_i2c_match_adapter(dev, adapter))
148 continue;
149 if (!of_device_is_compatible(dev, "max6690"))
150 continue;
151 addr = pmac_i2c_get_dev_addr(dev);
152 loc = of_get_property(dev, "hwsensor-location", NULL);
153 if (loc == NULL || addr == 0)
154 continue;
155 printk("found max6690, loc=%s addr=0x%02x\n", loc, addr);
156 wf_max6690_create(adapter, addr, loc);
157 }
158
159 return 0;
160}
161
108static int wf_max6690_remove(struct i2c_client *client) 162static int wf_max6690_remove(struct i2c_client *client)
109{ 163{
110 struct wf_6690_sensor *max = i2c_get_clientdata(client); 164 struct wf_6690_sensor *max = i2c_get_clientdata(client);
@@ -116,21 +170,37 @@ static int wf_max6690_remove(struct i2c_client *client)
116} 170}
117 171
118static const struct i2c_device_id wf_max6690_id[] = { 172static const struct i2c_device_id wf_max6690_id[] = {
119 { "MAC,max6690", 0 }, 173 { "wf_max6690", 0 },
120 { } 174 { }
121}; 175};
122MODULE_DEVICE_TABLE(i2c, wf_max6690_id);
123 176
124static struct i2c_driver wf_max6690_driver = { 177static struct i2c_driver wf_max6690_driver = {
125 .driver = { 178 .driver = {
126 .name = "wf_max6690", 179 .name = "wf_max6690",
127 }, 180 },
181 .attach_adapter = wf_max6690_attach,
128 .probe = wf_max6690_probe, 182 .probe = wf_max6690_probe,
129 .remove = wf_max6690_remove, 183 .remove = wf_max6690_remove,
130 .id_table = wf_max6690_id, 184 .id_table = wf_max6690_id,
131}; 185};
132 186
133module_i2c_driver(wf_max6690_driver); 187static int __init wf_max6690_sensor_init(void)
188{
189 /* Don't register on old machines that use therm_pm72 for now */
190 if (of_machine_is_compatible("PowerMac7,2") ||
191 of_machine_is_compatible("PowerMac7,3") ||
192 of_machine_is_compatible("RackMac3,1"))
193 return -ENODEV;
194 return i2c_add_driver(&wf_max6690_driver);
195}
196
197static void __exit wf_max6690_sensor_exit(void)
198{
199 i2c_del_driver(&wf_max6690_driver);
200}
201
202module_init(wf_max6690_sensor_init);
203module_exit(wf_max6690_sensor_exit);
134 204
135MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); 205MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
136MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control"); 206MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");
diff --git a/drivers/macintosh/windfarm_mpu.h b/drivers/macintosh/windfarm_mpu.h
deleted file mode 100644
index 046edc8c2ec..00000000000
--- a/drivers/macintosh/windfarm_mpu.h
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * Windfarm PowerMac thermal control
3 *
4 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp.
5 *
6 * Released under the term of the GNU GPL v2.
7 */
8
9#ifndef __WINDFARM_MPU_H
10#define __WINDFARM_MPU_H
11
12typedef unsigned short fu16;
13typedef int fs32;
14typedef short fs16;
15
16/* Definition of the MPU data structure which contains per CPU
17 * calibration information (among others) for the G5 machines
18 */
19struct mpu_data
20{
21 u8 signature; /* 0x00 - EEPROM sig. */
22 u8 bytes_used; /* 0x01 - Bytes used in eeprom (160 ?) */
23 u8 size; /* 0x02 - EEPROM size (256 ?) */
24 u8 version; /* 0x03 - EEPROM version */
25 u32 data_revision; /* 0x04 - Dataset revision */
26 u8 processor_bin_code[3]; /* 0x08 - Processor BIN code */
27 u8 bin_code_expansion; /* 0x0b - ??? (padding ?) */
28 u8 processor_num; /* 0x0c - Number of CPUs on this MPU */
29 u8 input_mul_bus_div; /* 0x0d - Clock input multiplier/bus divider */
30 u8 reserved1[2]; /* 0x0e - */
31 u32 input_clk_freq_high; /* 0x10 - Input clock frequency high */
32 u8 cpu_nb_target_cycles; /* 0x14 - ??? */
33 u8 cpu_statlat; /* 0x15 - ??? */
34 u8 cpu_snooplat; /* 0x16 - ??? */
35 u8 cpu_snoopacc; /* 0x17 - ??? */
36 u8 nb_paamwin; /* 0x18 - ??? */
37 u8 nb_statlat; /* 0x19 - ??? */
38 u8 nb_snooplat; /* 0x1a - ??? */
39 u8 nb_snoopwin; /* 0x1b - ??? */
40 u8 api_bus_mode; /* 0x1c - ??? */
41 u8 reserved2[3]; /* 0x1d - */
42 u32 input_clk_freq_low; /* 0x20 - Input clock frequency low */
43 u8 processor_card_slot; /* 0x24 - Processor card slot number */
44 u8 reserved3[2]; /* 0x25 - */
45 u8 padjmax; /* 0x27 - Max power adjustment (Not in OF!) */
46 u8 ttarget; /* 0x28 - Target temperature */
47 u8 tmax; /* 0x29 - Max temperature */
48 u8 pmaxh; /* 0x2a - Max power */
49 u8 tguardband; /* 0x2b - Guardband temp ??? Hist. len in OSX */
50 fs32 pid_gp; /* 0x2c - PID proportional gain */
51 fs32 pid_gr; /* 0x30 - PID reset gain */
52 fs32 pid_gd; /* 0x34 - PID derivative gain */
53 fu16 voph; /* 0x38 - Vop High */
54 fu16 vopl; /* 0x3a - Vop Low */
55 fs16 nactual_die; /* 0x3c - nActual Die */
56 fs16 nactual_heatsink; /* 0x3e - nActual Heatsink */
57 fs16 nactual_system; /* 0x40 - nActual System */
58 u16 calibration_flags; /* 0x42 - Calibration flags */
59 fu16 mdiode; /* 0x44 - Diode M value (scaling factor) */
60 fs16 bdiode; /* 0x46 - Diode B value (offset) */
61 fs32 theta_heat_sink; /* 0x48 - Theta heat sink */
62 u16 rminn_intake_fan; /* 0x4c - Intake fan min RPM */
63 u16 rmaxn_intake_fan; /* 0x4e - Intake fan max RPM */
64 u16 rminn_exhaust_fan; /* 0x50 - Exhaust fan min RPM */
65 u16 rmaxn_exhaust_fan; /* 0x52 - Exhaust fan max RPM */
66 u8 processor_part_num[8]; /* 0x54 - Processor part number XX pumps min/max */
67 u32 processor_lot_num; /* 0x5c - Processor lot number */
68 u8 orig_card_sernum[0x10]; /* 0x60 - Card original serial number */
69 u8 curr_card_sernum[0x10]; /* 0x70 - Card current serial number */
70 u8 mlb_sernum[0x18]; /* 0x80 - MLB serial number */
71 u32 checksum1; /* 0x98 - */
72 u32 checksum2; /* 0x9c - */
73}; /* Total size = 0xa0 */
74
75static inline const struct mpu_data *wf_get_mpu(int cpu)
76{
77 struct device_node *np;
78 char nodename[64];
79 const void *data;
80 int len;
81
82 /*
83 * prom.c routine for finding a node by path is a bit brain dead
84 * and requires exact @xxx unit numbers. This is a bit ugly but
85 * will work for these machines
86 */
87 sprintf(nodename, "/u3@0,f8000000/i2c@f8001000/cpuid@a%d", cpu ? 2 : 0);
88 np = of_find_node_by_path(nodename);
89 if (!np)
90 return NULL;
91 data = of_get_property(np, "cpuid", &len);
92 of_node_put(np);
93 if (!data)
94 return NULL;
95
96 /*
97 * We are naughty, we have dropped the reference to the device
98 * node and still return a pointer to the content. We know we
99 * can do that though as this is only ever called on PowerMac
100 * which cannot remove those nodes
101 */
102 return data;
103}
104
105#endif /* __WINDFARM_MPU_H */
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
index 35ef6e2582b..e0ee80700cd 100644
--- a/drivers/macintosh/windfarm_pm112.c
+++ b/drivers/macintosh/windfarm_pm112.c
@@ -656,7 +656,7 @@ static int wf_pm112_probe(struct platform_device *dev)
656 return 0; 656 return 0;
657} 657}
658 658
659static int wf_pm112_remove(struct platform_device *dev) 659static int __devexit wf_pm112_remove(struct platform_device *dev)
660{ 660{
661 wf_unregister_client(&pm112_events); 661 wf_unregister_client(&pm112_events);
662 /* should release all sensors and controls */ 662 /* should release all sensors and controls */
@@ -665,7 +665,7 @@ static int wf_pm112_remove(struct platform_device *dev)
665 665
666static struct platform_driver wf_pm112_driver = { 666static struct platform_driver wf_pm112_driver = {
667 .probe = wf_pm112_probe, 667 .probe = wf_pm112_probe,
668 .remove = wf_pm112_remove, 668 .remove = __devexit_p(wf_pm112_remove),
669 .driver = { 669 .driver = {
670 .name = "windfarm", 670 .name = "windfarm",
671 .owner = THIS_MODULE, 671 .owner = THIS_MODULE,
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c
index af605e915d4..30e6195e19d 100644
--- a/drivers/macintosh/windfarm_pm121.c
+++ b/drivers/macintosh/windfarm_pm121.c
@@ -215,6 +215,7 @@
215#include <asm/prom.h> 215#include <asm/prom.h>
216#include <asm/machdep.h> 216#include <asm/machdep.h>
217#include <asm/io.h> 217#include <asm/io.h>
218#include <asm/system.h>
218#include <asm/sections.h> 219#include <asm/sections.h>
219#include <asm/smu.h> 220#include <asm/smu.h>
220 221
@@ -987,7 +988,7 @@ static int pm121_probe(struct platform_device *ddev)
987 return 0; 988 return 0;
988} 989}
989 990
990static int pm121_remove(struct platform_device *ddev) 991static int __devexit pm121_remove(struct platform_device *ddev)
991{ 992{
992 wf_unregister_client(&pm121_events); 993 wf_unregister_client(&pm121_events);
993 return 0; 994 return 0;
@@ -995,7 +996,7 @@ static int pm121_remove(struct platform_device *ddev)
995 996
996static struct platform_driver pm121_driver = { 997static struct platform_driver pm121_driver = {
997 .probe = pm121_probe, 998 .probe = pm121_probe,
998 .remove = pm121_remove, 999 .remove = __devexit_p(pm121_remove),
999 .driver = { 1000 .driver = {
1000 .name = "windfarm", 1001 .name = "windfarm",
1001 .bus = &platform_bus_type, 1002 .bus = &platform_bus_type,
diff --git a/drivers/macintosh/windfarm_pm72.c b/drivers/macintosh/windfarm_pm72.c
deleted file mode 100644
index 6e5585357cd..00000000000
--- a/drivers/macintosh/windfarm_pm72.c
+++ /dev/null
@@ -1,847 +0,0 @@
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], &amps);
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, &param);
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, &param);
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 (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; )
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");
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index f84933ff329..749d174b0dc 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -107,6 +107,7 @@
107#include <asm/prom.h> 107#include <asm/prom.h>
108#include <asm/machdep.h> 108#include <asm/machdep.h>
109#include <asm/io.h> 109#include <asm/io.h>
110#include <asm/system.h>
110#include <asm/sections.h> 111#include <asm/sections.h>
111#include <asm/smu.h> 112#include <asm/smu.h>
112 113
@@ -302,13 +303,13 @@ static void wf_smu_create_sys_fans(void)
302 pid_param.interval = WF_SMU_SYS_FANS_INTERVAL; 303 pid_param.interval = WF_SMU_SYS_FANS_INTERVAL;
303 pid_param.history_len = WF_SMU_SYS_FANS_HISTORY_SIZE; 304 pid_param.history_len = WF_SMU_SYS_FANS_HISTORY_SIZE;
304 pid_param.itarget = param->itarget; 305 pid_param.itarget = param->itarget;
305 pid_param.min = wf_control_get_min(fan_system); 306 pid_param.min = fan_system->ops->get_min(fan_system);
306 pid_param.max = wf_control_get_max(fan_system); 307 pid_param.max = fan_system->ops->get_max(fan_system);
307 if (fan_hd) { 308 if (fan_hd) {
308 pid_param.min = 309 pid_param.min =
309 max(pid_param.min, wf_control_get_min(fan_hd)); 310 max(pid_param.min,fan_hd->ops->get_min(fan_hd));
310 pid_param.max = 311 pid_param.max =
311 min(pid_param.max, wf_control_get_max(fan_hd)); 312 min(pid_param.max,fan_hd->ops->get_max(fan_hd));
312 } 313 }
313 wf_pid_init(&wf_smu_sys_fans->pid, &pid_param); 314 wf_pid_init(&wf_smu_sys_fans->pid, &pid_param);
314 315
@@ -337,7 +338,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st)
337 } 338 }
338 st->ticks = WF_SMU_SYS_FANS_INTERVAL; 339 st->ticks = WF_SMU_SYS_FANS_INTERVAL;
339 340
340 rc = wf_sensor_get(sensor_hd_temp, &temp); 341 rc = sensor_hd_temp->ops->get_value(sensor_hd_temp, &temp);
341 if (rc) { 342 if (rc) {
342 printk(KERN_WARNING "windfarm: HD temp sensor error %d\n", 343 printk(KERN_WARNING "windfarm: HD temp sensor error %d\n",
343 rc); 344 rc);
@@ -373,7 +374,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st)
373 st->hd_setpoint = new_setpoint; 374 st->hd_setpoint = new_setpoint;
374 readjust: 375 readjust:
375 if (fan_system && wf_smu_failure_state == 0) { 376 if (fan_system && wf_smu_failure_state == 0) {
376 rc = wf_control_set(fan_system, st->sys_setpoint); 377 rc = fan_system->ops->set_value(fan_system, st->sys_setpoint);
377 if (rc) { 378 if (rc) {
378 printk(KERN_WARNING "windfarm: Sys fan error %d\n", 379 printk(KERN_WARNING "windfarm: Sys fan error %d\n",
379 rc); 380 rc);
@@ -381,7 +382,7 @@ static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st)
381 } 382 }
382 } 383 }
383 if (fan_hd && wf_smu_failure_state == 0) { 384 if (fan_hd && wf_smu_failure_state == 0) {
384 rc = wf_control_set(fan_hd, st->hd_setpoint); 385 rc = fan_hd->ops->set_value(fan_hd, st->hd_setpoint);
385 if (rc) { 386 if (rc) {
386 printk(KERN_WARNING "windfarm: HD fan error %d\n", 387 printk(KERN_WARNING "windfarm: HD fan error %d\n",
387 rc); 388 rc);
@@ -447,8 +448,8 @@ static void wf_smu_create_cpu_fans(void)
447 pid_param.ttarget = tmax - tdelta; 448 pid_param.ttarget = tmax - tdelta;
448 pid_param.pmaxadj = maxpow - powadj; 449 pid_param.pmaxadj = maxpow - powadj;
449 450
450 pid_param.min = wf_control_get_min(fan_cpu_main); 451 pid_param.min = fan_cpu_main->ops->get_min(fan_cpu_main);
451 pid_param.max = wf_control_get_max(fan_cpu_main); 452 pid_param.max = fan_cpu_main->ops->get_max(fan_cpu_main);
452 453
453 wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param); 454 wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param);
454 455
@@ -481,7 +482,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
481 } 482 }
482 st->ticks = WF_SMU_CPU_FANS_INTERVAL; 483 st->ticks = WF_SMU_CPU_FANS_INTERVAL;
483 484
484 rc = wf_sensor_get(sensor_cpu_temp, &temp); 485 rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
485 if (rc) { 486 if (rc) {
486 printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n", 487 printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n",
487 rc); 488 rc);
@@ -489,7 +490,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
489 return; 490 return;
490 } 491 }
491 492
492 rc = wf_sensor_get(sensor_cpu_power, &power); 493 rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
493 if (rc) { 494 if (rc) {
494 printk(KERN_WARNING "windfarm: CPU power sensor error %d\n", 495 printk(KERN_WARNING "windfarm: CPU power sensor error %d\n",
495 rc); 496 rc);
@@ -525,7 +526,8 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
525 st->cpu_setpoint = new_setpoint; 526 st->cpu_setpoint = new_setpoint;
526 readjust: 527 readjust:
527 if (fan_cpu_main && wf_smu_failure_state == 0) { 528 if (fan_cpu_main && wf_smu_failure_state == 0) {
528 rc = wf_control_set(fan_cpu_main, st->cpu_setpoint); 529 rc = fan_cpu_main->ops->set_value(fan_cpu_main,
530 st->cpu_setpoint);
529 if (rc) { 531 if (rc) {
530 printk(KERN_WARNING "windfarm: CPU main fan" 532 printk(KERN_WARNING "windfarm: CPU main fan"
531 " error %d\n", rc); 533 " error %d\n", rc);
@@ -720,7 +722,7 @@ static int wf_smu_probe(struct platform_device *ddev)
720 return 0; 722 return 0;
721} 723}
722 724
723static int wf_smu_remove(struct platform_device *ddev) 725static int __devexit wf_smu_remove(struct platform_device *ddev)
724{ 726{
725 wf_unregister_client(&wf_smu_events); 727 wf_unregister_client(&wf_smu_events);
726 728
@@ -763,7 +765,7 @@ static int wf_smu_remove(struct platform_device *ddev)
763 765
764static struct platform_driver wf_smu_driver = { 766static struct platform_driver wf_smu_driver = {
765 .probe = wf_smu_probe, 767 .probe = wf_smu_probe,
766 .remove = wf_smu_remove, 768 .remove = __devexit_p(wf_smu_remove),
767 .driver = { 769 .driver = {
768 .name = "windfarm", 770 .name = "windfarm",
769 .owner = THIS_MODULE, 771 .owner = THIS_MODULE,
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
index 2eb484f213c..34427323512 100644
--- a/drivers/macintosh/windfarm_pm91.c
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -41,6 +41,7 @@
41#include <asm/prom.h> 41#include <asm/prom.h>
42#include <asm/machdep.h> 42#include <asm/machdep.h>
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/system.h>
44#include <asm/sections.h> 45#include <asm/sections.h>
45#include <asm/smu.h> 46#include <asm/smu.h>
46 47
@@ -192,8 +193,8 @@ static void wf_smu_create_cpu_fans(void)
192 pid_param.ttarget = tmax - tdelta; 193 pid_param.ttarget = tmax - tdelta;
193 pid_param.pmaxadj = maxpow - powadj; 194 pid_param.pmaxadj = maxpow - powadj;
194 195
195 pid_param.min = wf_control_get_min(fan_cpu_main); 196 pid_param.min = fan_cpu_main->ops->get_min(fan_cpu_main);
196 pid_param.max = wf_control_get_max(fan_cpu_main); 197 pid_param.max = fan_cpu_main->ops->get_max(fan_cpu_main);
197 198
198 wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param); 199 wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param);
199 200
@@ -226,7 +227,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
226 } 227 }
227 st->ticks = WF_SMU_CPU_FANS_INTERVAL; 228 st->ticks = WF_SMU_CPU_FANS_INTERVAL;
228 229
229 rc = wf_sensor_get(sensor_cpu_temp, &temp); 230 rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
230 if (rc) { 231 if (rc) {
231 printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n", 232 printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n",
232 rc); 233 rc);
@@ -234,7 +235,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
234 return; 235 return;
235 } 236 }
236 237
237 rc = wf_sensor_get(sensor_cpu_power, &power); 238 rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
238 if (rc) { 239 if (rc) {
239 printk(KERN_WARNING "windfarm: CPU power sensor error %d\n", 240 printk(KERN_WARNING "windfarm: CPU power sensor error %d\n",
240 rc); 241 rc);
@@ -261,7 +262,8 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
261 st->cpu_setpoint = new_setpoint; 262 st->cpu_setpoint = new_setpoint;
262 readjust: 263 readjust:
263 if (fan_cpu_main && wf_smu_failure_state == 0) { 264 if (fan_cpu_main && wf_smu_failure_state == 0) {
264 rc = wf_control_set(fan_cpu_main, st->cpu_setpoint); 265 rc = fan_cpu_main->ops->set_value(fan_cpu_main,
266 st->cpu_setpoint);
265 if (rc) { 267 if (rc) {
266 printk(KERN_WARNING "windfarm: CPU main fan" 268 printk(KERN_WARNING "windfarm: CPU main fan"
267 " error %d\n", rc); 269 " error %d\n", rc);
@@ -269,7 +271,8 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
269 } 271 }
270 } 272 }
271 if (fan_cpu_second && wf_smu_failure_state == 0) { 273 if (fan_cpu_second && wf_smu_failure_state == 0) {
272 rc = wf_control_set(fan_cpu_second, st->cpu_setpoint); 274 rc = fan_cpu_second->ops->set_value(fan_cpu_second,
275 st->cpu_setpoint);
273 if (rc) { 276 if (rc) {
274 printk(KERN_WARNING "windfarm: CPU second fan" 277 printk(KERN_WARNING "windfarm: CPU second fan"
275 " error %d\n", rc); 278 " error %d\n", rc);
@@ -277,7 +280,8 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
277 } 280 }
278 } 281 }
279 if (fan_cpu_third && wf_smu_failure_state == 0) { 282 if (fan_cpu_third && wf_smu_failure_state == 0) {
280 rc = wf_control_set(fan_cpu_third, st->cpu_setpoint); 283 rc = fan_cpu_main->ops->set_value(fan_cpu_third,
284 st->cpu_setpoint);
281 if (rc) { 285 if (rc) {
282 printk(KERN_WARNING "windfarm: CPU third fan" 286 printk(KERN_WARNING "windfarm: CPU third fan"
283 " error %d\n", rc); 287 " error %d\n", rc);
@@ -309,8 +313,8 @@ static void wf_smu_create_drive_fans(void)
309 313
310 /* Fill PID params */ 314 /* Fill PID params */
311 param.additive = (fan_hd->type == WF_CONTROL_RPM_FAN); 315 param.additive = (fan_hd->type == WF_CONTROL_RPM_FAN);
312 param.min = wf_control_get_min(fan_hd); 316 param.min = fan_hd->ops->get_min(fan_hd);
313 param.max = wf_control_get_max(fan_hd); 317 param.max = fan_hd->ops->get_max(fan_hd);
314 wf_pid_init(&wf_smu_drive_fans->pid, &param); 318 wf_pid_init(&wf_smu_drive_fans->pid, &param);
315 319
316 DBG("wf: Drive Fan control initialized.\n"); 320 DBG("wf: Drive Fan control initialized.\n");
@@ -335,7 +339,7 @@ static void wf_smu_drive_fans_tick(struct wf_smu_drive_fans_state *st)
335 } 339 }
336 st->ticks = st->pid.param.interval; 340 st->ticks = st->pid.param.interval;
337 341
338 rc = wf_sensor_get(sensor_hd_temp, &temp); 342 rc = sensor_hd_temp->ops->get_value(sensor_hd_temp, &temp);
339 if (rc) { 343 if (rc) {
340 printk(KERN_WARNING "windfarm: HD temp sensor error %d\n", 344 printk(KERN_WARNING "windfarm: HD temp sensor error %d\n",
341 rc); 345 rc);
@@ -358,7 +362,7 @@ static void wf_smu_drive_fans_tick(struct wf_smu_drive_fans_state *st)
358 st->setpoint = new_setpoint; 362 st->setpoint = new_setpoint;
359 readjust: 363 readjust:
360 if (fan_hd && wf_smu_failure_state == 0) { 364 if (fan_hd && wf_smu_failure_state == 0) {
361 rc = wf_control_set(fan_hd, st->setpoint); 365 rc = fan_hd->ops->set_value(fan_hd, st->setpoint);
362 if (rc) { 366 if (rc) {
363 printk(KERN_WARNING "windfarm: HD fan error %d\n", 367 printk(KERN_WARNING "windfarm: HD fan error %d\n",
364 rc); 368 rc);
@@ -390,8 +394,8 @@ static void wf_smu_create_slots_fans(void)
390 394
391 /* Fill PID params */ 395 /* Fill PID params */
392 param.additive = (fan_slots->type == WF_CONTROL_RPM_FAN); 396 param.additive = (fan_slots->type == WF_CONTROL_RPM_FAN);
393 param.min = wf_control_get_min(fan_slots); 397 param.min = fan_slots->ops->get_min(fan_slots);
394 param.max = wf_control_get_max(fan_slots); 398 param.max = fan_slots->ops->get_max(fan_slots);
395 wf_pid_init(&wf_smu_slots_fans->pid, &param); 399 wf_pid_init(&wf_smu_slots_fans->pid, &param);
396 400
397 DBG("wf: Slots Fan control initialized.\n"); 401 DBG("wf: Slots Fan control initialized.\n");
@@ -416,7 +420,7 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st)
416 } 420 }
417 st->ticks = st->pid.param.interval; 421 st->ticks = st->pid.param.interval;
418 422
419 rc = wf_sensor_get(sensor_slots_power, &power); 423 rc = sensor_slots_power->ops->get_value(sensor_slots_power, &power);
420 if (rc) { 424 if (rc) {
421 printk(KERN_WARNING "windfarm: Slots power sensor error %d\n", 425 printk(KERN_WARNING "windfarm: Slots power sensor error %d\n",
422 rc); 426 rc);
@@ -441,7 +445,7 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st)
441 st->setpoint = new_setpoint; 445 st->setpoint = new_setpoint;
442 readjust: 446 readjust:
443 if (fan_slots && wf_smu_failure_state == 0) { 447 if (fan_slots && wf_smu_failure_state == 0) {
444 rc = wf_control_set(fan_slots, st->setpoint); 448 rc = fan_slots->ops->set_value(fan_slots, st->setpoint);
445 if (rc) { 449 if (rc) {
446 printk(KERN_WARNING "windfarm: Slots fan error %d\n", 450 printk(KERN_WARNING "windfarm: Slots fan error %d\n",
447 rc); 451 rc);
@@ -642,7 +646,7 @@ static int wf_smu_probe(struct platform_device *ddev)
642 return 0; 646 return 0;
643} 647}
644 648
645static int wf_smu_remove(struct platform_device *ddev) 649static int __devexit wf_smu_remove(struct platform_device *ddev)
646{ 650{
647 wf_unregister_client(&wf_smu_events); 651 wf_unregister_client(&wf_smu_events);
648 652
@@ -692,7 +696,7 @@ static int wf_smu_remove(struct platform_device *ddev)
692 696
693static struct platform_driver wf_smu_driver = { 697static struct platform_driver wf_smu_driver = {
694 .probe = wf_smu_probe, 698 .probe = wf_smu_probe,
695 .remove = wf_smu_remove, 699 .remove = __devexit_p(wf_smu_remove),
696 .driver = { 700 .driver = {
697 .name = "windfarm", 701 .name = "windfarm",
698 .owner = THIS_MODULE, 702 .owner = THIS_MODULE,
diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c
deleted file mode 100644
index 844003fb4ef..00000000000
--- a/drivers/macintosh/windfarm_rm31.c
+++ /dev/null
@@ -1,740 +0,0 @@
1/*
2 * Windfarm PowerMac thermal control.
3 * Control loops for RackMack3,1 (Xserve G5)
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 *slots_temp;
54static struct wf_sensor *dimms_temp;
55
56static struct wf_control *cpu_fans[NR_CHIPS][3];
57static struct wf_control *backside_fan;
58static struct wf_control *slots_fan;
59static struct wf_control *cpufreq_clamp;
60
61/* We keep a temperature history for average calculation of 180s */
62#define CPU_TEMP_HIST_SIZE 180
63
64/* PID loop state */
65static const struct mpu_data *cpu_mpu_data[NR_CHIPS];
66static struct wf_cpu_pid_state cpu_pid[NR_CHIPS];
67static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
68static int cpu_thist_pt;
69static s64 cpu_thist_total;
70static s32 cpu_all_tmax = 100 << 16;
71static struct wf_pid_state backside_pid;
72static int backside_tick;
73static struct wf_pid_state slots_pid;
74static int slots_tick;
75static int slots_speed;
76static struct wf_pid_state dimms_pid;
77static int dimms_output_clamp;
78
79static int nr_chips;
80static bool have_all_controls;
81static bool have_all_sensors;
82static bool started;
83
84static int failure_state;
85#define FAILURE_SENSOR 1
86#define FAILURE_FAN 2
87#define FAILURE_PERM 4
88#define FAILURE_LOW_OVERTEMP 8
89#define FAILURE_HIGH_OVERTEMP 16
90
91/* Overtemp values */
92#define LOW_OVER_AVERAGE 0
93#define LOW_OVER_IMMEDIATE (10 << 16)
94#define LOW_OVER_CLEAR ((-10) << 16)
95#define HIGH_OVER_IMMEDIATE (14 << 16)
96#define HIGH_OVER_AVERAGE (10 << 16)
97#define HIGH_OVER_IMMEDIATE (14 << 16)
98
99
100static void cpu_max_all_fans(void)
101{
102 int i;
103
104 /* We max all CPU fans in case of a sensor error. We also do the
105 * cpufreq clamping now, even if it's supposedly done later by the
106 * generic code anyway, we do it earlier here to react faster
107 */
108 if (cpufreq_clamp)
109 wf_control_set_max(cpufreq_clamp);
110 for (i = 0; i < nr_chips; i++) {
111 if (cpu_fans[i][0])
112 wf_control_set_max(cpu_fans[i][0]);
113 if (cpu_fans[i][1])
114 wf_control_set_max(cpu_fans[i][1]);
115 if (cpu_fans[i][2])
116 wf_control_set_max(cpu_fans[i][2]);
117 }
118}
119
120static int cpu_check_overtemp(s32 temp)
121{
122 int new_state = 0;
123 s32 t_avg, t_old;
124 static bool first = true;
125
126 /* First check for immediate overtemps */
127 if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
128 new_state |= FAILURE_LOW_OVERTEMP;
129 if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
130 printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
131 " temperature !\n");
132 }
133 if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
134 new_state |= FAILURE_HIGH_OVERTEMP;
135 if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
136 printk(KERN_ERR "windfarm: Critical overtemp due to"
137 " immediate CPU temperature !\n");
138 }
139
140 /*
141 * The first time around, initialize the array with the first
142 * temperature reading
143 */
144 if (first) {
145 int i;
146
147 cpu_thist_total = 0;
148 for (i = 0; i < CPU_TEMP_HIST_SIZE; i++) {
149 cpu_thist[i] = temp;
150 cpu_thist_total += temp;
151 }
152 first = false;
153 }
154
155 /*
156 * We calculate a history of max temperatures and use that for the
157 * overtemp management
158 */
159 t_old = cpu_thist[cpu_thist_pt];
160 cpu_thist[cpu_thist_pt] = temp;
161 cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
162 cpu_thist_total -= t_old;
163 cpu_thist_total += temp;
164 t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
165
166 DBG_LOTS(" t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
167 FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
168
169 /* Now check for average overtemps */
170 if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
171 new_state |= FAILURE_LOW_OVERTEMP;
172 if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
173 printk(KERN_ERR "windfarm: Overtemp due to average CPU"
174 " temperature !\n");
175 }
176 if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
177 new_state |= FAILURE_HIGH_OVERTEMP;
178 if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
179 printk(KERN_ERR "windfarm: Critical overtemp due to"
180 " average CPU temperature !\n");
181 }
182
183 /* Now handle overtemp conditions. We don't currently use the windfarm
184 * overtemp handling core as it's not fully suited to the needs of those
185 * new machine. This will be fixed later.
186 */
187 if (new_state) {
188 /* High overtemp -> immediate shutdown */
189 if (new_state & FAILURE_HIGH_OVERTEMP)
190 machine_power_off();
191 if ((failure_state & new_state) != new_state)
192 cpu_max_all_fans();
193 failure_state |= new_state;
194 } else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
195 (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
196 printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
197 failure_state &= ~FAILURE_LOW_OVERTEMP;
198 }
199
200 return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
201}
202
203static int read_one_cpu_vals(int cpu, s32 *temp, s32 *power)
204{
205 s32 dtemp, volts, amps;
206 int rc;
207
208 /* Get diode temperature */
209 rc = wf_sensor_get(sens_cpu_temp[cpu], &dtemp);
210 if (rc) {
211 DBG(" CPU%d: temp reading error !\n", cpu);
212 return -EIO;
213 }
214 DBG_LOTS(" CPU%d: temp = %d.%03d\n", cpu, FIX32TOPRINT((dtemp)));
215 *temp = dtemp;
216
217 /* Get voltage */
218 rc = wf_sensor_get(sens_cpu_volts[cpu], &volts);
219 if (rc) {
220 DBG(" CPU%d, volts reading error !\n", cpu);
221 return -EIO;
222 }
223 DBG_LOTS(" CPU%d: volts = %d.%03d\n", cpu, FIX32TOPRINT((volts)));
224
225 /* Get current */
226 rc = wf_sensor_get(sens_cpu_amps[cpu], &amps);
227 if (rc) {
228 DBG(" CPU%d, current reading error !\n", cpu);
229 return -EIO;
230 }
231 DBG_LOTS(" CPU%d: amps = %d.%03d\n", cpu, FIX32TOPRINT((amps)));
232
233 /* Calculate power */
234
235 /* Scale voltage and current raw sensor values according to fixed scales
236 * obtained in Darwin and calculate power from I and V
237 */
238 *power = (((u64)volts) * ((u64)amps)) >> 16;
239
240 DBG_LOTS(" CPU%d: power = %d.%03d\n", cpu, FIX32TOPRINT((*power)));
241
242 return 0;
243
244}
245
246static void cpu_fans_tick(void)
247{
248 int err, cpu, i;
249 s32 speed, temp, power, t_max = 0;
250
251 DBG_LOTS("* cpu fans_tick_split()\n");
252
253 for (cpu = 0; cpu < nr_chips; ++cpu) {
254 struct wf_cpu_pid_state *sp = &cpu_pid[cpu];
255
256 /* Read current speed */
257 wf_control_get(cpu_fans[cpu][0], &sp->target);
258
259 err = read_one_cpu_vals(cpu, &temp, &power);
260 if (err) {
261 failure_state |= FAILURE_SENSOR;
262 cpu_max_all_fans();
263 return;
264 }
265
266 /* Keep track of highest temp */
267 t_max = max(t_max, temp);
268
269 /* Handle possible overtemps */
270 if (cpu_check_overtemp(t_max))
271 return;
272
273 /* Run PID */
274 wf_cpu_pid_run(sp, power, temp);
275
276 DBG_LOTS(" CPU%d: target = %d RPM\n", cpu, sp->target);
277
278 /* Apply DIMMs clamp */
279 speed = max(sp->target, dimms_output_clamp);
280
281 /* Apply result to all cpu fans */
282 for (i = 0; i < 3; i++) {
283 err = wf_control_set(cpu_fans[cpu][i], speed);
284 if (err) {
285 pr_warning("wf_rm31: Fan %s reports error %d\n",
286 cpu_fans[cpu][i]->name, err);
287 failure_state |= FAILURE_FAN;
288 }
289 }
290 }
291}
292
293/* Implementation... */
294static int cpu_setup_pid(int cpu)
295{
296 struct wf_cpu_pid_param pid;
297 const struct mpu_data *mpu = cpu_mpu_data[cpu];
298 s32 tmax, ttarget, ptarget;
299 int fmin, fmax, hsize;
300
301 /* Get PID params from the appropriate MPU EEPROM */
302 tmax = mpu->tmax << 16;
303 ttarget = mpu->ttarget << 16;
304 ptarget = ((s32)(mpu->pmaxh - mpu->padjmax)) << 16;
305
306 DBG("wf_72: CPU%d ttarget = %d.%03d, tmax = %d.%03d\n",
307 cpu, FIX32TOPRINT(ttarget), FIX32TOPRINT(tmax));
308
309 /* We keep a global tmax for overtemp calculations */
310 if (tmax < cpu_all_tmax)
311 cpu_all_tmax = tmax;
312
313 /* Set PID min/max by using the rear fan min/max */
314 fmin = wf_control_get_min(cpu_fans[cpu][0]);
315 fmax = wf_control_get_max(cpu_fans[cpu][0]);
316 DBG("wf_72: CPU%d max RPM range = [%d..%d]\n", cpu, fmin, fmax);
317
318 /* History size */
319 hsize = min_t(int, mpu->tguardband, WF_PID_MAX_HISTORY);
320 DBG("wf_72: CPU%d history size = %d\n", cpu, hsize);
321
322 /* Initialize PID loop */
323 pid.interval = 1; /* seconds */
324 pid.history_len = hsize;
325 pid.gd = mpu->pid_gd;
326 pid.gp = mpu->pid_gp;
327 pid.gr = mpu->pid_gr;
328 pid.tmax = tmax;
329 pid.ttarget = ttarget;
330 pid.pmaxadj = ptarget;
331 pid.min = fmin;
332 pid.max = fmax;
333
334 wf_cpu_pid_init(&cpu_pid[cpu], &pid);
335 cpu_pid[cpu].target = 4000;
336
337 return 0;
338}
339
340/* Backside/U3 fan */
341static struct wf_pid_param backside_param = {
342 .interval = 1,
343 .history_len = 2,
344 .gd = 0x00500000,
345 .gp = 0x0004cccc,
346 .gr = 0,
347 .itarget = 70 << 16,
348 .additive = 0,
349 .min = 20,
350 .max = 100,
351};
352
353/* DIMMs temperature (clamp the backside fan) */
354static struct wf_pid_param dimms_param = {
355 .interval = 1,
356 .history_len = 20,
357 .gd = 0,
358 .gp = 0,
359 .gr = 0x06553600,
360 .itarget = 50 << 16,
361 .additive = 0,
362 .min = 4000,
363 .max = 14000,
364};
365
366static void backside_fan_tick(void)
367{
368 s32 temp, dtemp;
369 int speed, dspeed, fan_min;
370 int err;
371
372 if (!backside_fan || !backside_temp || !dimms_temp || !backside_tick)
373 return;
374 if (--backside_tick > 0)
375 return;
376 backside_tick = backside_pid.param.interval;
377
378 DBG_LOTS("* backside fans tick\n");
379
380 /* Update fan speed from actual fans */
381 err = wf_control_get(backside_fan, &speed);
382 if (!err)
383 backside_pid.target = speed;
384
385 err = wf_sensor_get(backside_temp, &temp);
386 if (err) {
387 printk(KERN_WARNING "windfarm: U3 temp sensor error %d\n",
388 err);
389 failure_state |= FAILURE_SENSOR;
390 wf_control_set_max(backside_fan);
391 return;
392 }
393 speed = wf_pid_run(&backside_pid, temp);
394
395 DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
396 FIX32TOPRINT(temp), speed);
397
398 err = wf_sensor_get(dimms_temp, &dtemp);
399 if (err) {
400 printk(KERN_WARNING "windfarm: DIMMs temp sensor error %d\n",
401 err);
402 failure_state |= FAILURE_SENSOR;
403 wf_control_set_max(backside_fan);
404 return;
405 }
406 dspeed = wf_pid_run(&dimms_pid, dtemp);
407 dimms_output_clamp = dspeed;
408
409 fan_min = (dspeed * 100) / 14000;
410 fan_min = max(fan_min, backside_param.min);
411 speed = max(speed, fan_min);
412
413 err = wf_control_set(backside_fan, speed);
414 if (err) {
415 printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
416 failure_state |= FAILURE_FAN;
417 }
418}
419
420static void backside_setup_pid(void)
421{
422 /* first time initialize things */
423 s32 fmin = wf_control_get_min(backside_fan);
424 s32 fmax = wf_control_get_max(backside_fan);
425 struct wf_pid_param param;
426
427 param = backside_param;
428 param.min = max(param.min, fmin);
429 param.max = min(param.max, fmax);
430 wf_pid_init(&backside_pid, &param);
431
432 param = dimms_param;
433 wf_pid_init(&dimms_pid, &param);
434
435 backside_tick = 1;
436
437 pr_info("wf_rm31: Backside control loop started.\n");
438}
439
440/* Slots fan */
441static const struct wf_pid_param slots_param = {
442 .interval = 5,
443 .history_len = 2,
444 .gd = 30 << 20,
445 .gp = 5 << 20,
446 .gr = 0,
447 .itarget = 40 << 16,
448 .additive = 1,
449 .min = 300,
450 .max = 4000,
451};
452
453static void slots_fan_tick(void)
454{
455 s32 temp;
456 int speed;
457 int err;
458
459 if (!slots_fan || !slots_temp || !slots_tick)
460 return;
461 if (--slots_tick > 0)
462 return;
463 slots_tick = slots_pid.param.interval;
464
465 DBG_LOTS("* slots fans tick\n");
466
467 err = wf_sensor_get(slots_temp, &temp);
468 if (err) {
469 pr_warning("wf_rm31: slots temp sensor error %d\n", err);
470 failure_state |= FAILURE_SENSOR;
471 wf_control_set_max(slots_fan);
472 return;
473 }
474 speed = wf_pid_run(&slots_pid, temp);
475
476 DBG_LOTS("slots PID temp=%d.%.3d speed=%d\n",
477 FIX32TOPRINT(temp), speed);
478
479 slots_speed = speed;
480 err = wf_control_set(slots_fan, speed);
481 if (err) {
482 printk(KERN_WARNING "windfarm: slots bay fan error %d\n", err);
483 failure_state |= FAILURE_FAN;
484 }
485}
486
487static void slots_setup_pid(void)
488{
489 /* first time initialize things */
490 s32 fmin = wf_control_get_min(slots_fan);
491 s32 fmax = wf_control_get_max(slots_fan);
492 struct wf_pid_param param = slots_param;
493
494 param.min = max(param.min, fmin);
495 param.max = min(param.max, fmax);
496 wf_pid_init(&slots_pid, &param);
497 slots_tick = 1;
498
499 pr_info("wf_rm31: Slots control loop started.\n");
500}
501
502static void set_fail_state(void)
503{
504 cpu_max_all_fans();
505
506 if (backside_fan)
507 wf_control_set_max(backside_fan);
508 if (slots_fan)
509 wf_control_set_max(slots_fan);
510}
511
512static void rm31_tick(void)
513{
514 int i, last_failure;
515
516 if (!started) {
517 started = 1;
518 printk(KERN_INFO "windfarm: CPUs control loops started.\n");
519 for (i = 0; i < nr_chips; ++i) {
520 if (cpu_setup_pid(i) < 0) {
521 failure_state = FAILURE_PERM;
522 set_fail_state();
523 break;
524 }
525 }
526 DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
527
528 backside_setup_pid();
529 slots_setup_pid();
530
531#ifdef HACKED_OVERTEMP
532 cpu_all_tmax = 60 << 16;
533#endif
534 }
535
536 /* Permanent failure, bail out */
537 if (failure_state & FAILURE_PERM)
538 return;
539
540 /*
541 * Clear all failure bits except low overtemp which will be eventually
542 * cleared by the control loop itself
543 */
544 last_failure = failure_state;
545 failure_state &= FAILURE_LOW_OVERTEMP;
546 backside_fan_tick();
547 slots_fan_tick();
548
549 /* We do CPUs last because they can be clamped high by
550 * DIMM temperature
551 */
552 cpu_fans_tick();
553
554 DBG_LOTS(" last_failure: 0x%x, failure_state: %x\n",
555 last_failure, failure_state);
556
557 /* Check for failures. Any failure causes cpufreq clamping */
558 if (failure_state && last_failure == 0 && cpufreq_clamp)
559 wf_control_set_max(cpufreq_clamp);
560 if (failure_state == 0 && last_failure && cpufreq_clamp)
561 wf_control_set_min(cpufreq_clamp);
562
563 /* That's it for now, we might want to deal with other failures
564 * differently in the future though
565 */
566}
567
568static void rm31_new_control(struct wf_control *ct)
569{
570 bool all_controls;
571
572 if (!strcmp(ct->name, "cpu-fan-a-0"))
573 cpu_fans[0][0] = ct;
574 else if (!strcmp(ct->name, "cpu-fan-b-0"))
575 cpu_fans[0][1] = ct;
576 else if (!strcmp(ct->name, "cpu-fan-c-0"))
577 cpu_fans[0][2] = ct;
578 else if (!strcmp(ct->name, "cpu-fan-a-1"))
579 cpu_fans[1][0] = ct;
580 else if (!strcmp(ct->name, "cpu-fan-b-1"))
581 cpu_fans[1][1] = ct;
582 else if (!strcmp(ct->name, "cpu-fan-c-1"))
583 cpu_fans[1][2] = ct;
584 else if (!strcmp(ct->name, "backside-fan"))
585 backside_fan = ct;
586 else if (!strcmp(ct->name, "slots-fan"))
587 slots_fan = ct;
588 else if (!strcmp(ct->name, "cpufreq-clamp"))
589 cpufreq_clamp = ct;
590
591 all_controls =
592 cpu_fans[0][0] &&
593 cpu_fans[0][1] &&
594 cpu_fans[0][2] &&
595 backside_fan &&
596 slots_fan;
597 if (nr_chips > 1)
598 all_controls &=
599 cpu_fans[1][0] &&
600 cpu_fans[1][1] &&
601 cpu_fans[1][2];
602 have_all_controls = all_controls;
603}
604
605
606static void rm31_new_sensor(struct wf_sensor *sr)
607{
608 bool all_sensors;
609
610 if (!strcmp(sr->name, "cpu-diode-temp-0"))
611 sens_cpu_temp[0] = sr;
612 else if (!strcmp(sr->name, "cpu-diode-temp-1"))
613 sens_cpu_temp[1] = sr;
614 else if (!strcmp(sr->name, "cpu-voltage-0"))
615 sens_cpu_volts[0] = sr;
616 else if (!strcmp(sr->name, "cpu-voltage-1"))
617 sens_cpu_volts[1] = sr;
618 else if (!strcmp(sr->name, "cpu-current-0"))
619 sens_cpu_amps[0] = sr;
620 else if (!strcmp(sr->name, "cpu-current-1"))
621 sens_cpu_amps[1] = sr;
622 else if (!strcmp(sr->name, "backside-temp"))
623 backside_temp = sr;
624 else if (!strcmp(sr->name, "slots-temp"))
625 slots_temp = sr;
626 else if (!strcmp(sr->name, "dimms-temp"))
627 dimms_temp = sr;
628
629 all_sensors =
630 sens_cpu_temp[0] &&
631 sens_cpu_volts[0] &&
632 sens_cpu_amps[0] &&
633 backside_temp &&
634 slots_temp &&
635 dimms_temp;
636 if (nr_chips > 1)
637 all_sensors &=
638 sens_cpu_temp[1] &&
639 sens_cpu_volts[1] &&
640 sens_cpu_amps[1];
641
642 have_all_sensors = all_sensors;
643}
644
645static int rm31_wf_notify(struct notifier_block *self,
646 unsigned long event, void *data)
647{
648 switch (event) {
649 case WF_EVENT_NEW_SENSOR:
650 rm31_new_sensor(data);
651 break;
652 case WF_EVENT_NEW_CONTROL:
653 rm31_new_control(data);
654 break;
655 case WF_EVENT_TICK:
656 if (have_all_controls && have_all_sensors)
657 rm31_tick();
658 }
659 return 0;
660}
661
662static struct notifier_block rm31_events = {
663 .notifier_call = rm31_wf_notify,
664};
665
666static int wf_rm31_probe(struct platform_device *dev)
667{
668 wf_register_client(&rm31_events);
669 return 0;
670}
671
672static int wf_rm31_remove(struct platform_device *dev)
673{
674 wf_unregister_client(&rm31_events);
675
676 /* should release all sensors and controls */
677 return 0;
678}
679
680static struct platform_driver wf_rm31_driver = {
681 .probe = wf_rm31_probe,
682 .remove = wf_rm31_remove,
683 .driver = {
684 .name = "windfarm",
685 .owner = THIS_MODULE,
686 },
687};
688
689static int __init wf_rm31_init(void)
690{
691 struct device_node *cpu;
692 int i;
693
694 if (!of_machine_is_compatible("RackMac3,1"))
695 return -ENODEV;
696
697 /* Count the number of CPU cores */
698 nr_chips = 0;
699 for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; )
700 ++nr_chips;
701 if (nr_chips > NR_CHIPS)
702 nr_chips = NR_CHIPS;
703
704 pr_info("windfarm: Initializing for desktop G5 with %d chips\n",
705 nr_chips);
706
707 /* Get MPU data for each CPU */
708 for (i = 0; i < nr_chips; i++) {
709 cpu_mpu_data[i] = wf_get_mpu(i);
710 if (!cpu_mpu_data[i]) {
711 pr_err("wf_rm31: Failed to find MPU data for CPU %d\n", i);
712 return -ENXIO;
713 }
714 }
715
716#ifdef MODULE
717 request_module("windfarm_fcu_controls");
718 request_module("windfarm_lm75_sensor");
719 request_module("windfarm_lm87_sensor");
720 request_module("windfarm_ad7417_sensor");
721 request_module("windfarm_max6690_sensor");
722 request_module("windfarm_cpufreq_clamp");
723#endif /* MODULE */
724
725 platform_driver_register(&wf_rm31_driver);
726 return 0;
727}
728
729static void __exit wf_rm31_exit(void)
730{
731 platform_driver_unregister(&wf_rm31_driver);
732}
733
734module_init(wf_rm31_init);
735module_exit(wf_rm31_exit);
736
737MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
738MODULE_DESCRIPTION("Thermal control for Xserve G5");
739MODULE_LICENSE("GPL");
740MODULE_ALIAS("platform:windfarm");
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index c155a54e863..43137b421f9 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -18,6 +18,7 @@
18#include <asm/prom.h> 18#include <asm/prom.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/system.h>
21#include <asm/sections.h> 22#include <asm/sections.h>
22#include <asm/smu.h> 23#include <asm/smu.h>
23 24
@@ -172,6 +173,7 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
172 173
173 fct->fan_type = pwm_fan; 174 fct->fan_type = pwm_fan;
174 fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN; 175 fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN;
176 sysfs_attr_init(&fct->ctrl.attr.attr);
175 177
176 /* We use the name & location here the same way we do for SMU sensors, 178 /* We use the name & location here the same way we do for SMU sensors,
177 * see the comment in windfarm_smu_sensors.c. The locations are a bit 179 * see the comment in windfarm_smu_sensors.c. The locations are a bit
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index d87f5ee04ca..65a8ff3e1f8 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -20,7 +20,7 @@
20 20
21#include "windfarm.h" 21#include "windfarm.h"
22 22
23#define VERSION "1.0" 23#define VERSION "0.2"
24 24
25#define DEBUG 25#define DEBUG
26 26
@@ -34,12 +34,11 @@
34#define MAX_AGE msecs_to_jiffies(800) 34#define MAX_AGE msecs_to_jiffies(800)
35 35
36struct wf_sat { 36struct wf_sat {
37 struct kref ref;
38 int nr; 37 int nr;
38 atomic_t refcnt;
39 struct mutex mutex; 39 struct mutex mutex;
40 unsigned long last_read; /* jiffies when cache last updated */ 40 unsigned long last_read; /* jiffies when cache last updated */
41 u8 cache[16]; 41 u8 cache[16];
42 struct list_head sensors;
43 struct i2c_client *i2c; 42 struct i2c_client *i2c;
44 struct device_node *node; 43 struct device_node *node;
45}; 44};
@@ -47,12 +46,11 @@ struct wf_sat {
47static struct wf_sat *sats[2]; 46static struct wf_sat *sats[2];
48 47
49struct wf_sat_sensor { 48struct wf_sat_sensor {
50 struct list_head link; 49 int index;
51 int index; 50 int index2; /* used for power sensors */
52 int index2; /* used for power sensors */ 51 int shift;
53 int shift; 52 struct wf_sat *sat;
54 struct wf_sat *sat; 53 struct wf_sensor sens;
55 struct wf_sensor sens;
56}; 54};
57 55
58#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) 56#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens)
@@ -144,7 +142,7 @@ static int wf_sat_read_cache(struct wf_sat *sat)
144 return 0; 142 return 0;
145} 143}
146 144
147static int wf_sat_sensor_get(struct wf_sensor *sr, s32 *value) 145static int wf_sat_get(struct wf_sensor *sr, s32 *value)
148{ 146{
149 struct wf_sat_sensor *sens = wf_to_sat(sr); 147 struct wf_sat_sensor *sens = wf_to_sat(sr);
150 struct wf_sat *sat = sens->sat; 148 struct wf_sat *sat = sens->sat;
@@ -177,34 +175,62 @@ static int wf_sat_sensor_get(struct wf_sensor *sr, s32 *value)
177 return err; 175 return err;
178} 176}
179 177
180static void wf_sat_release(struct kref *ref) 178static void wf_sat_release(struct wf_sensor *sr)
181{
182 struct wf_sat *sat = container_of(ref, struct wf_sat, ref);
183
184 if (sat->nr >= 0)
185 sats[sat->nr] = NULL;
186 kfree(sat);
187}
188
189static void wf_sat_sensor_release(struct wf_sensor *sr)
190{ 179{
191 struct wf_sat_sensor *sens = wf_to_sat(sr); 180 struct wf_sat_sensor *sens = wf_to_sat(sr);
192 struct wf_sat *sat = sens->sat; 181 struct wf_sat *sat = sens->sat;
193 182
183 if (atomic_dec_and_test(&sat->refcnt)) {
184 if (sat->nr >= 0)
185 sats[sat->nr] = NULL;
186 kfree(sat);
187 }
194 kfree(sens); 188 kfree(sens);
195 kref_put(&sat->ref, wf_sat_release);
196} 189}
197 190
198static struct wf_sensor_ops wf_sat_ops = { 191static struct wf_sensor_ops wf_sat_ops = {
199 .get_value = wf_sat_sensor_get, 192 .get_value = wf_sat_get,
200 .release = wf_sat_sensor_release, 193 .release = wf_sat_release,
201 .owner = THIS_MODULE, 194 .owner = THIS_MODULE,
202}; 195};
203 196
197static struct i2c_driver wf_sat_driver;
198
199static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
200{
201 struct i2c_board_info info;
202 struct i2c_client *client;
203 const u32 *reg;
204 u8 addr;
205
206 reg = of_get_property(dev, "reg", NULL);
207 if (reg == NULL)
208 return;
209 addr = *reg;
210 DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
211
212 memset(&info, 0, sizeof(struct i2c_board_info));
213 info.addr = (addr >> 1) & 0x7f;
214 info.platform_data = dev;
215 strlcpy(info.type, "wf_sat", I2C_NAME_SIZE);
216
217 client = i2c_new_device(adapter, &info);
218 if (client == NULL) {
219 printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
220 return;
221 }
222
223 /*
224 * Let i2c-core delete that device on driver removal.
225 * This is safe because i2c-core holds the core_lock mutex for us.
226 */
227 list_add_tail(&client->detected, &wf_sat_driver.clients);
228}
229
204static int wf_sat_probe(struct i2c_client *client, 230static int wf_sat_probe(struct i2c_client *client,
205 const struct i2c_device_id *id) 231 const struct i2c_device_id *id)
206{ 232{
207 struct device_node *dev = client->dev.of_node; 233 struct device_node *dev = client->dev.platform_data;
208 struct wf_sat *sat; 234 struct wf_sat *sat;
209 struct wf_sat_sensor *sens; 235 struct wf_sat_sensor *sens;
210 const u32 *reg; 236 const u32 *reg;
@@ -220,10 +246,9 @@ static int wf_sat_probe(struct i2c_client *client,
220 return -ENOMEM; 246 return -ENOMEM;
221 sat->nr = -1; 247 sat->nr = -1;
222 sat->node = of_node_get(dev); 248 sat->node = of_node_get(dev);
223 kref_init(&sat->ref); 249 atomic_set(&sat->refcnt, 0);
224 mutex_init(&sat->mutex); 250 mutex_init(&sat->mutex);
225 sat->i2c = client; 251 sat->i2c = client;
226 INIT_LIST_HEAD(&sat->sensors);
227 i2c_set_clientdata(client, sat); 252 i2c_set_clientdata(client, sat);
228 253
229 vsens[0] = vsens[1] = -1; 254 vsens[0] = vsens[1] = -1;
@@ -285,15 +310,14 @@ static int wf_sat_probe(struct i2c_client *client,
285 sens->index2 = -1; 310 sens->index2 = -1;
286 sens->shift = shift; 311 sens->shift = shift;
287 sens->sat = sat; 312 sens->sat = sat;
313 atomic_inc(&sat->refcnt);
288 sens->sens.ops = &wf_sat_ops; 314 sens->sens.ops = &wf_sat_ops;
289 sens->sens.name = (char *) (sens + 1); 315 sens->sens.name = (char *) (sens + 1);
290 snprintf((char *)sens->sens.name, 16, "%s-%d", name, cpu); 316 snprintf(sens->sens.name, 16, "%s-%d", name, cpu);
291 317
292 if (wf_register_sensor(&sens->sens)) 318 if (wf_register_sensor(&sens->sens)) {
319 atomic_dec(&sat->refcnt);
293 kfree(sens); 320 kfree(sens);
294 else {
295 list_add(&sens->link, &sat->sensors);
296 kref_get(&sat->ref);
297 } 321 }
298 } 322 }
299 323
@@ -312,15 +336,14 @@ static int wf_sat_probe(struct i2c_client *client,
312 sens->index2 = isens[core]; 336 sens->index2 = isens[core];
313 sens->shift = 0; 337 sens->shift = 0;
314 sens->sat = sat; 338 sens->sat = sat;
339 atomic_inc(&sat->refcnt);
315 sens->sens.ops = &wf_sat_ops; 340 sens->sens.ops = &wf_sat_ops;
316 sens->sens.name = (char *) (sens + 1); 341 sens->sens.name = (char *) (sens + 1);
317 snprintf((char *)sens->sens.name, 16, "cpu-power-%d", cpu); 342 snprintf(sens->sens.name, 16, "cpu-power-%d", cpu);
318 343
319 if (wf_register_sensor(&sens->sens)) 344 if (wf_register_sensor(&sens->sens)) {
345 atomic_dec(&sat->refcnt);
320 kfree(sens); 346 kfree(sens);
321 else {
322 list_add(&sens->link, &sat->sensors);
323 kref_get(&sat->ref);
324 } 347 }
325 } 348 }
326 349
@@ -330,41 +353,61 @@ static int wf_sat_probe(struct i2c_client *client,
330 return 0; 353 return 0;
331} 354}
332 355
356static int wf_sat_attach(struct i2c_adapter *adapter)
357{
358 struct device_node *busnode, *dev = NULL;
359 struct pmac_i2c_bus *bus;
360
361 bus = pmac_i2c_adapter_to_bus(adapter);
362 if (bus == NULL)
363 return -ENODEV;
364 busnode = pmac_i2c_get_bus_node(bus);
365
366 while ((dev = of_get_next_child(busnode, dev)) != NULL)
367 if (of_device_is_compatible(dev, "smu-sat"))
368 wf_sat_create(adapter, dev);
369 return 0;
370}
371
333static int wf_sat_remove(struct i2c_client *client) 372static int wf_sat_remove(struct i2c_client *client)
334{ 373{
335 struct wf_sat *sat = i2c_get_clientdata(client); 374 struct wf_sat *sat = i2c_get_clientdata(client);
336 struct wf_sat_sensor *sens;
337 375
338 /* release sensors */ 376 /* XXX TODO */
339 while(!list_empty(&sat->sensors)) {
340 sens = list_first_entry(&sat->sensors,
341 struct wf_sat_sensor, link);
342 list_del(&sens->link);
343 wf_unregister_sensor(&sens->sens);
344 }
345 sat->i2c = NULL;
346 i2c_set_clientdata(client, NULL);
347 kref_put(&sat->ref, wf_sat_release);
348 377
378 sat->i2c = NULL;
349 return 0; 379 return 0;
350} 380}
351 381
352static const struct i2c_device_id wf_sat_id[] = { 382static const struct i2c_device_id wf_sat_id[] = {
353 { "MAC,smu-sat", 0 }, 383 { "wf_sat", 0 },
354 { } 384 { }
355}; 385};
356MODULE_DEVICE_TABLE(i2c, wf_sat_id);
357 386
358static struct i2c_driver wf_sat_driver = { 387static struct i2c_driver wf_sat_driver = {
359 .driver = { 388 .driver = {
360 .name = "wf_smu_sat", 389 .name = "wf_smu_sat",
361 }, 390 },
391 .attach_adapter = wf_sat_attach,
362 .probe = wf_sat_probe, 392 .probe = wf_sat_probe,
363 .remove = wf_sat_remove, 393 .remove = wf_sat_remove,
364 .id_table = wf_sat_id, 394 .id_table = wf_sat_id,
365}; 395};
366 396
367module_i2c_driver(wf_sat_driver); 397static int __init sat_sensors_init(void)
398{
399 return i2c_add_driver(&wf_sat_driver);
400}
401
402#if 0 /* uncomment when module_exit() below is uncommented */
403static void __exit sat_sensors_exit(void)
404{
405 i2c_del_driver(&wf_sat_driver);
406}
407#endif
408
409module_init(sat_sensors_init);
410/*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */
368 411
369MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); 412MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
370MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control"); 413MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control");
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
index 1cc4e4953d8..3c193504bb8 100644
--- a/drivers/macintosh/windfarm_smu_sensors.c
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -18,6 +18,7 @@
18#include <asm/prom.h> 18#include <asm/prom.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/system.h>
21#include <asm/sections.h> 22#include <asm/sections.h>
22#include <asm/smu.h> 23#include <asm/smu.h>
23 24