[MIPS] Cacheops.h: Fix typo.
[linux-2.6/linux-2.6-openrd.git] / drivers / hwmon / coretemp.c
blob3ee60d26e3a2e5cbad5e08a6c83353059f43a524
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 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;
52 const char *name;
53 u32 id;
54 char valid; /* zero until following fields are valid */
55 unsigned long last_updated; /* in jiffies */
56 int temp;
57 int tjmax;
58 u8 alarm;
62 * Sysfs stuff
65 static ssize_t show_name(struct device *dev, struct device_attribute
66 *devattr, char *buf)
68 int ret;
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);
74 else /* show label */
75 ret = sprintf(buf, "Core %d\n", data->id);
76 return ret;
79 static ssize_t show_alarm(struct device *dev, struct device_attribute
80 *devattr, char *buf)
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);
92 int err;
94 if (attr->index == SHOW_TEMP)
95 err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
96 else
97 err = sprintf(buf, "%d\n", data->tjmax);
99 return err;
102 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
103 SHOW_TEMP);
104 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
105 SHOW_TJMAX);
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,
116 NULL
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)) {
130 u32 eax, edx;
132 data->valid = 0;
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)
138 & 0x7f) * 1000);
139 data->valid = 1;
140 } else {
141 dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
143 data->last_updated = jiffies;
146 mutex_unlock(&data->update_lock);
147 return data;
150 static int __devinit coretemp_probe(struct platform_device *pdev)
152 struct coretemp_data *data;
153 struct cpuinfo_x86 *c = &cpu_data(pdev->id);
154 int err;
155 u32 eax, edx;
157 if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
158 err = -ENOMEM;
159 dev_err(&pdev->dev, "Out of memory\n");
160 goto exit;
163 data->id = pdev->id;
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);
171 if (err) {
172 dev_err(&pdev->dev,
173 "Unable to access THERM_STATUS MSR, giving up\n");
174 goto exit_free;
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);
185 if (edx < 0x39) {
186 err = -ENODEV;
187 dev_err(&pdev->dev,
188 "Errata AE18 not fixed, update BIOS or "
189 "microcode of the CPU!\n");
190 goto exit_free;
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);
202 if (err) {
203 dev_warn(&pdev->dev,
204 "Unable to access MSR 0xEE, Tjmax left at %d "
205 "degrees C\n", data->tjmax/1000);
206 } else if (eax & 0x40000000) {
207 data->tjmax = 85000;
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)))
227 goto exit_free;
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",
233 err);
234 goto exit_class;
237 return 0;
239 exit_class:
240 sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
241 exit_free:
242 kfree(data);
243 exit:
244 return err;
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);
254 kfree(data);
255 return 0;
258 static struct platform_driver coretemp_driver = {
259 .driver = {
260 .owner = THIS_MODULE,
261 .name = DRVNAME,
263 .probe = coretemp_probe,
264 .remove = __devexit_p(coretemp_remove),
267 struct pdev_entry {
268 struct list_head list;
269 struct platform_device *pdev;
270 unsigned int cpu;
273 static LIST_HEAD(pdev_list);
274 static DEFINE_MUTEX(pdev_list_mutex);
276 static int __cpuinit coretemp_device_add(unsigned int cpu)
278 int err;
279 struct platform_device *pdev;
280 struct pdev_entry *pdev_entry;
282 pdev = platform_device_alloc(DRVNAME, cpu);
283 if (!pdev) {
284 err = -ENOMEM;
285 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
286 goto exit;
289 pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
290 if (!pdev_entry) {
291 err = -ENOMEM;
292 goto exit_device_put;
295 err = platform_device_add(pdev);
296 if (err) {
297 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
298 err);
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);
308 return 0;
310 exit_device_free:
311 kfree(pdev_entry);
312 exit_device_put:
313 platform_device_put(pdev);
314 exit:
315 return err;
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) {
324 if (p->cpu == cpu) {
325 platform_device_unregister(p->pdev);
326 list_del(&p->list);
327 kfree(p);
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;
338 switch (action) {
339 case CPU_ONLINE:
340 case CPU_DOWN_FAILED:
341 coretemp_device_add(cpu);
342 break;
343 case CPU_DOWN_PREPARE:
344 coretemp_device_remove(cpu);
345 break;
347 return NOTIFY_OK;
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)
362 goto exit;
364 err = platform_driver_register(&coretemp_driver);
365 if (err)
366 goto exit;
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
377 family 6 CPU */
378 if ((c->x86 == 0x6) && (c->x86_model > 0xf))
379 printk(KERN_WARNING DRVNAME ": Unknown CPU "
380 "model %x\n", c->x86_model);
381 continue;
384 err = coretemp_device_add(i);
385 if (err)
386 goto exit_devices_unreg;
388 if (list_empty(&pdev_list)) {
389 err = -ENODEV;
390 goto exit_driver_unreg;
393 #ifdef CONFIG_HOTPLUG_CPU
394 register_hotcpu_notifier(&coretemp_cpu_notifier);
395 #endif
396 return 0;
398 exit_devices_unreg:
399 mutex_lock(&pdev_list_mutex);
400 list_for_each_entry_safe(p, n, &pdev_list, list) {
401 platform_device_unregister(p->pdev);
402 list_del(&p->list);
403 kfree(p);
405 mutex_unlock(&pdev_list_mutex);
406 exit_driver_unreg:
407 platform_driver_unregister(&coretemp_driver);
408 exit:
409 return err;
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);
417 #endif
418 mutex_lock(&pdev_list_mutex);
419 list_for_each_entry_safe(p, n, &pdev_list, list) {
420 platform_device_unregister(p->pdev);
421 list_del(&p->list);
422 kfree(p);
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)