xref: /openbmc/linux/drivers/hwmon/coretemp.c (revision 64c70b1c)
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 			err = -ENODEV;
189 			dev_err(&pdev->dev,
190 				"Errata AE18 not fixed, update BIOS or "
191 				"microcode of the CPU!\n");
192 			goto exit_free;
193 		}
194 	}
195 
196 	/* Some processors have Tjmax 85 following magic should detect it
197 	   Intel won't disclose the information without signed NDA, but
198 	   individuals cannot sign it. Catch(ed) 22.
199 	*/
200 
201 	if (((c->x86_model == 0xf) && (c->x86_mask > 3)) ||
202 		(c->x86_model == 0xe))  {
203 		err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx);
204 		if (err) {
205 			dev_warn(&pdev->dev,
206 				 "Unable to access MSR 0xEE, Tjmax left at %d "
207 				 "degrees C\n", data->tjmax/1000);
208 		} else if (eax & 0x40000000) {
209 			data->tjmax = 85000;
210 		}
211 	}
212 
213 	/* Intel says that above should not work for desktop Core2 processors,
214 	   but it seems to work. There is no other way how get the absolute
215 	   readings. Warn the user about this. First check if are desktop,
216 	   bit 50 of MSR_IA32_PLATFORM_ID should be 0.
217 	*/
218 
219 	rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
220 
221 	if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
222 		dev_warn(&pdev->dev, "Using undocumented features, absolute "
223 			 "temperature might be wrong!\n");
224 	}
225 
226 	platform_set_drvdata(pdev, data);
227 
228 	if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
229 		goto exit_free;
230 
231 	data->class_dev = hwmon_device_register(&pdev->dev);
232 	if (IS_ERR(data->class_dev)) {
233 		err = PTR_ERR(data->class_dev);
234 		dev_err(&pdev->dev, "Class registration failed (%d)\n",
235 			err);
236 		goto exit_class;
237 	}
238 
239 	return 0;
240 
241 exit_class:
242 	sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
243 exit_free:
244 	kfree(data);
245 exit:
246 	return err;
247 }
248 
249 static int __devexit coretemp_remove(struct platform_device *pdev)
250 {
251 	struct coretemp_data *data = platform_get_drvdata(pdev);
252 
253 	hwmon_device_unregister(data->class_dev);
254 	sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
255 	platform_set_drvdata(pdev, NULL);
256 	kfree(data);
257 	return 0;
258 }
259 
260 static struct platform_driver coretemp_driver = {
261 	.driver = {
262 		.owner = THIS_MODULE,
263 		.name = DRVNAME,
264 	},
265 	.probe = coretemp_probe,
266 	.remove = __devexit_p(coretemp_remove),
267 };
268 
269 struct pdev_entry {
270 	struct list_head list;
271 	struct platform_device *pdev;
272 	unsigned int cpu;
273 };
274 
275 static LIST_HEAD(pdev_list);
276 static DEFINE_MUTEX(pdev_list_mutex);
277 
278 static int __cpuinit coretemp_device_add(unsigned int cpu)
279 {
280 	int err;
281 	struct platform_device *pdev;
282 	struct pdev_entry *pdev_entry;
283 
284 	pdev = platform_device_alloc(DRVNAME, cpu);
285 	if (!pdev) {
286 		err = -ENOMEM;
287 		printk(KERN_ERR DRVNAME ": Device allocation failed\n");
288 		goto exit;
289 	}
290 
291 	pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
292 	if (!pdev_entry) {
293 		err = -ENOMEM;
294 		goto exit_device_put;
295 	}
296 
297 	err = platform_device_add(pdev);
298 	if (err) {
299 		printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
300 		       err);
301 		goto exit_device_free;
302 	}
303 
304 	pdev_entry->pdev = pdev;
305 	pdev_entry->cpu = cpu;
306 	mutex_lock(&pdev_list_mutex);
307 	list_add_tail(&pdev_entry->list, &pdev_list);
308 	mutex_unlock(&pdev_list_mutex);
309 
310 	return 0;
311 
312 exit_device_free:
313 	kfree(pdev_entry);
314 exit_device_put:
315 	platform_device_put(pdev);
316 exit:
317 	return err;
318 }
319 
320 #ifdef CONFIG_HOTPLUG_CPU
321 void coretemp_device_remove(unsigned int cpu)
322 {
323 	struct pdev_entry *p, *n;
324 	mutex_lock(&pdev_list_mutex);
325 	list_for_each_entry_safe(p, n, &pdev_list, list) {
326 		if (p->cpu == cpu) {
327 			platform_device_unregister(p->pdev);
328 			list_del(&p->list);
329 			kfree(p);
330 		}
331 	}
332 	mutex_unlock(&pdev_list_mutex);
333 }
334 
335 static int coretemp_cpu_callback(struct notifier_block *nfb,
336 				 unsigned long action, void *hcpu)
337 {
338 	unsigned int cpu = (unsigned long) hcpu;
339 
340 	switch (action) {
341 	case CPU_ONLINE:
342 	case CPU_ONLINE_FROZEN:
343 		coretemp_device_add(cpu);
344 		break;
345 	case CPU_DEAD:
346 	case CPU_DEAD_FROZEN:
347 		coretemp_device_remove(cpu);
348 		break;
349 	}
350 	return NOTIFY_OK;
351 }
352 
353 static struct notifier_block __cpuinitdata coretemp_cpu_notifier = {
354 	.notifier_call = coretemp_cpu_callback,
355 };
356 #endif				/* !CONFIG_HOTPLUG_CPU */
357 
358 static int __init coretemp_init(void)
359 {
360 	int i, err = -ENODEV;
361 	struct pdev_entry *p, *n;
362 
363 	/* quick check if we run Intel */
364 	if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
365 		goto exit;
366 
367 	err = platform_driver_register(&coretemp_driver);
368 	if (err)
369 		goto exit;
370 
371 	for_each_online_cpu(i) {
372 		struct cpuinfo_x86 *c = &(cpu_data)[i];
373 
374 		/* check if family 6, models e, f */
375 		if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
376 		    !((c->x86_model == 0xe) || (c->x86_model == 0xf))) {
377 
378 			/* supported CPU not found, but report the unknown
379 			   family 6 CPU */
380 			if ((c->x86 == 0x6) && (c->x86_model > 0xf))
381 				printk(KERN_WARNING DRVNAME ": Unknown CPU "
382 					"model %x\n", c->x86_model);
383 			continue;
384 		}
385 
386 		err = coretemp_device_add(i);
387 		if (err)
388 			goto exit_devices_unreg;
389 	}
390 	if (list_empty(&pdev_list)) {
391 		err = -ENODEV;
392 		goto exit_driver_unreg;
393 	}
394 
395 #ifdef CONFIG_HOTPLUG_CPU
396 	register_hotcpu_notifier(&coretemp_cpu_notifier);
397 #endif
398 	return 0;
399 
400 exit_devices_unreg:
401 	mutex_lock(&pdev_list_mutex);
402 	list_for_each_entry_safe(p, n, &pdev_list, list) {
403 		platform_device_unregister(p->pdev);
404 		list_del(&p->list);
405 		kfree(p);
406 	}
407 	mutex_unlock(&pdev_list_mutex);
408 exit_driver_unreg:
409 	platform_driver_unregister(&coretemp_driver);
410 exit:
411 	return err;
412 }
413 
414 static void __exit coretemp_exit(void)
415 {
416 	struct pdev_entry *p, *n;
417 #ifdef CONFIG_HOTPLUG_CPU
418 	unregister_hotcpu_notifier(&coretemp_cpu_notifier);
419 #endif
420 	mutex_lock(&pdev_list_mutex);
421 	list_for_each_entry_safe(p, n, &pdev_list, list) {
422 		platform_device_unregister(p->pdev);
423 		list_del(&p->list);
424 		kfree(p);
425 	}
426 	mutex_unlock(&pdev_list_mutex);
427 	platform_driver_unregister(&coretemp_driver);
428 }
429 
430 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
431 MODULE_DESCRIPTION("Intel Core temperature monitor");
432 MODULE_LICENSE("GPL");
433 
434 module_init(coretemp_init)
435 module_exit(coretemp_exit)
436