38
38
39
39
#include <linux/kernel.h>
40
40
#include <linux/module.h>
41
+ #include <linux/debugfs.h>
41
42
#include <linux/pci.h>
42
43
#include "processor_thermal_device.h"
43
44
@@ -49,14 +50,16 @@ struct mmio_reg {
49
50
};
50
51
51
52
#define MAX_ATTR_GROUP_NAME_LEN 32
52
- #define PTC_MAX_ATTRS 3
53
+ #define PTC_MAX_ATTRS 4
53
54
54
55
struct ptc_data {
55
56
u32 offset ;
57
+ struct pci_dev * pdev ;
56
58
struct attribute_group ptc_attr_group ;
57
59
struct attribute * ptc_attrs [PTC_MAX_ATTRS ];
58
60
struct device_attribute temperature_target_attr ;
59
61
struct device_attribute enable_attr ;
62
+ struct device_attribute thermal_tolerance_attr ;
60
63
char group_name [MAX_ATTR_GROUP_NAME_LEN ];
61
64
};
62
65
@@ -78,6 +81,7 @@ static u32 ptc_offsets[PTC_MAX_INSTANCES] = {0x5B20, 0x5B28, 0x5B30};
78
81
static const char * const ptc_strings [] = {
79
82
"temperature_target" ,
80
83
"enable" ,
84
+ "thermal_tolerance" ,
81
85
NULL
82
86
};
83
87
@@ -177,6 +181,8 @@ PTC_SHOW(temperature_target);
177
181
PTC_STORE (temperature_target );
178
182
PTC_SHOW (enable );
179
183
PTC_STORE (enable );
184
+ PTC_SHOW (thermal_tolerance );
185
+ PTC_STORE (thermal_tolerance );
180
186
181
187
#define ptc_init_attribute (_name )\
182
188
do {\
@@ -193,9 +199,11 @@ static int ptc_create_groups(struct pci_dev *pdev, int instance, struct ptc_data
193
199
194
200
ptc_init_attribute (temperature_target );
195
201
ptc_init_attribute (enable );
202
+ ptc_init_attribute (thermal_tolerance );
196
203
197
204
data -> ptc_attrs [index ++ ] = & data -> temperature_target_attr .attr ;
198
205
data -> ptc_attrs [index ++ ] = & data -> enable_attr .attr ;
206
+ data -> ptc_attrs [index ++ ] = & data -> thermal_tolerance_attr .attr ;
199
207
data -> ptc_attrs [index ] = NULL ;
200
208
201
209
snprintf (data -> group_name , MAX_ATTR_GROUP_NAME_LEN ,
@@ -209,6 +217,63 @@ static int ptc_create_groups(struct pci_dev *pdev, int instance, struct ptc_data
209
217
}
210
218
211
219
static struct ptc_data ptc_instance [PTC_MAX_INSTANCES ];
220
+ static struct dentry * ptc_debugfs ;
221
+
222
+ #define PTC_TEMP_OVERRIDE_ENABLE_INDEX 4
223
+ #define PTC_TEMP_OVERRIDE_INDEX 5
224
+
225
+ static ssize_t ptc_temperature_write (struct file * file , const char __user * data ,
226
+ size_t count , loff_t * ppos )
227
+ {
228
+ struct ptc_data * ptc_instance = file -> private_data ;
229
+ struct pci_dev * pdev = ptc_instance -> pdev ;
230
+ char buf [32 ];
231
+ ssize_t len ;
232
+ u32 value ;
233
+
234
+ len = min (count , sizeof (buf ) - 1 );
235
+ if (copy_from_user (buf , data , len ))
236
+ return - EFAULT ;
237
+
238
+ buf [len ] = '\0' ;
239
+ if (kstrtouint (buf , 0 , & value ))
240
+ return - EINVAL ;
241
+
242
+ if (ptc_mmio_regs [PTC_TEMP_OVERRIDE_INDEX ].units )
243
+ value /= ptc_mmio_regs [PTC_TEMP_OVERRIDE_INDEX ].units ;
244
+
245
+ if (value > ptc_mmio_regs [PTC_TEMP_OVERRIDE_INDEX ].mask )
246
+ return - EINVAL ;
247
+
248
+ if (!value ) {
249
+ ptc_mmio_write (pdev , ptc_instance -> offset , PTC_TEMP_OVERRIDE_ENABLE_INDEX , 0 );
250
+ } else {
251
+ ptc_mmio_write (pdev , ptc_instance -> offset , PTC_TEMP_OVERRIDE_INDEX , value );
252
+ ptc_mmio_write (pdev , ptc_instance -> offset , PTC_TEMP_OVERRIDE_ENABLE_INDEX , 1 );
253
+ }
254
+
255
+ return count ;
256
+ }
257
+
258
+ static const struct file_operations ptc_fops = {
259
+ .open = simple_open ,
260
+ .write = ptc_temperature_write ,
261
+ .llseek = generic_file_llseek ,
262
+ };
263
+
264
+ static void ptc_create_debugfs (void )
265
+ {
266
+ ptc_debugfs = debugfs_create_dir ("platform_temperature_control" , NULL );
267
+
268
+ debugfs_create_file ("temperature_0" , 0200 , ptc_debugfs , & ptc_instance [0 ], & ptc_fops );
269
+ debugfs_create_file ("temperature_1" , 0200 , ptc_debugfs , & ptc_instance [1 ], & ptc_fops );
270
+ debugfs_create_file ("temperature_2" , 0200 , ptc_debugfs , & ptc_instance [2 ], & ptc_fops );
271
+ }
272
+
273
+ static void ptc_delete_debugfs (void )
274
+ {
275
+ debugfs_remove_recursive (ptc_debugfs );
276
+ }
212
277
213
278
int proc_thermal_ptc_add (struct pci_dev * pdev , struct proc_thermal_device * proc_priv )
214
279
{
@@ -217,8 +282,11 @@ int proc_thermal_ptc_add(struct pci_dev *pdev, struct proc_thermal_device *proc_
217
282
218
283
for (i = 0 ; i < PTC_MAX_INSTANCES ; i ++ ) {
219
284
ptc_instance [i ].offset = ptc_offsets [i ];
285
+ ptc_instance [i ].pdev = pdev ;
220
286
ptc_create_groups (pdev , i , & ptc_instance [i ]);
221
287
}
288
+
289
+ ptc_create_debugfs ();
222
290
}
223
291
224
292
return 0 ;
@@ -234,6 +302,8 @@ void proc_thermal_ptc_remove(struct pci_dev *pdev)
234
302
235
303
for (i = 0 ; i < PTC_MAX_INSTANCES ; i ++ )
236
304
sysfs_remove_group (& pdev -> dev .kobj , & ptc_instance [i ].ptc_attr_group );
305
+
306
+ ptc_delete_debugfs ();
237
307
}
238
308
}
239
309
EXPORT_SYMBOL_GPL (proc_thermal_ptc_remove );
0 commit comments