2008-12-25 13:39:50 +01:00
/*
* Copyright IBM Corp . 2008
* Author ( s ) : Martin Schwidefsky ( schwidefsky @ de . ibm . com )
*/
# define KMSG_COMPONENT "cpu"
# define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/smp.h>
# include <linux/seq_file.h>
# include <linux/delay.h>
2011-01-05 12:48:17 +01:00
# include <linux/cpu.h>
2008-12-25 13:39:50 +01:00
# include <asm/elf.h>
# include <asm/lowcore.h>
# include <asm/param.h>
2010-05-17 10:00:00 +02:00
static DEFINE_PER_CPU ( struct cpuid , cpu_id ) ;
/*
* cpu_init - initializes state that is per - CPU .
*/
void __cpuinit cpu_init ( void )
{
2012-07-13 15:45:33 +02:00
struct s390_idle_data * idle = & __get_cpu_var ( s390_idle ) ;
2012-07-13 16:12:04 +02:00
struct cpuid * id = & __get_cpu_var ( cpu_id ) ;
2010-05-17 10:00:00 +02:00
get_cpu_id ( id ) ;
atomic_inc ( & init_mm . mm_count ) ;
current - > active_mm = & init_mm ;
BUG_ON ( current - > mm ) ;
enter_lazy_tlb ( & init_mm , current ) ;
2012-07-13 15:45:33 +02:00
memset ( idle , 0 , sizeof ( * idle ) ) ;
2010-05-17 10:00:00 +02:00
}
2008-12-25 13:39:50 +01:00
/*
* show_cpuinfo - Get information on one CPU for use by procfs .
*/
static int show_cpuinfo ( struct seq_file * m , void * v )
{
2012-07-31 11:03:04 +02:00
static const char * hwcap_str [ 11 ] = {
2008-12-25 13:39:50 +01:00
" esan3 " , " zarch " , " stfle " , " msa " , " ldisp " , " eimm " , " dfp " ,
2012-07-31 11:03:04 +02:00
" edat " , " etf3eh " , " highgprs " , " te "
2008-12-25 13:39:50 +01:00
} ;
2009-03-26 15:24:42 +01:00
unsigned long n = ( unsigned long ) v - 1 ;
int i ;
2008-12-25 13:39:50 +01:00
2009-03-26 15:24:42 +01:00
if ( ! n ) {
2011-01-05 12:48:18 +01:00
s390_adjust_jiffies ( ) ;
2009-03-26 15:24:42 +01:00
seq_printf ( m , " vendor_id : IBM/S390 \n "
" # processors : %i \n "
" bogomips per cpu: %lu.%02lu \n " ,
num_online_cpus ( ) , loops_per_jiffy / ( 500000 / HZ ) ,
( loops_per_jiffy / ( 5000 / HZ ) ) % 100 ) ;
seq_puts ( m , " features \t : " ) ;
2012-07-31 11:03:04 +02:00
for ( i = 0 ; i < 11 ; i + + )
2009-03-26 15:24:42 +01:00
if ( hwcap_str [ i ] & & ( elf_hwcap & ( 1UL < < i ) ) )
seq_printf ( m , " %s " , hwcap_str [ i ] ) ;
seq_puts ( m , " \n " ) ;
}
2011-01-05 12:48:17 +01:00
get_online_cpus ( ) ;
2009-03-26 15:24:42 +01:00
if ( cpu_online ( n ) ) {
2010-05-17 10:00:00 +02:00
struct cpuid * id = & per_cpu ( cpu_id , n ) ;
2009-03-26 15:24:42 +01:00
seq_printf ( m , " processor %li: "
" version = %02X, "
" identification = %06X, "
" machine = %04X \n " ,
2010-05-17 10:00:00 +02:00
n , id - > version , id - > ident , id - > machine ) ;
2009-03-26 15:24:42 +01:00
}
2011-01-05 12:48:17 +01:00
put_online_cpus ( ) ;
2009-03-26 15:24:42 +01:00
return 0 ;
2008-12-25 13:39:50 +01:00
}
static void * c_start ( struct seq_file * m , loff_t * pos )
{
[S390] avoid warning in show_cpuinfo
The .start function and indirectly the .next function of the show_cpuinfo
sequential operation uses NR_CPUS as limit instead of nr_cpu_ids.
This can cause warnings like this:
WARNING: at /usr/src/linux/include/linux/cpumask.h:107
Process lscpu (pid: 575, task: 000000007deb4338, ksp: 000000007794f588)
Krnl PSW : 0704000180000000 0000000000106db4 (show_cpuinfo+0x108/0x234)
R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:0 PM:0 EA:3
Krnl GPRS: 0000000000000003 0000000000791988 000000000071b478 0000000000000004
0000000000000001 0000000000000000 000000007d139500 0000000000000400
0000000000000000 000000000070e24c 000000007d48d600 0000000000000005
000000007d48d600 00000000004dfa10 0000000000106cf8 000000007794fcc0
Krnl Code: 0000000000106da8: 95001000 cli 0(%r1),0
0000000000106dac: a774ffac brc 7,106d04
0000000000106db0: a7f40001 brc 15,106db2
>0000000000106db4: 92011000 mvi 0(%r1),1
0000000000106db8: a7f4ffa6 brc 15,106d04
0000000000106dbc: c0e5000065b4 brasl %r14,113924
0000000000106dc2: c09000303a45 larl %r9,70e24c
0000000000106dc8: c020001eefd4 larl %r2,4e4d70
Replacing NR_CPUS with nr_cpu_ids fixes it.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2011-10-30 15:16:05 +01:00
return * pos < nr_cpu_ids ? ( void * ) ( ( unsigned long ) * pos + 1 ) : NULL ;
2008-12-25 13:39:50 +01:00
}
static void * c_next ( struct seq_file * m , void * v , loff_t * pos )
{
+ + * pos ;
return c_start ( m , pos ) ;
}
static void c_stop ( struct seq_file * m , void * v )
{
}
const struct seq_operations cpuinfo_op = {
. start = c_start ,
. next = c_next ,
. stop = c_stop ,
. show = show_cpuinfo ,
} ;