1 /* 2 * arch/s390/kernel/processor.c 3 * 4 * Copyright IBM Corp. 2008 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6 */ 7 8 #define KMSG_COMPONENT "cpu" 9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/smp.h> 14 #include <linux/seq_file.h> 15 #include <linux/delay.h> 16 17 #include <asm/elf.h> 18 #include <asm/lowcore.h> 19 #include <asm/param.h> 20 21 void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) 22 { 23 pr_info("Processor %d started, address %d, identification %06X\n", 24 cpuinfo->cpu_nr, cpuinfo->cpu_addr, cpuinfo->cpu_id.ident); 25 } 26 27 /* 28 * show_cpuinfo - Get information on one CPU for use by procfs. 29 */ 30 31 static int show_cpuinfo(struct seq_file *m, void *v) 32 { 33 static const char *hwcap_str[8] = { 34 "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", 35 "edat" 36 }; 37 struct cpuinfo_S390 *cpuinfo; 38 unsigned long n = (unsigned long) v - 1; 39 int i; 40 41 s390_adjust_jiffies(); 42 preempt_disable(); 43 if (!n) { 44 seq_printf(m, "vendor_id : IBM/S390\n" 45 "# processors : %i\n" 46 "bogomips per cpu: %lu.%02lu\n", 47 num_online_cpus(), loops_per_jiffy/(500000/HZ), 48 (loops_per_jiffy/(5000/HZ))%100); 49 seq_puts(m, "features\t: "); 50 for (i = 0; i < 8; i++) 51 if (hwcap_str[i] && (elf_hwcap & (1UL << i))) 52 seq_printf(m, "%s ", hwcap_str[i]); 53 seq_puts(m, "\n"); 54 } 55 56 if (cpu_online(n)) { 57 #ifdef CONFIG_SMP 58 if (smp_processor_id() == n) 59 cpuinfo = &S390_lowcore.cpu_data; 60 else 61 cpuinfo = &lowcore_ptr[n]->cpu_data; 62 #else 63 cpuinfo = &S390_lowcore.cpu_data; 64 #endif 65 seq_printf(m, "processor %li: " 66 "version = %02X, " 67 "identification = %06X, " 68 "machine = %04X\n", 69 n, cpuinfo->cpu_id.version, 70 cpuinfo->cpu_id.ident, 71 cpuinfo->cpu_id.machine); 72 } 73 preempt_enable(); 74 return 0; 75 } 76 77 static void *c_start(struct seq_file *m, loff_t *pos) 78 { 79 return *pos < NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL; 80 } 81 82 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 83 { 84 ++*pos; 85 return c_start(m, pos); 86 } 87 88 static void c_stop(struct seq_file *m, void *v) 89 { 90 } 91 92 const struct seq_operations cpuinfo_op = { 93 .start = c_start, 94 .next = c_next, 95 .stop = c_stop, 96 .show = show_cpuinfo, 97 }; 98 99