HWMON: coretemp, suspend fix
[linux-2.6] / 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 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;
59 };
60
61 /*
62  * Sysfs stuff
63  */
64
65 static ssize_t show_name(struct device *dev, struct device_attribute
66                           *devattr, char *buf)
67 {
68         int ret;
69         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
70         struct coretemp_data *data = dev_get_drvdata(dev);
71
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;
77 }
78
79 static ssize_t show_alarm(struct device *dev, struct device_attribute
80                           *devattr, char *buf)
81 {
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);
85 }
86
87 static ssize_t show_temp(struct device *dev,
88                          struct device_attribute *devattr, char *buf)
89 {
90         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
91         struct coretemp_data *data = coretemp_update_device(dev);
92         int err;
93
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);
98
99         return err;
100 }
101
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);
109
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
117 };
118
119 static const struct attribute_group coretemp_group = {
120         .attrs = coretemp_attributes,
121 };
122
123 static struct coretemp_data *coretemp_update_device(struct device *dev)
124 {
125         struct coretemp_data *data = dev_get_drvdata(dev);
126
127         mutex_lock(&data->update_lock);
128
129         if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
130                 u32 eax, edx;
131
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);
142                 }
143                 data->last_updated = jiffies;
144         }
145
146         mutex_unlock(&data->update_lock);
147         return data;
148 }
149
150 static int __devinit coretemp_probe(struct platform_device *pdev)
151 {
152         struct coretemp_data *data;
153         struct cpuinfo_x86 *c = &cpu_data(pdev->id);
154         int err;
155         u32 eax, edx;
156
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;
161         }
162
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;
168
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;
175         }
176
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).
180         */
181
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;
191                 }
192         }
193
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.
197         */
198
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;
208                 }
209         }
210
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.
215         */
216
217         rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
218
219         if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
220                 dev_warn(&pdev->dev, "Using undocumented features, absolute "
221                          "temperature might be wrong!\n");
222         }
223
224         platform_set_drvdata(pdev, data);
225
226         if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
227                 goto exit_free;
228
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;
235         }
236
237         return 0;
238
239 exit_class:
240         sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
241 exit_free:
242         kfree(data);
243 exit:
244         return err;
245 }
246
247 static int __devexit coretemp_remove(struct platform_device *pdev)
248 {
249         struct coretemp_data *data = platform_get_drvdata(pdev);
250
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;
256 }
257
258 static struct platform_driver coretemp_driver = {
259         .driver = {
260                 .owner = THIS_MODULE,
261                 .name = DRVNAME,
262         },
263         .probe = coretemp_probe,
264         .remove = __devexit_p(coretemp_remove),
265 };
266
267 struct pdev_entry {
268         struct list_head list;
269         struct platform_device *pdev;
270         unsigned int cpu;
271 };
272
273 static LIST_HEAD(pdev_list);
274 static DEFINE_MUTEX(pdev_list_mutex);
275
276 static int __cpuinit coretemp_device_add(unsigned int cpu)
277 {
278         int err;
279         struct platform_device *pdev;
280         struct pdev_entry *pdev_entry;
281
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;
287         }
288
289         pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
290         if (!pdev_entry) {
291                 err = -ENOMEM;
292                 goto exit_device_put;
293         }
294
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;
300         }
301
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);
307
308         return 0;
309
310 exit_device_free:
311         kfree(pdev_entry);
312 exit_device_put:
313         platform_device_put(pdev);
314 exit:
315         return err;
316 }
317
318 #ifdef CONFIG_HOTPLUG_CPU
319 static void coretemp_device_remove(unsigned int cpu)
320 {
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);
328                 }
329         }
330         mutex_unlock(&pdev_list_mutex);
331 }
332
333 static int coretemp_cpu_callback(struct notifier_block *nfb,
334                                  unsigned long action, void *hcpu)
335 {
336         unsigned int cpu = (unsigned long) hcpu;
337
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;
346         }
347         return NOTIFY_OK;
348 }
349
350 static struct notifier_block coretemp_cpu_notifier = {
351         .notifier_call = coretemp_cpu_callback,
352 };
353 #endif                          /* !CONFIG_HOTPLUG_CPU */
354
355 static int __init coretemp_init(void)
356 {
357         int i, err = -ENODEV;
358         struct pdev_entry *p, *n;
359
360         /* quick check if we run Intel */
361         if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
362                 goto exit;
363
364         err = platform_driver_register(&coretemp_driver);
365         if (err)
366                 goto exit;
367
368         for_each_online_cpu(i) {
369                 struct cpuinfo_x86 *c = &cpu_data(i);
370
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))) {
375
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;
382                 }
383
384                 err = coretemp_device_add(i);
385                 if (err)
386                         goto exit_devices_unreg;
387         }
388         if (list_empty(&pdev_list)) {
389                 err = -ENODEV;
390                 goto exit_driver_unreg;
391         }
392
393 #ifdef CONFIG_HOTPLUG_CPU
394         register_hotcpu_notifier(&coretemp_cpu_notifier);
395 #endif
396         return 0;
397
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);
404         }
405         mutex_unlock(&pdev_list_mutex);
406 exit_driver_unreg:
407         platform_driver_unregister(&coretemp_driver);
408 exit:
409         return err;
410 }
411
412 static void __exit coretemp_exit(void)
413 {
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);
423         }
424         mutex_unlock(&pdev_list_mutex);
425         platform_driver_unregister(&coretemp_driver);
426 }
427
428 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
429 MODULE_DESCRIPTION("Intel Core temperature monitor");
430 MODULE_LICENSE("GPL");
431
432 module_init(coretemp_init)
433 module_exit(coretemp_exit)