diff options
| -rw-r--r-- | drivers/hwmon/coretemp.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 6a27eb2fed17..3ae16c37bd92 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
| @@ -51,6 +51,7 @@ static int force_tjmax; | |||
| 51 | module_param_named(tjmax, force_tjmax, int, 0444); | 51 | module_param_named(tjmax, force_tjmax, int, 0444); |
| 52 | MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); | 52 | MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); |
| 53 | 53 | ||
| 54 | #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ | ||
| 54 | #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ | 55 | #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ |
| 55 | #define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ | 56 | #define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ |
| 56 | #define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */ | 57 | #define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */ |
| @@ -138,7 +139,9 @@ static ssize_t show_crit_alarm(struct device *dev, | |||
| 138 | struct platform_data *pdata = dev_get_drvdata(dev); | 139 | struct platform_data *pdata = dev_get_drvdata(dev); |
| 139 | struct temp_data *tdata = pdata->core_data[attr->index]; | 140 | struct temp_data *tdata = pdata->core_data[attr->index]; |
| 140 | 141 | ||
| 142 | mutex_lock(&tdata->update_lock); | ||
| 141 | rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); | 143 | rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); |
| 144 | mutex_unlock(&tdata->update_lock); | ||
| 142 | 145 | ||
| 143 | return sprintf(buf, "%d\n", (eax >> 5) & 1); | 146 | return sprintf(buf, "%d\n", (eax >> 5) & 1); |
| 144 | } | 147 | } |
| @@ -483,7 +486,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, | |||
| 483 | * The attr number is always core id + 2 | 486 | * The attr number is always core id + 2 |
| 484 | * The Pkgtemp will always show up as temp1_*, if available | 487 | * The Pkgtemp will always show up as temp1_*, if available |
| 485 | */ | 488 | */ |
| 486 | attr_no = pkg_flag ? 1 : TO_ATTR_NO(cpu); | 489 | attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu); |
| 487 | 490 | ||
| 488 | if (attr_no > MAX_CORE_DATA - 1) | 491 | if (attr_no > MAX_CORE_DATA - 1) |
| 489 | return -ERANGE; | 492 | return -ERANGE; |
| @@ -662,7 +665,7 @@ static void coretemp_device_remove(unsigned int cpu) | |||
| 662 | mutex_unlock(&pdev_list_mutex); | 665 | mutex_unlock(&pdev_list_mutex); |
| 663 | } | 666 | } |
| 664 | 667 | ||
| 665 | static bool is_any_core_online(struct platform_data *pdata) | 668 | static int get_online_core_in_package(struct platform_data *pdata) |
| 666 | { | 669 | { |
| 667 | int i; | 670 | int i; |
| 668 | 671 | ||
| @@ -670,10 +673,10 @@ static bool is_any_core_online(struct platform_data *pdata) | |||
| 670 | for (i = MAX_CORE_DATA - 1; i >= 0; --i) { | 673 | for (i = MAX_CORE_DATA - 1; i >= 0; --i) { |
| 671 | if (pdata->core_data[i] && | 674 | if (pdata->core_data[i] && |
| 672 | !pdata->core_data[i]->is_pkg_data) { | 675 | !pdata->core_data[i]->is_pkg_data) { |
| 673 | return true; | 676 | return pdata->core_data[i]->cpu; |
| 674 | } | 677 | } |
| 675 | } | 678 | } |
| 676 | return false; | 679 | return nr_cpu_ids; |
| 677 | } | 680 | } |
| 678 | 681 | ||
| 679 | static void get_core_online(unsigned int cpu) | 682 | static void get_core_online(unsigned int cpu) |
| @@ -720,9 +723,10 @@ static void get_core_online(unsigned int cpu) | |||
| 720 | 723 | ||
| 721 | static void put_core_offline(unsigned int cpu) | 724 | static void put_core_offline(unsigned int cpu) |
| 722 | { | 725 | { |
| 723 | int i, indx; | ||
| 724 | struct platform_data *pdata; | ||
| 725 | struct platform_device *pdev = coretemp_get_pdev(cpu); | 726 | struct platform_device *pdev = coretemp_get_pdev(cpu); |
| 727 | struct platform_data *pdata; | ||
| 728 | struct temp_data *tdata; | ||
| 729 | int i, indx, target; | ||
| 726 | 730 | ||
| 727 | /* If the physical CPU device does not exist, just return */ | 731 | /* If the physical CPU device does not exist, just return */ |
| 728 | if (!pdev) | 732 | if (!pdev) |
| @@ -762,8 +766,21 @@ static void put_core_offline(unsigned int cpu) | |||
| 762 | * which in turn calls coretemp_remove. This removes the | 766 | * which in turn calls coretemp_remove. This removes the |
| 763 | * pkgtemp entry and does other clean ups. | 767 | * pkgtemp entry and does other clean ups. |
| 764 | */ | 768 | */ |
| 765 | if (!is_any_core_online(pdata)) | 769 | target = get_online_core_in_package(pdata); |
| 770 | if (target >= nr_cpu_ids) { | ||
| 766 | coretemp_device_remove(cpu); | 771 | coretemp_device_remove(cpu); |
| 772 | return; | ||
| 773 | } | ||
| 774 | /* | ||
| 775 | * Check whether this core is the target for the package | ||
| 776 | * interface. We need to assign it to some other cpu. | ||
| 777 | */ | ||
| 778 | tdata = pdata->core_data[PKG_SYSFS_ATTR_NO]; | ||
| 779 | if (tdata && tdata->cpu == cpu) { | ||
| 780 | mutex_lock(&tdata->update_lock); | ||
| 781 | tdata->cpu = target; | ||
| 782 | mutex_unlock(&tdata->update_lock); | ||
| 783 | } | ||
| 767 | } | 784 | } |
| 768 | 785 | ||
| 769 | static int coretemp_cpu_callback(struct notifier_block *nfb, | 786 | static int coretemp_cpu_callback(struct notifier_block *nfb, |
