aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/coretemp.c
diff options
context:
space:
mode:
authorCarsten Emde <C.Emde@osadl.org>2010-05-24 17:33:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 11:07:07 -0400
commita321cedb12904114e2ba5041a3673ca24deb09c9 (patch)
tree43481f2751380094a9873b3b474ae6e7e0019167 /drivers/hwmon/coretemp.c
parent5db47b009d17d69a2f8d84357e7b24c3e3c2edec (diff)
drivers/hwmon/coretemp.c: get TjMax value from MSR
The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer Intel processors. Signed-off-by: Huaxu Wan <huaxu.wan@linux.intel.com> Signed-off-by: Carsten Emde <C.Emde@osadl.org> Cc: Jean Delvare <khali@linux-fr.org> Cc: Valdis Kletnieks <valdis.kletnieks@vt.edu> Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: Yong Wang <yong.y.wang@linux.intel.com> Cc: Rudolf Marek <r.marek@assembler.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon/coretemp.c')
-rw-r--r--drivers/hwmon/coretemp.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 9fae7cbc5d76..2988da150ed6 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -241,6 +241,55 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
241 return tjmax; 241 return tjmax;
242} 242}
243 243
244static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id,
245 struct device *dev)
246{
247 /* The 100C is default for both mobile and non mobile CPUs */
248 int err;
249 u32 eax, edx;
250 u32 val;
251
252 /* A new feature of current Intel(R) processors, the
253 IA32_TEMPERATURE_TARGET contains the TjMax value */
254 err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
255 if (err) {
256 dev_warn(dev, "Unable to read TjMax from CPU.\n");
257 } else {
258 val = (eax >> 16) & 0xff;
259 /*
260 * If the TjMax is not plausible, an assumption
261 * will be used
262 */
263 if ((val > 80) && (val < 120)) {
264 dev_info(dev, "TjMax is %d C.\n", val);
265 return val * 1000;
266 }
267 }
268
269 /*
270 * An assumption is made for early CPUs and unreadable MSR.
271 * NOTE: the given value may not be correct.
272 */
273
274 switch (c->x86_model) {
275 case 0xe:
276 case 0xf:
277 case 0x16:
278 case 0x1a:
279 dev_warn(dev, "TjMax is assumed as 100 C!\n");
280 return 100000;
281 break;
282 case 0x17:
283 case 0x1c: /* Atom CPUs */
284 return adjust_tjmax(c, id, dev);
285 break;
286 default:
287 dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
288 " using default TjMax of 100C.\n", c->x86_model);
289 return 100000;
290 }
291}
292
244static int __devinit coretemp_probe(struct platform_device *pdev) 293static int __devinit coretemp_probe(struct platform_device *pdev)
245{ 294{
246 struct coretemp_data *data; 295 struct coretemp_data *data;
@@ -283,14 +332,18 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
283 } 332 }
284 } 333 }
285 334
286 data->tjmax = adjust_tjmax(c, data->id, &pdev->dev); 335 data->tjmax = get_tjmax(c, data->id, &pdev->dev);
287 platform_set_drvdata(pdev, data); 336 platform_set_drvdata(pdev, data);
288 337
289 /* read the still undocumented IA32_TEMPERATURE_TARGET it exists 338 /*
290 on older CPUs but not in this register, Atoms don't have it either */ 339 * read the still undocumented IA32_TEMPERATURE_TARGET. It exists
340 * on older CPUs but not in this register,
341 * Atoms don't have it either.
342 */
291 343
292 if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { 344 if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) {
293 err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); 345 err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET,
346 &eax, &edx);
294 if (err) { 347 if (err) {
295 dev_warn(&pdev->dev, "Unable to read" 348 dev_warn(&pdev->dev, "Unable to read"
296 " IA32_TEMPERATURE_TARGET MSR\n"); 349 " IA32_TEMPERATURE_TARGET MSR\n");