Loongson-3 machines may have as many as 4 physical packages. Signed-off-by: Huacai Chen <chenhc@xxxxxxxxxx> --- drivers/platform/mips/cpu_hwmon.c | 112 +++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 33 deletions(-) diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c index 46ab7d86..0a7529e 100644 --- a/drivers/platform/mips/cpu_hwmon.c +++ b/drivers/platform/mips/cpu_hwmon.c @@ -37,6 +37,7 @@ int loongson3_cpu_temp(int cpu) return (int)reg * 1000; } +static int nr_packages; static struct device *cpu_hwmon_dev; static ssize_t get_hwmon_name(struct device *dev, @@ -64,26 +65,49 @@ static ssize_t get_cpu0_temp(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t get_cpu1_temp(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t get_cpu2_temp(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t get_cpu3_temp(struct device *dev, + struct device_attribute *attr, char *buf); static ssize_t cpu0_temp_label(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t cpu1_temp_label(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t cpu2_temp_label(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t cpu3_temp_label(struct device *dev, + struct device_attribute *attr, char *buf); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2); static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2); - -static const struct attribute *hwmon_cputemp1[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_label.dev_attr.attr, - NULL -}; - -static const struct attribute *hwmon_cputemp2[] = { - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp2_label.dev_attr.attr, - NULL +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, get_cpu2_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, cpu2_temp_label, NULL, 1); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, get_cpu3_temp, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, cpu3_temp_label, NULL, 2); + +static const struct attribute *hwmon_cputemp[4][3] = { + { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_label.dev_attr.attr, + NULL + }, + { + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_label.dev_attr.attr, + NULL + }, + { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_label.dev_attr.attr, + NULL + }, + { + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_label.dev_attr.attr, + NULL + } }; static ssize_t cpu0_temp_label(struct device *dev, @@ -98,6 +122,18 @@ static ssize_t cpu1_temp_label(struct device *dev, return sprintf(buf, "CPU 1 Temperature\n"); } +static ssize_t cpu2_temp_label(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "CPU 2 Temperature\n"); +} + +static ssize_t cpu3_temp_label(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "CPU 3 Temperature\n"); +} + static ssize_t get_cpu0_temp(struct device *dev, struct device_attribute *attr, char *buf) { @@ -112,36 +148,36 @@ static ssize_t get_cpu1_temp(struct device *dev, return sprintf(buf, "%d\n", value); } -static int create_sysfs_cputemp_files(struct kobject *kobj) +static ssize_t get_cpu2_temp(struct device *dev, + struct device_attribute *attr, char *buf) { - int ret; - - ret = sysfs_create_files(kobj, hwmon_cputemp1); - if (ret) - goto sysfs_create_temp1_fail; - - if (loongson_sysconf.nr_cpus <= loongson_sysconf.cores_per_package) - return 0; + int value = loongson3_cpu_temp(2); + return sprintf(buf, "%d\n", value); +} - ret = sysfs_create_files(kobj, hwmon_cputemp2); - if (ret) - goto sysfs_create_temp2_fail; +static ssize_t get_cpu3_temp(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int value = loongson3_cpu_temp(3); + return sprintf(buf, "%d\n", value); +} - return 0; +static int create_sysfs_cputemp_files(struct kobject *kobj) +{ + int i, ret = 0; -sysfs_create_temp2_fail: - sysfs_remove_files(kobj, hwmon_cputemp1); + for (i=0; i<nr_packages; i++) + ret = sysfs_create_files(kobj, hwmon_cputemp[i]); -sysfs_create_temp1_fail: - return -1; + return ret; } static void remove_sysfs_cputemp_files(struct kobject *kobj) { - sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp1); + int i; - if (loongson_sysconf.nr_cpus > loongson_sysconf.cores_per_package) - sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp2); + for (i=0; i<nr_packages; i++) + sysfs_remove_files(kobj, hwmon_cputemp[i]); } #define CPU_THERMAL_THRESHOLD 90000 @@ -149,8 +185,15 @@ static struct delayed_work thermal_work; static void do_thermal_timer(struct work_struct *work) { - int value = loongson3_cpu_temp(0); - if (value <= CPU_THERMAL_THRESHOLD) + int i, value, temp_max = 0; + + for (i=0; i<nr_packages; i++) { + value = loongson3_cpu_temp(i); + if (value > temp_max) + temp_max = value; + } + + if (temp_max <= CPU_THERMAL_THRESHOLD) schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000)); else orderly_poweroff(true); @@ -169,6 +212,9 @@ static int __init loongson_hwmon_init(void) goto fail_hwmon_device_register; } + nr_packages = loongson_sysconf.nr_cpus / + loongson_sysconf.cores_per_package; + ret = sysfs_create_group(&cpu_hwmon_dev->kobj, &cpu_hwmon_attribute_group); if (ret) { -- 2.7.0