thermal: export thermal_zone_parameters to sysfs
authorJavi Merino <javi.merino@arm.com>
Thu, 26 Mar 2015 15:53:02 +0000 (15:53 +0000)
committerEduardo Valentin <edubezval@gmail.com>
Tue, 5 May 2015 04:27:54 +0000 (21:27 -0700)
It's useful for tuning to be able to edit thermal_zone_parameters from
userspace.  Export them to the thermal_zone sysfs so that they can be
easily changed.

Cc: Zhang Rui <rui.zhang@intel.com>
Cc: Eduardo Valentin <edubezval@gmail.com>
Signed-off-by: Javi Merino <javi.merino@arm.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
Documentation/thermal/sysfs-api.txt
drivers/thermal/thermal_core.c

index fc7dfe10778be5ab99ba3469531ec6f4143c24c5..7d44d7f1a71bfdf2ff12beb662a2704312334738 100644 (file)
@@ -184,6 +184,12 @@ Thermal zone device sys I/F, created once it's registered:
     |---trip_point_[0-*]_type: Trip point type
     |---trip_point_[0-*]_hyst: Hysteresis value for this trip point
     |---emul_temp:             Emulated temperature set node
     |---trip_point_[0-*]_type: Trip point type
     |---trip_point_[0-*]_hyst: Hysteresis value for this trip point
     |---emul_temp:             Emulated temperature set node
+    |---sustainable_power:      Sustainable dissipatable power
+    |---k_po:                   Proportional term during temperature overshoot
+    |---k_pu:                   Proportional term during temperature undershoot
+    |---k_i:                    PID's integral term in the power allocator gov
+    |---k_d:                    PID's derivative term in the power allocator
+    |---integral_cutoff:        Offset above which errors are accumulated
 
 Thermal cooling device sys I/F, created once it's registered:
 /sys/class/thermal/cooling_device[0-*]:
 
 Thermal cooling device sys I/F, created once it's registered:
 /sys/class/thermal/cooling_device[0-*]:
@@ -307,6 +313,52 @@ emul_temp
          because userland can easily disable the thermal policy by simply
          flooding this sysfs node with low temperature values.
 
          because userland can easily disable the thermal policy by simply
          flooding this sysfs node with low temperature values.
 
+sustainable_power
+       An estimate of the sustained power that can be dissipated by
+       the thermal zone. Used by the power allocator governor. For
+       more information see Documentation/thermal/power_allocator.txt
+       Unit: milliwatts
+       RW, Optional
+
+k_po
+       The proportional term of the power allocator governor's PID
+       controller during temperature overshoot. Temperature overshoot
+       is when the current temperature is above the "desired
+       temperature" trip point. For more information see
+       Documentation/thermal/power_allocator.txt
+       RW, Optional
+
+k_pu
+       The proportional term of the power allocator governor's PID
+       controller during temperature undershoot. Temperature undershoot
+       is when the current temperature is below the "desired
+       temperature" trip point. For more information see
+       Documentation/thermal/power_allocator.txt
+       RW, Optional
+
+k_i
+       The integral term of the power allocator governor's PID
+       controller. This term allows the PID controller to compensate
+       for long term drift. For more information see
+       Documentation/thermal/power_allocator.txt
+       RW, Optional
+
+k_d
+       The derivative term of the power allocator governor's PID
+       controller. For more information see
+       Documentation/thermal/power_allocator.txt
+       RW, Optional
+
+integral_cutoff
+       Temperature offset from the desired temperature trip point
+       above which the integral term of the power allocator
+       governor's PID controller starts accumulating errors. For
+       example, if integral_cutoff is 0, then the integral term only
+       accumulates error when temperature is above the desired
+       temperature trip point. For more information see
+       Documentation/thermal/power_allocator.txt
+       RW, Optional
+
 *****************************
 * Cooling device attributes *
 *****************************
 *****************************
 * Cooling device attributes *
 *****************************
