xref: /linux/drivers/hwmon/coretemp.c (revision a17627ef8833ac30622a7b39b7be390e1b174405)
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)
435