diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2013-05-05 22:42:10 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2013-05-05 22:42:10 +0000 |
commit | cc397fc8ec15c200c46798a083861996e34faf96 (patch) | |
tree | 1b9c63a2e4cc14d3d1087de19083f1a577100b99 /sys/powerpc/powermac | |
parent | 9e0ab53d2eabc0b0aeed7f413dc8180537d0d421 (diff) | |
download | FreeBSD-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.c | 51 |
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) { |