Skip to contentSkip to conversation

ppc64: Thermal control for SMU based machines

PATCH In review Benjamin Herrenschmidt 5 participants 14 messages Oct 4, 2005 – Oct 18, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ppc64: Thermal control for SMU based machines

This is the actual thermal control support for PowerMac8,1, PowerMac8,2 and PowerMac9,1 machines (SMU based), that is iMac G5 and single CPU desktop. It requires CPUFREQ to be enabled to properly deal with overtemp conditions. The new thermal control code implements a new framework (nicknamed "windfarm") to which I expect to port the old G5 thermal control, and possibly some of the powerbook thermal control drivers as well in the future.

drivers/macintosh/smu.c +2 -0
Index: linux-work/drivers/macintosh/smu.c
===================================================================
@@ -590,6 +590,8 @@
 			sprintf(name, "smu-i2c-%02x", *reg);
 			of_platform_device_create(np, name, &smu->of_dev->dev);
 		}
+		if (device_is_compatible(np, "smu-sensors"))
+			of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev);
 	}
 
 }
drivers/macintosh/Kconfig +10 -0
Index: linux-work/drivers/macintosh/Kconfig
===================================================================
@@ -169,6 +169,16 @@
 	  This driver provides thermostat and fan control for the desktop
 	  G5 machines. 
 
+config WINDFARM
+	tristate "New PowerMac thermal control infrastructure"
+
+config WINDFARM_SMU
+	tristate "Support for thermal management on SMU based PowerMacs"
+	depends on WINDFARM && I2C && CPU_FREQ_PMAC && PMAC_SMU
+	select I2C_PMAC_SMU
+	help
+	  This driver provides thermal control for iMacG5 and newer
+
 config ANSLCD
 	tristate "Support for ANS LCD display"
 	depends on ADB_CUDA && PPC_PMAC
drivers/macintosh/Makefile +5 -0
Index: linux-work/drivers/macintosh/Makefile
===================================================================
@@ -26,3 +26,8 @@
 obj-$(CONFIG_THERM_PM72)	+= therm_pm72.o
 obj-$(CONFIG_THERM_WINDTUNNEL)	+= therm_windtunnel.o
 obj-$(CONFIG_THERM_ADT746X)	+= therm_adt746x.o
+obj-$(CONFIG_WINDFARM)	        += windfarm_core.o
+obj-$(CONFIG_WINDFARM_SMU)      += windfarm_smu_controls.o \
+				   windfarm_smu_sensors.o \
+				   windfarm_lm75_sensor.o windfarm_pid.o \
+				   windfarm_cpufreq_clamp.o windfarm_smu.o
drivers/macintosh/windfarm.h new file +122 -0

122 lines not on this page · raw message

drivers/macintosh/windfarm_core.c new file +428 -0

428 lines not on this page · raw message

drivers/macintosh/windfarm_smu_controls.c new file +274 -0

274 lines not on this page · raw message

drivers/macintosh/windfarm_smu_sensors.c new file +471 -0

471 lines not on this page · raw message

drivers/macintosh/windfarm_smu.c new file +1221 -0

1,221 lines not on this page · raw message

include/asm-ppc64/smu.h +101 -8

143 lines not on this page · raw message

drivers/macintosh/windfarm_lm75_sensor.c new file +255 -0

255 lines not on this page · raw message

drivers/macintosh/windfarm_pid.c new file +146 -0

54 lines not on this page · raw message

drivers/macintosh/windfarm_pid.h new file +84 -0

84 lines not on this page · raw message

arch/ppc64/kernel/pmac_cpufreq.c +37 -7

44 lines not on this page · raw message

drivers/macintosh/windfarm_cpufreq_clamp.c new file +105 -0

105 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.

#1 lore raw
Quoted 6 lines · Benjamin Herrenschmidt

This is the actual thermal control support for PowerMac8,1, PowerMac8,2 and PowerMac9,1 machines (SMU based), that is iMac G5 and single CPU desktop. It requires CPUFREQ to be enabled to properly deal with overtemp conditions. The new thermal control code implements a new framework (nicknamed "windfarm") to which I expect to port the old G5 thermal control, and possibly some of the powerbook thermal control drivers as well in the future.

