summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powermac
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2013-05-05 22:42:10 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2013-05-05 22:42:10 +0000
commitcc397fc8ec15c200c46798a083861996e34faf96 (patch)
tree1b9c63a2e4cc14d3d1087de19083f1a577100b99 /sys/powerpc/powermac
parent9e0ab53d2eabc0b0aeed7f413dc8180537d0d421 (diff)
downloadFreeBSD-src-cc397fc8ec15c200c46798a083861996e34faf96.zip
FreeBSD-src-cc397fc8ec15c200c46798a083861996e34faf96.tar.gz
Only check fan type once. Not only is continuously rechecking pointless, a
single random failure can reprogram what control mechanism we try to use. MFC after: 2 weeks
Diffstat (limited to 'sys/powerpc/powermac')
-rw-r--r--sys/powerpc/powermac/smu.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c
index 72c5dc7..5c622e3 100644
--- a/sys/powerpc/powermac/smu.c
+++ b/sys/powerpc/powermac/smu.c
@@ -78,8 +78,8 @@ struct smu_fan {
SMU_FAN_RPM,
SMU_FAN_PWM
} type;
- int old_style;
int setpoint;
+ int old_style;
int rpm;
};
@@ -123,6 +123,7 @@ struct smu_softc {
struct smu_fan *sc_fans;
int sc_nfans;
+ int old_style_fans;
struct smu_sensor *sc_sensors;
int sc_nsensors;
@@ -654,6 +655,37 @@ doorbell_attach(device_t dev)
*/
static int
+smu_fan_check_old_style(struct smu_fan *fan)
+{
+ device_t smu = fan->dev;
+ struct smu_softc *sc = device_get_softc(smu);
+ struct smu_cmd cmd;
+ int error;
+
+ if (sc->old_style_fans != -1)
+ return (sc->old_style_fans);
+
+ /*
+ * Apple has two fan control mechanisms. We can't distinguish
+ * them except by seeing if the new one fails. If the new one
+ * fails, use the old one.
+ */
+
+ cmd.cmd = SMU_FAN;
+ cmd.len = 2;
+ cmd.data[0] = 0x31;
+ cmd.data[1] = fan->reg;
+
+ do {
+ error = smu_run_cmd(smu, &cmd, 1);
+ } while (error == EWOULDBLOCK);
+
+ sc->old_style_fans = (error != 0);
+
+ return (sc->old_style_fans);
+}
+
+static int
smu_fan_set_rpm(struct smu_fan *fan, int rpm)
{
device_t smu = fan->dev;
@@ -667,12 +699,8 @@ smu_fan_set_rpm(struct smu_fan *fan, int rpm)
rpm = max(fan->fan.min_rpm, rpm);
rpm = min(fan->fan.max_rpm, rpm);
- /*
- * Apple has two fan control mechanisms. We can't distinguish
- * them except by seeing if the new one fails. If the new one
- * fails, use the old one.
- */
-
+ smu_fan_check_old_style(fan);
+
if (!fan->old_style) {
cmd.len = 4;
cmd.data[0] = 0x30;
@@ -683,9 +711,7 @@ smu_fan_set_rpm(struct smu_fan *fan, int rpm)
error = smu_run_cmd(smu, &cmd, 1);
if (error && error != EWOULDBLOCK)
fan->old_style = 1;
- }
-
- if (fan->old_style) {
+ } else {
cmd.len = 14;
cmd.data[0] = 0x00; /* RPM fan. */
cmd.data[1] = 1 << fan->reg;
@@ -707,6 +733,8 @@ smu_fan_read_rpm(struct smu_fan *fan)
struct smu_cmd cmd;
int rpm, error;
+ smu_fan_check_old_style(fan);
+
if (!fan->old_style) {
cmd.cmd = SMU_FAN;
cmd.len = 2;
@@ -944,9 +972,10 @@ smu_count_fans(device_t dev)
child = OF_peer(child)) {
nfans++;
/* When allocated, fill the fan properties. */
- if (sc->sc_fans != NULL)
+ if (sc->sc_fans != NULL) {
smu_fill_fan_prop(dev, child,
nfans - 1);
+ }
}
}
if (nfans == 0) {
OpenPOWER on IntegriCloud