summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuacai Chen <chenhc@lemote.com>2017-06-22 11:06:51 -0400
committerRalf Baechle <ralf@linux-mips.org>2017-06-28 20:42:22 -0400
commit99b0b5a3a1e994247e7533de0fd7e4d13ead0ddd (patch)
tree54f4e0f9fc0fa7cc87d4851fefc28d206ad2aff2
parentb392ee07999aa1f19b3a845fad47ec4275341f71 (diff)
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>
-rw-r--r--drivers/platform/mips/cpu_hwmon.c119
1 files changed, 58 insertions, 61 deletions
diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c
index 46ab7d86ae1c..322de58eebaf 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)
37 return (int)reg * 1000; 37 return (int)reg * 1000;
38} 38}
39 39
40static int nr_packages;
40static struct device *cpu_hwmon_dev; 41static struct device *cpu_hwmon_dev;
41 42
42static ssize_t get_hwmon_name(struct device *dev, 43static ssize_t get_hwmon_name(struct device *dev,
@@ -60,88 +61,74 @@ static ssize_t get_hwmon_name(struct device *dev,
60 return sprintf(buf, "cpu-hwmon\n"); 61 return sprintf(buf, "cpu-hwmon\n");
61} 62}
62 63
63static ssize_t get_cpu0_temp(struct device *dev, 64static ssize_t get_cpu_temp(struct device *dev,
64 struct device_attribute *attr, char *buf); 65 struct device_attribute *attr, char *buf);
65static ssize_t get_cpu1_temp(struct device *dev, 66static ssize_t cpu_temp_label(struct device *dev,
66 struct device_attribute *attr, char *buf);
67static ssize_t cpu0_temp_label(struct device *dev,
68 struct device_attribute *attr, char *buf);
69static ssize_t cpu1_temp_label(struct device *dev,
70 struct device_attribute *attr, char *buf); 67 struct device_attribute *attr, char *buf);
71 68
72static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1); 69static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL, 1);
73static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1); 70static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu_temp_label, NULL, 1);
74static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2); 71static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu_temp, NULL, 2);
75static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2); 72static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu_temp_label, NULL, 2);
76 73static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, get_cpu_temp, NULL, 3);
77static const struct attribute *hwmon_cputemp1[] = { 74static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, cpu_temp_label, NULL, 3);
78 &sensor_dev_attr_temp1_input.dev_attr.attr, 75static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, get_cpu_temp, NULL, 4);
79 &sensor_dev_attr_temp1_label.dev_attr.attr, 76static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, cpu_temp_label, NULL, 4);
80 NULL 77
81}; 78static const struct attribute *hwmon_cputemp[4][3] = {
82 79 {
83static const struct attribute *hwmon_cputemp2[] = { 80 &sensor_dev_attr_temp1_input.dev_attr.attr,
84 &sensor_dev_attr_temp2_input.dev_attr.attr, 81 &sensor_dev_attr_temp1_label.dev_attr.attr,
85 &sensor_dev_attr_temp2_label.dev_attr.attr, 82 NULL
86 NULL 83 },
84 {
85 &sensor_dev_attr_temp2_input.dev_attr.attr,
86 &sensor_dev_attr_temp2_label.dev_attr.attr,
87 NULL
88 },
89 {
90 &sensor_dev_attr_temp3_input.dev_attr.attr,
91 &sensor_dev_attr_temp3_label.dev_attr.attr,
92 NULL
93 },
94 {
95 &sensor_dev_attr_temp4_input.dev_attr.attr,
96 &sensor_dev_attr_temp4_label.dev_attr.attr,
97 NULL
98 }
87}; 99};
88 100
89static ssize_t cpu0_temp_label(struct device *dev, 101static ssize_t cpu_temp_label(struct device *dev,
90 struct device_attribute *attr, char *buf) 102 struct device_attribute *attr, char *buf)
91{ 103{
92 return sprintf(buf, "CPU 0 Temperature\n"); 104 int id = (to_sensor_dev_attr(attr))->index - 1;
105 return sprintf(buf, "CPU %d Temperature\n", id);
93} 106}
94 107
95static ssize_t cpu1_temp_label(struct device *dev, 108static ssize_t get_cpu_temp(struct device *dev,
96 struct device_attribute *attr, char *buf) 109 struct device_attribute *attr, char *buf)
97{ 110{
98 return sprintf(buf, "CPU 1 Temperature\n"); 111 int id = (to_sensor_dev_attr(attr))->index - 1;
99} 112 int value = loongson3_cpu_temp(id);
100
101static ssize_t get_cpu0_temp(struct device *dev,
102 struct device_attribute *attr, char *buf)
103{
104 int value = loongson3_cpu_temp(0);
105 return sprintf(buf, "%d\n", value);
106}
107
108static ssize_t get_cpu1_temp(struct device *dev,
109 struct device_attribute *attr, char *buf)
110{
111 int value = loongson3_cpu_temp(1);
112 return sprintf(buf, "%d\n", value); 113 return sprintf(buf, "%d\n", value);
113} 114}
114 115
115static int create_sysfs_cputemp_files(struct kobject *kobj) 116static int create_sysfs_cputemp_files(struct kobject *kobj)
116{ 117{
117 int ret; 118 int i, ret = 0;
118
119 ret = sysfs_create_files(kobj, hwmon_cputemp1);
120 if (ret)
121 goto sysfs_create_temp1_fail;
122
123 if (loongson_sysconf.nr_cpus <= loongson_sysconf.cores_per_package)
124 return 0;
125
126 ret = sysfs_create_files(kobj, hwmon_cputemp2);
127 if (ret)
128 goto sysfs_create_temp2_fail;
129 119
130 return 0; 120 for (i=0; i<nr_packages; i++)
121 ret = sysfs_create_files(kobj, hwmon_cputemp[i]);
131 122
132sysfs_create_temp2_fail: 123 return ret;
133 sysfs_remove_files(kobj, hwmon_cputemp1);
134
135sysfs_create_temp1_fail:
136 return -1;
137} 124}
138 125
139static void remove_sysfs_cputemp_files(struct kobject *kobj) 126static void remove_sysfs_cputemp_files(struct kobject *kobj)
140{ 127{
141 sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp1); 128 int i;
142 129
143 if (loongson_sysconf.nr_cpus > loongson_sysconf.cores_per_package) 130 for (i=0; i<nr_packages; i++)
144 sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp2); 131 sysfs_remove_files(kobj, hwmon_cputemp[i]);
145} 132}
146 133
147#define CPU_THERMAL_THRESHOLD 90000 134#define CPU_THERMAL_THRESHOLD 90000
@@ -149,8 +136,15 @@ static struct delayed_work thermal_work;
149 136
150static void do_thermal_timer(struct work_struct *work) 137static void do_thermal_timer(struct work_struct *work)
151{ 138{
152 int value = loongson3_cpu_temp(0); 139 int i, value, temp_max = 0;
153 if (value <= CPU_THERMAL_THRESHOLD) 140
141 for (i=0; i<nr_packages; i++) {
142 value = loongson3_cpu_temp(i);
143 if (value > temp_max)
144 temp_max = value;
145 }
146
147 if (temp_max <= CPU_THERMAL_THRESHOLD)
154 schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000)); 148 schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000));
155 else 149 else
156 orderly_poweroff(true); 150 orderly_poweroff(true);
@@ -169,6 +163,9 @@ static int __init loongson_hwmon_init(void)
169 goto fail_hwmon_device_register; 163 goto fail_hwmon_device_register;
170 } 164 }
171 165
166 nr_packages = loongson_sysconf.nr_cpus /
167 loongson_sysconf.cores_per_package;
168
172 ret = sysfs_create_group(&cpu_hwmon_dev->kobj, 169 ret = sysfs_create_group(&cpu_hwmon_dev->kobj,
173 &cpu_hwmon_attribute_group); 170 &cpu_hwmon_attribute_group);
174 if (ret) { 171 if (ret) {