<snip>

Quoted 2 lines
drivers/macintosh/windfarm_core.c 2005-10-04 15:17:33.000000000 +1000 renamed from dev/null 1970-01-01 00:00:00.000000000 +0000 +0 -0

<snip>

Quoted 24 lines
drivers/macintosh/windfarm_core.c 2005-10-04 15:17:33.000000000 +1000 renamed from dev/null 1970-01-01 00:00:00.000000000 +0000 +24 -0
+static int wf_thread_func(void *data)
+{
+       unsigned long next, delay;
+
+       next = jiffies;
+
+       DBG("wf: thread started\n");
+
+       while(!kthread_should_stop()) {
+               try_to_freeze();
+
+               if (time_after_eq(jiffies, next)) {
+                       wf_notify(WF_EVENT_TICK, NULL);
+                       if (wf_overtemp) {
+                               wf_overtemp_counter++;
+                               /* 10 seconds overtemp, notify userland */
+                               if (wf_overtemp_counter > 10)
+                                       wf_critical_overtemp();
+                               /* 30 seconds, shutdown */
+                               if (wf_overtemp_counter > 30) {
+                                       printk(KERN_ERR "windfarm: Overtemp "
+                                              "for more than 30"
+                                              " seconds, shutting down\n");
+                                       machine_power_off();

drivers/macintosh/windfarm_core.c 2005-10-04 15:17:33.000000000 +1000

Quoted 10 lines
drivers/macintosh/windfarm_core.c 2005-10-04 15:17:33.000000000 +1000 renamed from dev/null 1970-01-01 00:00:00.000000000 +0000 +10 -0
+                               }
+                       }
+                       next += HZ;
+               }
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               delay = next - jiffies;
+               if (delay <= HZ)
+                       schedule_timeout(delay);
+               set_current_state(TASK_RUNNING);

This can be schedule_timeout_interruptible(delay); and then you can get rid of the set_current_state(TASK_RUNNING);

Thanks,
NIsh

#2 lore raw
Quoted 3 lines · Nish Aravamudan

This can be schedule_timeout_interruptible(delay); and then you can get rid of the set_current_state(TASK_RUNNING);

Ah, those lovely new "do-it-all" helpers :) Thanks.

Ben.

#3 lore raw
In reply to Benjamin Herrenschmidt
Quoted 12 lines · Benjamin Herrenschmidt
drivers/macintosh/windfarm_core.c new file +11 -0
+int wf_register_client(struct notifier_block *nb)
+{
+	int rc;
+	struct wf_control *ct;
+	struct wf_sensor *sr;
+
+	down(&wf_lock);
+	rc = notifier_chain_register(&wf_client_list, nb);
+	if (rc != 0)
+		goto bail;
+	wf_client_count++;

drivers/macintosh/windfarm_core.c line 348

Quoted 10 lines
drivers/macintosh/windfarm_core.c new file +10 -0
+	list_for_each_entry(ct, &wf_controls, link)
+		wf_notify(WF_EVENT_NEW_CONTROL, ct);
+	list_for_each_entry(sr, &wf_sensors, link)
+		wf_notify(WF_EVENT_NEW_SENSOR, sr);
+	if (wf_client_count == 1)
+		wf_start_thread();
+	up(&wf_lock);
+ bail:
+	return rc;
+}

This will leave wf_lock held on error.

#4 lore raw
Quoted 1 line · Andrew Morton

This will leave wf_lock held on error.

Oops. Will fix along with the other ones you spotted asap.

Ben.

#5 lore raw
In reply to Benjamin Herrenschmidt

drivers/macintosh/windfarm_smu.c line 327

Quoted 4 lines · Benjamin Herrenschmidt
drivers/macintosh/windfarm_smu.c new file +3 -0
+	/* First, locate the params for this model */
+	for (i = 0; i < WF_SMU_SYS_FANS_NUM_CONFIGS; i++)
+		if (wf_smu_sys_all_params[i].model_id == mach_model) {

The loop control is a bit scary here. If you were to do

	#define WF_SMU_SYS_FANS_NUM_CONFIGS ARRAY_SIZE(wf_smu_sys_all_params)

then we wouldn't need duplicated into in two places.

Quoted 9 lines
drivers/macintosh/windfarm_smu.c new file +9 -0
+			param = &wf_smu_sys_all_params[i];
+			break;
+		}
+	/* No params found, put fans to max */
+	if (param == NULL) {
+		printk(KERN_WARNING "windfarm: System fan config not found "
+		       "for this machine model, max fan speed\n");
+		goto fail;
+	}

drivers/macintosh/windfarm_smu.c line 346

Quoted 10 lines
drivers/macintosh/windfarm_smu.c new file +10 -0
+
+	/* Alloc & initialize state */
+	wf_smu_sys_fans = kmalloc(sizeof(struct wf_smu_sys_fans_state),
+					GFP_KERNEL);
+	if (wf_smu_sys_fans == NULL) {
+		printk(KERN_WARNING "windfarm: Memory allocation error"
+		       " max fan speed\n");
+		goto fail;
+	}
+       	wf_smu_sys_fans->ticks = 1;

whitespace broke.

#6 lore raw
Quoted 4 lines · Andrew Morton
Quoted 4 lines
drivers/macintosh/windfarm_smu.c new file +4 -0
+
+	/* Alloc & initialize state */
+	wf_smu_sys_fans = kmalloc(sizeof(struct wf_smu_sys_fans_state),
+					GFP_KERNEL);
Quoted 8 lines

drivers/macintosh/windfarm_smu.c line 346

Quoted 6 lines
drivers/macintosh/windfarm_smu.c new file +6 -0
+	if (wf_smu_sys_fans == NULL) {
+		printk(KERN_WARNING "windfarm: Memory allocation error"
+		       " max fan speed\n");
+		goto fail;
+	}
+       	wf_smu_sys_fans->ticks = 1;

whitespace broke.

How so ? You mean the GFP_KERNEL a little bit too much on the right ? :)

