[COMMON] thermal: samsung: Introduce balance mode for DTM v0.2.2
authorHyeonseong Gil <hs.gil@samsung.com>
Tue, 15 Nov 2016 02:02:45 +0000 (11:02 +0900)
committerChungwoo Park <cww.park@samsung.com>
Mon, 21 May 2018 08:13:33 +0000 (17:13 +0900)
Resolved migration conflicts from kernel 4.9 to 4.14.
- Move sysfs attrs to thermal_sysfs.c

Change-Id: I100b28897f45e00c8d1b8bc4d62949ac5d1ddb03
Signed-off-by: Hyeonseong Gil <hs.gil@samsung.com>
drivers/thermal/samsung/exynos_tmu.c
drivers/thermal/samsung/exynos_tmu.h
drivers/thermal/thermal_sysfs.c

index e3af8479ff5f4fb23b113193fda3602b757b6678..5767be2e60f1372937ad661d3092f36fcbe59528 100644 (file)
 #define EXYNOS_TMU_NUM_PROBE_MASK              (0x7)
 
 #define TOTAL_SENSORS  8
+#define DEFAULT_BALANCE_OFFSET 20
 
 static bool suspended;
 static bool is_cpu_hotplugged_out;
@@ -886,6 +887,15 @@ static int exynos8895_tmu_read(struct exynos_tmu_data *data)
                                break;
                        case MIN : result = result < temp_cel ? result : temp_cel;
                                break;
+                       case BALANCE:
+                               if (data->sensor_info[i].sensor_num != 0) {
+                                       if (temp_cel >= data->balance_offset)
+                                               temp_cel = temp_cel - data->balance_offset;
+                                       else
+                                               temp_cel = 0;
+                               }
+                               result = result > temp_cel ? result : temp_cel;
+                               break;
                        default : result = temp_cel;
                                break;
                }
@@ -899,6 +909,7 @@ static int exynos8895_tmu_read(struct exynos_tmu_data *data)
                        break;
                case MAX :
                case MIN :
+               case BALANCE:
                default :
                        break;
        }
@@ -1108,6 +1119,8 @@ static int exynos_map_dt_data(struct platform_device *pdev)
                                data->sensing_mode = i;
        }
 
