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_ONLINE_FROZEN
:
341 coretemp_device_add(cpu
);
344 case CPU_DEAD_FROZEN
:
345 coretemp_device_remove(cpu
);
351 static struct notifier_block coretemp_cpu_notifier
= {
352 .notifier_call
= coretemp_cpu_callback
,
354 #endif /* !CONFIG_HOTPLUG_CPU */
356 static int __init
coretemp_init(void)
358 int i
, err
= -ENODEV
;
359 struct pdev_entry
*p
, *n
;
361 /* quick check if we run Intel */
362 if (cpu_data
[0].x86_vendor
!= X86_VENDOR_INTEL
)
365 err
= platform_driver_register(&coretemp_driver
);
369 for_each_online_cpu(i
) {
370 struct cpuinfo_x86
*c
= &(cpu_data
)[i
];
372 /* check if family 6, models e, f, 16 */
373 if ((c
->cpuid_level
< 0) || (c
->x86
!= 0x6) ||
374 !((c
->x86_model
== 0xe) || (c
->x86_model
== 0xf) ||
375 (c
->x86_model
== 0x16))) {
377 /* supported CPU not found, but report the unknown
379 if ((c
->x86
== 0x6) && (c
->x86_model
> 0xf))
380 printk(KERN_WARNING DRVNAME
": Unknown CPU "
381 "model %x\n", c
->x86_model
);
385 err
= coretemp_device_add(i
);
387 goto exit_devices_unreg
;
389 if (list_empty(&pdev_list
)) {
391 goto exit_driver_unreg
;
394 #ifdef CONFIG_HOTPLUG_CPU
395 register_hotcpu_notifier(&coretemp_cpu_notifier
);
400 mutex_lock(&pdev_list_mutex
);
401 list_for_each_entry_safe(p
, n
, &pdev_list
, list
) {
402 platform_device_unregister(p
->pdev
);
406 mutex_unlock(&pdev_list_mutex
);
408 platform_driver_unregister(&coretemp_driver
);
413 static void __exit
coretemp_exit(void)
415 struct pdev_entry
*p
, *n
;
416 #ifdef CONFIG_HOTPLUG_CPU
417 unregister_hotcpu_notifier(&coretemp_cpu_notifier
);
419 mutex_lock(&pdev_list_mutex
);
420 list_for_each_entry_safe(p
, n
, &pdev_list
, list
) {
421 platform_device_unregister(p
->pdev
);
425 mutex_unlock(&pdev_list_mutex
);
426 platform_driver_unregister(&coretemp_driver
);
429 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
430 MODULE_DESCRIPTION("Intel Core temperature monitor");
431 MODULE_LICENSE("GPL");
433 module_init(coretemp_init
)
434 module_exit(coretemp_exit
)