diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2006-06-29 01:07:42 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-06-29 02:22:46 -0400 |
commit | 16e9f994442b599987ce5dd4a5ebe50865e6573d (patch) | |
tree | bec5f383daccafc48e0149c0da05ef87f59db77f /arch/powerpc | |
parent | f86c9747fe1cd72b2c5c6bdf72d17aeb2a3c6cb0 (diff) |
[POWERPC] Make lparcfg.c work when both iseries and pseries are selected
This also consolidates the initial bits of lparcfg_data() and adds the
partition number to the iSeries flattened device tree.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 147 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/dt.c | 2 |
2 files changed, 78 insertions, 71 deletions
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..73edc3c16137 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -45,11 +45,9 @@ | |||
45 | static struct proc_dir_entry *proc_ppc64_lparcfg; | 45 | static struct proc_dir_entry *proc_ppc64_lparcfg; |
46 | #define LPARCFG_BUFF_SIZE 4096 | 46 | #define LPARCFG_BUFF_SIZE 4096 |
47 | 47 | ||
48 | #ifdef CONFIG_PPC_ISERIES | ||
49 | |||
50 | /* | 48 | /* |
51 | * For iSeries legacy systems, the PPA purr function is available from the | 49 | * Track sum of all purrs across all processors. This is used to further |
52 | * emulated_time_base field in the paca. | 50 | * calculate usage values by different applications |
53 | */ | 51 | */ |
54 | static unsigned long get_purr(void) | 52 | static unsigned long get_purr(void) |
55 | { | 53 | { |
@@ -57,48 +55,31 @@ static unsigned long get_purr(void) | |||
57 | int cpu; | 55 | int cpu; |
58 | 56 | ||
59 | for_each_possible_cpu(cpu) { | 57 | for_each_possible_cpu(cpu) { |
60 | sum_purr += lppaca[cpu].emulated_time_base; | 58 | if (firmware_has_feature(FW_FEATURE_ISERIES)) |
59 | sum_purr += lppaca[cpu].emulated_time_base; | ||
60 | else { | ||
61 | struct cpu_usage *cu; | ||
61 | 62 | ||
62 | #ifdef PURR_DEBUG | 63 | cu = &per_cpu(cpu_usage_array, cpu); |
63 | printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", | 64 | sum_purr += cu->current_tb; |
64 | cpu, lppaca[cpu].emulated_time_base); | 65 | } |
65 | #endif | ||
66 | } | 66 | } |
67 | return sum_purr; | 67 | return sum_purr; |
68 | } | 68 | } |
69 | 69 | ||
70 | #define lparcfg_write NULL | 70 | #ifdef CONFIG_PPC_ISERIES |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Methods used to fetch LPAR data when running on an iSeries platform. | 73 | * Methods used to fetch LPAR data when running on an iSeries platform. |
74 | */ | 74 | */ |
75 | static int lparcfg_data(struct seq_file *m, void *v) | 75 | static int iseries_lparcfg_data(struct seq_file *m, void *v) |
76 | { | 76 | { |
77 | unsigned long pool_id, lp_index; | 77 | unsigned long pool_id; |
78 | int shared, entitled_capacity, max_entitled_capacity; | 78 | int shared, entitled_capacity, max_entitled_capacity; |
79 | int processors, max_processors; | 79 | int processors, max_processors; |
80 | unsigned long purr = get_purr(); | 80 | unsigned long purr = get_purr(); |
81 | 81 | ||
82 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
83 | |||
84 | shared = (int)(get_lppaca()->shared_proc); | 82 | shared = (int)(get_lppaca()->shared_proc); |
85 | seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", | ||
86 | e2a(xItExtVpdPanel.mfgID[2]), | ||
87 | e2a(xItExtVpdPanel.mfgID[3]), | ||
88 | e2a(xItExtVpdPanel.systemSerial[1]), | ||
89 | e2a(xItExtVpdPanel.systemSerial[2]), | ||
90 | e2a(xItExtVpdPanel.systemSerial[3]), | ||
91 | e2a(xItExtVpdPanel.systemSerial[4]), | ||
92 | e2a(xItExtVpdPanel.systemSerial[5])); | ||
93 | |||
94 | seq_printf(m, "system_type=%c%c%c%c\n", | ||
95 | e2a(xItExtVpdPanel.machineType[0]), | ||
96 | e2a(xItExtVpdPanel.machineType[1]), | ||
97 | e2a(xItExtVpdPanel.machineType[2]), | ||
98 | e2a(xItExtVpdPanel.machineType[3])); | ||
99 | |||
100 | lp_index = HvLpConfig_getLpIndex(); | ||
101 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
102 | 83 | ||
103 | seq_printf(m, "system_active_processors=%d\n", | 84 | seq_printf(m, "system_active_processors=%d\n", |
104 | (int)HvLpConfig_getSystemPhysicalProcessors()); | 85 | (int)HvLpConfig_getSystemPhysicalProcessors()); |
@@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
137 | 118 | ||
138 | return 0; | 119 | return 0; |
139 | } | 120 | } |
121 | |||
122 | #else /* CONFIG_PPC_ISERIES */ | ||
123 | |||
124 | static int iseries_lparcfg_data(struct seq_file *m, void *v) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
140 | #endif /* CONFIG_PPC_ISERIES */ | 129 | #endif /* CONFIG_PPC_ISERIES */ |
141 | 130 | ||
142 | #ifdef CONFIG_PPC_PSERIES | 131 | #ifdef CONFIG_PPC_PSERIES |
@@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) | |||
213 | log_plpar_hcall_return(rc, "H_PIC"); | 202 | log_plpar_hcall_return(rc, "H_PIC"); |
214 | } | 203 | } |
215 | 204 | ||
216 | /* Track sum of all purrs across all processors. This is used to further */ | ||
217 | /* calculate usage values by different applications */ | ||
218 | |||
219 | static unsigned long get_purr(void) | ||
220 | { | ||
221 | unsigned long sum_purr = 0; | ||
222 | int cpu; | ||
223 | struct cpu_usage *cu; | ||
224 | |||
225 | for_each_possible_cpu(cpu) { | ||
226 | cu = &per_cpu(cpu_usage_array, cpu); | ||
227 | sum_purr += cu->current_tb; | ||
228 | } | ||
229 | return sum_purr; | ||
230 | } | ||
231 | |||
232 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 | 205 | #define SPLPAR_CHARACTERISTICS_TOKEN 20 |
233 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) | 206 | #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) |
234 | 207 | ||
@@ -333,35 +306,13 @@ static int lparcfg_count_active_processors(void) | |||
333 | return count; | 306 | return count; |
334 | } | 307 | } |
335 | 308 | ||
336 | static int lparcfg_data(struct seq_file *m, void *v) | 309 | static int pseries_lparcfg_data(struct seq_file *m, void *v) |
337 | { | 310 | { |
338 | int partition_potential_processors; | 311 | int partition_potential_processors; |
339 | int partition_active_processors; | 312 | int partition_active_processors; |
340 | struct device_node *rootdn; | ||
341 | const char *model = ""; | ||
342 | const char *system_id = ""; | ||
343 | unsigned int *lp_index_ptr, lp_index = 0; | ||
344 | struct device_node *rtas_node; | 313 | struct device_node *rtas_node; |
345 | int *lrdrp = NULL; | 314 | int *lrdrp = NULL; |
346 | 315 | ||
347 | rootdn = find_path_device("/"); | ||
348 | if (rootdn) { | ||
349 | model = get_property(rootdn, "model", NULL); | ||
350 | system_id = get_property(rootdn, "system-id", NULL); | ||
351 | lp_index_ptr = (unsigned int *) | ||
352 | get_property(rootdn, "ibm,partition-no", NULL); | ||
353 | if (lp_index_ptr) | ||
354 | lp_index = *lp_index_ptr; | ||
355 | } | ||
356 | |||
357 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
358 | |||
359 | seq_printf(m, "serial_number=%s\n", system_id); | ||
360 | |||
361 | seq_printf(m, "system_type=%s\n", model); | ||
362 | |||
363 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
364 | |||
365 | rtas_node = find_path_device("/rtas"); | 316 | rtas_node = find_path_device("/rtas"); |
366 | if (rtas_node) | 317 | if (rtas_node) |
367 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", | 318 | lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", |
@@ -549,8 +500,61 @@ out: | |||
549 | return retval; | 500 | return retval; |
550 | } | 501 | } |
551 | 502 | ||
503 | #else /* CONFIG_PPC_PSERIES */ | ||
504 | |||
505 | static int pseries_lparcfg_data(struct seq_file *m, void *v) | ||
506 | { | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, | ||
511 | size_t count, loff_t * off) | ||
512 | { | ||
513 | return count; | ||
514 | } | ||
515 | |||
552 | #endif /* CONFIG_PPC_PSERIES */ | 516 | #endif /* CONFIG_PPC_PSERIES */ |
553 | 517 | ||
518 | static int lparcfg_data(struct seq_file *m, void *v) | ||
519 | { | ||
520 | struct device_node *rootdn; | ||
521 | const char *model = ""; | ||
522 | const char *system_id = ""; | ||
523 | const char *tmp; | ||
524 | unsigned int *lp_index_ptr, lp_index = 0; | ||
525 | |||
526 | seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); | ||
527 | |||
528 | rootdn = find_path_device("/"); | ||
529 | if (rootdn) { | ||
530 | tmp = get_property(rootdn, "model", NULL); | ||
531 | if (tmp) { | ||
532 | model = tmp; | ||
533 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
534 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
535 | model += 4; | ||
536 | } | ||
537 | tmp = get_property(rootdn, "system-id", NULL); | ||
538 | if (tmp) { | ||
539 | system_id = tmp; | ||
540 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
541 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
542 | system_id += 4; | ||
543 | } | ||
544 | lp_index_ptr = (unsigned int *) | ||
545 | get_property(rootdn, "ibm,partition-no", NULL); | ||
546 | if (lp_index_ptr) | ||
547 | lp_index = *lp_index_ptr; | ||
548 | } | ||
549 | seq_printf(m, "serial_number=%s\n", system_id); | ||
550 | seq_printf(m, "system_type=%s\n", model); | ||
551 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | ||
552 | |||
553 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
554 | return iseries_lparcfg_data(m, v); | ||
555 | return pseries_lparcfg_data(m, v); | ||
556 | } | ||
557 | |||
554 | static int lparcfg_open(struct inode *inode, struct file *file) | 558 | static int lparcfg_open(struct inode *inode, struct file *file) |
555 | { | 559 | { |
556 | return single_open(file, lparcfg_data, NULL); | 560 | return single_open(file, lparcfg_data, NULL); |
@@ -569,7 +573,8 @@ int __init lparcfg_init(void) | |||
569 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | 573 | mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; |
570 | 574 | ||
571 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 575 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
572 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 576 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && |
577 | !firmware_has_feature(FW_FEATURE_ISERIES)) { | ||
573 | lparcfg_fops.write = lparcfg_write; | 578 | lparcfg_fops.write = lparcfg_write; |
574 | mode |= S_IWUSR; | 579 | mode |= S_IWUSR; |
575 | } | 580 | } |
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index d3444aabe76e..d194140c1ebf 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c | |||
@@ -252,6 +252,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) | |||
252 | { | 252 | { |
253 | char buf[16] = "IBM,"; | 253 | char buf[16] = "IBM,"; |
254 | 254 | ||
255 | /* N.B. lparcfg.c knows about the "IBM," prefixes ... */ | ||
255 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ | 256 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ |
256 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); | 257 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); |
257 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); | 258 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); |
@@ -264,6 +265,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) | |||
264 | dt_prop_str(dt, "model", buf); | 265 | dt_prop_str(dt, "model", buf); |
265 | 266 | ||
266 | dt_prop_str(dt, "compatible", "IBM,iSeries"); | 267 | dt_prop_str(dt, "compatible", "IBM,iSeries"); |
268 | dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); | ||
267 | } | 269 | } |
268 | 270 | ||
269 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, | 271 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, |