summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2016-05-20 21:56:01 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2016-05-20 21:56:01 +0000
commitcc3ddd78931d81ab2fee1fd4fc9790a9c1a0a687 (patch)
tree18c6bc42900c0b086531f99ec767af8b40909af2
parent5e340ff2e04f2212ad351e4c5eeb6243520ea31e (diff)
Hook up smu(4) to the thermal management framework.
ok kettenis
-rw-r--r--sys/arch/macppc/dev/smu.c99
1 files changed, 92 insertions, 7 deletions
diff --git a/sys/arch/macppc/dev/smu.c b/sys/arch/macppc/dev/smu.c
index 6a6e3a75cfe..d4ea5e63201 100644
--- a/sys/arch/macppc/dev/smu.c
+++ b/sys/arch/macppc/dev/smu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smu.c,v 1.31 2016/05/14 21:22:17 mglocker Exp $ */
+/* $OpenBSD: smu.c,v 1.32 2016/05/20 21:56:00 mglocker Exp $ */
/*
* Copyright (c) 2005 Mark Kettenis
@@ -32,14 +32,20 @@
#include <dev/ofw/openfirm.h>
#include <macppc/dev/maci2cvar.h>
+#include <macppc/dev/thermal.h>
#include <macppc/pci/macobio.h>
int smu_match(struct device *, void *, void *);
void smu_attach(struct device *, struct device *, void *);
+/* Target and Max. temperature in muK. */
+#define TEMP_TRG 38 * 1000000 + 273150000
+#define TEMP_MAX 70 * 1000000 + 273150000
+
#define SMU_MAXFANS 8
struct smu_fan {
+ struct thermal_fan fan;
u_int8_t reg;
u_int16_t min_rpm;
u_int16_t max_rpm;
@@ -53,6 +59,7 @@ struct smu_fan {
#define SMU_MAXSENSORS 4
struct smu_sensor {
+ struct thermal_temp therm;
u_int8_t reg;
struct ksensor sensor;
};
@@ -152,9 +159,13 @@ int smu_fan_read_rpm(struct smu_softc *, struct smu_fan *, u_int16_t *);
int smu_fan_read_pwm(struct smu_softc *, struct smu_fan *, u_int16_t *,
u_int16_t *);
int smu_fan_refresh(struct smu_softc *, struct smu_fan *);
-int smu_sensor_refresh(struct smu_softc *, struct smu_sensor *);
+int smu_sensor_refresh(struct smu_softc *, struct smu_sensor *, int);
void smu_refresh_sensors(void *);
+int smu_fan_set_rpm_thermal(struct smu_fan *, int);
+int smu_fan_set_pwm_thermal(struct smu_fan *, int);
+int smu_sensor_refresh_thermal(struct smu_sensor *);
+
int smu_i2c_acquire_bus(void *, int);
void smu_i2c_release_bus(void *, int);
int smu_i2c_exec(void *, i2c_op_t, i2c_addr_t,
@@ -301,6 +312,15 @@ smu_attach(struct device *parent, struct device *self, void *aux)
/* Start running fans at their "unmanaged" speed. */
smu_fan_set_rpm(sc, fan, fan->unmanaged_rpm);
+ /* Register fan at thermal management framework. */
+ fan->fan.min_rpm = fan->min_rpm;
+ fan->fan.max_rpm = fan->max_rpm;
+ fan->fan.default_rpm = fan->unmanaged_rpm;
+ strlcpy(fan->fan.name, loc, sizeof fan->fan.name);
+ OF_getprop(node, "zone", &fan->fan.zone, sizeof fan->fan.zone);
+ fan->fan.set = (int (*)(struct thermal_fan *, int))
+ smu_fan_set_rpm_thermal;
+ thermal_fan_register(&fan->fan);
#ifndef SMALL_KERNEL
sensor_attach(&sc->sc_sensordev, &fan->sensor);
#endif
@@ -348,6 +368,15 @@ smu_attach(struct device *parent, struct device *self, void *aux)
/* Start running fans at their "unmanaged" speed. */
smu_fan_set_pwm(sc, fan, fan->unmanaged_pwm);
+ /* Register fan at thermal management framework. */
+ fan->fan.min_rpm = fan->min_pwm;
+ fan->fan.max_rpm = fan->max_pwm;
+ fan->fan.default_rpm = fan->unmanaged_pwm;
+ strlcpy(fan->fan.name, loc, sizeof fan->fan.name);
+ OF_getprop(node, "zone", &fan->fan.zone, sizeof fan->fan.zone);
+ fan->fan.set = (int (*)(struct thermal_fan *, int))
+ smu_fan_set_pwm_thermal;
+ thermal_fan_register(&fan->fan);
#ifndef SMALL_KERNEL
sensor_attach(&sc->sc_sensordev, &fan->sensor);
#endif
@@ -397,6 +426,19 @@ smu_attach(struct device *parent, struct device *self, void *aux)
strlcpy(loc, "Unknown", sizeof loc);
strlcpy(sensor->sensor.desc, loc, sizeof sensor->sensor.desc);
+ /* Register temp. sensor at thermal management framework. */
+ if (sensor->sensor.type == SENSOR_TEMP) {
+ sensor->therm.target_temp = TEMP_TRG;
+ sensor->therm.max_temp = TEMP_MAX;
+ strlcpy(sensor->therm.name, loc,
+ sizeof sensor->therm.name);
+ OF_getprop(node, "zone", &sensor->therm.zone,
+ sizeof sensor->therm.zone);
+ sensor->therm.read = (int (*)
+ (struct thermal_temp *))smu_sensor_refresh_thermal;
+ thermal_sensor_register(&sensor->therm);
+ }
+
sensor_attach(&sc->sc_sensordev, &sensor->sensor);
}
@@ -700,7 +742,8 @@ smu_fan_refresh(struct smu_softc *sc, struct smu_fan *fan)
}
int
-smu_sensor_refresh(struct smu_softc *sc, struct smu_sensor *sensor)
+smu_sensor_refresh(struct smu_softc *sc, struct smu_sensor *sensor,
+ int update_sysctl)
{
struct smu_cmd *cmd = (struct smu_cmd *)sc->sc_cmd;
int64_t value;
@@ -761,9 +804,11 @@ smu_sensor_refresh(struct smu_softc *sc, struct smu_sensor *sensor)
default:
break;
}
- sensor->sensor.value = value;
- sensor->sensor.flags = 0;
- return (0);
+ if (update_sysctl) {
+ sensor->sensor.value = value;
+ sensor->sensor.flags = 0;
+ }
+ return (value);
}
void
@@ -774,12 +819,52 @@ smu_refresh_sensors(void *arg)
rw_enter_write(&sc->sc_lock);
for (i = 0; i < sc->sc_num_sensors; i++)
- smu_sensor_refresh(sc, &sc->sc_sensors[i]);
+ smu_sensor_refresh(sc, &sc->sc_sensors[i], 1);
for (i = 0; i < sc->sc_num_fans; i++)
smu_fan_refresh(sc, &sc->sc_fans[i]);
rw_exit_write(&sc->sc_lock);
}
+/*
+ * Wrapper functions for the thermal management framework.
+ */
+int
+smu_fan_set_rpm_thermal(struct smu_fan *fan, int rpm)
+{
+ struct smu_softc *sc = smu_cd.cd_devs[0];
+
+ rw_enter_write(&sc->sc_lock);
+ (void)smu_fan_set_rpm(sc, fan, rpm);
+ rw_exit_write(&sc->sc_lock);
+
+ return (0);
+}
+
+int
+smu_fan_set_pwm_thermal(struct smu_fan *fan, int pwm)
+{
+ struct smu_softc *sc = smu_cd.cd_devs[0];
+
+ rw_enter_write(&sc->sc_lock);
+ (void)smu_fan_set_pwm(sc, fan, pwm);
+ rw_exit_write(&sc->sc_lock);
+
+ return (0);
+}
+
+int
+smu_sensor_refresh_thermal(struct smu_sensor *sensor)
+{
+ struct smu_softc *sc = smu_cd.cd_devs[0];
+ int value;
+
+ rw_enter_write(&sc->sc_lock);
+ value = smu_sensor_refresh(sc, sensor, 0);
+ rw_exit_write(&sc->sc_lock);
+
+ return (value);
+}
+
int
smu_i2c_acquire_bus(void *cookie, int flags)
{