aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorRudolf Marek <r.marek@assembler.cz>2008-01-17 18:42:54 -0500
committerMark M. Hoffman <mhoffman@lightlink.com>2008-02-17 10:21:39 -0500
commit6369a2887a1b35fde91573adc650528e3efea8e9 (patch)
treec1e9d888a20c2070c549934ee02b7d02218ed468 /drivers/hwmon
parent1d5f2c16c6125ae6da1435ac5a190ae08429902a (diff)
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>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/coretemp.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 3ee60d26e3a2..52914e95e9dc 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -38,7 +38,8 @@
38 38
39#define DRVNAME "coretemp" 39#define DRVNAME "coretemp"
40 40
41typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; 41typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL,
42 SHOW_NAME } SHOW;
42 43
43/* 44/*
44 * Functions declaration 45 * Functions declaration
@@ -55,6 +56,7 @@ struct coretemp_data {
55 unsigned long last_updated; /* in jiffies */ 56 unsigned long last_updated; /* in jiffies */
56 int temp; 57 int temp;
57 int tjmax; 58 int tjmax;
59 int ttarget;
58 u8 alarm; 60 u8 alarm;
59}; 61};
60 62
@@ -93,9 +95,10 @@ static ssize_t show_temp(struct device *dev,
93 95
94 if (attr->index == SHOW_TEMP) 96 if (attr->index == SHOW_TEMP)
95 err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN; 97 err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
96 else 98 else if (attr->index == SHOW_TJMAX)
97 err = sprintf(buf, "%d\n", data->tjmax); 99 err = sprintf(buf, "%d\n", data->tjmax);
98 100 else
101 err = sprintf(buf, "%d\n", data->ttarget);
99 return err; 102 return err;
100} 103}
101 104
@@ -103,6 +106,8 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
103 SHOW_TEMP); 106 SHOW_TEMP);
104static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, 107static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
105 SHOW_TJMAX); 108 SHOW_TJMAX);
109static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL,
110 SHOW_TTARGET);
106static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL); 111static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
107static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); 112static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
108static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); 113static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
@@ -223,8 +228,26 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
223 228
224 platform_set_drvdata(pdev, data); 229 platform_set_drvdata(pdev, data);
225 230
231 /* read the still undocumented IA32_TEMPERATURE_TARGET it exists
232 on older CPUs but not in this register */
233
234 if (c->x86_model > 0xe) {
235 err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
236 if (err) {
237 dev_warn(&pdev->dev, "Unable to read"
238 " IA32_TEMPERATURE_TARGET MSR\n");
239 } else {
240 data->ttarget = data->tjmax -
241 (((eax >> 8) & 0xff) * 1000);
242 err = device_create_file(&pdev->dev,
243 &sensor_dev_attr_temp1_max.dev_attr);
244 if (err)
245 goto exit_free;
246 }
247 }
248
226 if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) 249 if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
227 goto exit_free; 250 goto exit_dev;
228 251
229 data->hwmon_dev = hwmon_device_register(&pdev->dev); 252 data->hwmon_dev = hwmon_device_register(&pdev->dev);
230 if (IS_ERR(data->hwmon_dev)) { 253 if (IS_ERR(data->hwmon_dev)) {
@@ -238,6 +261,8 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
238 261
239exit_class: 262exit_class:
240 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); 263 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
264exit_dev:
265 device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
241exit_free: 266exit_free:
242 kfree(data); 267 kfree(data);
243exit: 268exit:
@@ -250,6 +275,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev)
250 275
251 hwmon_device_unregister(data->hwmon_dev); 276 hwmon_device_unregister(data->hwmon_dev);
252 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); 277 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
278 device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
253 platform_set_drvdata(pdev, NULL); 279 platform_set_drvdata(pdev, NULL);
254 kfree(data); 280 kfree(data);
255 return 0; 281 return 0;