Commit 99b0b5a3 authored by Huacai Chen's avatar Huacai Chen Committed by Ralf Baechle

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

Loongson-3 machines may have as many as 4 physical packages.
Signed-off-by: default avatarHuacai 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent b392ee07
...@@ -37,6 +37,7 @@ int loongson3_cpu_temp(int cpu) ...@@ -37,6 +37,7 @@ int loongson3_cpu_temp(int cpu)
return (int)reg * 1000; return (int)reg * 1000;
} }
static int nr_packages;
static struct device *cpu_hwmon_dev; static struct device *cpu_hwmon_dev;
static ssize_t get_hwmon_name(struct device *dev, static ssize_t get_hwmon_name(struct device *dev,
...@@ -60,88 +61,74 @@ static ssize_t get_hwmon_name(struct device *dev, ...@@ -60,88 +61,74 @@ static ssize_t get_hwmon_name(struct device *dev,
return sprintf(buf, "cpu-hwmon\n"); return sprintf(buf, "cpu-hwmon\n");
} }
static ssize_t get_cpu0_temp(struct device *dev, static ssize_t get_cpu_temp(struct device *dev,
struct device_attribute *attr, char *buf); struct device_attribute *attr, char *buf);
static ssize_t get_cpu1_temp(struct device *dev, static ssize_t cpu_temp_label(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); struct device_attribute *attr, char *buf);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL, 1);
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1); static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu_temp_label, NULL, 1);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu_temp, NULL, 2);
static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2); static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu_temp_label, NULL, 2);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, get_cpu_temp, NULL, 3);
static const struct attribute *hwmon_cputemp1[] = { static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, cpu_temp_label, NULL, 3);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, get_cpu_temp, NULL, 4);
static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, cpu_temp_label, NULL, 4);
static const struct attribute *hwmon_cputemp[4][3] = {
{
&sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_label.dev_attr.attr, &sensor_dev_attr_temp1_label.dev_attr.attr,
NULL NULL
}; },
{
static const struct attribute *hwmon_cputemp2[] = {
&sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_label.dev_attr.attr, &sensor_dev_attr_temp2_label.dev_attr.attr,
NULL 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, static ssize_t cpu_temp_label(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
return sprintf(buf, "CPU 0 Temperature\n"); int id = (to_sensor_dev_attr(attr))->index - 1;
return sprintf(buf, "CPU %d Temperature\n", id);
} }
static ssize_t cpu1_temp_label(struct device *dev, static ssize_t get_cpu_temp(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
return sprintf(buf, "CPU 1 Temperature\n"); int id = (to_sensor_dev_attr(attr))->index - 1;
} int value = loongson3_cpu_temp(id);
static ssize_t get_cpu0_temp(struct device *dev,
struct device_attribute *attr, char *buf)
{
int value = loongson3_cpu_temp(0);
return sprintf(buf, "%d\n", value);
}
static ssize_t get_cpu1_temp(struct device *dev,
struct device_attribute *attr, char *buf)
{
int value = loongson3_cpu_temp(1);
return sprintf(buf, "%d\n", value); return sprintf(buf, "%d\n", value);
} }
static int create_sysfs_cputemp_files(struct kobject *kobj) static int create_sysfs_cputemp_files(struct kobject *kobj)
{ {
int ret; int i, ret = 0;
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;
ret = sysfs_create_files(kobj, hwmon_cputemp2);
if (ret)
goto sysfs_create_temp2_fail;
return 0; for (i=0; i<nr_packages; i++)
ret = sysfs_create_files(kobj, hwmon_cputemp[i]);
sysfs_create_temp2_fail: return ret;
sysfs_remove_files(kobj, hwmon_cputemp1);
sysfs_create_temp1_fail:
return -1;
} }
static void remove_sysfs_cputemp_files(struct kobject *kobj) 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) for (i=0; i<nr_packages; i++)
sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp2); sysfs_remove_files(kobj, hwmon_cputemp[i]);
} }
#define CPU_THERMAL_THRESHOLD 90000 #define CPU_THERMAL_THRESHOLD 90000
...@@ -149,8 +136,15 @@ static struct delayed_work thermal_work; ...@@ -149,8 +136,15 @@ static struct delayed_work thermal_work;
static void do_thermal_timer(struct work_struct *work) static void do_thermal_timer(struct work_struct *work)
{ {
int value = loongson3_cpu_temp(0); int i, value, temp_max = 0;
if (value <= CPU_THERMAL_THRESHOLD)
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)); schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000));
else else
orderly_poweroff(true); orderly_poweroff(true);
...@@ -169,6 +163,9 @@ static int __init loongson_hwmon_init(void) ...@@ -169,6 +163,9 @@ static int __init loongson_hwmon_init(void)
goto fail_hwmon_device_register; goto fail_hwmon_device_register;
} }
nr_packages = loongson_sysconf.nr_cpus /
loongson_sysconf.cores_per_package;
ret = sysfs_create_group(&cpu_hwmon_dev->kobj, ret = sysfs_create_group(&cpu_hwmon_dev->kobj,
&cpu_hwmon_attribute_group); &cpu_hwmon_attribute_group);
if (ret) { if (ret) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment