@@ -46,9 +46,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
46
46
#define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
47
47
#define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
48
48
49
- #define TO_CORE_ID (cpu ) (cpu_data(cpu).cpu_core_id)
50
- #define TO_ATTR_NO (cpu ) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
51
-
52
49
#ifdef CONFIG_SMP
53
50
#define for_each_sibling (i , cpu ) \
54
51
for_each_cpu(i, topology_sibling_cpumask(cpu))
@@ -91,6 +88,8 @@ struct temp_data {
91
88
struct platform_data {
92
89
struct device * hwmon_dev ;
93
90
u16 pkg_id ;
91
+ u16 cpu_map [NUM_REAL_CORES ];
92
+ struct ida ida ;
94
93
struct cpumask cpumask ;
95
94
struct temp_data * core_data [MAX_CORE_DATA ];
96
95
struct device_attribute name_attr ;
@@ -441,7 +440,7 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
441
440
MSR_IA32_THERM_STATUS ;
442
441
tdata -> is_pkg_data = pkg_flag ;
443
442
tdata -> cpu = cpu ;
444
- tdata -> cpu_core_id = TO_CORE_ID (cpu );
443
+ tdata -> cpu_core_id = topology_core_id (cpu );
445
444
tdata -> attr_size = MAX_CORE_ATTRS ;
446
445
mutex_init (& tdata -> update_lock );
447
446
return tdata ;
@@ -454,22 +453,34 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
454
453
struct platform_data * pdata = platform_get_drvdata (pdev );
455
454
struct cpuinfo_x86 * c = & cpu_data (cpu );
456
455
u32 eax , edx ;
457
- int err , attr_no ;
456
+ int err , index , attr_no ;
458
457
459
458
/*
460
459
* Find attr number for sysfs:
461
460
* We map the attr number to core id of the CPU
462
461
* The attr number is always core id + 2
463
462
* The Pkgtemp will always show up as temp1_*, if available
464
463
*/
465
- attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO (cpu );
464
+ if (pkg_flag ) {
465
+ attr_no = PKG_SYSFS_ATTR_NO ;
466
+ } else {
467
+ index = ida_alloc (& pdata -> ida , GFP_KERNEL );
468
+ if (index < 0 )
469
+ return index ;
470
+ pdata -> cpu_map [index ] = topology_core_id (cpu );
471
+ attr_no = index + BASE_SYSFS_ATTR_NO ;
472
+ }
466
473
467
- if (attr_no > MAX_CORE_DATA - 1 )
468
- return - ERANGE ;
474
+ if (attr_no > MAX_CORE_DATA - 1 ) {
475
+ err = - ERANGE ;
476
+ goto ida_free ;
477
+ }
469
478
470
479
tdata = init_temp_data (cpu , pkg_flag );
471
- if (!tdata )
472
- return - ENOMEM ;
480
+ if (!tdata ) {
481
+ err = - ENOMEM ;
482
+ goto ida_free ;
483
+ }
473
484
474
485
/* Test if we can access the status register */
475
486
err = rdmsr_safe_on_cpu (cpu , tdata -> status_reg , & eax , & edx );
@@ -505,6 +516,9 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
505
516
exit_free :
506
517
pdata -> core_data [attr_no ] = NULL ;
507
518
kfree (tdata );
519
+ ida_free :
520
+ if (!pkg_flag )
521
+ ida_free (& pdata -> ida , index );
508
522
return err ;
509
523
}
510
524
@@ -524,6 +538,9 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx)
524
538
525
539
kfree (pdata -> core_data [indx ]);
526
540
pdata -> core_data [indx ] = NULL ;
541
+
542
+ if (indx >= BASE_SYSFS_ATTR_NO )
543
+ ida_free (& pdata -> ida , indx - BASE_SYSFS_ATTR_NO );
527
544
}
528
545
529
546
static int coretemp_probe (struct platform_device * pdev )
@@ -537,6 +554,7 @@ static int coretemp_probe(struct platform_device *pdev)
537
554
return - ENOMEM ;
538
555
539
556
pdata -> pkg_id = pdev -> id ;
557
+ ida_init (& pdata -> ida );
540
558
platform_set_drvdata (pdev , pdata );
541
559
542
560
pdata -> hwmon_dev = devm_hwmon_device_register_with_groups (dev , DRVNAME ,
@@ -553,6 +571,7 @@ static int coretemp_remove(struct platform_device *pdev)
553
571
if (pdata -> core_data [i ])
554
572
coretemp_remove_core (pdata , i );
555
573
574
+ ida_destroy (& pdata -> ida );
556
575
return 0 ;
557
576
}
558
577
@@ -647,7 +666,7 @@ static int coretemp_cpu_offline(unsigned int cpu)
647
666
struct platform_device * pdev = coretemp_get_pdev (cpu );
648
667
struct platform_data * pd ;
649
668
struct temp_data * tdata ;
650
- int indx , target ;
669
+ int i , indx = -1 , target ;
651
670
652
671
/*
653
672
* Don't execute this on suspend as the device remove locks
@@ -660,12 +679,19 @@ static int coretemp_cpu_offline(unsigned int cpu)
660
679
if (!pdev )
661
680
return 0 ;
662
681
663
- /* The core id is too big, just return */
664
- indx = TO_ATTR_NO (cpu );
665
- if (indx > MAX_CORE_DATA - 1 )
682
+ pd = platform_get_drvdata (pdev );
683
+
684
+ for (i = 0 ; i < NUM_REAL_CORES ; i ++ ) {
685
+ if (pd -> cpu_map [i ] == topology_core_id (cpu )) {
686
+ indx = i + BASE_SYSFS_ATTR_NO ;
687
+ break ;
688
+ }
689
+ }
690
+
691
+ /* Too many cores and this core is not populated, just return */
692
+ if (indx < 0 )
666
693
return 0 ;
667
694
668
- pd = platform_get_drvdata (pdev );
669
695
tdata = pd -> core_data [indx ];
670
696
671
697
cpumask_clear_cpu (cpu , & pd -> cpumask );
0 commit comments