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 class_device *class_dev;
51 struct mutex update_lock;
54 char valid; /* zero until following fields are valid */
55 unsigned long last_updated; /* in jiffies */
61 static struct coretemp_data *coretemp_update_device(struct device *dev);
67 static ssize_t show_name(struct device *dev, struct device_attribute
71 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
72 struct coretemp_data *data = dev_get_drvdata(dev);
74 if (attr->index == SHOW_NAME)
75 ret = sprintf(buf, "%s\n", data->name);
77 ret = sprintf(buf, "Core %d\n", data->id);
81 static ssize_t show_alarm(struct device *dev, struct device_attribute
84 struct coretemp_data *data = coretemp_update_device(dev);
85 /* read the Out-of-spec log, never clear */
86 return sprintf(buf, "%d\n", data->alarm);
89 static ssize_t show_temp(struct device *dev,
90 struct device_attribute *devattr, char *buf)
92 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
93 struct coretemp_data *data = coretemp_update_device(dev);
96 if (attr->index == SHOW_TEMP)
97 err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
99 err = sprintf(buf, "%d\n", data->tjmax);
104 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
106 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
108 static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
109 static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
110 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
112 static struct attribute *coretemp_attributes[] = {
113 &sensor_dev_attr_name.dev_attr.attr,
114 &sensor_dev_attr_temp1_label.dev_attr.attr,
115 &dev_attr_temp1_crit_alarm.attr,
116 &sensor_dev_attr_temp1_input.dev_attr.attr,
117 &sensor_dev_attr_temp1_crit.dev_attr.attr,
121 static const struct attribute_group coretemp_group = {
122 .attrs = coretemp_attributes,
125 static struct coretemp_data *coretemp_update_device(struct device *dev)
127 struct coretemp_data *data = dev_get_drvdata(dev);
129 mutex_lock(&data->update_lock);
131 if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
135 rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
136 data->alarm = (eax >> 5) & 1;
137 /* update only if data has been valid */
138 if (eax & 0x80000000) {
139 data->temp = data->tjmax - (((eax >> 16)
143 dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
145 data->last_updated = jiffies;
148 mutex_unlock(&data->update_lock);
152 static int __devinit coretemp_probe(struct platform_device *pdev)
154 struct coretemp_data *data;
155 struct cpuinfo_x86 *c = &(cpu_data)[pdev->id];
159 if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
161 dev_err(&pdev->dev, "Out of memory\n");
166 data->name = "coretemp";
167 mutex_init(&data->update_lock);
168 /* Tjmax default is 100 degrees C */
169 data->tjmax = 100000;
171 /* test if we can access the THERM_STATUS MSR */
172 err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
175 "Unable to access THERM_STATUS MSR, giving up\n");
179 /* Check if we have problem with errata AE18 of Core processors:
180 Readings might stop update when processor visited too deep sleep,
181 fixed for stepping D0 (6EC).
184 if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
185 /* check for microcode update */
186 rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx);
189 "Errata AE18 not fixed, update BIOS or "
190 "microcode of the CPU!\n");
195 /* Some processors have Tjmax 85 following magic should detect it
196 Intel won't disclose the information without signed NDA, but
197 individuals cannot sign it. Catch(ed) 22.
200 if (((c->x86_model == 0xf) && (c->x86_mask > 3)) ||
201 (c->x86_model == 0xe)) {
202 err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx);
205 "Unable to access MSR 0xEE, Tjmax left at %d "
206 "degrees C\n", data->tjmax/1000);
207 } else if (eax & 0x40000000) {
212 /* Intel says that above should not work for desktop Core2 processors,
213 but it seems to work. There is no other way how get the absolute
214 readings. Warn the user about this. First check if are desktop,
215 bit 50 of MSR_IA32_PLATFORM_ID should be 0.
218 rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
220 if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
221 dev_warn(&pdev->dev, "Using undocumented features, absolute "
222 "temperature might be wrong!\n");
225 platform_set_drvdata(pdev, data);
227 if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
230 data->class_dev = hwmon_device_register(&pdev->dev);
231 if (IS_ERR(data->class_dev)) {
232 err = PTR_ERR(data->class_dev);
233 dev_err(&pdev->dev, "Class registration failed (%d)\n",
241 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
248 static int __devexit coretemp_remove(struct platform_device *pdev)
250 struct coretemp_data *data = platform_get_drvdata(pdev);
252 hwmon_device_unregister(data->class_dev);
253 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
254 platform_set_drvdata(pdev, NULL);
259 static struct platform_driver coretemp_driver = {
261 .owner = THIS_MODULE,
264 .probe = coretemp_probe,
265 .remove = __devexit_p(coretemp_remove),
269 struct list_head list;
270 struct platform_device *pdev;
274 static LIST_HEAD(pdev_list);
275 static DEFINE_MUTEX(pdev_list_mutex);
277 static int __cpuinit coretemp_device_add(unsigned int cpu)
280 struct platform_device *pdev;
281 struct pdev_entry *pdev_entry;
283 pdev = platform_device_alloc(DRVNAME, cpu);
286 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
290 pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
293 goto exit_device_put;
296 err = platform_device_add(pdev);
298 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
300 goto exit_device_free;
303 pdev_entry->pdev = pdev;
304 pdev_entry->cpu = cpu;
305 mutex_lock(&pdev_list_mutex);
306 list_add_tail(&pdev_entry->list, &pdev_list);
307 mutex_unlock(&pdev_list_mutex);
314 platform_device_put(pdev);
319 #ifdef CONFIG_HOTPLUG_CPU
320 void coretemp_device_remove(unsigned int cpu)
322 struct pdev_entry *p, *n;
323 mutex_lock(&pdev_list_mutex);
324 list_for_each_entry_safe(p, n, &pdev_list, list) {
326 platform_device_unregister(p->pdev);
331 mutex_unlock(&pdev_list_mutex);
334 static int coretemp_cpu_callback(struct notifier_block *nfb,
335 unsigned long action, void *hcpu)
337 unsigned int cpu = (unsigned long) hcpu;
341 case CPU_ONLINE_FROZEN:
342 coretemp_device_add(cpu);
345 case CPU_DEAD_FROZEN:
346 coretemp_device_remove(cpu);
352 static struct notifier_block __cpuinitdata coretemp_cpu_notifier = {
353 .notifier_call = coretemp_cpu_callback,
355 #endif /* !CONFIG_HOTPLUG_CPU */
357 static int __init coretemp_init(void)
359 int i, err = -ENODEV;
360 struct pdev_entry *p, *n;
362 /* quick check if we run Intel */
363 if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
366 err = platform_driver_register(&coretemp_driver);
370 for_each_online_cpu(i) {
371 struct cpuinfo_x86 *c = &(cpu_data)[i];
373 /* check if family 6, models e, f */
374 if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
375 !((c->x86_model == 0xe) || (c->x86_model == 0xf))) {
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)