OSDN Git Service

thermal/drivers/intel: Use generic thermal_zone_get_trip() function
authorDaniel Lezcano <daniel.lezcano@linaro.org>
Mon, 3 Oct 2022 09:26:02 +0000 (11:26 +0200)
committerDaniel Lezcano <daniel.lezcano@kernel.org>
Fri, 6 Jan 2023 13:14:48 +0000 (14:14 +0100)
The thermal framework gives the possibility to register the trip
points with the thermal zone. When that is done, no get_trip_* ops are
needed and they can be removed.

Convert ops content logic into generic trip points and register them with the
thermal zone.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://lore.kernel.org/r/20221003092602.1323944-30-daniel.lezcano@linaro.org
drivers/thermal/intel/x86_pkg_temp_thermal.c

index 84c3a11..494f252 100644 (file)
@@ -53,6 +53,7 @@ struct zone_device {
        u32                             msr_pkg_therm_high;
        struct delayed_work             work;
        struct thermal_zone_device      *tzone;
+       struct thermal_trip             *trips;
        struct cpumask                  cpumask;
 };
 
@@ -138,40 +139,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
        return -EINVAL;
 }
 
-static int sys_get_trip_temp(struct thermal_zone_device *tzd,
-                            int trip, int *temp)
-{
-       struct zone_device *zonedev = tzd->devdata;
-       unsigned long thres_reg_value;
-       u32 mask, shift, eax, edx;
-       int ret;
-
-       if (trip >= MAX_NUMBER_OF_TRIPS)
-               return -EINVAL;
-
-       if (trip) {
-               mask = THERM_MASK_THRESHOLD1;
-               shift = THERM_SHIFT_THRESHOLD1;
-       } else {
-               mask = THERM_MASK_THRESHOLD0;
-               shift = THERM_SHIFT_THRESHOLD0;
-       }
-
-       ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
-                          &eax, &edx);
-       if (ret < 0)
-               return ret;
-
-       thres_reg_value = (eax & mask) >> shift;
-       if (thres_reg_value)
-               *temp = zonedev->tj_max - thres_reg_value * 1000;
-       else
-               *temp = THERMAL_TEMP_INVALID;
-       pr_debug("sys_get_trip_temp %d\n", *temp);
-
-       return 0;
-}
-
 static int
 sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
 {
@@ -212,18 +179,9 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
                        l, h);
 }
 
-static int sys_get_trip_type(struct thermal_zone_device *thermal, int trip,
-                            enum thermal_trip_type *type)
-{
-       *type = THERMAL_TRIP_PASSIVE;
-       return 0;
-}
-
 /* Thermal zone callback registry */
 static struct thermal_zone_device_ops tzone_ops = {
        .get_temp = sys_get_curr_temp,
-       .get_trip_temp = sys_get_trip_temp,
-       .get_trip_type = sys_get_trip_type,
        .set_trip_temp = sys_set_trip_temp,
 };
 
@@ -323,6 +281,48 @@ static int pkg_thermal_notify(u64 msr_val)
        return 0;
 }
 
+static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int num_trips)
+{
+       struct thermal_trip *trips;
+       unsigned long thres_reg_value;
+       u32 mask, shift, eax, edx;
+       int ret, i;
+
+       trips = kzalloc(sizeof(*trips) * num_trips, GFP_KERNEL);
+       if (!trips)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < num_trips; i++) {
+
+               if (i) {
+                       mask = THERM_MASK_THRESHOLD1;
+                       shift = THERM_SHIFT_THRESHOLD1;
+               } else {
+                       mask = THERM_MASK_THRESHOLD0;
+                       shift = THERM_SHIFT_THRESHOLD0;
+               }
+
+               ret = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
+                                  &eax, &edx);
+               if (ret < 0) {
+                       kfree(trips);
+                       return ERR_PTR(ret);
+               }
+
+               thres_reg_value = (eax & mask) >> shift;
+
+               trips[i].temperature = thres_reg_value ?
+                       tj_max - thres_reg_value * 1000 : THERMAL_TEMP_INVALID;
+
+               trips[i].type = THERMAL_TRIP_PASSIVE;
+
+               pr_debug("%s: cpu=%d, trip=%d, temp=%d\n",
+                        __func__, cpu, i, trips[i].temperature);
+       }
+
+       return trips;
+}
+
 static int pkg_temp_thermal_device_add(unsigned int cpu)
 {
        int id = topology_logical_die_id(cpu);
@@ -348,24 +348,27 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
        if (!zonedev)
                return -ENOMEM;
 
+       zonedev->trips = pkg_temp_thermal_trips_init(cpu, tj_max, thres_count);
+       if (IS_ERR(zonedev->trips)) {
+               err = PTR_ERR(zonedev->trips);
+               goto out_kfree_zonedev;
+       }
+
        INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
        zonedev->cpu = cpu;
        zonedev->tj_max = tj_max;
-       zonedev->tzone = thermal_zone_device_register("x86_pkg_temp",
-                       thres_count,
+       zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp",
+                       zonedev->trips, thres_count,
                        (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01,
                        zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0);
        if (IS_ERR(zonedev->tzone)) {
                err = PTR_ERR(zonedev->tzone);
-               kfree(zonedev);
-               return err;
+               goto out_kfree_trips;
        }
        err = thermal_zone_device_enable(zonedev->tzone);
-       if (err) {
-               thermal_zone_device_unregister(zonedev->tzone);
-               kfree(zonedev);
-               return err;
-       }
+       if (err)
+               goto out_unregister_tz;
+
        /* Store MSR value for package thermal interrupt, to restore at exit */
        rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low,
              zonedev->msr_pkg_therm_high);
@@ -374,7 +377,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
        raw_spin_lock_irq(&pkg_temp_lock);
        zones[id] = zonedev;
        raw_spin_unlock_irq(&pkg_temp_lock);
+
        return 0;
+
+out_unregister_tz:
+       thermal_zone_device_unregister(zonedev->tzone);
+out_kfree_trips:
+       kfree(zonedev->trips);
+out_kfree_zonedev:
+       kfree(zonedev);
+       return err;
 }
 
 static int pkg_thermal_cpu_offline(unsigned int cpu)
@@ -458,8 +470,10 @@ static int pkg_thermal_cpu_offline(unsigned int cpu)
        raw_spin_unlock_irq(&pkg_temp_lock);
 
        /* Final cleanup if this is the last cpu */
-       if (lastcpu)
+       if (lastcpu) {
+               kfree(zonedev->trips);
                kfree(zonedev);
+       }
        return 0;
 }