0328382df8fae74a3edf1e0560404cd8f6f3f18a
[sfrench/cifs-2.6.git] / drivers / hwmon / coretemp.c
1 /*
2  * coretemp.c - Linux kernel module for hardware monitoring
3  *
4  * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
5  *
6  * Inspired from many hwmon drivers
7  *
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.
11  *
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.
16  *
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.
21  */
22
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>
38
39 #define DRVNAME "coretemp"
40
41 typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW;
42
43 /*
44  * Functions declaration
45  */
46
47 static struct coretemp_data *coretemp_update_device(struct device *dev);
48
49 struct coretemp_data {
50         struct class_device *class_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;
59 };
60
61 static struct coretemp_data *coretemp_update_device(struct device *dev);
62
63 /*
64  * Sysfs stuff
65  */
66
67 static ssize_t show_name(struct device *dev, struct device_attribute
68                           *devattr, char *buf)
69 {
70         int ret;
71         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
72         struct coretemp_data *data = dev_get_drvdata(dev);
73
74         if (attr->index == SHOW_NAME)
75                 ret = sprintf(buf, "%s\n", data->name);
76         else    /* show label */
77                 ret = sprintf(buf, "Core %d\n", data->id);
78         return ret;
79 }
80
81 static ssize_t show_alarm(struct device *dev, struct device_attribute
82                           *devattr, char *buf)
83 {
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);
87 }
88
89 static ssize_t show_temp(struct device *dev,
90                          struct device_attribute *devattr, char *buf)
91 {
92         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
93         struct coretemp_data *data = coretemp_update_device(dev);
94         int err;
95
96         if (attr->index == SHOW_TEMP)
97                 err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
98         else
99                 err = sprintf(buf, "%d\n", data->tjmax);
100
101         return err;
102 }
103
104 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
105                           SHOW_TEMP);
106 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
107                           SHOW_TJMAX);
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);
111
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,
118         NULL
119 };
120
121 static const struct attribute_group coretemp_group = {
122         .attrs = coretemp_attributes,
123 };
124
125 static struct coretemp_data *coretemp_update_device(struct device *dev)
126 {
127         struct coretemp_data *data = dev_get_drvdata(dev);
128
129         mutex_lock(&data->update_lock);
130
131         if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
132                 u32 eax, edx;
133
134                 data->valid = 0;
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)
140                                                         & 0x7f) * 1000);
141                         data->valid = 1;
142                 } else {
143                         dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
144                 }
145                 data->last_updated = jiffies;
146         }
147
148         mutex_unlock(&data->update_lock);
149         return data;
150 }
151
152 static int __devinit coretemp_probe(struct platform_device *pdev)
153 {
154         struct coretemp_data *data;
155         struct cpuinfo_x86 *c = &(cpu_data)[pdev->id];
156         int err;
157         u32 eax, edx;
158
159         if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
160                 err = -ENOMEM;
161                 dev_err(&pdev->dev, "Out of memory\n");
162                 goto exit;
163         }
164
165         data->id = pdev->id;
166         data->name = "coretemp";
167         mutex_init(&data->update_lock);
168         /* Tjmax default is 100 degrees C */
169         data->tjmax = 100000;
170
171         /* test if we can access the THERM_STATUS MSR */
172         err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
173         if (err) {
174                 dev_err(&pdev->dev,
175                         "Unable to access THERM_STATUS MSR, giving up\n");
176                 goto exit_free;
177         }
178
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).
182         */
183
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);
187                 if (edx < 0x39) {
188                         dev_err(&pdev->dev,
189                                 "Errata AE18 not fixed, update BIOS or "
190                                 "microcode of the CPU!\n");
191                         goto exit_free;
192                 }
193         }
194
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.
198         */
199
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);
203                 if (err) {
204                         dev_warn(&pdev->dev,
205                                  "Unable to access MSR 0xEE, Tjmax left at %d "
206                                  "degrees C\n", data->tjmax/1000);
207                 } else if (eax & 0x40000000) {
208                         data->tjmax = 85000;
209                 }
210         }
211
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.
216         */
217
218         rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
219
220         if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
221                 dev_warn(&pdev->dev, "Using undocumented features, absolute "
222                          "temperature might be wrong!\n");
223         }
224
225         platform_set_drvdata(pdev, data);
226
227         if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
228                 goto exit_free;
229
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",
234                         err);
235                 goto exit_class;
236         }
237
238         return 0;
239
240 exit_class:
241         sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
242 exit_free:
243         kfree(data);
244 exit:
245         return err;
246 }
247
248 static int __devexit coretemp_remove(struct platform_device *pdev)
249 {
250         struct coretemp_data *data = platform_get_drvdata(pdev);
251
252         hwmon_device_unregister(data->class_dev);
253         sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
254         platform_set_drvdata(pdev, NULL);
255         kfree(data);
256         return 0;
257 }
258
259 static struct platform_driver coretemp_driver = {
260         .driver = {
261                 .owner = THIS_MODULE,
262                 .name = DRVNAME,
263         },
264         .probe = coretemp_probe,
265         .remove = __devexit_p(coretemp_remove),
266 };
267
268 struct pdev_entry {
269         struct list_head list;
270         struct platform_device *pdev;
271         unsigned int cpu;
272 };
273
274 static LIST_HEAD(pdev_list);
275 static DEFINE_MUTEX(pdev_list_mutex);
276
277 static int __cpuinit coretemp_device_add(unsigned int cpu)
278 {
279         int err;
280         struct platform_device *pdev;
281         struct pdev_entry *pdev_entry;
282
283         pdev = platform_device_alloc(DRVNAME, cpu);
284         if (!pdev) {
285                 err = -ENOMEM;
286                 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
287                 goto exit;
288         }
289
290         pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
291         if (!pdev_entry) {
292                 err = -ENOMEM;
293                 goto exit_device_put;
294         }
295
296         err = platform_device_add(pdev);
297         if (err) {
298                 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
299                        err);
300                 goto exit_device_free;
301         }
302
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);
308
309         return 0;
310
311 exit_device_free:
312         kfree(pdev_entry);
313 exit_device_put:
314         platform_device_put(pdev);
315 exit:
316         return err;
317 }
318
319 #ifdef CONFIG_HOTPLUG_CPU
320 void coretemp_device_remove(unsigned int cpu)
321 {
322         struct pdev_entry *p, *n;
323         mutex_lock(&pdev_list_mutex);
324         list_for_each_entry_safe(p, n, &pdev_list, list) {
325                 if (p->cpu == cpu) {
326                         platform_device_unregister(p->pdev);
327                         list_del(&p->list);
328                         kfree(p);
329                 }
330         }
331         mutex_unlock(&pdev_list_mutex);
332 }
333
334 static int coretemp_cpu_callback(struct notifier_block *nfb,
335                                  unsigned long action, void *hcpu)
336 {
337         unsigned int cpu = (unsigned long) hcpu;
338
339         switch (action) {
340         case CPU_ONLINE:
341         case CPU_ONLINE_FROZEN:
342                 coretemp_device_add(cpu);
343                 break;
344         case CPU_DEAD:
345         case CPU_DEAD_FROZEN:
346                 coretemp_device_remove(cpu);
347                 break;
348         }
349         return NOTIFY_OK;
350 }
351
352 static struct notifier_block __cpuinitdata coretemp_cpu_notifier = {
353         .notifier_call = coretemp_cpu_callback,
354 };
355 #endif                          /* !CONFIG_HOTPLUG_CPU */
356
357 static int __init coretemp_init(void)
358 {
359         int i, err = -ENODEV;
360         struct pdev_entry *p, *n;
361
362         /* quick check if we run Intel */
363         if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
364                 goto exit;
365
366         err = platform_driver_register(&coretemp_driver);
367         if (err)
368                 goto exit;
369
370         for_each_online_cpu(i) {
371                 struct cpuinfo_x86 *c = &(cpu_data)[i];
372
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))) {
376
377                         /* supported CPU not found, but report the unknown
378                            family 6 CPU */
379                         if ((c->x86 == 0x6) && (c->x86_model > 0xf))
380                                 printk(KERN_WARNING DRVNAME ": Unknown CPU "
381                                         "model %x\n", c->x86_model);
382                         continue;
383                 }
384
385                 err = coretemp_device_add(i);
386                 if (err)
387                         goto exit_devices_unreg;
388         }
389         if (list_empty(&pdev_list)) {
390                 err = -ENODEV;
391                 goto exit_driver_unreg;
392         }
393
394 #ifdef CONFIG_HOTPLUG_CPU
395         register_hotcpu_notifier(&coretemp_cpu_notifier);
396 #endif
397         return 0;
398
399 exit_devices_unreg:
400         mutex_lock(&pdev_list_mutex);
401         list_for_each_entry_safe(p, n, &pdev_list, list) {
402                 platform_device_unregister(p->pdev);
403                 list_del(&p->list);
404                 kfree(p);
405         }
406         mutex_unlock(&pdev_list_mutex);
407 exit_driver_unreg:
408         platform_driver_unregister(&coretemp_driver);
409 exit:
410         return err;
411 }
412
413 static void __exit coretemp_exit(void)
414 {
415         struct pdev_entry *p, *n;
416 #ifdef CONFIG_HOTPLUG_CPU
417         unregister_hotcpu_notifier(&coretemp_cpu_notifier);
418 #endif
419         mutex_lock(&pdev_list_mutex);
420         list_for_each_entry_safe(p, n, &pdev_list, list) {
421                 platform_device_unregister(p->pdev);
422                 list_del(&p->list);
423                 kfree(p);
424         }
425         mutex_unlock(&pdev_list_mutex);
426         platform_driver_unregister(&coretemp_driver);
427 }
428
429 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
430 MODULE_DESCRIPTION("Intel Core temperature monitor");
431 MODULE_LICENSE("GPL");
432
433 module_init(coretemp_init)
434 module_exit(coretemp_exit)