aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/thermal/x86_pkg_temp_thermal.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
index 5de56f671a9d..f36950e4134f 100644
--- a/drivers/thermal/x86_pkg_temp_thermal.c
+++ b/drivers/thermal/x86_pkg_temp_thermal.c
@@ -54,6 +54,8 @@ MODULE_PARM_DESC(notify_delay_ms,
54* is some wrong values returned by cpuid for number of thresholds. 54* is some wrong values returned by cpuid for number of thresholds.
55*/ 55*/
56#define MAX_NUMBER_OF_TRIPS 2 56#define MAX_NUMBER_OF_TRIPS 2
57/* Limit number of package temp zones */
58#define MAX_PKG_TEMP_ZONE_IDS 256
57 59
58struct phy_dev_entry { 60struct phy_dev_entry {
59 struct list_head list; 61 struct list_head list;
@@ -394,12 +396,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
394 char buffer[30]; 396 char buffer[30];
395 int thres_count; 397 int thres_count;
396 u32 eax, ebx, ecx, edx; 398 u32 eax, ebx, ecx, edx;
399 u8 *temp;
397 400
398 cpuid(6, &eax, &ebx, &ecx, &edx); 401 cpuid(6, &eax, &ebx, &ecx, &edx);
399 thres_count = ebx & 0x07; 402 thres_count = ebx & 0x07;
400 if (!thres_count) 403 if (!thres_count)
401 return -ENODEV; 404 return -ENODEV;
402 405
406 if (topology_physical_package_id(cpu) > MAX_PKG_TEMP_ZONE_IDS)
407 return -ENODEV;
408
403 thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS); 409 thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
404 410
405 err = get_tj_max(cpu, &tj_max); 411 err = get_tj_max(cpu, &tj_max);
@@ -417,13 +423,14 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
417 spin_lock(&pkg_work_lock); 423 spin_lock(&pkg_work_lock);
418 if (topology_physical_package_id(cpu) > max_phy_id) 424 if (topology_physical_package_id(cpu) > max_phy_id)
419 max_phy_id = topology_physical_package_id(cpu); 425 max_phy_id = topology_physical_package_id(cpu);
420 pkg_work_scheduled = krealloc(pkg_work_scheduled, 426 temp = krealloc(pkg_work_scheduled,
421 (max_phy_id+1) * sizeof(u8), GFP_ATOMIC); 427 (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
422 if (!pkg_work_scheduled) { 428 if (!temp) {
423 spin_unlock(&pkg_work_lock); 429 spin_unlock(&pkg_work_lock);
424 err = -ENOMEM; 430 err = -ENOMEM;
425 goto err_ret_free; 431 goto err_ret_free;
426 } 432 }
433 pkg_work_scheduled = temp;
427 pkg_work_scheduled[topology_physical_package_id(cpu)] = 0; 434 pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
428 spin_unlock(&pkg_work_lock); 435 spin_unlock(&pkg_work_lock);
429 436
@@ -511,7 +518,7 @@ static int get_core_online(unsigned int cpu)
511 518
512 /* Check if there is already an instance for this package */ 519 /* Check if there is already an instance for this package */
513 if (!phdev) { 520 if (!phdev) {
514 if (!cpu_has(c, X86_FEATURE_DTHERM) && 521 if (!cpu_has(c, X86_FEATURE_DTHERM) ||
515 !cpu_has(c, X86_FEATURE_PTS)) 522 !cpu_has(c, X86_FEATURE_PTS))
516 return -ENODEV; 523 return -ENODEV;
517 if (pkg_temp_thermal_device_add(cpu)) 524 if (pkg_temp_thermal_device_add(cpu))
@@ -562,7 +569,7 @@ static struct notifier_block pkg_temp_thermal_notifier __refdata = {
562}; 569};
563 570
564static const struct x86_cpu_id __initconst pkg_temp_thermal_ids[] = { 571static const struct x86_cpu_id __initconst pkg_temp_thermal_ids[] = {
565 { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, 572 { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_PTS },
566 {} 573 {}
567}; 574};
568MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids); 575MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids);
@@ -592,7 +599,6 @@ static int __init pkg_temp_thermal_init(void)
592 return 0; 599 return 0;
593 600
594err_ret: 601err_ret:
595 get_online_cpus();
596 for_each_online_cpu(i) 602 for_each_online_cpu(i)
597 put_core_offline(i); 603 put_core_offline(i);
598 put_online_cpus(); 604 put_online_cpus();