+       data->balance_offset = DEFAULT_BALANCE_OFFSET;
+
        data->hotplug_enable = of_property_read_bool(pdev->dev.of_node, "hotplug_enable");
        if (data->hotplug_enable) {
                dev_info(&pdev->dev, "thermal zone use hotplug function \n");
@@ -1419,6 +1432,156 @@ static int exynos_isp_cooling_register(struct exynos_tmu_data *data)
 static int exynos_isp_cooling_register(struct exynos_tmu_data *data) {return 0;}
 #endif
 
+static ssize_t
+balance_offset_show(struct device *dev, struct device_attribute *devattr,
+                      char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", data->balance_offset);
+}
+
+static ssize_t
+balance_offset_store(struct device *dev, struct device_attribute *devattr,
+                       const char *buf, size_t count)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       int balance_offset = 0;
+
+       mutex_lock(&data->lock);
+
+       if (kstrtos32(buf, 10, &balance_offset)) {
+               mutex_unlock(&data->lock);
+               return -EINVAL;
+       }
+
+       data->balance_offset = balance_offset;
+
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+static ssize_t
+all_temp_show(struct device *dev, struct device_attribute *devattr,
+                      char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       int i, len = 0;
+       u32 reg_offset, bit_offset;
+       u32 temp_code, temp_cel;
+
+       for (i = 0; i < data->num_of_sensors; i++) {
+               if (data->sensor_info[i].sensor_num < 2) {
+                       reg_offset = 0;
+                       bit_offset = EXYNOS_TMU_TEMP_SHIFT * data->sensor_info[i].sensor_num;
+               } else {
+                       reg_offset = ((data->sensor_info[i].sensor_num - 2) / 3 + 1) * 4;
+                       bit_offset = EXYNOS_TMU_TEMP_SHIFT * ((data->sensor_info[i].sensor_num - 2) % 3);
+               }
+
+               temp_code = (readl(data->base + EXYNOS_TMU_REG_CURRENT_TEMP1_0 + reg_offset)
+                               >> bit_offset) & EXYNOS_TMU_TEMP_MASK;
+               temp_cel = code_to_temp_with_sensorinfo(data, temp_code, &data->sensor_info[i]);
+
+               len += snprintf(&buf[len], PAGE_SIZE, "%u, ", temp_cel);
+       }
+
+       len += snprintf(&buf[len], PAGE_SIZE, "\n");
+
+       return len;
+}
+
+static ssize_t
+hotplug_out_temp_show(struct device *dev, struct device_attribute *devattr,
+                      char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", data->hotplug_out_threshold);
+}
+
+static ssize_t
+hotplug_out_temp_store(struct device *dev, struct device_attribute *devattr,
+                       const char *buf, size_t count)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       int hotplug_out = 0;
+
+       mutex_lock(&data->lock);
+
+       if (kstrtos32(buf, 10, &hotplug_out)) {
+               mutex_unlock(&data->lock);
+               return -EINVAL;
+       }
+
+       data->hotplug_out_threshold = hotplug_out;
+
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+static ssize_t
+hotplug_in_temp_show(struct device *dev, struct device_attribute *devattr,
+                      char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", data->hotplug_in_threshold);
+}
+
+static ssize_t
+hotplug_in_temp_store(struct device *dev, struct device_attribute *devattr,
+                       const char *buf, size_t count)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       int hotplug_in = 0;
+
+       mutex_lock(&data->lock);
+
+       if (kstrtos32(buf, 10, &hotplug_in)) {
+               mutex_unlock(&data->lock);
+               return -EINVAL;
+       }
+
+       data->hotplug_in_threshold = hotplug_in;
+
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+static DEVICE_ATTR(balance_offset, S_IWUSR | S_IRUGO, balance_offset_show,
+               balance_offset_store);
+
+static DEVICE_ATTR(all_temp, S_IRUGO, all_temp_show, NULL);
+
+static DEVICE_ATTR(hotplug_out_temp, S_IWUSR | S_IRUGO, hotplug_out_temp_show,
+               hotplug_out_temp_store);
+
+static DEVICE_ATTR(hotplug_in_temp, S_IWUSR | S_IRUGO, hotplug_in_temp_show,
+               hotplug_in_temp_store);
+
+static struct attribute *exynos_tmu_attrs[] = {
+       &dev_attr_balance_offset.attr,
+       &dev_attr_all_temp.attr,
+       &dev_attr_hotplug_out_temp.attr,
+       &dev_attr_hotplug_in_temp.attr,
+       NULL,
+};
+
+static const struct attribute_group exynos_tmu_attr_group = {
+       .attrs = exynos_tmu_attrs,
+};
+
 static int exynos_tmu_probe(struct platform_device *pdev)
 {
        struct exynos_tmu_data *data;
@@ -1507,6 +1670,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 
        exynos_tmu_control(pdev, true);
 
+       ret = sysfs_create_group(&pdev->dev.kobj, &exynos_tmu_attr_group);
+       if (ret)
+               dev_err(&pdev->dev, "cannot create exynos tmu attr group");
+
        mutex_lock(&data->lock);
        list_add_tail(&data->node, &dtm_dev_list);
        mutex_unlock(&data->lock);
index d5142e2255f111433e81246410f01d14c35b0033..f541f6b830677f9e4106d3bd82c9e7f0a5f34ece 100644 (file)
@@ -71,6 +71,7 @@ enum sensing_type {
        AVG = 0,
        MAX,
        MIN,
+       BALANCE,
        END_OF_TYPE,
 };
 
@@ -78,6 +79,7 @@ static const char * const sensing_method[] = {
        [AVG] = "avg",
        [MAX] = "max",
        [MIN] = "min",
+       [BALANCE] = "balance",
 };
 
 enum thermal_zone_name {
@@ -154,6 +156,7 @@ struct exynos_tmu_data {
        int sensing_mode;
        char tmu_name[THERMAL_NAME_LENGTH];
        struct device_node *np;
+       int balance_offset;
 
        int (*tmu_initialize)(struct platform_device *pdev);
        void (*tmu_control)(struct platform_device *pdev, bool on);
index fb80c96d8f73a52a6d821a3bd57b78c08b6f5e26..f76446e3f7a7220030a83a0915ebb13cd93d6cd3 100644 (file)
@@ -389,6 +389,7 @@ create_s32_tzp_attr(k_d);
 create_s32_tzp_attr(integral_cutoff);
 create_s32_tzp_attr(slope);
 create_s32_tzp_attr(offset);
+create_s32_tzp_attr(integral_max);
 #undef create_s32_tzp_attr
 
 /*
@@ -424,6 +425,7 @@ static struct attribute *thermal_zone_dev_attrs[] = {
        &dev_attr_integral_cutoff.attr,
        &dev_attr_slope.attr,
        &dev_attr_offset.attr,
+       &dev_attr_integral_max.attr,
        NULL,
 };