hwmon: (coretemp) Add maximum cooling temperature readout
Following patch will add reporting of maximum temperature, at which all fans should spin full speed. It may be non-physical temperature on Desktop/Server CPUs. Signed-off-by: Rudolf Marek <r.marek@assembler.cz> Acked-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
This commit is contained in:
parent
1d5f2c16c6
commit
6369a2887a
2 changed files with 32 additions and 5 deletions
|
@ -25,7 +25,8 @@ may be raised, if the temperature grows enough (more than TjMax) to trigger
|
||||||
the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
|
the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
|
||||||
|
|
||||||
temp1_input - Core temperature (in millidegrees Celsius).
|
temp1_input - Core temperature (in millidegrees Celsius).
|
||||||
temp1_crit - Maximum junction temperature (in millidegrees Celsius).
|
temp1_max - All cooling devices should be turned on (on Core2).
|
||||||
|
temp1_crit - Maximum junction temperature (in millidegrees Celsius).
|
||||||
temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
|
temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
|
||||||
Correct CPU operation is no longer guaranteed.
|
Correct CPU operation is no longer guaranteed.
|
||||||
temp1_label - Contains string "Core X", where X is processor
|
temp1_label - Contains string "Core X", where X is processor
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
|
|
||||||
#define DRVNAME "coretemp"
|
#define DRVNAME "coretemp"
|
||||||
|
|
||||||
typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW;
|
typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL,
|
||||||
|
SHOW_NAME } SHOW;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions declaration
|
* Functions declaration
|
||||||
|
@ -55,6 +56,7 @@ struct coretemp_data {
|
||||||
unsigned long last_updated; /* in jiffies */
|
unsigned long last_updated; /* in jiffies */
|
||||||
int temp;
|
int temp;
|
||||||
int tjmax;
|
int tjmax;
|
||||||
|
int ttarget;
|
||||||
u8 alarm;
|
u8 alarm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,9 +95,10 @@ static ssize_t show_temp(struct device *dev,
|
||||||
|
|
||||||
if (attr->index == SHOW_TEMP)
|
if (attr->index == SHOW_TEMP)
|
||||||
err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
|
err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
|
||||||
else
|
else if (attr->index == SHOW_TJMAX)
|
||||||
err = sprintf(buf, "%d\n", data->tjmax);
|
err = sprintf(buf, "%d\n", data->tjmax);
|
||||||
|
else
|
||||||
|
err = sprintf(buf, "%d\n", data->ttarget);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +106,8 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
|
||||||
SHOW_TEMP);
|
SHOW_TEMP);
|
||||||
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
|
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
|
||||||
SHOW_TJMAX);
|
SHOW_TJMAX);
|
||||||
|
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL,
|
||||||
|
SHOW_TTARGET);
|
||||||
static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
|
static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
|
||||||
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
|
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
|
||||||
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
|
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
|
||||||
|
@ -223,8 +228,26 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_set_drvdata(pdev, data);
|
platform_set_drvdata(pdev, data);
|
||||||
|
|
||||||
|
/* read the still undocumented IA32_TEMPERATURE_TARGET it exists
|
||||||
|
on older CPUs but not in this register */
|
||||||
|
|
||||||
|
if (c->x86_model > 0xe) {
|
||||||
|
err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
|
||||||
|
if (err) {
|
||||||
|
dev_warn(&pdev->dev, "Unable to read"
|
||||||
|
" IA32_TEMPERATURE_TARGET MSR\n");
|
||||||
|
} else {
|
||||||
|
data->ttarget = data->tjmax -
|
||||||
|
(((eax >> 8) & 0xff) * 1000);
|
||||||
|
err = device_create_file(&pdev->dev,
|
||||||
|
&sensor_dev_attr_temp1_max.dev_attr);
|
||||||
|
if (err)
|
||||||
|
goto exit_free;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
|
if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
|
||||||
goto exit_free;
|
goto exit_dev;
|
||||||
|
|
||||||
data->hwmon_dev = hwmon_device_register(&pdev->dev);
|
data->hwmon_dev = hwmon_device_register(&pdev->dev);
|
||||||
if (IS_ERR(data->hwmon_dev)) {
|
if (IS_ERR(data->hwmon_dev)) {
|
||||||
|
@ -238,6 +261,8 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
exit_class:
|
exit_class:
|
||||||
sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
|
sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
|
||||||
|
exit_dev:
|
||||||
|
device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
|
||||||
exit_free:
|
exit_free:
|
||||||
kfree(data);
|
kfree(data);
|
||||||
exit:
|
exit:
|
||||||
|
@ -250,6 +275,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
hwmon_device_unregister(data->hwmon_dev);
|
hwmon_device_unregister(data->hwmon_dev);
|
||||||
sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
|
sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
|
||||||
|
device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
|
||||||
platform_set_drvdata(pdev, NULL);
|
platform_set_drvdata(pdev, NULL);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Reference in a new issue