hwmon: (coretemp) fix section mismatch warning
[safe/jmp/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_TTARGET, SHOW_LABEL,
42                 SHOW_NAME } SHOW;
43
44 /*
45  * Functions declaration
46  */
47
48 static struct coretemp_data *coretemp_update_device(struct device *dev);
49
50 struct coretemp_data {
51         struct device *hwmon_dev;
52         struct mutex update_lock;
53         const char *name;
54         u32 id;
55         char valid;             /* zero until following fields are valid */
56         unsigned long last_updated;     /* in jiffies */
57         int temp;
58         int tjmax;
59         int ttarget;
60         u8 alarm;
61 };
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 if (attr->index == SHOW_TJMAX)
99                 err = sprintf(buf, "%d\n", data->tjmax);
100         else
101                 err = sprintf(buf, "%d\n", data->ttarget);
102         return err;
103 }
104
105 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
106                           SHOW_TEMP);
107 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
108                           SHOW_TJMAX);
109 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL,
110                           SHOW_TTARGET);
111 static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
112 static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
113 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
114
115 static struct attribute *coretemp_attributes[] = {
116         &sensor_dev_attr_name.dev_attr.attr,
117         &sensor_dev_attr_temp1_label.dev_attr.attr,
118         &dev_attr_temp1_crit_alarm.attr,
119         &sensor_dev_attr_temp1_input.dev_attr.attr,
120         &sensor_dev_attr_temp1_crit.dev_attr.attr,
121         NULL
122 };
123
124 static const struct attribute_group coretemp_group = {
125         .attrs = coretemp_attributes,
126 };
127
128 static struct coretemp_data *coretemp_update_device(struct device *dev)
129 {
130         struct coretemp_data *data = dev_get_drvdata(dev);
131
132         mutex_lock(&data->update_lock);
133
134         if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
135                 u32 eax, edx;
136
137                 data->valid = 0;
138                 rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
139                 data->alarm = (eax >> 5) & 1;
140                 /* update only if data has been valid */
141                 if (eax & 0x80000000) {
142                         data->temp = data->tjmax - (((eax >> 16)
143                                                         & 0x7f) * 1000);
144                         data->valid = 1;
145                 } else {
146                         dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
147                 }
148                 data->last_updated = jiffies;
149         }
150
151         mutex_unlock(&data->update_lock);
152         return data;
153 }
154
155 static int __devinit coretemp_probe(struct platform_device *pdev)
156 {
157         struct coretemp_data *data;
158         struct cpuinfo_x86 *c = &cpu_data(pdev->id);
159         int err;
160         u32 eax, edx;
161
162         if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
163                 err = -ENOMEM;
164                 dev_err(&pdev->dev, "Out of memory\n");
165                 goto exit;
166         }
167
168         data->id = pdev->id;
169         data->name = "coretemp";
170         mutex_init(&data->update_lock);
171         /* Tjmax default is 100 degrees C */
172         data->tjmax = 100000;
173
174         /* test if we can access the THERM_STATUS MSR */
175         err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
176         if (err) {
177                 dev_err(&pdev->dev,
178                         "Unable to access THERM_STATUS MSR, giving up\n");
179                 goto exit_free;
180         }
181
182         /* Check if we have problem with errata AE18 of Core processors:
183            Readings might stop update when processor visited too deep sleep,
184            fixed for stepping D0 (6EC).
185         */
186
187         if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
188                 /* check for microcode update */
189                 rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx);
190                 if (edx < 0x39) {
191                         err = -ENODEV;
192                         dev_err(&pdev->dev,
193                                 "Errata AE18 not fixed, update BIOS or "
194                                 "microcode of the CPU!\n");
195                         goto exit_free;
196                 }
197         }
198
199         /* Some processors have Tjmax 85 following magic should detect it
200            Intel won't disclose the information without signed NDA, but
201            individuals cannot sign it. Catch(ed) 22.
202         */
203
204         if (((c->x86_model == 0xf) && (c->x86_mask > 3)) ||
205                 (c->x86_model == 0xe))  {
206                 err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx);
207                 if (err) {
208                         dev_warn(&pdev->dev,
209                                  "Unable to access MSR 0xEE, Tjmax left at %d "
210                                  "degrees C\n", data->tjmax/1000);
211                 } else if (eax & 0x40000000) {
212                         data->tjmax = 85000;
213                 }
214         }
215
216         /* Intel says that above should not work for desktop Core2 processors,
217            but it seems to work. There is no other way how get the absolute
218            readings. Warn the user about this. First check if are desktop,
219            bit 50 of MSR_IA32_PLATFORM_ID should be 0.
220         */
221
222         rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
223
224         if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
225                 dev_warn(&pdev->dev, "Using undocumented features, absolute "
226                          "temperature might be wrong!\n");
227         }
228
229         platform_set_drvdata(pdev, data);
230
231         /* read the still undocumented IA32_TEMPERATURE_TARGET it exists
232            on older CPUs but not in this register */
233
234         if (c->x86_model > 0xe) {
235                 err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
236                 if (err) {
237                         dev_warn(&pdev->dev, "Unable to read"
238                                         " IA32_TEMPERATURE_TARGET MSR\n");
239                 } else {
240                         data->ttarget = data->tjmax -
241                                         (((eax >> 8) & 0xff) * 1000);
242                         err = device_create_file(&pdev->dev,
243                                         &sensor_dev_attr_temp1_max.dev_attr);
244                         if (err)
245                                 goto exit_free;
246                 }
247         }
248
249         if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
250                 goto exit_dev;
251
252         data->hwmon_dev = hwmon_device_register(&pdev->dev);
253         if (IS_ERR(data->hwmon_dev)) {
254                 err = PTR_ERR(data->hwmon_dev);
255                 dev_err(&pdev->dev, "Class registration failed (%d)\n",
256                         err);
257                 goto exit_class;
258         }
259
260         return 0;
261
262 exit_class:
263         sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
264 exit_dev:
265         device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
266 exit_free:
267         kfree(data);
268 exit:
269         return err;
270 }
271
272 static int __devexit coretemp_remove(struct platform_device *pdev)
273 {
274         struct coretemp_data *data = platform_get_drvdata(pdev);
275
276         hwmon_device_unregister(data->hwmon_dev);
277         sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
278         device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
279         platform_set_drvdata(pdev, NULL);
280         kfree(data);
281         return 0;
282 }
283
284 static struct platform_driver coretemp_driver = {
285         .driver = {
286                 .owner = THIS_MODULE,
287                 .name = DRVNAME,
288         },
289         .probe = coretemp_probe,
290         .remove = __devexit_p(coretemp_remove),
291 };
292
293 struct pdev_entry {
294         struct list_head list;
295         struct platform_device *pdev;
296         unsigned int cpu;
297 };
298
299 static LIST_HEAD(pdev_list);
300 static DEFINE_MUTEX(pdev_list_mutex);
301
302 static int __cpuinit coretemp_device_add(unsigned int cpu)
303 {
304         int err;
305         struct platform_device *pdev;
306         struct pdev_entry *pdev_entry;
307
308         pdev = platform_device_alloc(DRVNAME, cpu);
309         if (!pdev) {
310                 err = -ENOMEM;
311                 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
312                 goto exit;
313         }
314
315         pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
316         if (!pdev_entry) {
317                 err = -ENOMEM;
318                 goto exit_device_put;
319         }
320
321         err = platform_device_add(pdev);
322         if (err) {
323                 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
324                        err);
325                 goto exit_device_free;
326         }
327
328         pdev_entry->pdev = pdev;
329         pdev_entry->cpu = cpu;
330         mutex_lock(&pdev_list_mutex);
331         list_add_tail(&pdev_entry->list, &pdev_list);
332         mutex_unlock(&pdev_list_mutex);
333
334         return 0;
335
336 exit_device_free:
337         kfree(pdev_entry);
338 exit_device_put:
339         platform_device_put(pdev);
340 exit:
341         return err;
342 }
343
344 #ifdef CONFIG_HOTPLUG_CPU
345 static void coretemp_device_remove(unsigned int cpu)
346 {
347         struct pdev_entry *p, *n;
348         mutex_lock(&pdev_list_mutex);
349         list_for_each_entry_safe(p, n, &pdev_list, list) {
350                 if (p->cpu == cpu) {
351                         platform_device_unregister(p->pdev);
352                         list_del(&p->list);
353                         kfree(p);
354                 }
355         }
356         mutex_unlock(&pdev_list_mutex);
357 }
358
359 static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb,
360                                  unsigned long action, void *hcpu)
361 {
362         unsigned int cpu = (unsigned long) hcpu;
363
364         switch (action) {
365         case CPU_ONLINE:
366         case CPU_DOWN_FAILED:
367                 coretemp_device_add(cpu);
368                 break;
369         case CPU_DOWN_PREPARE:
370                 coretemp_device_remove(cpu);
371                 break;
372         }
373         return NOTIFY_OK;
374 }
375
376 static struct notifier_block coretemp_cpu_notifier __refdata = {
377         .notifier_call = coretemp_cpu_callback,
378 };
379 #endif                          /* !CONFIG_HOTPLUG_CPU */
380
381 static int __init coretemp_init(void)
382 {
383         int i, err = -ENODEV;
384         struct pdev_entry *p, *n;
385
386         /* quick check if we run Intel */
387         if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
388                 goto exit;
389
390         err = platform_driver_register(&coretemp_driver);
391         if (err)
392                 goto exit;
393
394         for_each_online_cpu(i) {
395                 struct cpuinfo_x86 *c = &cpu_data(i);
396
397                 /* check if family 6, models e, f, 16 */
398                 if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
399                     !((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
400                         (c->x86_model == 0x16))) {
401
402                         /* supported CPU not found, but report the unknown
403                            family 6 CPU */
404                         if ((c->x86 == 0x6) && (c->x86_model > 0xf))
405                                 printk(KERN_WARNING DRVNAME ": Unknown CPU "
406                                         "model %x\n", c->x86_model);
407                         continue;
408                 }
409
410                 err = coretemp_device_add(i);
411                 if (err)
412                         goto exit_devices_unreg;
413         }
414         if (list_empty(&pdev_list)) {
415                 err = -ENODEV;
416                 goto exit_driver_unreg;
417         }
418
419 #ifdef CONFIG_HOTPLUG_CPU
420         register_hotcpu_notifier(&coretemp_cpu_notifier);
421 #endif
422         return 0;
423
424 exit_devices_unreg:
425         mutex_lock(&pdev_list_mutex);
426         list_for_each_entry_safe(p, n, &pdev_list, list) {
427                 platform_device_unregister(p->pdev);
428                 list_del(&p->list);
429                 kfree(p);
430         }
431         mutex_unlock(&pdev_list_mutex);
432 exit_driver_unreg:
433         platform_driver_unregister(&coretemp_driver);
434 exit:
435         return err;
436 }
437
438 static void __exit coretemp_exit(void)
439 {
440         struct pdev_entry *p, *n;
441 #ifdef CONFIG_HOTPLUG_CPU
442         unregister_hotcpu_notifier(&coretemp_cpu_notifier);
443 #endif
444         mutex_lock(&pdev_list_mutex);
445         list_for_each_entry_safe(p, n, &pdev_list, list) {
446                 platform_device_unregister(p->pdev);
447                 list_del(&p->list);
448                 kfree(p);
449         }
450         mutex_unlock(&pdev_list_mutex);
451         platform_driver_unregister(&coretemp_driver);
452 }
453
454 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
455 MODULE_DESCRIPTION("Intel Core temperature monitor");
456 MODULE_LICENSE("GPL");
457
458 module_init(coretemp_init)
459 module_exit(coretemp_exit)