2 * coretemp.c - Linux kernel module for hardware monitoring
4 * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
6 * Inspired from many hwmon drivers
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include <linux/module.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/slab.h>
27 #include <linux/jiffies.h>
28 #include <linux/hwmon.h>
29 #include <linux/sysfs.h>
30 #include <linux/hwmon-sysfs.h>
31 #include <linux/err.h>
32 #include <linux/mutex.h>
33 #include <linux/list.h>
34 #include <linux/platform_device.h>
35 #include <linux/cpu.h>
37 #include <asm/processor.h>
39 #define DRVNAME "coretemp"
41 typedef enum { SHOW_TEMP
, SHOW_TJMAX
, SHOW_LABEL
, SHOW_NAME
} SHOW
;
44 * Functions declaration
47 static struct coretemp_data
*coretemp_update_device(struct device
*dev
);
49 struct coretemp_data
{
50 struct device
*hwmon_dev
;
51 struct mutex update_lock
;
54 char valid
; /* zero until following fields are valid */
55 unsigned long last_updated
; /* in jiffies */
65 static ssize_t
show_name(struct device
*dev
, struct device_attribute
69 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
70 struct coretemp_data
*data
= dev_get_drvdata(dev
);
72 if (attr
->index
== SHOW_NAME
)
73 ret
= sprintf(buf
, "%s\n", data
->name
);
75 ret
= sprintf(buf
, "Core %d\n", data
->id
);
79 static ssize_t
show_alarm(struct device
*dev
, struct device_attribute
82 struct coretemp_data
*data
= coretemp_update_device(dev
);
83 /* read the Out-of-spec log, never clear */
84 return sprintf(buf
, "%d\n", data
->alarm
);
87 static ssize_t
show_temp(struct device
*dev
,
88 struct device_attribute
*devattr
, char *buf
)
90 struct sensor_device_attribute
*attr
= to_sensor_dev_attr(devattr
);
91 struct coretemp_data
*data
= coretemp_update_device(dev
);
94 if (attr
->index
== SHOW_TEMP
)
95 err
= data
->valid
? sprintf(buf
, "%d\n", data
->temp
) : -EAGAIN
;
97 err
= sprintf(buf
, "%d\n", data
->tjmax
);
102 static SENSOR_DEVICE_ATTR(temp1_input
, S_IRUGO
, show_temp
, NULL
,
104 static SENSOR_DEVICE_ATTR(temp1_crit
, S_IRUGO
, show_temp
, NULL
,
106 static DEVICE_ATTR(temp1_crit_alarm
, S_IRUGO
, show_alarm
, NULL
);
107 static SENSOR_DEVICE_ATTR(temp1_label
, S_IRUGO
, show_name
, NULL
, SHOW_LABEL
);
108 static SENSOR_DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
, SHOW_NAME
);
110 static struct attribute
*coretemp_attributes
[] = {
111 &sensor_dev_attr_name
.dev_attr
.attr
,
112 &sensor_dev_attr_temp1_label
.dev_attr
.attr
,
113 &dev_attr_temp1_crit_alarm
.attr
,
114 &sensor_dev_attr_temp1_input
.dev_attr
.attr
,
115 &sensor_dev_attr_temp1_crit
.dev_attr
.attr
,
119 static const struct attribute_group coretemp_group
= {
120 .attrs
= coretemp_attributes
,
123 static struct coretemp_data
*coretemp_update_device(struct device
*dev
)
125 struct coretemp_data
*data
= dev_get_drvdata(dev
);
127 mutex_lock(&data
->update_lock
);
129 if (!data
->valid
|| time_after(jiffies
, data
->last_updated
+ HZ
)) {
133 rdmsr_on_cpu(data
->id
, MSR_IA32_THERM_STATUS
, &eax
, &edx
);
134 data
->alarm
= (eax
>> 5) & 1;
135 /* update only if data has been valid */
136 if (eax
& 0x80000000) {
137 data
->temp
= data
->tjmax
- (((eax
>> 16)
141 dev_dbg(dev
, "Temperature data invalid (0x%x)\n", eax
);
143 data
->last_updated
= jiffies
;
146 mutex_unlock(&data
->update_lock
);
150 static int __devinit
coretemp_probe(struct platform_device
*pdev
)
152 struct coretemp_data
*data
;
153 struct cpuinfo_x86
*c
= &cpu_data(pdev
->id
);
157 if (!(data
= kzalloc(sizeof(struct coretemp_data
), GFP_KERNEL
))) {
159 dev_err(&pdev
->dev
, "Out of memory\n");
164 data
->name
= "coretemp";
165 mutex_init(&data
->update_lock
);
166 /* Tjmax default is 100 degrees C */
167 data
->tjmax
= 100000;
169 /* test if we can access the THERM_STATUS MSR */
170 err
= rdmsr_safe_on_cpu(data
->id
, MSR_IA32_THERM_STATUS
, &eax
, &edx
);
173 "Unable to access THERM_STATUS MSR, giving up\n");
177 /* Check if we have problem with errata AE18 of Core processors:
178 Readings might stop update when processor visited too deep sleep,
179 fixed for stepping D0 (6EC).
182 if ((c
->x86_model
== 0xe) && (c
->x86_mask
< 0xc)) {
183 /* check for microcode update */
184 rdmsr_on_cpu(data
->id
, MSR_IA32_UCODE_REV
, &eax
, &edx
);
188 "Errata AE18 not fixed, update BIOS or "
189 "microcode of the CPU!\n");
194 /* Some processors have Tjmax 85 following magic should detect it
195 Intel won't disclose the information without signed NDA, but
196 individuals cannot sign it. Catch(ed) 22.
199 if (((c
->x86_model
== 0xf) && (c
->x86_mask
> 3)) ||
200 (c
->x86_model
== 0xe)) {
201 err
= rdmsr_safe_on_cpu(data
->id
, 0xee, &eax
, &edx
);
204 "Unable to access MSR 0xEE, Tjmax left at %d "
205 "degrees C\n", data
->tjmax
/1000);
206 } else if (eax
& 0x40000000) {
211 /* Intel says that above should not work for desktop Core2 processors,
212 but it seems to work. There is no other way how get the absolute
213 readings. Warn the user about this. First check if are desktop,
214 bit 50 of MSR_IA32_PLATFORM_ID should be 0.
217 rdmsr_safe_on_cpu(data
->id
, MSR_IA32_PLATFORM_ID
, &eax
, &edx
);
219 if ((c
->x86_model
== 0xf) && (!(edx
& 0x00040000))) {
220 dev_warn(&pdev
->dev
, "Using undocumented features, absolute "
221 "temperature might be wrong!\n");
224 platform_set_drvdata(pdev
, data
);
226 if ((err
= sysfs_create_group(&pdev
->dev
.kobj
, &coretemp_group
)))
229 data
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
230 if (IS_ERR(data
->hwmon_dev
)) {
231 err
= PTR_ERR(data
->hwmon_dev
);
232 dev_err(&pdev
->dev
, "Class registration failed (%d)\n",
240 sysfs_remove_group(&pdev
->dev
.kobj
, &coretemp_group
);
247 static int __devexit
coretemp_remove(struct platform_device
*pdev
)
249 struct coretemp_data
*data
= platform_get_drvdata(pdev
);
251 hwmon_device_unregister(data
->hwmon_dev
);
252 sysfs_remove_group(&pdev
->dev
.kobj
, &coretemp_group
);
253 platform_set_drvdata(pdev
, NULL
);
258 static struct platform_driver coretemp_driver
= {
260 .owner
= THIS_MODULE
,
263 .probe
= coretemp_probe
,
264 .remove
= __devexit_p(coretemp_remove
),
268 struct list_head list
;
269 struct platform_device
*pdev
;
273 static LIST_HEAD(pdev_list
);
274 static DEFINE_MUTEX(pdev_list_mutex
);
276 static int __cpuinit
coretemp_device_add(unsigned int cpu
)
279 struct platform_device
*pdev
;
280 struct pdev_entry
*pdev_entry
;
282 pdev
= platform_device_alloc(DRVNAME
, cpu
);
285 printk(KERN_ERR DRVNAME
": Device allocation failed\n");
289 pdev_entry
= kzalloc(sizeof(struct pdev_entry
), GFP_KERNEL
);
292 goto exit_device_put
;
295 err
= platform_device_add(pdev
);
297 printk(KERN_ERR DRVNAME
": Device addition failed (%d)\n",
299 goto exit_device_free
;
302 pdev_entry
->pdev
= pdev
;
303 pdev_entry
->cpu
= cpu
;
304 mutex_lock(&pdev_list_mutex
);
305 list_add_tail(&pdev_entry
->list
, &pdev_list
);
306 mutex_unlock(&pdev_list_mutex
);
313 platform_device_put(pdev
);
318 #ifdef CONFIG_HOTPLUG_CPU
319 static void coretemp_device_remove(unsigned int cpu
)
321 struct pdev_entry
*p
, *n
;
322 mutex_lock(&pdev_list_mutex
);
323 list_for_each_entry_safe(p
, n
, &pdev_list
, list
) {
325 platform_device_unregister(p
->pdev
);
330 mutex_unlock(&pdev_list_mutex
);
333 static int coretemp_cpu_callback(struct notifier_block
*nfb
,
334 unsigned long action
, void *hcpu
)
336 unsigned int cpu
= (unsigned long) hcpu
;
340 case CPU_DOWN_FAILED
:
341 coretemp_device_add(cpu
);
343 case CPU_DOWN_PREPARE
:
344 coretemp_device_remove(cpu
);
350 static struct notifier_block coretemp_cpu_notifier
= {
351 .notifier_call
= coretemp_cpu_callback
,
353 #endif /* !CONFIG_HOTPLUG_CPU */
355 static int __init
coretemp_init(void)
357 int i
, err
= -ENODEV
;
358 struct pdev_entry
*p
, *n
;
360 /* quick check if we run Intel */
361 if (cpu_data(0).x86_vendor
!= X86_VENDOR_INTEL
)
364 err
= platform_driver_register(&coretemp_driver
);
368 for_each_online_cpu(i
) {
369 struct cpuinfo_x86
*c
= &cpu_data(i
);
371 /* check if family 6, models e, f, 16 */
372 if ((c
->cpuid_level
< 0) || (c
->x86
!= 0x6) ||
373 !((c
->x86_model
== 0xe) || (c
->x86_model
== 0xf) ||
374 (c
->x86_model
== 0x16))) {
376 /* supported CPU not found, but report the unknown
378 if ((c
->x86
== 0x6) && (c
->x86_model
> 0xf))
379 printk(KERN_WARNING DRVNAME
": Unknown CPU "
380 "model %x\n", c
->x86_model
);
384 err
= coretemp_device_add(i
);
386 goto exit_devices_unreg
;
388 if (list_empty(&pdev_list
)) {
390 goto exit_driver_unreg
;
393 #ifdef CONFIG_HOTPLUG_CPU
394 register_hotcpu_notifier(&coretemp_cpu_notifier
);
399 mutex_lock(&pdev_list_mutex
);
400 list_for_each_entry_safe(p
, n
, &pdev_list
, list
) {
401 platform_device_unregister(p
->pdev
);
405 mutex_unlock(&pdev_list_mutex
);
407 platform_driver_unregister(&coretemp_driver
);
412 static void __exit
coretemp_exit(void)
414 struct pdev_entry
*p
, *n
;
415 #ifdef CONFIG_HOTPLUG_CPU
416 unregister_hotcpu_notifier(&coretemp_cpu_notifier
);
418 mutex_lock(&pdev_list_mutex
);
419 list_for_each_entry_safe(p
, n
, &pdev_list
, list
) {
420 platform_device_unregister(p
->pdev
);
424 mutex_unlock(&pdev_list_mutex
);
425 platform_driver_unregister(&coretemp_driver
);
428 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
429 MODULE_DESCRIPTION("Intel Core temperature monitor");
430 MODULE_LICENSE("GPL");
432 module_init(coretemp_init
)
433 module_exit(coretemp_exit
)