diff options
| -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, |