index 78bb9aa9d4e402bd221b34797c84f172533bf879..962de1847cc08b40855df8c532e9f7e2d5ed0766 100644 (file)
@@ -875,6 +875,102 @@ emul_temp_store(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
 #endif/*CONFIG_THERMAL_EMULATION*/
 
 static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
 #endif/*CONFIG_THERMAL_EMULATION*/
 
+static ssize_t
+sustainable_power_show(struct device *dev, struct device_attribute *devattr,
+                      char *buf)
+{
+       struct thermal_zone_device *tz = to_thermal_zone(dev);
+
+       if (tz->tzp)
+               return sprintf(buf, "%u\n", tz->tzp->sustainable_power);
+       else
+               return -EIO;
+}
+
+static ssize_t
+sustainable_power_store(struct device *dev, struct device_attribute *devattr,
+                       const char *buf, size_t count)
+{
+       struct thermal_zone_device *tz = to_thermal_zone(dev);
+       u32 sustainable_power;
+
+       if (!tz->tzp)
+               return -EIO;
+
+       if (kstrtou32(buf, 10, &sustainable_power))
+               return -EINVAL;
+
+       tz->tzp->sustainable_power = sustainable_power;
+
+       return count;
+}
+static DEVICE_ATTR(sustainable_power, S_IWUSR | S_IRUGO, sustainable_power_show,
+               sustainable_power_store);
+
+#define create_s32_tzp_attr(name)                                      \
+       static ssize_t                                                  \
+       name##_show(struct device *dev, struct device_attribute *devattr, \
+               char *buf)                                              \
+       {                                                               \
+       struct thermal_zone_device *tz = to_thermal_zone(dev);          \
+                                                                       \
+       if (tz->tzp)                                                    \
+               return sprintf(buf, "%u\n", tz->tzp->name);             \
+       else                                                            \
+               return -EIO;                                            \
+       }                                                               \
+                                                                       \
+       static ssize_t                                                  \
+       name##_store(struct device *dev, struct device_attribute *devattr, \
+               const char *buf, size_t count)                          \
+       {                                                               \
+               struct thermal_zone_device *tz = to_thermal_zone(dev);  \
+               s32 value;                                              \
+                                                                       \
+               if (!tz->tzp)                                           \
+                       return -EIO;                                    \
+                                                                       \
+               if (kstrtos32(buf, 10, &value))                         \
+                       return -EINVAL;                                 \
+                                                                       \
+               tz->tzp->name = value;                                  \
+                                                                       \
+               return count;                                           \
+       }                                                               \
+       static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, name##_show, name##_store)
+
+create_s32_tzp_attr(k_po);
+create_s32_tzp_attr(k_pu);
+create_s32_tzp_attr(k_i);
+create_s32_tzp_attr(k_d);
+create_s32_tzp_attr(integral_cutoff);
+#undef create_s32_tzp_attr
+
+static struct device_attribute *dev_tzp_attrs[] = {
+       &dev_attr_sustainable_power,
+       &dev_attr_k_po,
+       &dev_attr_k_pu,
+       &dev_attr_k_i,
+       &dev_attr_k_d,
+       &dev_attr_integral_cutoff,
+};
+
+static int create_tzp_attrs(struct device *dev)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dev_tzp_attrs); i++) {
+               int ret;
+               struct device_attribute *dev_attr = dev_tzp_attrs[i];
+
+               ret = device_create_file(dev, dev_attr);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 /**
  * power_actor_get_max_power() - get the maximum power that a cdev can consume
  * @cdev:      pointer to &thermal_cooling_device
 /**
  * power_actor_get_max_power() - get the maximum power that a cdev can consume
  * @cdev:      pointer to &thermal_cooling_device
@@ -1712,6 +1808,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
        if (result)
                goto unregister;
 
        if (result)
                goto unregister;
 
+       /* Add thermal zone params */
+       result = create_tzp_attrs(&tz->device);
+       if (result)
+               goto unregister;
+
        /* Update 'this' zone's governor information */
        mutex_lock(&thermal_governor_lock);
 
        /* Update 'this' zone's governor information */
        mutex_lock(&thermal_governor_lock);
 
This page took 0.027674 seconds and 5 git commands to generate.