hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/hwmon/coretemp.c
....@@ -550,66 +550,49 @@
550550 ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
551551 }
552552
553
-static int coretemp_probe(struct platform_device *pdev)
553
+static int coretemp_device_add(int zoneid)
554554 {
555
- struct device *dev = &pdev->dev;
555
+ struct platform_device *pdev;
556556 struct platform_data *pdata;
557
+ int err;
557558
558559 /* Initialize the per-zone data structures */
559
- pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL);
560
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
560561 if (!pdata)
561562 return -ENOMEM;
562563
563
- pdata->pkg_id = pdev->id;
564
+ pdata->pkg_id = zoneid;
564565 ida_init(&pdata->ida);
565
- platform_set_drvdata(pdev, pdata);
566
-
567
- pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
568
- pdata, NULL);
569
- return PTR_ERR_OR_ZERO(pdata->hwmon_dev);
570
-}
571
-
572
-static int coretemp_remove(struct platform_device *pdev)
573
-{
574
- struct platform_data *pdata = platform_get_drvdata(pdev);
575
- int i;
576
-
577
- for (i = MAX_CORE_DATA - 1; i >= 0; --i)
578
- if (pdata->core_data[i])
579
- coretemp_remove_core(pdata, i);
580
-
581
- ida_destroy(&pdata->ida);
582
- return 0;
583
-}
584
-
585
-static struct platform_driver coretemp_driver = {
586
- .driver = {
587
- .name = DRVNAME,
588
- },
589
- .probe = coretemp_probe,
590
- .remove = coretemp_remove,
591
-};
592
-
593
-static struct platform_device *coretemp_device_add(unsigned int cpu)
594
-{
595
- int err, zoneid = topology_logical_die_id(cpu);
596
- struct platform_device *pdev;
597
-
598
- if (zoneid < 0)
599
- return ERR_PTR(-ENOMEM);
600566
601567 pdev = platform_device_alloc(DRVNAME, zoneid);
602
- if (!pdev)
603
- return ERR_PTR(-ENOMEM);
604
-
605
- err = platform_device_add(pdev);
606
- if (err) {
607
- platform_device_put(pdev);
608
- return ERR_PTR(err);
568
+ if (!pdev) {
569
+ err = -ENOMEM;
570
+ goto err_free_pdata;
609571 }
610572
573
+ err = platform_device_add(pdev);
574
+ if (err)
575
+ goto err_put_dev;
576
+
577
+ platform_set_drvdata(pdev, pdata);
611578 zone_devices[zoneid] = pdev;
612
- return pdev;
579
+ return 0;
580
+
581
+err_put_dev:
582
+ platform_device_put(pdev);
583
+err_free_pdata:
584
+ kfree(pdata);
585
+ return err;
586
+}
587
+
588
+static void coretemp_device_remove(int zoneid)
589
+{
590
+ struct platform_device *pdev = zone_devices[zoneid];
591
+ struct platform_data *pdata = platform_get_drvdata(pdev);
592
+
593
+ ida_destroy(&pdata->ida);
594
+ kfree(pdata);
595
+ platform_device_unregister(pdev);
613596 }
614597
615598 static int coretemp_cpu_online(unsigned int cpu)
....@@ -633,7 +616,10 @@
633616 if (!cpu_has(c, X86_FEATURE_DTHERM))
634617 return -ENODEV;
635618
636
- if (!pdev) {
619
+ pdata = platform_get_drvdata(pdev);
620
+ if (!pdata->hwmon_dev) {
621
+ struct device *hwmon;
622
+
637623 /* Check the microcode version of the CPU */
638624 if (chk_ucode_version(cpu))
639625 return -EINVAL;
....@@ -644,9 +630,11 @@
644630 * online. So, initialize per-pkg data structures and
645631 * then bring this core online.
646632 */
647
- pdev = coretemp_device_add(cpu);
648
- if (IS_ERR(pdev))
649
- return PTR_ERR(pdev);
633
+ hwmon = hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
634
+ pdata, NULL);
635
+ if (IS_ERR(hwmon))
636
+ return PTR_ERR(hwmon);
637
+ pdata->hwmon_dev = hwmon;
650638
651639 /*
652640 * Check whether pkgtemp support is available.
....@@ -656,7 +644,6 @@
656644 coretemp_add_core(pdev, cpu, 1);
657645 }
658646
659
- pdata = platform_get_drvdata(pdev);
660647 /*
661648 * Check whether a thread sibling is already online. If not add the
662649 * interface for this CPU core.
....@@ -675,18 +662,14 @@
675662 struct temp_data *tdata;
676663 int i, indx = -1, target;
677664
678
- /*
679
- * Don't execute this on suspend as the device remove locks
680
- * up the machine.
681
- */
665
+ /* No need to tear down any interfaces for suspend */
682666 if (cpuhp_tasks_frozen)
683667 return 0;
684668
685669 /* If the physical CPU device does not exist, just return */
686
- if (!pdev)
687
- return 0;
688
-
689670 pd = platform_get_drvdata(pdev);
671
+ if (!pd->hwmon_dev)
672
+ return 0;
690673
691674 for (i = 0; i < NUM_REAL_CORES; i++) {
692675 if (pd->cpu_map[i] == topology_core_id(cpu)) {
....@@ -718,13 +701,14 @@
718701 }
719702
720703 /*
721
- * If all cores in this pkg are offline, remove the device. This
722
- * will invoke the platform driver remove function, which cleans up
723
- * the rest.
704
+ * If all cores in this pkg are offline, remove the interface.
724705 */
706
+ tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
725707 if (cpumask_empty(&pd->cpumask)) {
726
- zone_devices[topology_logical_die_id(cpu)] = NULL;
727
- platform_device_unregister(pdev);
708
+ if (tdata)
709
+ coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO);
710
+ hwmon_device_unregister(pd->hwmon_dev);
711
+ pd->hwmon_dev = NULL;
728712 return 0;
729713 }
730714
....@@ -732,7 +716,6 @@
732716 * Check whether this core is the target for the package
733717 * interface. We need to assign it to some other cpu.
734718 */
735
- tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
736719 if (tdata && tdata->cpu == cpu) {
737720 target = cpumask_first(&pd->cpumask);
738721 mutex_lock(&tdata->update_lock);
....@@ -751,7 +734,7 @@
751734
752735 static int __init coretemp_init(void)
753736 {
754
- int err;
737
+ int i, err;
755738
756739 /*
757740 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
....@@ -767,20 +750,22 @@
767750 if (!zone_devices)
768751 return -ENOMEM;
769752
770
- err = platform_driver_register(&coretemp_driver);
771
- if (err)
772
- goto outzone;
753
+ for (i = 0; i < max_zones; i++) {
754
+ err = coretemp_device_add(i);
755
+ if (err)
756
+ goto outzone;
757
+ }
773758
774759 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online",
775760 coretemp_cpu_online, coretemp_cpu_offline);
776761 if (err < 0)
777
- goto outdrv;
762
+ goto outzone;
778763 coretemp_hp_online = err;
779764 return 0;
780765
781
-outdrv:
782
- platform_driver_unregister(&coretemp_driver);
783766 outzone:
767
+ while (i--)
768
+ coretemp_device_remove(i);
784769 kfree(zone_devices);
785770 return err;
786771 }
....@@ -788,8 +773,11 @@
788773
789774 static void __exit coretemp_exit(void)
790775 {
776
+ int i;
777
+
791778 cpuhp_remove_state(coretemp_hp_online);
792
- platform_driver_unregister(&coretemp_driver);
779
+ for (i = 0; i < max_zones; i++)
780
+ coretemp_device_remove(i);
793781 kfree(zone_devices);
794782 }
795783 module_exit(coretemp_exit)