diff options
author | Huacai Chen <chenhc@lemote.com> | 2017-06-22 11:06:51 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2017-06-28 20:42:22 -0400 |
commit | 99b0b5a3a1e994247e7533de0fd7e4d13ead0ddd (patch) | |
tree | 54f4e0f9fc0fa7cc87d4851fefc28d206ad2aff2 | |
parent | b392ee07999aa1f19b3a845fad47ec4275341f71 (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.c | 119 |
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 | ||
40 | static int nr_packages; | ||
40 | static struct device *cpu_hwmon_dev; | 41 | static struct device *cpu_hwmon_dev; |
41 | 42 | ||
42 | static ssize_t get_hwmon_name(struct device *dev, | 43 | static 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 | ||
63 | static ssize_t get_cpu0_temp(struct device *dev, | 64 | static ssize_t get_cpu_temp(struct device *dev, |
64 | struct device_attribute *attr, char *buf); | 65 | struct device_attribute *attr, char *buf); |
65 | static ssize_t get_cpu1_temp(struct device *dev, | 66 | static ssize_t cpu_temp_label(struct device *dev, |
66 | struct device_attribute *attr, char *buf); | ||
67 | static ssize_t cpu0_temp_label(struct device *dev, | ||
68 | struct device_attribute *attr, char *buf); | ||
69 | static ssize_t cpu1_temp_label(struct device *dev, | ||
70 | struct device_attribute *attr, char *buf); | 67 | struct device_attribute *attr, char *buf); |
71 | 68 | ||
72 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1); | 69 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL, 1); |
73 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1); | 70 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu_temp_label, NULL, 1); |
74 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2); | 71 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu_temp, NULL, 2); |
75 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2); | 72 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu_temp_label, NULL, 2); |
76 | 73 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, get_cpu_temp, NULL, 3); | |
77 | static const struct attribute *hwmon_cputemp1[] = { | 74 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, cpu_temp_label, NULL, 3); |
78 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 75 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, get_cpu_temp, NULL, 4); |
79 | &sensor_dev_attr_temp1_label.dev_attr.attr, | 76 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, cpu_temp_label, NULL, 4); |
80 | NULL | 77 | |
81 | }; | 78 | static const struct attribute *hwmon_cputemp[4][3] = { |
82 | 79 | { | |
83 | static 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 | ||
89 | static ssize_t cpu0_temp_label(struct device *dev, | 101 | static 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 | ||
95 | static ssize_t cpu1_temp_label(struct device *dev, | 108 | static 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 | |||
101 | static 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 | |||
108 | static 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 | ||
115 | static int create_sysfs_cputemp_files(struct kobject *kobj) | 116 | static 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 | ||
132 | sysfs_create_temp2_fail: | 123 | return ret; |
133 | sysfs_remove_files(kobj, hwmon_cputemp1); | ||
134 | |||
135 | sysfs_create_temp1_fail: | ||
136 | return -1; | ||
137 | } | 124 | } |
138 | 125 | ||
139 | static void remove_sysfs_cputemp_files(struct kobject *kobj) | 126 | static 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 | ||
150 | static void do_thermal_timer(struct work_struct *work) | 137 | static 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) { |