Ben.

#7 lore raw
Quoted 17 lines · Benjamin Herrenschmidt wrote/
Quoted 4 lines · Andrew Morton
Quoted 4 lines
drivers/macintosh/windfarm_smu.c new file +4 -0
+
+	/* Alloc & initialize state */
+	wf_smu_sys_fans = kmalloc(sizeof(struct wf_smu_sys_fans_state),
+					GFP_KERNEL);
Quoted 8 lines

drivers/macintosh/windfarm_smu.c line 346

Quoted 6 lines
drivers/macintosh/windfarm_smu.c new file +6 -0
+	if (wf_smu_sys_fans == NULL) {
+		printk(KERN_WARNING "windfarm: Memory allocation error"
+		       " max fan speed\n");
+		goto fail;
+	}
+       	wf_smu_sys_fans->ticks = 1;

whitespace broke.

Quoted 2 lines

How so ? You mean the GFP_KERNEL a little bit too much on the right ? :)

I think Andrew was talking about the spaces instead of tabs on the last line.

Eric

#8 lore raw
Quoted 3 lines

I think Andrew was talking about the spaces instead of tabs on the last line.

Yah, found them, send a fixed patch already.

Ben.

#9 lore raw
In reply to Benjamin Herrenschmidt
Quoted 14 lines · Benjamin Herrenschmidt
drivers/macintosh/windfarm_smu.c new file +13 -0
+#define BUILD_SHOW_FUNC_FIX(name, data)				\
+static ssize_t show_##name(struct device *dev,                  \
+			   struct device_attribute *attr,       \
+			   char *buf)	                        \
+{								\
+	ssize_t r;						\
+        s32 val = 0;                                            \
+        data->ops->get_value(data, &val);                       \
+	r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); 	\
+	return r;						\
+}                                                               \
+static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
+

drivers/macintosh/windfarm_smu.c line 803

