Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / drivers / hwmon / coretemp.c
blob8815223ecd4386a59ef5ea617b5e0111ca47c28f
1 /*
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
20 * 02110-1301 USA.
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>
36 #include <asm/msr.h>
37 #include <asm/processor.h>
39 #define DRVNAME "coretemp"
41 <<<<<<< HEAD:drivers/hwmon/coretemp.c
42 typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW;
43 =======
44 typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL,
45 SHOW_NAME } SHOW;
46 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
49 * Functions declaration
52 static struct coretemp_data *coretemp_update_device(struct device *dev);
54 struct coretemp_data {
55 struct device *hwmon_dev;
56 struct mutex update_lock;
57 const char *name;
58 u32 id;
59 char valid; /* zero until following fields are valid */
60 unsigned long last_updated; /* in jiffies */
61 int temp;
62 int tjmax;
63 <<<<<<< HEAD:drivers/hwmon/coretemp.c
64 =======
65 int ttarget;
66 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
67 u8 alarm;
71 * Sysfs stuff
74 static ssize_t show_name(struct device *dev, struct device_attribute
75 *devattr, char *buf)
77 int ret;
78 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
79 struct coretemp_data *data = dev_get_drvdata(dev);
81 if (attr->index == SHOW_NAME)
82 ret = sprintf(buf, "%s\n", data->name);
83 else /* show label */
84 ret = sprintf(buf, "Core %d\n", data->id);
85 return ret;
88 static ssize_t show_alarm(struct device *dev, struct device_attribute
89 *devattr, char *buf)
91 struct coretemp_data *data = coretemp_update_device(dev);
92 /* read the Out-of-spec log, never clear */
93 return sprintf(buf, "%d\n", data->alarm);
96 static ssize_t show_temp(struct device *dev,
97 struct device_attribute *devattr, char *buf)
99 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
100 struct coretemp_data *data = coretemp_update_device(dev);
101 int err;
103 if (attr->index == SHOW_TEMP)
104 err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
105 <<<<<<< HEAD:drivers/hwmon/coretemp.c
106 else
107 =======
108 else if (attr->index == SHOW_TJMAX)
109 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
110 err = sprintf(buf, "%d\n", data->tjmax);
111 <<<<<<< HEAD:drivers/hwmon/coretemp.c
113 =======
114 else
115 err = sprintf(buf, "%d\n", data->ttarget);
116 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
117 return err;
120 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
121 SHOW_TEMP);
122 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
123 SHOW_TJMAX);
124 <<<<<<< HEAD:drivers/hwmon/coretemp.c
125 =======
126 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL,
127 SHOW_TTARGET);
128 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
129 static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
130 static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
131 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
133 static struct attribute *coretemp_attributes[] = {
134 &sensor_dev_attr_name.dev_attr.attr,
135 &sensor_dev_attr_temp1_label.dev_attr.attr,
136 &dev_attr_temp1_crit_alarm.attr,
137 &sensor_dev_attr_temp1_input.dev_attr.attr,
138 &sensor_dev_attr_temp1_crit.dev_attr.attr,
139 NULL
142 static const struct attribute_group coretemp_group = {
143 .attrs = coretemp_attributes,
146 static struct coretemp_data *coretemp_update_device(struct device *dev)
148 struct coretemp_data *data = dev_get_drvdata(dev);
150 mutex_lock(&data->update_lock);
152 if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
153 u32 eax, edx;
155 data->valid = 0;
156 rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
157 data->alarm = (eax >> 5) & 1;
158 /* update only if data has been valid */
159 if (eax & 0x80000000) {
160 data->temp = data->tjmax - (((eax >> 16)
161 & 0x7f) * 1000);
162 data->valid = 1;
163 } else {
164 dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
166 data->last_updated = jiffies;
169 mutex_unlock(&data->update_lock);
170 return data;
173 <<<<<<< HEAD:drivers/hwmon/coretemp.c
174 =======
175 static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
177 /* The 100C is default for both mobile and non mobile CPUs */
179 int tjmax = 100000;
180 int ismobile = 1;
181 int err;
182 u32 eax, edx;
184 /* Early chips have no MSR for TjMax */
186 if ((c->x86_model == 0xf) && (c->x86_mask < 4)) {
187 ismobile = 0;
190 if ((c->x86_model > 0xe) && (ismobile)) {
192 /* Now we can detect the mobile CPU using Intel provided table
193 http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
194 For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU
197 err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx);
198 if (err) {
199 dev_warn(dev,
200 "Unable to access MSR 0x17, assuming desktop"
201 " CPU\n");
202 ismobile = 0;
203 } else if (!(eax & 0x10000000)) {
204 ismobile = 0;
208 if (ismobile) {
210 err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx);
211 if (err) {
212 dev_warn(dev,
213 "Unable to access MSR 0xEE, for Tjmax, left"
214 " at default");
215 } else if (eax & 0x40000000) {
216 tjmax = 85000;
218 } else {
219 dev_warn(dev, "Using relative temperature scale!\n");
222 return tjmax;
225 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
226 static int __devinit coretemp_probe(struct platform_device *pdev)
228 struct coretemp_data *data;
229 struct cpuinfo_x86 *c = &cpu_data(pdev->id);
230 int err;
231 u32 eax, edx;
233 if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
234 err = -ENOMEM;
235 dev_err(&pdev->dev, "Out of memory\n");
236 goto exit;
239 data->id = pdev->id;
240 data->name = "coretemp";
241 mutex_init(&data->update_lock);
242 <<<<<<< HEAD:drivers/hwmon/coretemp.c
243 /* Tjmax default is 100 degrees C */
244 data->tjmax = 100000;
245 =======
246 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
248 /* test if we can access the THERM_STATUS MSR */
249 err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
250 if (err) {
251 dev_err(&pdev->dev,
252 "Unable to access THERM_STATUS MSR, giving up\n");
253 goto exit_free;
256 /* Check if we have problem with errata AE18 of Core processors:
257 Readings might stop update when processor visited too deep sleep,
258 fixed for stepping D0 (6EC).
261 if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
262 /* check for microcode update */
263 rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx);
264 if (edx < 0x39) {
265 err = -ENODEV;
266 dev_err(&pdev->dev,
267 "Errata AE18 not fixed, update BIOS or "
268 "microcode of the CPU!\n");
269 goto exit_free;
273 <<<<<<< HEAD:drivers/hwmon/coretemp.c
274 /* Some processors have Tjmax 85 following magic should detect it
275 Intel won't disclose the information without signed NDA, but
276 individuals cannot sign it. Catch(ed) 22.
278 =======
279 data->tjmax = adjust_tjmax(c, data->id, &pdev->dev);
280 platform_set_drvdata(pdev, data);
281 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
283 <<<<<<< HEAD:drivers/hwmon/coretemp.c
284 if (((c->x86_model == 0xf) && (c->x86_mask > 3)) ||
285 (c->x86_model == 0xe)) {
286 err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx);
287 =======
288 /* read the still undocumented IA32_TEMPERATURE_TARGET it exists
289 on older CPUs but not in this register */
291 if (c->x86_model > 0xe) {
292 err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
293 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
294 if (err) {
295 <<<<<<< HEAD:drivers/hwmon/coretemp.c
296 dev_warn(&pdev->dev,
297 "Unable to access MSR 0xEE, Tjmax left at %d "
298 "degrees C\n", data->tjmax/1000);
299 } else if (eax & 0x40000000) {
300 data->tjmax = 85000;
301 =======
302 dev_warn(&pdev->dev, "Unable to read"
303 " IA32_TEMPERATURE_TARGET MSR\n");
304 } else {
305 data->ttarget = data->tjmax -
306 (((eax >> 8) & 0xff) * 1000);
307 err = device_create_file(&pdev->dev,
308 &sensor_dev_attr_temp1_max.dev_attr);
309 if (err)
310 goto exit_free;
311 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
315 <<<<<<< HEAD:drivers/hwmon/coretemp.c
316 /* Intel says that above should not work for desktop Core2 processors,
317 but it seems to work. There is no other way how get the absolute
318 readings. Warn the user about this. First check if are desktop,
319 bit 50 of MSR_IA32_PLATFORM_ID should be 0.
322 rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
324 if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
325 dev_warn(&pdev->dev, "Using undocumented features, absolute "
326 "temperature might be wrong!\n");
329 platform_set_drvdata(pdev, data);
331 =======
332 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
333 if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
334 <<<<<<< HEAD:drivers/hwmon/coretemp.c
335 goto exit_free;
336 =======
337 goto exit_dev;
338 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
340 data->hwmon_dev = hwmon_device_register(&pdev->dev);
341 if (IS_ERR(data->hwmon_dev)) {
342 err = PTR_ERR(data->hwmon_dev);
343 dev_err(&pdev->dev, "Class registration failed (%d)\n",
344 err);
345 goto exit_class;
348 return 0;
350 exit_class:
351 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
352 <<<<<<< HEAD:drivers/hwmon/coretemp.c
353 =======
354 exit_dev:
355 device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
356 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
357 exit_free:
358 kfree(data);
359 exit:
360 return err;
363 static int __devexit coretemp_remove(struct platform_device *pdev)
365 struct coretemp_data *data = platform_get_drvdata(pdev);
367 hwmon_device_unregister(data->hwmon_dev);
368 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
369 <<<<<<< HEAD:drivers/hwmon/coretemp.c
370 =======
371 device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
372 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
373 platform_set_drvdata(pdev, NULL);
374 kfree(data);
375 return 0;
378 static struct platform_driver coretemp_driver = {
379 .driver = {
380 .owner = THIS_MODULE,
381 .name = DRVNAME,
383 .probe = coretemp_probe,
384 .remove = __devexit_p(coretemp_remove),
387 struct pdev_entry {
388 struct list_head list;
389 struct platform_device *pdev;
390 unsigned int cpu;
393 static LIST_HEAD(pdev_list);
394 static DEFINE_MUTEX(pdev_list_mutex);
396 static int __cpuinit coretemp_device_add(unsigned int cpu)
398 int err;
399 struct platform_device *pdev;
400 struct pdev_entry *pdev_entry;
402 pdev = platform_device_alloc(DRVNAME, cpu);
403 if (!pdev) {
404 err = -ENOMEM;
405 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
406 goto exit;
409 pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
410 if (!pdev_entry) {
411 err = -ENOMEM;
412 goto exit_device_put;
415 err = platform_device_add(pdev);
416 if (err) {
417 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
418 err);
419 goto exit_device_free;
422 pdev_entry->pdev = pdev;
423 pdev_entry->cpu = cpu;
424 mutex_lock(&pdev_list_mutex);
425 list_add_tail(&pdev_entry->list, &pdev_list);
426 mutex_unlock(&pdev_list_mutex);
428 return 0;
430 exit_device_free:
431 kfree(pdev_entry);
432 exit_device_put:
433 platform_device_put(pdev);
434 exit:
435 return err;
438 #ifdef CONFIG_HOTPLUG_CPU
439 static void coretemp_device_remove(unsigned int cpu)
441 struct pdev_entry *p, *n;
442 mutex_lock(&pdev_list_mutex);
443 list_for_each_entry_safe(p, n, &pdev_list, list) {
444 if (p->cpu == cpu) {
445 platform_device_unregister(p->pdev);
446 list_del(&p->list);
447 kfree(p);
450 mutex_unlock(&pdev_list_mutex);
453 <<<<<<< HEAD:drivers/hwmon/coretemp.c
454 static int coretemp_cpu_callback(struct notifier_block *nfb,
455 =======
456 static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb,
457 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
458 unsigned long action, void *hcpu)
460 unsigned int cpu = (unsigned long) hcpu;
462 switch (action) {
463 case CPU_ONLINE:
464 case CPU_DOWN_FAILED:
465 coretemp_device_add(cpu);
466 break;
467 case CPU_DOWN_PREPARE:
468 coretemp_device_remove(cpu);
469 break;
471 return NOTIFY_OK;
474 <<<<<<< HEAD:drivers/hwmon/coretemp.c
475 static struct notifier_block coretemp_cpu_notifier = {
476 =======
477 static struct notifier_block coretemp_cpu_notifier __refdata = {
478 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
479 .notifier_call = coretemp_cpu_callback,
481 #endif /* !CONFIG_HOTPLUG_CPU */
483 static int __init coretemp_init(void)
485 int i, err = -ENODEV;
486 struct pdev_entry *p, *n;
488 /* quick check if we run Intel */
489 if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
490 goto exit;
492 err = platform_driver_register(&coretemp_driver);
493 if (err)
494 goto exit;
496 for_each_online_cpu(i) {
497 struct cpuinfo_x86 *c = &cpu_data(i);
499 <<<<<<< HEAD:drivers/hwmon/coretemp.c
500 /* check if family 6, models e, f, 16 */
501 =======
502 /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */
503 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
504 if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
505 !((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
506 <<<<<<< HEAD:drivers/hwmon/coretemp.c
507 (c->x86_model == 0x16))) {
508 =======
509 (c->x86_model == 0x16) || (c->x86_model == 0x17))) {
510 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/hwmon/coretemp.c
512 /* supported CPU not found, but report the unknown
513 family 6 CPU */
514 if ((c->x86 == 0x6) && (c->x86_model > 0xf))
515 printk(KERN_WARNING DRVNAME ": Unknown CPU "
516 "model %x\n", c->x86_model);
517 continue;
520 err = coretemp_device_add(i);
521 if (err)
522 goto exit_devices_unreg;
524 if (list_empty(&pdev_list)) {
525 err = -ENODEV;
526 goto exit_driver_unreg;
529 #ifdef CONFIG_HOTPLUG_CPU
530 register_hotcpu_notifier(&coretemp_cpu_notifier);
531 #endif
532 return 0;
534 exit_devices_unreg:
535 mutex_lock(&pdev_list_mutex);
536 list_for_each_entry_safe(p, n, &pdev_list, list) {
537 platform_device_unregister(p->pdev);
538 list_del(&p->list);
539 kfree(p);
541 mutex_unlock(&pdev_list_mutex);
542 exit_driver_unreg:
543 platform_driver_unregister(&coretemp_driver);
544 exit:
545 return err;
548 static void __exit coretemp_exit(void)
550 struct pdev_entry *p, *n;
551 #ifdef CONFIG_HOTPLUG_CPU
552 unregister_hotcpu_notifier(&coretemp_cpu_notifier);
553 #endif
554 mutex_lock(&pdev_list_mutex);
555 list_for_each_entry_safe(p, n, &pdev_list, list) {
556 platform_device_unregister(p->pdev);
557 list_del(&p->list);
558 kfree(p);
560 mutex_unlock(&pdev_list_mutex);
561 platform_driver_unregister(&coretemp_driver);
564 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
565 MODULE_DESCRIPTION("Intel Core temperature monitor");
566 MODULE_LICENSE("GPL");
568 module_init(coretemp_init)
569 module_exit(coretemp_exit)