Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: Loongson-3: Support 4 packages in CPU Hwmon driver

Loongson-3 machines may have as many as 4 physical packages.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Cc: John Crispin <john@phrozen.org>
Cc: Steven J . Hill <Steven.Hill@cavium.com>
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16588/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Huacai Chen and committed by
Ralf Baechle
99b0b5a3 b392ee07

+57 -60
+57 -60
drivers/platform/mips/cpu_hwmon.c
··· 37 37 return (int)reg * 1000; 38 38 } 39 39 40 + static int nr_packages; 40 41 static struct device *cpu_hwmon_dev; 41 42 42 43 static ssize_t get_hwmon_name(struct device *dev, ··· 61 60 return sprintf(buf, "cpu-hwmon\n"); 62 61 } 63 62 64 - static ssize_t get_cpu0_temp(struct device *dev, 63 + static ssize_t get_cpu_temp(struct device *dev, 65 64 struct device_attribute *attr, char *buf); 66 - static ssize_t get_cpu1_temp(struct device *dev, 67 - struct device_attribute *attr, char *buf); 68 - static ssize_t cpu0_temp_label(struct device *dev, 69 - struct device_attribute *attr, char *buf); 70 - static ssize_t cpu1_temp_label(struct device *dev, 65 + static ssize_t cpu_temp_label(struct device *dev, 71 66 struct device_attribute *attr, char *buf); 72 67 73 - static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1); 74 - static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1); 75 - static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2); 76 - static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2); 68 + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL, 1); 69 + static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu_temp_label, NULL, 1); 70 + static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu_temp, NULL, 2); 71 + static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu_temp_label, NULL, 2); 72 + static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, get_cpu_temp, NULL, 3); 73 + static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, cpu_temp_label, NULL, 3); 74 + static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, get_cpu_temp, NULL, 4); 75 + static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, cpu_temp_label, NULL, 4); 77 76 78 - static const struct attribute *hwmon_cputemp1[] = { 79 - &sensor_dev_attr_temp1_input.dev_attr.attr, 80 - &sensor_dev_attr_temp1_label.dev_attr.attr, 81 - NULL 77 + static const struct attribute *hwmon_cputemp[4][3] = { 78 + { 79 + &sensor_dev_attr_temp1_input.dev_attr.attr, 80 + &sensor_dev_attr_temp1_label.dev_attr.attr, 81 + NULL 82 + }, 83 + { 84 + &sensor_dev_attr_temp2_input.dev_attr.attr, 85 + &sensor_dev_attr_temp2_label.dev_attr.attr, 86 + NULL 87 + }, 88 + { 89 + &sensor_dev_attr_temp3_input.dev_attr.attr, 90 + &sensor_dev_attr_temp3_label.dev_attr.attr, 91 + NULL 92 + }, 93 + { 94 + &sensor_dev_attr_temp4_input.dev_attr.attr, 95 + &sensor_dev_attr_temp4_label.dev_attr.attr, 96 + NULL 97 + } 82 98 }; 83 99 84 - static const struct attribute *hwmon_cputemp2[] = { 85 - &sensor_dev_attr_temp2_input.dev_attr.attr, 86 - &sensor_dev_attr_temp2_label.dev_attr.attr, 87 - NULL 88 - }; 89 - 90 - static ssize_t cpu0_temp_label(struct device *dev, 100 + static ssize_t cpu_temp_label(struct device *dev, 91 101 struct device_attribute *attr, char *buf) 92 102 { 93 - return sprintf(buf, "CPU 0 Temperature\n"); 103 + int id = (to_sensor_dev_attr(attr))->index - 1; 104 + return sprintf(buf, "CPU %d Temperature\n", id); 94 105 } 95 106 96 - static ssize_t cpu1_temp_label(struct device *dev, 107 + static ssize_t get_cpu_temp(struct device *dev, 97 108 struct device_attribute *attr, char *buf) 98 109 { 99 - return sprintf(buf, "CPU 1 Temperature\n"); 100 - } 101 - 102 - static ssize_t get_cpu0_temp(struct device *dev, 103 - struct device_attribute *attr, char *buf) 104 - { 105 - int value = loongson3_cpu_temp(0); 106 - return sprintf(buf, "%d\n", value); 107 - } 108 - 109 - static ssize_t get_cpu1_temp(struct device *dev, 110 - struct device_attribute *attr, char *buf) 111 - { 112 - int value = loongson3_cpu_temp(1); 110 + int id = (to_sensor_dev_attr(attr))->index - 1; 111 + int value = loongson3_cpu_temp(id); 113 112 return sprintf(buf, "%d\n", value); 114 113 } 115 114 116 115 static int create_sysfs_cputemp_files(struct kobject *kobj) 117 116 { 118 - int ret; 117 + int i, ret = 0; 119 118 120 - ret = sysfs_create_files(kobj, hwmon_cputemp1); 121 - if (ret) 122 - goto sysfs_create_temp1_fail; 119 + for (i=0; i<nr_packages; i++) 120 + ret = sysfs_create_files(kobj, hwmon_cputemp[i]); 123 121 124 - if (loongson_sysconf.nr_cpus <= loongson_sysconf.cores_per_package) 125 - return 0; 126 - 127 - ret = sysfs_create_files(kobj, hwmon_cputemp2); 128 - if (ret) 129 - goto sysfs_create_temp2_fail; 130 - 131 - return 0; 132 - 133 - sysfs_create_temp2_fail: 134 - sysfs_remove_files(kobj, hwmon_cputemp1); 135 - 136 - sysfs_create_temp1_fail: 137 - return -1; 122 + return ret; 138 123 } 139 124 140 125 static void remove_sysfs_cputemp_files(struct kobject *kobj) 141 126 { 142 - sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp1); 127 + int i; 143 128 144 - if (loongson_sysconf.nr_cpus > loongson_sysconf.cores_per_package) 145 - sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp2); 129 + for (i=0; i<nr_packages; i++) 130 + sysfs_remove_files(kobj, hwmon_cputemp[i]); 146 131 } 147 132 148 133 #define CPU_THERMAL_THRESHOLD 90000 ··· 136 149 137 150 static void do_thermal_timer(struct work_struct *work) 138 151 { 139 - int value = loongson3_cpu_temp(0); 140 - if (value <= CPU_THERMAL_THRESHOLD) 152 + int i, value, temp_max = 0; 153 + 154 + for (i=0; i<nr_packages; i++) { 155 + value = loongson3_cpu_temp(i); 156 + if (value > temp_max) 157 + temp_max = value; 158 + } 159 + 160 + if (temp_max <= CPU_THERMAL_THRESHOLD) 141 161 schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000)); 142 162 else 143 163 orderly_poweroff(true); ··· 162 168 pr_err("hwmon_device_register fail!\n"); 163 169 goto fail_hwmon_device_register; 164 170 } 171 + 172 + nr_packages = loongson_sysconf.nr_cpus / 173 + loongson_sysconf.cores_per_package; 165 174 166 175 ret = sysfs_create_group(&cpu_hwmon_dev->kobj, 167 176 &cpu_hwmon_attribute_group);