aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/coretemp.c31
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;
51module_param_named(tjmax, force_tjmax, int, 0444); 51module_param_named(tjmax, force_tjmax, int, 0444);
52MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); 52MODULE_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
665static bool is_any_core_online(struct platform_data *pdata) 668static 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
679static void get_core_online(unsigned int cpu) 682static void get_core_online(unsigned int cpu)
@@ -720,9 +723,10 @@ static void get_core_online(unsigned int cpu)
720 723
721static void put_core_offline(unsigned int cpu) 724static 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
769static int coretemp_cpu_callback(struct notifier_block *nfb, 786static int coretemp_cpu_callback(struct notifier_block *nfb,