diff options
author | David Howells <dhowells@redhat.com> | 2013-04-10 20:28:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-04-29 15:41:58 -0400 |
commit | e781c3d794282d9fa3ba377fdef221fc948974ec (patch) | |
tree | 360dce408ba52deaebb85318422a0c756a97442d /arch/ia64/kernel/palinfo.c | |
parent | 24270156ac94a54cfaa7326375ed44d0902f58c5 (diff) |
ia64: Don't use create_proc_read_entry()
Don't use create_proc_read_entry() as that is deprecated, but rather use
proc_create_data() and seq_file instead.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Tony Luck <tony.luck@intel.com>
cc: Fenghua Yu <fenghua.yu@intel.com>
cc: linux-ia64@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/ia64/kernel/palinfo.c')
-rw-r--r-- | arch/ia64/kernel/palinfo.c | 502 |
1 files changed, 238 insertions, 264 deletions
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 79521d5499f9..b17129e3b7c8 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/proc_fs.h> | 24 | #include <linux/proc_fs.h> |
25 | #include <linux/seq_file.h> | ||
25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
26 | #include <linux/module.h> | 27 | #include <linux/module.h> |
27 | #include <linux/efi.h> | 28 | #include <linux/efi.h> |
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL"); | |||
41 | 42 | ||
42 | #define PALINFO_VERSION "0.5" | 43 | #define PALINFO_VERSION "0.5" |
43 | 44 | ||
44 | typedef int (*palinfo_func_t)(char*); | 45 | typedef int (*palinfo_func_t)(struct seq_file *); |
45 | 46 | ||
46 | typedef struct { | 47 | typedef struct { |
47 | const char *name; /* name of the proc entry */ | 48 | const char *name; /* name of the proc entry */ |
@@ -54,7 +55,7 @@ typedef struct { | |||
54 | * A bunch of string array to get pretty printing | 55 | * A bunch of string array to get pretty printing |
55 | */ | 56 | */ |
56 | 57 | ||
57 | static char *cache_types[] = { | 58 | static const char *cache_types[] = { |
58 | "", /* not used */ | 59 | "", /* not used */ |
59 | "Instruction", | 60 | "Instruction", |
60 | "Data", | 61 | "Data", |
@@ -122,19 +123,16 @@ static const char *mem_attrib[]={ | |||
122 | * - a pointer to the end of the buffer | 123 | * - a pointer to the end of the buffer |
123 | * | 124 | * |
124 | */ | 125 | */ |
125 | static char * | 126 | static void bitvector_process(struct seq_file *m, u64 vector) |
126 | bitvector_process(char *p, u64 vector) | ||
127 | { | 127 | { |
128 | int i,j; | 128 | int i,j; |
129 | const char *units[]={ "", "K", "M", "G", "T" }; | 129 | static const char *units[]={ "", "K", "M", "G", "T" }; |
130 | 130 | ||
131 | for (i=0, j=0; i < 64; i++ , j=i/10) { | 131 | for (i=0, j=0; i < 64; i++ , j=i/10) { |
132 | if (vector & 0x1) { | 132 | if (vector & 0x1) |
133 | p += sprintf(p, "%d%s ", 1 << (i-j*10), units[j]); | 133 | seq_printf(m, "%d%s ", 1 << (i-j*10), units[j]); |
134 | } | ||
135 | vector >>= 1; | 134 | vector >>= 1; |
136 | } | 135 | } |
137 | return p; | ||
138 | } | 136 | } |
139 | 137 | ||
140 | /* | 138 | /* |
@@ -149,8 +147,7 @@ bitvector_process(char *p, u64 vector) | |||
149 | * - a pointer to the end of the buffer | 147 | * - a pointer to the end of the buffer |
150 | * | 148 | * |
151 | */ | 149 | */ |
152 | static char * | 150 | static void bitregister_process(struct seq_file *m, u64 *reg_info, int max) |
153 | bitregister_process(char *p, u64 *reg_info, int max) | ||
154 | { | 151 | { |
155 | int i, begin, skip = 0; | 152 | int i, begin, skip = 0; |
156 | u64 value = reg_info[0]; | 153 | u64 value = reg_info[0]; |
@@ -163,9 +160,9 @@ bitregister_process(char *p, u64 *reg_info, int max) | |||
163 | 160 | ||
164 | if ((value & 0x1) == 0 && skip == 0) { | 161 | if ((value & 0x1) == 0 && skip == 0) { |
165 | if (begin <= i - 2) | 162 | if (begin <= i - 2) |
166 | p += sprintf(p, "%d-%d ", begin, i-1); | 163 | seq_printf(m, "%d-%d ", begin, i-1); |
167 | else | 164 | else |
168 | p += sprintf(p, "%d ", i-1); | 165 | seq_printf(m, "%d ", i-1); |
169 | skip = 1; | 166 | skip = 1; |
170 | begin = -1; | 167 | begin = -1; |
171 | } else if ((value & 0x1) && skip == 1) { | 168 | } else if ((value & 0x1) && skip == 1) { |
@@ -176,19 +173,15 @@ bitregister_process(char *p, u64 *reg_info, int max) | |||
176 | } | 173 | } |
177 | if (begin > -1) { | 174 | if (begin > -1) { |
178 | if (begin < 127) | 175 | if (begin < 127) |
179 | p += sprintf(p, "%d-127", begin); | 176 | seq_printf(m, "%d-127", begin); |
180 | else | 177 | else |
181 | p += sprintf(p, "127"); | 178 | seq_puts(m, "127"); |
182 | } | 179 | } |
183 | |||
184 | return p; | ||
185 | } | 180 | } |
186 | 181 | ||
187 | static int | 182 | static int power_info(struct seq_file *m) |
188 | power_info(char *page) | ||
189 | { | 183 | { |
190 | s64 status; | 184 | s64 status; |
191 | char *p = page; | ||
192 | u64 halt_info_buffer[8]; | 185 | u64 halt_info_buffer[8]; |
193 | pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer; | 186 | pal_power_mgmt_info_u_t *halt_info =(pal_power_mgmt_info_u_t *)halt_info_buffer; |
194 | int i; | 187 | int i; |
@@ -198,26 +191,25 @@ power_info(char *page) | |||
198 | 191 | ||
199 | for (i=0; i < 8 ; i++ ) { | 192 | for (i=0; i < 8 ; i++ ) { |
200 | if (halt_info[i].pal_power_mgmt_info_s.im == 1) { | 193 | if (halt_info[i].pal_power_mgmt_info_s.im == 1) { |
201 | p += sprintf(p, "Power level %d:\n" | 194 | seq_printf(m, |
202 | "\tentry_latency : %d cycles\n" | 195 | "Power level %d:\n" |
203 | "\texit_latency : %d cycles\n" | 196 | "\tentry_latency : %d cycles\n" |
204 | "\tpower consumption : %d mW\n" | 197 | "\texit_latency : %d cycles\n" |
205 | "\tCache+TLB coherency : %s\n", i, | 198 | "\tpower consumption : %d mW\n" |
206 | halt_info[i].pal_power_mgmt_info_s.entry_latency, | 199 | "\tCache+TLB coherency : %s\n", i, |
207 | halt_info[i].pal_power_mgmt_info_s.exit_latency, | 200 | halt_info[i].pal_power_mgmt_info_s.entry_latency, |
208 | halt_info[i].pal_power_mgmt_info_s.power_consumption, | 201 | halt_info[i].pal_power_mgmt_info_s.exit_latency, |
209 | halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); | 202 | halt_info[i].pal_power_mgmt_info_s.power_consumption, |
203 | halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No"); | ||
210 | } else { | 204 | } else { |
211 | p += sprintf(p,"Power level %d: not implemented\n",i); | 205 | seq_printf(m,"Power level %d: not implemented\n", i); |
212 | } | 206 | } |
213 | } | 207 | } |
214 | return p - page; | 208 | return 0; |
215 | } | 209 | } |
216 | 210 | ||
217 | static int | 211 | static int cache_info(struct seq_file *m) |
218 | cache_info(char *page) | ||
219 | { | 212 | { |
220 | char *p = page; | ||
221 | unsigned long i, levels, unique_caches; | 213 | unsigned long i, levels, unique_caches; |
222 | pal_cache_config_info_t cci; | 214 | pal_cache_config_info_t cci; |
223 | int j, k; | 215 | int j, k; |
@@ -228,73 +220,74 @@ cache_info(char *page) | |||
228 | return 0; | 220 | return 0; |
229 | } | 221 | } |
230 | 222 | ||
231 | p += sprintf(p, "Cache levels : %ld\nUnique caches : %ld\n\n", levels, unique_caches); | 223 | seq_printf(m, "Cache levels : %ld\nUnique caches : %ld\n\n", |
224 | levels, unique_caches); | ||
232 | 225 | ||
233 | for (i=0; i < levels; i++) { | 226 | for (i=0; i < levels; i++) { |
234 | |||
235 | for (j=2; j >0 ; j--) { | 227 | for (j=2; j >0 ; j--) { |
236 | |||
237 | /* even without unification some level may not be present */ | 228 | /* even without unification some level may not be present */ |
238 | if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) { | 229 | if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) |
239 | continue; | 230 | continue; |
240 | } | 231 | |
241 | p += sprintf(p, | 232 | seq_printf(m, |
242 | "%s Cache level %lu:\n" | 233 | "%s Cache level %lu:\n" |
243 | "\tSize : %u bytes\n" | 234 | "\tSize : %u bytes\n" |
244 | "\tAttributes : ", | 235 | "\tAttributes : ", |
245 | cache_types[j+cci.pcci_unified], i+1, | 236 | cache_types[j+cci.pcci_unified], i+1, |
246 | cci.pcci_cache_size); | 237 | cci.pcci_cache_size); |
247 | 238 | ||
248 | if (cci.pcci_unified) p += sprintf(p, "Unified "); | 239 | if (cci.pcci_unified) |
249 | 240 | seq_puts(m, "Unified "); | |
250 | p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]); | 241 | |
251 | 242 | seq_printf(m, "%s\n", cache_mattrib[cci.pcci_cache_attr]); | |
252 | p += sprintf(p, | 243 | |
253 | "\tAssociativity : %d\n" | 244 | seq_printf(m, |
254 | "\tLine size : %d bytes\n" | 245 | "\tAssociativity : %d\n" |
255 | "\tStride : %d bytes\n", | 246 | "\tLine size : %d bytes\n" |
256 | cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride); | 247 | "\tStride : %d bytes\n", |
248 | cci.pcci_assoc, | ||
249 | 1<<cci.pcci_line_size, | ||
250 | 1<<cci.pcci_stride); | ||
257 | if (j == 1) | 251 | if (j == 1) |
258 | p += sprintf(p, "\tStore latency : N/A\n"); | 252 | seq_puts(m, "\tStore latency : N/A\n"); |
259 | else | 253 | else |
260 | p += sprintf(p, "\tStore latency : %d cycle(s)\n", | 254 | seq_printf(m, "\tStore latency : %d cycle(s)\n", |
261 | cci.pcci_st_latency); | 255 | cci.pcci_st_latency); |
262 | 256 | ||
263 | p += sprintf(p, | 257 | seq_printf(m, |
264 | "\tLoad latency : %d cycle(s)\n" | 258 | "\tLoad latency : %d cycle(s)\n" |
265 | "\tStore hints : ", cci.pcci_ld_latency); | 259 | "\tStore hints : ", cci.pcci_ld_latency); |
266 | 260 | ||
267 | for(k=0; k < 8; k++ ) { | 261 | for(k=0; k < 8; k++ ) { |
268 | if ( cci.pcci_st_hints & 0x1) | 262 | if ( cci.pcci_st_hints & 0x1) |
269 | p += sprintf(p, "[%s]", cache_st_hints[k]); | 263 | seq_printf(m, "[%s]", cache_st_hints[k]); |
270 | cci.pcci_st_hints >>=1; | 264 | cci.pcci_st_hints >>=1; |
271 | } | 265 | } |
272 | p += sprintf(p, "\n\tLoad hints : "); | 266 | seq_puts(m, "\n\tLoad hints : "); |
273 | 267 | ||
274 | for(k=0; k < 8; k++ ) { | 268 | for(k=0; k < 8; k++ ) { |
275 | if (cci.pcci_ld_hints & 0x1) | 269 | if (cci.pcci_ld_hints & 0x1) |
276 | p += sprintf(p, "[%s]", cache_ld_hints[k]); | 270 | seq_printf(m, "[%s]", cache_ld_hints[k]); |
277 | cci.pcci_ld_hints >>=1; | 271 | cci.pcci_ld_hints >>=1; |
278 | } | 272 | } |
279 | p += sprintf(p, | 273 | seq_printf(m, |
280 | "\n\tAlias boundary : %d byte(s)\n" | 274 | "\n\tAlias boundary : %d byte(s)\n" |
281 | "\tTag LSB : %d\n" | 275 | "\tTag LSB : %d\n" |
282 | "\tTag MSB : %d\n", | 276 | "\tTag MSB : %d\n", |
283 | 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb, | 277 | 1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb, |
284 | cci.pcci_tag_msb); | 278 | cci.pcci_tag_msb); |
285 | 279 | ||
286 | /* when unified, data(j=2) is enough */ | 280 | /* when unified, data(j=2) is enough */ |
287 | if (cci.pcci_unified) break; | 281 | if (cci.pcci_unified) |
282 | break; | ||
288 | } | 283 | } |
289 | } | 284 | } |
290 | return p - page; | 285 | return 0; |
291 | } | 286 | } |
292 | 287 | ||
293 | 288 | ||
294 | static int | 289 | static int vm_info(struct seq_file *m) |
295 | vm_info(char *page) | ||
296 | { | 290 | { |
297 | char *p = page; | ||
298 | u64 tr_pages =0, vw_pages=0, tc_pages; | 291 | u64 tr_pages =0, vw_pages=0, tc_pages; |
299 | u64 attrib; | 292 | u64 attrib; |
300 | pal_vm_info_1_u_t vm_info_1; | 293 | pal_vm_info_1_u_t vm_info_1; |
@@ -309,7 +302,7 @@ vm_info(char *page) | |||
309 | printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); | 302 | printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); |
310 | } else { | 303 | } else { |
311 | 304 | ||
312 | p += sprintf(p, | 305 | seq_printf(m, |
313 | "Physical Address Space : %d bits\n" | 306 | "Physical Address Space : %d bits\n" |
314 | "Virtual Address Space : %d bits\n" | 307 | "Virtual Address Space : %d bits\n" |
315 | "Protection Key Registers(PKR) : %d\n" | 308 | "Protection Key Registers(PKR) : %d\n" |
@@ -324,49 +317,49 @@ vm_info(char *page) | |||
324 | vm_info_1.pal_vm_info_1_s.hash_tag_id, | 317 | vm_info_1.pal_vm_info_1_s.hash_tag_id, |
325 | vm_info_2.pal_vm_info_2_s.rid_size); | 318 | vm_info_2.pal_vm_info_2_s.rid_size); |
326 | if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES) | 319 | if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES) |
327 | p += sprintf(p, "unlimited\n"); | 320 | seq_puts(m, "unlimited\n"); |
328 | else | 321 | else |
329 | p += sprintf(p, "%d\n", | 322 | seq_printf(m, "%d\n", |
330 | vm_info_2.pal_vm_info_2_s.max_purges ? | 323 | vm_info_2.pal_vm_info_2_s.max_purges ? |
331 | vm_info_2.pal_vm_info_2_s.max_purges : 1); | 324 | vm_info_2.pal_vm_info_2_s.max_purges : 1); |
332 | } | 325 | } |
333 | 326 | ||
334 | if (ia64_pal_mem_attrib(&attrib) == 0) { | 327 | if (ia64_pal_mem_attrib(&attrib) == 0) { |
335 | p += sprintf(p, "Supported memory attributes : "); | 328 | seq_puts(m, "Supported memory attributes : "); |
336 | sep = ""; | 329 | sep = ""; |
337 | for (i = 0; i < 8; i++) { | 330 | for (i = 0; i < 8; i++) { |
338 | if (attrib & (1 << i)) { | 331 | if (attrib & (1 << i)) { |
339 | p += sprintf(p, "%s%s", sep, mem_attrib[i]); | 332 | seq_printf(m, "%s%s", sep, mem_attrib[i]); |
340 | sep = ", "; | 333 | sep = ", "; |
341 | } | 334 | } |
342 | } | 335 | } |
343 | p += sprintf(p, "\n"); | 336 | seq_putc(m, '\n'); |
344 | } | 337 | } |
345 | 338 | ||
346 | if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { | 339 | if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { |
347 | printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); | 340 | printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); |
348 | } else { | 341 | } else { |
349 | 342 | ||
350 | p += sprintf(p, | 343 | seq_printf(m, |
351 | "\nTLB walker : %simplemented\n" | 344 | "\nTLB walker : %simplemented\n" |
352 | "Number of DTR : %d\n" | 345 | "Number of DTR : %d\n" |
353 | "Number of ITR : %d\n" | 346 | "Number of ITR : %d\n" |
354 | "TLB insertable page sizes : ", | 347 | "TLB insertable page sizes : ", |
355 | vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", | 348 | vm_info_1.pal_vm_info_1_s.vw ? "" : "not ", |
356 | vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, | 349 | vm_info_1.pal_vm_info_1_s.max_dtr_entry+1, |
357 | vm_info_1.pal_vm_info_1_s.max_itr_entry+1); | 350 | vm_info_1.pal_vm_info_1_s.max_itr_entry+1); |
358 | |||
359 | 351 | ||
360 | p = bitvector_process(p, tr_pages); | 352 | bitvector_process(m, tr_pages); |
361 | 353 | ||
362 | p += sprintf(p, "\nTLB purgeable page sizes : "); | 354 | seq_puts(m, "\nTLB purgeable page sizes : "); |
363 | 355 | ||
364 | p = bitvector_process(p, vw_pages); | 356 | bitvector_process(m, vw_pages); |
365 | } | 357 | } |
366 | if ((status=ia64_get_ptce(&ptce)) != 0) { | 358 | |
359 | if ((status = ia64_get_ptce(&ptce)) != 0) { | ||
367 | printk(KERN_ERR "ia64_get_ptce=%ld\n", status); | 360 | printk(KERN_ERR "ia64_get_ptce=%ld\n", status); |
368 | } else { | 361 | } else { |
369 | p += sprintf(p, | 362 | seq_printf(m, |
370 | "\nPurge base address : 0x%016lx\n" | 363 | "\nPurge base address : 0x%016lx\n" |
371 | "Purge outer loop count : %d\n" | 364 | "Purge outer loop count : %d\n" |
372 | "Purge inner loop count : %d\n" | 365 | "Purge inner loop count : %d\n" |
@@ -375,7 +368,7 @@ vm_info(char *page) | |||
375 | ptce.base, ptce.count[0], ptce.count[1], | 368 | ptce.base, ptce.count[0], ptce.count[1], |
376 | ptce.stride[0], ptce.stride[1]); | 369 | ptce.stride[0], ptce.stride[1]); |
377 | 370 | ||
378 | p += sprintf(p, | 371 | seq_printf(m, |
379 | "TC Levels : %d\n" | 372 | "TC Levels : %d\n" |
380 | "Unique TC(s) : %d\n", | 373 | "Unique TC(s) : %d\n", |
381 | vm_info_1.pal_vm_info_1_s.num_tc_levels, | 374 | vm_info_1.pal_vm_info_1_s.num_tc_levels, |
@@ -385,13 +378,11 @@ vm_info(char *page) | |||
385 | for (j=2; j>0 ; j--) { | 378 | for (j=2; j>0 ; j--) { |
386 | tc_pages = 0; /* just in case */ | 379 | tc_pages = 0; /* just in case */ |
387 | 380 | ||
388 | |||
389 | /* even without unification, some levels may not be present */ | 381 | /* even without unification, some levels may not be present */ |
390 | if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) { | 382 | if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) |
391 | continue; | 383 | continue; |
392 | } | ||
393 | 384 | ||
394 | p += sprintf(p, | 385 | seq_printf(m, |
395 | "\n%s Translation Cache Level %d:\n" | 386 | "\n%s Translation Cache Level %d:\n" |
396 | "\tHash sets : %d\n" | 387 | "\tHash sets : %d\n" |
397 | "\tAssociativity : %d\n" | 388 | "\tAssociativity : %d\n" |
@@ -403,15 +394,15 @@ vm_info(char *page) | |||
403 | tc_info.tc_num_entries); | 394 | tc_info.tc_num_entries); |
404 | 395 | ||
405 | if (tc_info.tc_pf) | 396 | if (tc_info.tc_pf) |
406 | p += sprintf(p, "PreferredPageSizeOptimized "); | 397 | seq_puts(m, "PreferredPageSizeOptimized "); |
407 | if (tc_info.tc_unified) | 398 | if (tc_info.tc_unified) |
408 | p += sprintf(p, "Unified "); | 399 | seq_puts(m, "Unified "); |
409 | if (tc_info.tc_reduce_tr) | 400 | if (tc_info.tc_reduce_tr) |
410 | p += sprintf(p, "TCReduction"); | 401 | seq_puts(m, "TCReduction"); |
411 | 402 | ||
412 | p += sprintf(p, "\n\tSupported page sizes: "); | 403 | seq_puts(m, "\n\tSupported page sizes: "); |
413 | 404 | ||
414 | p = bitvector_process(p, tc_pages); | 405 | bitvector_process(m, tc_pages); |
415 | 406 | ||
416 | /* when unified date (j=2) is enough */ | 407 | /* when unified date (j=2) is enough */ |
417 | if (tc_info.tc_unified) | 408 | if (tc_info.tc_unified) |
@@ -419,16 +410,14 @@ vm_info(char *page) | |||
419 | } | 410 | } |
420 | } | 411 | } |
421 | } | 412 | } |
422 | p += sprintf(p, "\n"); | ||
423 | 413 | ||
424 | return p - page; | 414 | seq_putc(m, '\n'); |
415 | return 0; | ||
425 | } | 416 | } |
426 | 417 | ||
427 | 418 | ||
428 | static int | 419 | static int register_info(struct seq_file *m) |
429 | register_info(char *page) | ||
430 | { | 420 | { |
431 | char *p = page; | ||
432 | u64 reg_info[2]; | 421 | u64 reg_info[2]; |
433 | u64 info; | 422 | u64 info; |
434 | unsigned long phys_stacked; | 423 | unsigned long phys_stacked; |
@@ -442,35 +431,31 @@ register_info(char *page) | |||
442 | }; | 431 | }; |
443 | 432 | ||
444 | for(info=0; info < 4; info++) { | 433 | for(info=0; info < 4; info++) { |
445 | 434 | if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0) | |
446 | if (ia64_pal_register_info(info, ®_info[0], ®_info[1]) != 0) return 0; | 435 | return 0; |
447 | 436 | seq_printf(m, "%-32s : ", info_type[info]); | |
448 | p += sprintf(p, "%-32s : ", info_type[info]); | 437 | bitregister_process(m, reg_info, 128); |
449 | 438 | seq_putc(m, '\n'); | |
450 | p = bitregister_process(p, reg_info, 128); | ||
451 | |||
452 | p += sprintf(p, "\n"); | ||
453 | } | 439 | } |
454 | 440 | ||
455 | if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) { | 441 | if (ia64_pal_rse_info(&phys_stacked, &hints) == 0) |
442 | seq_printf(m, | ||
443 | "RSE stacked physical registers : %ld\n" | ||
444 | "RSE load/store hints : %ld (%s)\n", | ||
445 | phys_stacked, hints.ph_data, | ||
446 | hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); | ||
456 | 447 | ||
457 | p += sprintf(p, | ||
458 | "RSE stacked physical registers : %ld\n" | ||
459 | "RSE load/store hints : %ld (%s)\n", | ||
460 | phys_stacked, hints.ph_data, | ||
461 | hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); | ||
462 | } | ||
463 | if (ia64_pal_debug_info(&iregs, &dregs)) | 448 | if (ia64_pal_debug_info(&iregs, &dregs)) |
464 | return 0; | 449 | return 0; |
465 | 450 | ||
466 | p += sprintf(p, | 451 | seq_printf(m, |
467 | "Instruction debug register pairs : %ld\n" | 452 | "Instruction debug register pairs : %ld\n" |
468 | "Data debug register pairs : %ld\n", iregs, dregs); | 453 | "Data debug register pairs : %ld\n", iregs, dregs); |
469 | 454 | ||
470 | return p - page; | 455 | return 0; |
471 | } | 456 | } |
472 | 457 | ||
473 | static char *proc_features_0[]={ /* Feature set 0 */ | 458 | static const char *const proc_features_0[]={ /* Feature set 0 */ |
474 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 459 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
475 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, | 460 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, |
476 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 461 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
@@ -502,7 +487,7 @@ static char *proc_features_0[]={ /* Feature set 0 */ | |||
502 | "Enable BERR promotion" | 487 | "Enable BERR promotion" |
503 | }; | 488 | }; |
504 | 489 | ||
505 | static char *proc_features_16[]={ /* Feature set 16 */ | 490 | static const char *const proc_features_16[]={ /* Feature set 16 */ |
506 | "Disable ETM", | 491 | "Disable ETM", |
507 | "Enable ETM", | 492 | "Enable ETM", |
508 | "Enable MCA on half-way timer", | 493 | "Enable MCA on half-way timer", |
@@ -522,7 +507,7 @@ static char *proc_features_16[]={ /* Feature set 16 */ | |||
522 | NULL, NULL, NULL, NULL, NULL | 507 | NULL, NULL, NULL, NULL, NULL |
523 | }; | 508 | }; |
524 | 509 | ||
525 | static char **proc_features[]={ | 510 | static const char *const *const proc_features[]={ |
526 | proc_features_0, | 511 | proc_features_0, |
527 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 512 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
528 | NULL, NULL, NULL, NULL, | 513 | NULL, NULL, NULL, NULL, |
@@ -530,11 +515,10 @@ static char **proc_features[]={ | |||
530 | NULL, NULL, NULL, NULL, | 515 | NULL, NULL, NULL, NULL, |
531 | }; | 516 | }; |
532 | 517 | ||
533 | static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, | 518 | static void feature_set_info(struct seq_file *m, u64 avail, u64 status, u64 control, |
534 | unsigned long set) | 519 | unsigned long set) |
535 | { | 520 | { |
536 | char *p = page; | 521 | const char *const *vf, *const *v; |
537 | char **vf, **v; | ||
538 | int i; | 522 | int i; |
539 | 523 | ||
540 | vf = v = proc_features[set]; | 524 | vf = v = proc_features[set]; |
@@ -547,13 +531,13 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, | |||
547 | if (vf) | 531 | if (vf) |
548 | v = vf + i; | 532 | v = vf + i; |
549 | if ( v && *v ) { | 533 | if ( v && *v ) { |
550 | p += sprintf(p, "%-40s : %s %s\n", *v, | 534 | seq_printf(m, "%-40s : %s %s\n", *v, |
551 | avail & 0x1 ? (status & 0x1 ? | 535 | avail & 0x1 ? (status & 0x1 ? |
552 | "On " : "Off"): "", | 536 | "On " : "Off"): "", |
553 | avail & 0x1 ? (control & 0x1 ? | 537 | avail & 0x1 ? (control & 0x1 ? |
554 | "Ctrl" : "NoCtrl"): ""); | 538 | "Ctrl" : "NoCtrl"): ""); |
555 | } else { | 539 | } else { |
556 | p += sprintf(p, "Feature set %2ld bit %2d\t\t\t" | 540 | seq_printf(m, "Feature set %2ld bit %2d\t\t\t" |
557 | " : %s %s\n", | 541 | " : %s %s\n", |
558 | set, i, | 542 | set, i, |
559 | avail & 0x1 ? (status & 0x1 ? | 543 | avail & 0x1 ? (status & 0x1 ? |
@@ -562,36 +546,32 @@ static char * feature_set_info(char *page, u64 avail, u64 status, u64 control, | |||
562 | "Ctrl" : "NoCtrl"): ""); | 546 | "Ctrl" : "NoCtrl"): ""); |
563 | } | 547 | } |
564 | } | 548 | } |
565 | return p; | ||
566 | } | 549 | } |
567 | 550 | ||
568 | static int | 551 | static int processor_info(struct seq_file *m) |
569 | processor_info(char *page) | ||
570 | { | 552 | { |
571 | char *p = page; | ||
572 | u64 avail=1, status=1, control=1, feature_set=0; | 553 | u64 avail=1, status=1, control=1, feature_set=0; |
573 | s64 ret; | 554 | s64 ret; |
574 | 555 | ||
575 | do { | 556 | do { |
576 | ret = ia64_pal_proc_get_features(&avail, &status, &control, | 557 | ret = ia64_pal_proc_get_features(&avail, &status, &control, |
577 | feature_set); | 558 | feature_set); |
578 | if (ret < 0) { | 559 | if (ret < 0) |
579 | return p - page; | 560 | return 0; |
580 | } | 561 | |
581 | if (ret == 1) { | 562 | if (ret == 1) { |
582 | feature_set++; | 563 | feature_set++; |
583 | continue; | 564 | continue; |
584 | } | 565 | } |
585 | 566 | ||
586 | p = feature_set_info(p, avail, status, control, feature_set); | 567 | feature_set_info(m, avail, status, control, feature_set); |
587 | |||
588 | feature_set++; | 568 | feature_set++; |
589 | } while(1); | 569 | } while(1); |
590 | 570 | ||
591 | return p - page; | 571 | return 0; |
592 | } | 572 | } |
593 | 573 | ||
594 | static const char *bus_features[]={ | 574 | static const char *const bus_features[]={ |
595 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 575 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
596 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, | 576 | NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, |
597 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | 577 | NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, |
@@ -617,125 +597,118 @@ static const char *bus_features[]={ | |||
617 | }; | 597 | }; |
618 | 598 | ||
619 | 599 | ||
620 | static int | 600 | static int bus_info(struct seq_file *m) |
621 | bus_info(char *page) | ||
622 | { | 601 | { |
623 | char *p = page; | 602 | const char *const *v = bus_features; |
624 | const char **v = bus_features; | ||
625 | pal_bus_features_u_t av, st, ct; | 603 | pal_bus_features_u_t av, st, ct; |
626 | u64 avail, status, control; | 604 | u64 avail, status, control; |
627 | int i; | 605 | int i; |
628 | s64 ret; | 606 | s64 ret; |
629 | 607 | ||
630 | if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) return 0; | 608 | if ((ret=ia64_pal_bus_get_features(&av, &st, &ct)) != 0) |
609 | return 0; | ||
631 | 610 | ||
632 | avail = av.pal_bus_features_val; | 611 | avail = av.pal_bus_features_val; |
633 | status = st.pal_bus_features_val; | 612 | status = st.pal_bus_features_val; |
634 | control = ct.pal_bus_features_val; | 613 | control = ct.pal_bus_features_val; |
635 | 614 | ||
636 | for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) { | 615 | for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) { |
637 | if ( ! *v ) continue; | 616 | if ( ! *v ) |
638 | p += sprintf(p, "%-48s : %s%s %s\n", *v, | 617 | continue; |
639 | avail & 0x1 ? "" : "NotImpl", | 618 | seq_printf(m, "%-48s : %s%s %s\n", *v, |
640 | avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", | 619 | avail & 0x1 ? "" : "NotImpl", |
641 | avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); | 620 | avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "", |
621 | avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): ""); | ||
642 | } | 622 | } |
643 | return p - page; | 623 | return 0; |
644 | } | 624 | } |
645 | 625 | ||
646 | static int | 626 | static int version_info(struct seq_file *m) |
647 | version_info(char *page) | ||
648 | { | 627 | { |
649 | pal_version_u_t min_ver, cur_ver; | 628 | pal_version_u_t min_ver, cur_ver; |
650 | char *p = page; | ||
651 | 629 | ||
652 | if (ia64_pal_version(&min_ver, &cur_ver) != 0) | 630 | if (ia64_pal_version(&min_ver, &cur_ver) != 0) |
653 | return 0; | 631 | return 0; |
654 | 632 | ||
655 | p += sprintf(p, | 633 | seq_printf(m, |
656 | "PAL_vendor : 0x%02x (min=0x%02x)\n" | 634 | "PAL_vendor : 0x%02x (min=0x%02x)\n" |
657 | "PAL_A : %02x.%02x (min=%02x.%02x)\n" | 635 | "PAL_A : %02x.%02x (min=%02x.%02x)\n" |
658 | "PAL_B : %02x.%02x (min=%02x.%02x)\n", | 636 | "PAL_B : %02x.%02x (min=%02x.%02x)\n", |
659 | cur_ver.pal_version_s.pv_pal_vendor, | 637 | cur_ver.pal_version_s.pv_pal_vendor, |
660 | min_ver.pal_version_s.pv_pal_vendor, | 638 | min_ver.pal_version_s.pv_pal_vendor, |
661 | cur_ver.pal_version_s.pv_pal_a_model, | 639 | cur_ver.pal_version_s.pv_pal_a_model, |
662 | cur_ver.pal_version_s.pv_pal_a_rev, | 640 | cur_ver.pal_version_s.pv_pal_a_rev, |
663 | min_ver.pal_version_s.pv_pal_a_model, | 641 | min_ver.pal_version_s.pv_pal_a_model, |
664 | min_ver.pal_version_s.pv_pal_a_rev, | 642 | min_ver.pal_version_s.pv_pal_a_rev, |
665 | cur_ver.pal_version_s.pv_pal_b_model, | 643 | cur_ver.pal_version_s.pv_pal_b_model, |
666 | cur_ver.pal_version_s.pv_pal_b_rev, | 644 | cur_ver.pal_version_s.pv_pal_b_rev, |
667 | min_ver.pal_version_s.pv_pal_b_model, | 645 | min_ver.pal_version_s.pv_pal_b_model, |
668 | min_ver.pal_version_s.pv_pal_b_rev); | 646 | min_ver.pal_version_s.pv_pal_b_rev); |
669 | return p - page; | 647 | return 0; |
670 | } | 648 | } |
671 | 649 | ||
672 | static int | 650 | static int perfmon_info(struct seq_file *m) |
673 | perfmon_info(char *page) | ||
674 | { | 651 | { |
675 | char *p = page; | ||
676 | u64 pm_buffer[16]; | 652 | u64 pm_buffer[16]; |
677 | pal_perf_mon_info_u_t pm_info; | 653 | pal_perf_mon_info_u_t pm_info; |
678 | 654 | ||
679 | if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0; | 655 | if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) |
680 | 656 | return 0; | |
681 | p += sprintf(p, | ||
682 | "PMC/PMD pairs : %d\n" | ||
683 | "Counter width : %d bits\n" | ||
684 | "Cycle event number : %d\n" | ||
685 | "Retired event number : %d\n" | ||
686 | "Implemented PMC : ", | ||
687 | pm_info.pal_perf_mon_info_s.generic, pm_info.pal_perf_mon_info_s.width, | ||
688 | pm_info.pal_perf_mon_info_s.cycles, pm_info.pal_perf_mon_info_s.retired); | ||
689 | 657 | ||
690 | p = bitregister_process(p, pm_buffer, 256); | 658 | seq_printf(m, |
691 | p += sprintf(p, "\nImplemented PMD : "); | 659 | "PMC/PMD pairs : %d\n" |
692 | p = bitregister_process(p, pm_buffer+4, 256); | 660 | "Counter width : %d bits\n" |
693 | p += sprintf(p, "\nCycles count capable : "); | 661 | "Cycle event number : %d\n" |
694 | p = bitregister_process(p, pm_buffer+8, 256); | 662 | "Retired event number : %d\n" |
695 | p += sprintf(p, "\nRetired bundles count capable : "); | 663 | "Implemented PMC : ", |
664 | pm_info.pal_perf_mon_info_s.generic, | ||
665 | pm_info.pal_perf_mon_info_s.width, | ||
666 | pm_info.pal_perf_mon_info_s.cycles, | ||
667 | pm_info.pal_perf_mon_info_s.retired); | ||
668 | |||
669 | bitregister_process(m, pm_buffer, 256); | ||
670 | seq_puts(m, "\nImplemented PMD : "); | ||
671 | bitregister_process(m, pm_buffer+4, 256); | ||
672 | seq_puts(m, "\nCycles count capable : "); | ||
673 | bitregister_process(m, pm_buffer+8, 256); | ||
674 | seq_puts(m, "\nRetired bundles count capable : "); | ||
696 | 675 | ||
697 | #ifdef CONFIG_ITANIUM | 676 | #ifdef CONFIG_ITANIUM |
698 | /* | 677 | /* |
699 | * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES | 678 | * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES |
700 | * which is wrong, both PMC4 and PMD5 support it. | 679 | * which is wrong, both PMC4 and PMD5 support it. |
701 | */ | 680 | */ |
702 | if (pm_buffer[12] == 0x10) pm_buffer[12]=0x30; | 681 | if (pm_buffer[12] == 0x10) |
682 | pm_buffer[12]=0x30; | ||
703 | #endif | 683 | #endif |
704 | 684 | ||
705 | p = bitregister_process(p, pm_buffer+12, 256); | 685 | bitregister_process(m, pm_buffer+12, 256); |
706 | 686 | seq_putc(m, '\n'); | |
707 | p += sprintf(p, "\n"); | 687 | return 0; |
708 | |||
709 | return p - page; | ||
710 | } | 688 | } |
711 | 689 | ||
712 | static int | 690 | static int frequency_info(struct seq_file *m) |
713 | frequency_info(char *page) | ||
714 | { | 691 | { |
715 | char *p = page; | ||
716 | struct pal_freq_ratio proc, itc, bus; | 692 | struct pal_freq_ratio proc, itc, bus; |
717 | unsigned long base; | 693 | unsigned long base; |
718 | 694 | ||
719 | if (ia64_pal_freq_base(&base) == -1) | 695 | if (ia64_pal_freq_base(&base) == -1) |
720 | p += sprintf(p, "Output clock : not implemented\n"); | 696 | seq_puts(m, "Output clock : not implemented\n"); |
721 | else | 697 | else |
722 | p += sprintf(p, "Output clock : %ld ticks/s\n", base); | 698 | seq_printf(m, "Output clock : %ld ticks/s\n", base); |
723 | 699 | ||
724 | if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; | 700 | if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; |
725 | 701 | ||
726 | p += sprintf(p, | 702 | seq_printf(m, |
727 | "Processor/Clock ratio : %d/%d\n" | 703 | "Processor/Clock ratio : %d/%d\n" |
728 | "Bus/Clock ratio : %d/%d\n" | 704 | "Bus/Clock ratio : %d/%d\n" |
729 | "ITC/Clock ratio : %d/%d\n", | 705 | "ITC/Clock ratio : %d/%d\n", |
730 | proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); | 706 | proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); |
731 | 707 | return 0; | |
732 | return p - page; | ||
733 | } | 708 | } |
734 | 709 | ||
735 | static int | 710 | static int tr_info(struct seq_file *m) |
736 | tr_info(char *page) | ||
737 | { | 711 | { |
738 | char *p = page; | ||
739 | long status; | 712 | long status; |
740 | pal_tr_valid_u_t tr_valid; | 713 | pal_tr_valid_u_t tr_valid; |
741 | u64 tr_buffer[4]; | 714 | u64 tr_buffer[4]; |
@@ -794,39 +767,40 @@ tr_info(char *page) | |||
794 | 767 | ||
795 | ifa_reg = (struct ifa_reg *)&tr_buffer[2]; | 768 | ifa_reg = (struct ifa_reg *)&tr_buffer[2]; |
796 | 769 | ||
797 | if (ifa_reg->valid == 0) continue; | 770 | if (ifa_reg->valid == 0) |
771 | continue; | ||
798 | 772 | ||
799 | gr_reg = (struct gr_reg *)tr_buffer; | 773 | gr_reg = (struct gr_reg *)tr_buffer; |
800 | itir_reg = (struct itir_reg *)&tr_buffer[1]; | 774 | itir_reg = (struct itir_reg *)&tr_buffer[1]; |
801 | rid_reg = (struct rid_reg *)&tr_buffer[3]; | 775 | rid_reg = (struct rid_reg *)&tr_buffer[3]; |
802 | 776 | ||
803 | pgm = -1 << (itir_reg->ps - 12); | 777 | pgm = -1 << (itir_reg->ps - 12); |
804 | p += sprintf(p, | 778 | seq_printf(m, |
805 | "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" | 779 | "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n" |
806 | "\tppn : 0x%lx\n" | 780 | "\tppn : 0x%lx\n" |
807 | "\tvpn : 0x%lx\n" | 781 | "\tvpn : 0x%lx\n" |
808 | "\tps : ", | 782 | "\tps : ", |
809 | "ID"[i], j, | 783 | "ID"[i], j, |
810 | tr_valid.pal_tr_valid_s.access_rights_valid, | 784 | tr_valid.pal_tr_valid_s.access_rights_valid, |
811 | tr_valid.pal_tr_valid_s.priv_level_valid, | 785 | tr_valid.pal_tr_valid_s.priv_level_valid, |
812 | tr_valid.pal_tr_valid_s.dirty_bit_valid, | 786 | tr_valid.pal_tr_valid_s.dirty_bit_valid, |
813 | tr_valid.pal_tr_valid_s.mem_attr_valid, | 787 | tr_valid.pal_tr_valid_s.mem_attr_valid, |
814 | (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); | 788 | (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12); |
815 | 789 | ||
816 | p = bitvector_process(p, 1<< itir_reg->ps); | 790 | bitvector_process(m, 1<< itir_reg->ps); |
817 | 791 | ||
818 | p += sprintf(p, | 792 | seq_printf(m, |
819 | "\n\tpl : %d\n" | 793 | "\n\tpl : %d\n" |
820 | "\tar : %d\n" | 794 | "\tar : %d\n" |
821 | "\trid : %x\n" | 795 | "\trid : %x\n" |
822 | "\tp : %d\n" | 796 | "\tp : %d\n" |
823 | "\tma : %d\n" | 797 | "\tma : %d\n" |
824 | "\td : %d\n", | 798 | "\td : %d\n", |
825 | gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, | 799 | gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma, |
826 | gr_reg->d); | 800 | gr_reg->d); |
827 | } | 801 | } |
828 | } | 802 | } |
829 | return p - page; | 803 | return 0; |
830 | } | 804 | } |
831 | 805 | ||
832 | 806 | ||
@@ -834,7 +808,7 @@ tr_info(char *page) | |||
834 | /* | 808 | /* |
835 | * List {name,function} pairs for every entry in /proc/palinfo/cpu* | 809 | * List {name,function} pairs for every entry in /proc/palinfo/cpu* |
836 | */ | 810 | */ |
837 | static palinfo_entry_t palinfo_entries[]={ | 811 | static const palinfo_entry_t palinfo_entries[]={ |
838 | { "version_info", version_info, }, | 812 | { "version_info", version_info, }, |
839 | { "vm_info", vm_info, }, | 813 | { "vm_info", vm_info, }, |
840 | { "cache_info", cache_info, }, | 814 | { "cache_info", cache_info, }, |
@@ -876,7 +850,7 @@ typedef union { | |||
876 | */ | 850 | */ |
877 | typedef struct { | 851 | typedef struct { |
878 | palinfo_func_t func; /* pointer to function to call */ | 852 | palinfo_func_t func; /* pointer to function to call */ |
879 | char *page; /* buffer to store results */ | 853 | struct seq_file *m; /* buffer to store results */ |
880 | int ret; /* return value from call */ | 854 | int ret; /* return value from call */ |
881 | } palinfo_smp_data_t; | 855 | } palinfo_smp_data_t; |
882 | 856 | ||
@@ -889,7 +863,7 @@ static void | |||
889 | palinfo_smp_call(void *info) | 863 | palinfo_smp_call(void *info) |
890 | { | 864 | { |
891 | palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; | 865 | palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; |
892 | data->ret = (*data->func)(data->page); | 866 | data->ret = (*data->func)(data->m); |
893 | } | 867 | } |
894 | 868 | ||
895 | /* | 869 | /* |
@@ -899,13 +873,13 @@ palinfo_smp_call(void *info) | |||
899 | * otherwise how many bytes in the "page" buffer were written | 873 | * otherwise how many bytes in the "page" buffer were written |
900 | */ | 874 | */ |
901 | static | 875 | static |
902 | int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | 876 | int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f) |
903 | { | 877 | { |
904 | palinfo_smp_data_t ptr; | 878 | palinfo_smp_data_t ptr; |
905 | int ret; | 879 | int ret; |
906 | 880 | ||
907 | ptr.func = palinfo_entries[f->func_id].proc_read; | 881 | ptr.func = palinfo_entries[f->func_id].proc_read; |
908 | ptr.page = page; | 882 | ptr.m = m; |
909 | ptr.ret = 0; /* just in case */ | 883 | ptr.ret = 0; /* just in case */ |
910 | 884 | ||
911 | 885 | ||
@@ -919,7 +893,7 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | |||
919 | } | 893 | } |
920 | #else /* ! CONFIG_SMP */ | 894 | #else /* ! CONFIG_SMP */ |
921 | static | 895 | static |
922 | int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | 896 | int palinfo_handle_smp(struct seq_file *m, pal_func_cpu_u_t *f) |
923 | { | 897 | { |
924 | printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); | 898 | printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); |
925 | return 0; | 899 | return 0; |
@@ -929,34 +903,35 @@ int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) | |||
929 | /* | 903 | /* |
930 | * Entry point routine: all calls go through this function | 904 | * Entry point routine: all calls go through this function |
931 | */ | 905 | */ |
932 | static int | 906 | static int proc_palinfo_show(struct seq_file *m, void *v) |
933 | palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) | ||
934 | { | 907 | { |
935 | int len=0; | 908 | pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&m->private; |
936 | pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&data; | ||
937 | 909 | ||
938 | /* | 910 | /* |
939 | * in SMP mode, we may need to call another CPU to get correct | 911 | * in SMP mode, we may need to call another CPU to get correct |
940 | * information. PAL, by definition, is processor specific | 912 | * information. PAL, by definition, is processor specific |
941 | */ | 913 | */ |
942 | if (f->req_cpu == get_cpu()) | 914 | if (f->req_cpu == get_cpu()) |
943 | len = (*palinfo_entries[f->func_id].proc_read)(page); | 915 | (*palinfo_entries[f->func_id].proc_read)(m); |
944 | else | 916 | else |
945 | len = palinfo_handle_smp(f, page); | 917 | palinfo_handle_smp(m, f); |
946 | 918 | ||
947 | put_cpu(); | 919 | put_cpu(); |
920 | return 0; | ||
921 | } | ||
948 | 922 | ||
949 | if (len <= off+count) *eof = 1; | 923 | static int proc_palinfo_open(struct inode *inode, struct file *file) |
950 | 924 | { | |
951 | *start = page + off; | 925 | return single_open(file, proc_palinfo_show, PDE_DATA(inode)); |
952 | len -= off; | ||
953 | |||
954 | if (len>count) len = count; | ||
955 | if (len<0) len = 0; | ||
956 | |||
957 | return len; | ||
958 | } | 926 | } |
959 | 927 | ||
928 | static const struct file_operations proc_palinfo_fops = { | ||
929 | .open = proc_palinfo_open, | ||
930 | .read = seq_read, | ||
931 | .llseek = seq_lseek, | ||
932 | .release = seq_release, | ||
933 | }; | ||
934 | |||
960 | static void __cpuinit | 935 | static void __cpuinit |
961 | create_palinfo_proc_entries(unsigned int cpu) | 936 | create_palinfo_proc_entries(unsigned int cpu) |
962 | { | 937 | { |
@@ -974,9 +949,8 @@ create_palinfo_proc_entries(unsigned int cpu) | |||
974 | 949 | ||
975 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { | 950 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { |
976 | f.func_id = j; | 951 | f.func_id = j; |
977 | create_proc_read_entry( | 952 | proc_create_data(palinfo_entries[j].name, 0, cpu_dir, |
978 | palinfo_entries[j].name, 0, cpu_dir, | 953 | &proc_palinfo_fops, (void *)f.value); |
979 | palinfo_read_entry, (void *)f.value); | ||
980 | } | 954 | } |
981 | } | 955 | } |
982 | 956 | ||