diff options
-rw-r--r-- | share/man/man4/coretemp.4 | 20 | ||||
-rw-r--r-- | sys/dev/coretemp/coretemp.c | 79 |
2 files changed, 59 insertions, 40 deletions
diff --git a/share/man/man4/coretemp.4 b/share/man/man4/coretemp.4 index ce4eb36..a9ac4b8 100644 --- a/share/man/man4/coretemp.4 +++ b/share/man/man4/coretemp.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 23, 2007 +.Dd September 13, 2007 .Dt CORETEMP 4 .Os .Sh NAME @@ -51,12 +51,20 @@ The driver provides support for the on-die digital thermal sensor present in Intel Core and newer CPUs. .Pp -The -.Nm -driver reports each core's temperature through a sysctl node in the -corresponding CPU device's sysctl tree, named -.Va dev.cpu.%d.temperature . +The values are exposed through the +.Va HW_SENSORS +.Xr sysctl 3 +tree. +For example: +.Bd -literal -offset indent +%sysctl hw.sensors +hw.sensors.cpu0.temp0: 28.00 degC +hw.sensors.cpu1.temp0: 29.00 degC +.Ed .Sh SEE ALSO +.Xr systat 1 , +.Xr sysctl 3 , +.Xr sensorsd 8 , .Xr sysctl 8 .Sh HISTORY The diff --git a/sys/dev/coretemp/coretemp.c b/sys/dev/coretemp/coretemp.c index 61e4606..fcc0005 100644 --- a/sys/dev/coretemp/coretemp.c +++ b/sys/dev/coretemp/coretemp.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/conf.h> #include <sys/kernel.h> -#include <sys/sysctl.h> +#include <sys/sensors.h> #include <sys/proc.h> /* for curthread */ #include <sys/sched.h> @@ -50,10 +50,13 @@ __FBSDID("$FreeBSD$"); #include <machine/cpufunc.h> #include <machine/md_var.h> +extern int smp_cpus; + struct coretemp_softc { - device_t sc_dev; - int sc_tjmax; - struct sysctl_oid *sc_oid; + struct ksensordev sc_sensordev; + struct ksensor sc_sensor; + device_t sc_dev; + int sc_tjmax; }; /* @@ -65,7 +68,7 @@ static int coretemp_attach(device_t dev); static int coretemp_detach(device_t dev); static int coretemp_get_temp(device_t dev); -static int coretemp_get_temp_sysctl(SYSCTL_HANDLER_ARGS); +static void coretemp_refresh(void *arg); static device_method_t coretemp_methods[] = { /* Device interface */ @@ -174,14 +177,17 @@ coretemp_attach(device_t dev) } /* - * Add the "temperature" MIB to dev.cpu.N. + * Add hw.sensors.cpuN.temp0 MIB. */ - sc->sc_oid = SYSCTL_ADD_PROC(device_get_sysctl_ctx(pdev), - SYSCTL_CHILDREN(device_get_sysctl_tree(pdev)), - OID_AUTO, "temperature", - CTLTYPE_INT | CTLFLAG_RD, - dev, 0, coretemp_get_temp_sysctl, "I", - "Current temperature in degC"); + strlcpy(sc->sc_sensordev.xname, device_get_nameunit(pdev), + sizeof(sc->sc_sensordev.xname)); + sc->sc_sensor.type = SENSOR_TEMP; + sensor_attach(&sc->sc_sensordev, &sc->sc_sensor); + if (sensor_task_register(sc, coretemp_refresh, 2)) { + device_printf(dev, "unable to register update task\n"); + return (ENXIO); + } + sensordev_install(&sc->sc_sensordev); return (0); } @@ -191,7 +197,8 @@ coretemp_detach(device_t dev) { struct coretemp_softc *sc = device_get_softc(dev); - sysctl_remove_oid(sc->sc_oid, 1, 0); + sensordev_deinstall(&sc->sc_sensordev); + sensor_task_unregister(sc); return (0); } @@ -206,25 +213,21 @@ coretemp_get_temp(device_t dev) struct coretemp_softc *sc = device_get_softc(dev); char stemp[16]; - thread_lock(curthread); - sched_bind(curthread, cpu); - thread_unlock(curthread); - /* - * The digital temperature reading is located at bit 16 - * of MSR_THERM_STATUS. - * - * There is a bit on that MSR that indicates whether the - * temperature is valid or not. - * - * The temperature is computed by subtracting the temperature - * reading by Tj(max). + * Bind to specific CPU to read the correct temperature. + * If not all CPUs are initialised, then only read from + * cpu0, returning -1 on all other CPUs. */ - msr = rdmsr(MSR_THERM_STATUS); - - thread_lock(curthread); - sched_unbind(curthread); - thread_unlock(curthread); + if (smp_cpus > 1) { + thread_lock(curthread); + sched_bind(curthread, cpu); + msr = rdmsr(MSR_THERM_STATUS); + sched_unbind(curthread); + thread_unlock(curthread); + } else if (cpu != 0) + return (-1); + else + msr = rdmsr(MSR_THERM_STATUS); /* * Check for Thermal Status and Thermal Status Log. @@ -264,13 +267,21 @@ coretemp_get_temp(device_t dev) return (temp); } -static int -coretemp_get_temp_sysctl(SYSCTL_HANDLER_ARGS) +static void +coretemp_refresh(void *arg) { - device_t dev = (device_t) arg1; + struct coretemp_softc *sc = arg; + device_t dev = sc->sc_dev; + struct ksensor *s = &sc->sc_sensor; int temp; temp = coretemp_get_temp(dev); - return (sysctl_handle_int(oidp, &temp, 0, req)); + if (temp == -1) { + s->flags |= SENSOR_FINVALID; + s->value = 0; + } else { + s->flags &= ~SENSOR_FINVALID; + s->value = temp * 1000000 + 273150000; + } } |