1
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
2
/*
3
- * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h processor hardware monitoring
3
+ * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h/17h
4
+ * processor hardware monitoring
4
5
*
5
6
* Copyright (c) 2009 Clemens Ladisch <[email protected] >
7
+ * Copyright (c) 2020 Guenter Roeck <[email protected] >
6
8
*/
7
9
8
10
#include <linux/bitops.h>
9
11
#include <linux/err.h>
10
12
#include <linux/hwmon.h>
11
- #include <linux/hwmon-sysfs.h>
12
13
#include <linux/init.h>
13
14
#include <linux/module.h>
14
15
#include <linux/pci.h>
@@ -127,10 +128,10 @@ static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
127
128
F17H_M01H_REPORTED_TEMP_CTRL_OFFSET , regval );
128
129
}
129
130
130
- static unsigned int get_raw_temp (struct k10temp_data * data )
131
+ static long get_raw_temp (struct k10temp_data * data )
131
132
{
132
- unsigned int temp ;
133
133
u32 regval ;
134
+ long temp ;
134
135
135
136
data -> read_tempreg (data -> pdev , & regval );
136
137
temp = (regval >> CUR_TEMP_SHIFT ) * 125 ;
@@ -139,118 +140,108 @@ static unsigned int get_raw_temp(struct k10temp_data *data)
139
140
return temp ;
140
141
}
141
142
142
- static ssize_t temp1_input_show (struct device * dev ,
143
- struct device_attribute * attr , char * buf )
144
- {
145
- struct k10temp_data * data = dev_get_drvdata (dev );
146
- unsigned int temp = get_raw_temp (data );
147
-
148
- if (temp > data -> temp_offset )
149
- temp -= data -> temp_offset ;
150
- else
151
- temp = 0 ;
152
-
153
- return sprintf (buf , "%u\n" , temp );
154
- }
155
-
156
- static ssize_t temp2_input_show (struct device * dev ,
157
- struct device_attribute * devattr , char * buf )
158
- {
159
- struct k10temp_data * data = dev_get_drvdata (dev );
160
- unsigned int temp = get_raw_temp (data );
161
-
162
- return sprintf (buf , "%u\n" , temp );
163
- }
164
-
165
- static ssize_t temp_label_show (struct device * dev ,
166
- struct device_attribute * devattr , char * buf )
167
- {
168
- struct sensor_device_attribute * attr = to_sensor_dev_attr (devattr );
169
-
170
- return sprintf (buf , "%s\n" , attr -> index ? "Tctl" : "Tdie" );
171
- }
143
+ const char * k10temp_temp_label [] = {
144
+ "Tdie" ,
145
+ "Tctl" ,
146
+ };
172
147
173
- static ssize_t temp1_max_show (struct device * dev ,
174
- struct device_attribute * attr , char * buf )
148
+ static int k10temp_read_labels (struct device * dev ,
149
+ enum hwmon_sensor_types type ,
150
+ u32 attr , int channel , const char * * str )
175
151
{
176
- return sprintf (buf , "%d\n" , 70 * 1000 );
152
+ * str = k10temp_temp_label [channel ];
153
+ return 0 ;
177
154
}
178
155
179
- static ssize_t temp_crit_show (struct device * dev ,
180
- struct device_attribute * devattr , char * buf )
156
+ static int k10temp_read (struct device * dev , enum hwmon_sensor_types type ,
157
+ u32 attr , int channel , long * val )
181
158
{
182
- struct sensor_device_attribute * attr = to_sensor_dev_attr (devattr );
183
159
struct k10temp_data * data = dev_get_drvdata (dev );
184
- int show_hyst = attr -> index ;
185
160
u32 regval ;
186
- int value ;
187
161
188
- data -> read_htcreg (data -> pdev , & regval );
189
- value = ((regval >> 16 ) & 0x7f ) * 500 + 52000 ;
190
- if (show_hyst )
191
- value -= ((regval >> 24 ) & 0xf ) * 500 ;
192
- return sprintf (buf , "%d\n" , value );
162
+ switch (attr ) {
163
+ case hwmon_temp_input :
164
+ switch (channel ) {
165
+ case 0 : /* Tdie */
166
+ * val = get_raw_temp (data ) - data -> temp_offset ;
167
+ if (* val < 0 )
168
+ * val = 0 ;
169
+ break ;
170
+ case 1 : /* Tctl */
171
+ * val = get_raw_temp (data );
172
+ if (* val < 0 )
173
+ * val = 0 ;
174
+ break ;
175
+ default :
176
+ return - EOPNOTSUPP ;
177
+ }
178
+ break ;
179
+ case hwmon_temp_max :
180
+ * val = 70 * 1000 ;
181
+ break ;
182
+ case hwmon_temp_crit :
183
+ data -> read_htcreg (data -> pdev , & regval );
184
+ * val = ((regval >> 16 ) & 0x7f ) * 500 + 52000 ;
185
+ break ;
186
+ case hwmon_temp_crit_hyst :
187
+ data -> read_htcreg (data -> pdev , & regval );
188
+ * val = (((regval >> 16 ) & 0x7f )
189
+ - ((regval >> 24 ) & 0xf )) * 500 + 52000 ;
190
+ break ;
191
+ default :
192
+ return - EOPNOTSUPP ;
193
+ }
194
+ return 0 ;
193
195
}
194
196
195
- static DEVICE_ATTR_RO (temp1_input );
196
- static DEVICE_ATTR_RO (temp1_max );
197
- static SENSOR_DEVICE_ATTR_RO (temp1_crit , temp_crit , 0 ) ;
198
- static SENSOR_DEVICE_ATTR_RO (temp1_crit_hyst , temp_crit , 1 ) ;
199
-
200
- static SENSOR_DEVICE_ATTR_RO (temp1_label , temp_label , 0 ) ;
201
- static DEVICE_ATTR_RO (temp2_input );
202
- static SENSOR_DEVICE_ATTR_RO (temp2_label , temp_label , 1 ) ;
203
-
204
- static umode_t k10temp_is_visible (struct kobject * kobj ,
205
- struct attribute * attr , int index )
197
+ static umode_t k10temp_is_visible (const void * _data ,
198
+ enum hwmon_sensor_types type ,
199
+ u32 attr , int channel )
206
200
{
207
- struct device * dev = container_of (kobj , struct device , kobj );
208
- struct k10temp_data * data = dev_get_drvdata (dev );
201
+ const struct k10temp_data * data = _data ;
209
202
struct pci_dev * pdev = data -> pdev ;
210
203
u32 reg ;
211
204
212
- switch (index ) {
213
- case 0 ... 1 : /* temp1_input, temp1_max */
214
- default :
215
- break ;
216
- case 2 ... 3 : /* temp1_crit, temp1_crit_hyst */
217
- if (!data -> read_htcreg )
218
- return 0 ;
219
-
220
- pci_read_config_dword (pdev , REG_NORTHBRIDGE_CAPABILITIES ,
221
- & reg );
222
- if (!(reg & NB_CAP_HTC ))
223
- return 0 ;
224
-
225
- data -> read_htcreg (data -> pdev , & reg );
226
- if (!(reg & HTC_ENABLE ))
227
- return 0 ;
228
- break ;
229
- case 4 ... 6 : /* temp1_label, temp2_input, temp2_label */
230
- if (!data -> show_tdie )
205
+ switch (type ) {
206
+ case hwmon_temp :
207
+ switch (attr ) {
208
+ case hwmon_temp_input :
209
+ if (channel && !data -> show_tdie )
210
+ return 0 ;
211
+ break ;
212
+ case hwmon_temp_max :
213
+ if (channel )
214
+ return 0 ;
215
+ break ;
216
+ case hwmon_temp_crit :
217
+ case hwmon_temp_crit_hyst :
218
+ if (channel || !data -> read_htcreg )
219
+ return 0 ;
220
+
221
+ pci_read_config_dword (pdev ,
222
+ REG_NORTHBRIDGE_CAPABILITIES ,
223
+ & reg );
224
+ if (!(reg & NB_CAP_HTC ))
225
+ return 0 ;
226
+
227
+ data -> read_htcreg (data -> pdev , & reg );
228
+ if (!(reg & HTC_ENABLE ))
229
+ return 0 ;
230
+ break ;
231
+ case hwmon_temp_label :
232
+ if (!data -> show_tdie )
233
+ return 0 ;
234
+ break ;
235
+ default :
231
236
return 0 ;
237
+ }
232
238
break ;
239
+ default :
240
+ return 0 ;
233
241
}
234
- return attr -> mode ;
242
+ return 0444 ;
235
243
}
236
244
237
- static struct attribute * k10temp_attrs [] = {
238
- & dev_attr_temp1_input .attr ,
239
- & dev_attr_temp1_max .attr ,
240
- & sensor_dev_attr_temp1_crit .dev_attr .attr ,
241
- & sensor_dev_attr_temp1_crit_hyst .dev_attr .attr ,
242
- & sensor_dev_attr_temp1_label .dev_attr .attr ,
243
- & dev_attr_temp2_input .attr ,
244
- & sensor_dev_attr_temp2_label .dev_attr .attr ,
245
- NULL
246
- };
247
-
248
- static const struct attribute_group k10temp_group = {
249
- .attrs = k10temp_attrs ,
250
- .is_visible = k10temp_is_visible ,
251
- };
252
- __ATTRIBUTE_GROUPS (k10temp );
253
-
254
245
static bool has_erratum_319 (struct pci_dev * pdev )
255
246
{
256
247
u32 pkg_type , reg_dram_cfg ;
@@ -285,8 +276,27 @@ static bool has_erratum_319(struct pci_dev *pdev)
285
276
(boot_cpu_data .x86_model == 4 && boot_cpu_data .x86_stepping <= 2 );
286
277
}
287
278
288
- static int k10temp_probe (struct pci_dev * pdev ,
289
- const struct pci_device_id * id )
279
+ static const struct hwmon_channel_info * k10temp_info [] = {
280
+ HWMON_CHANNEL_INFO (temp ,
281
+ HWMON_T_INPUT | HWMON_T_MAX |
282
+ HWMON_T_CRIT | HWMON_T_CRIT_HYST |
283
+ HWMON_T_LABEL ,
284
+ HWMON_T_INPUT | HWMON_T_LABEL ),
285
+ NULL
286
+ };
287
+
288
+ static const struct hwmon_ops k10temp_hwmon_ops = {
289
+ .is_visible = k10temp_is_visible ,
290
+ .read = k10temp_read ,
291
+ .read_string = k10temp_read_labels ,
292
+ };
293
+
294
+ static const struct hwmon_chip_info k10temp_chip_info = {
295
+ .ops = & k10temp_hwmon_ops ,
296
+ .info = k10temp_info ,
297
+ };
298
+
299
+ static int k10temp_probe (struct pci_dev * pdev , const struct pci_device_id * id )
290
300
{
291
301
int unreliable = has_erratum_319 (pdev );
292
302
struct device * dev = & pdev -> dev ;
@@ -334,8 +344,9 @@ static int k10temp_probe(struct pci_dev *pdev,
334
344
}
335
345
}
336
346
337
- hwmon_dev = devm_hwmon_device_register_with_groups (dev , "k10temp" , data ,
338
- k10temp_groups );
347
+ hwmon_dev = devm_hwmon_device_register_with_info (dev , "k10temp" , data ,
348
+ & k10temp_chip_info ,
349
+ NULL );
339
350
return PTR_ERR_OR_ZERO (hwmon_dev );
340
351
}
341
352
0 commit comments