Quoted 10 lines
drivers/macintosh/windfarm_smu.c new file +10 -0
+
+#define BUILD_SHOW_FUNC_INT(name, data)				\
+static ssize_t show_##name(struct device *dev,                  \
+			   struct device_attribute *attr,       \
+			   char *buf)	                        \
+{								\
+        s32 val = 0;                                            \
+        data->ops->get_value(data, &val);                       \
+	return sprintf(buf, "%d", val);  			\
+}                                                               \

Someone needs a tab key ;)

#10 lore raw
Quoted 3 lines

\

Someone needs a tab key ;)

Or an emacs that stops turning tabs into spaces :)

Ben.

#11 lore raw
In reply to Andrew Morton
Quoted 19 lines · Andrew Morton
Quoted 18 lines · Benjamin Herrenschmidt
drivers/macintosh/windfarm_smu.c new file +17 -0
+#define BUILD_SHOW_FUNC_FIX(name, data)				\
+static ssize_t show_##name(struct device *dev,                  \
+			   struct device_attribute *attr,       \
+			   char *buf)	                        \
+{								\
+	ssize_t r;						\
+        s32 val = 0;                                            \
+        data->ops->get_value(data, &val);                       \
+	r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); 	\
+	return r;						\
+}                                                               \
+static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
+
+
+#define BUILD_SHOW_FUNC_INT(name, data)				\
+static ssize_t show_##name(struct device *dev,                  \
+			   struct device_attribute *attr,       \
Quoted 8 lines

drivers/macintosh/windfarm_smu.c line 803

Quoted 6 lines
drivers/macintosh/windfarm_smu.c new file +6 -0
+			   char *buf)	                        \
+{								\
+        s32 val = 0;                                            \
+        data->ops->get_value(data, &val);                       \
+	return sprintf(buf, "%d", val);  			\
+}                                                               \

Someone needs a tab key ;)

Ahh no, the problem here is that stupid emacs is very bad with tab and multi-line macros and just turns the whole thing into shit, so I used spaces. Sorry, I'm not an emacs guru and don't know how to work around that ...

Ben.

#12 lore raw

On Wed, Oct 12, 2005 at 10:24:51AM +1000, Benjamin Herrenschmidt was heard to remark:

Quoted 10 lines
Quoted 5 lines

drivers/macintosh/windfarm_smu.c line 785

Quoted 5 lines
drivers/macintosh/windfarm_smu.c new file +5 -0
+#define BUILD_SHOW_FUNC_FIX(name, data)				\
+static ssize_t show_##name(struct device *dev,                  \
+			   struct device_attribute *attr,       \
+			   char *buf)	                        \
+{								\

Ahh no, the problem here is that stupid emacs is very bad with tab and multi-line macros and just turns the whole thing into shit, so I used spaces. Sorry, I'm not an emacs guru and don't know how to work around that ...

Anyone who has tabstops set to 3 instead of 8 will see broken-ness for macros like this no matter what. Suggest that the right policy is to use only spaces, and neve tabs, inside of macros.

--linas

#13 lore raw
Quoted 13 lines · linas

On Wed, Oct 12, 2005 at 10:24:51AM +1000, Benjamin Herrenschmidt was heard to remark:

Quoted 10 lines
Quoted 5 lines

drivers/macintosh/windfarm_smu.c line 785

Quoted 5 lines
drivers/macintosh/windfarm_smu.c new file +5 -0
+#define BUILD_SHOW_FUNC_FIX(name, data)				\
+static ssize_t show_##name(struct device *dev,                  \
+			   struct device_attribute *attr,       \
+			   char *buf)	                        \
+{								\

Ahh no, the problem here is that stupid emacs is very bad with tab and multi-line macros and just turns the whole thing into shit, so I used spaces. Sorry, I'm not an emacs guru and don't know how to work around that ...

Quoted 1 line

Anyone who has tabstops set to 3 instead of 8

wtf? Anyone who has tabstops set to three gets their kernel license revoked.

Quoted 3 lines

will see broken-ness for
macros like this no matter what. Suggest that the right policy is to use only spaces, and neve tabs, inside of macros.

It works OK for everyone else...