2014-03-04 11:51:17 +04:00
/*
* arch / arm64 / kernel / topology . c
*
* Copyright ( C ) 2011 , 2013 , 2014 Linaro Limited .
*
* Based on the arm32 version written by Vincent Guittot in turn based on
* arch / sh / kernel / topology . c
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/cpu.h>
# include <linux/cpumask.h>
# include <linux/init.h>
# include <linux/percpu.h>
# include <linux/node.h>
# include <linux/nodemask.h>
# include <linux/sched.h>
# include <asm/topology.h>
/*
* cpu topology table
*/
struct cpu_topology cpu_topology [ NR_CPUS ] ;
EXPORT_SYMBOL_GPL ( cpu_topology ) ;
const struct cpumask * cpu_coregroup_mask ( int cpu )
{
return & cpu_topology [ cpu ] . core_sibling ;
}
static void update_siblings_masks ( unsigned int cpuid )
{
struct cpu_topology * cpu_topo , * cpuid_topo = & cpu_topology [ cpuid ] ;
int cpu ;
if ( cpuid_topo - > cluster_id = = - 1 ) {
/*
* DT does not contain topology information for this cpu
* reset it to default behaviour
*/
pr_debug ( " CPU%u: No topology information configured \n " , cpuid ) ;
return ;
}
/* update core and thread sibling masks */
for_each_possible_cpu ( cpu ) {
cpu_topo = & cpu_topology [ cpu ] ;
if ( cpuid_topo - > cluster_id ! = cpu_topo - > cluster_id )
continue ;
cpumask_set_cpu ( cpuid , & cpu_topo - > core_sibling ) ;
if ( cpu ! = cpuid )
cpumask_set_cpu ( cpu , & cpuid_topo - > core_sibling ) ;
if ( cpuid_topo - > core_id ! = cpu_topo - > core_id )
continue ;
cpumask_set_cpu ( cpuid , & cpu_topo - > thread_sibling ) ;
if ( cpu ! = cpuid )
cpumask_set_cpu ( cpu , & cpuid_topo - > thread_sibling ) ;
}
}
void store_cpu_topology ( unsigned int cpuid )
{
update_siblings_masks ( cpuid ) ;
}
/*
* init_cpu_topology is called at boot when only one cpu is running
* which prevent simultaneous write access to cpu_topology array
*/
void __init init_cpu_topology ( void )
{
unsigned int cpu ;
/* init core mask and power*/
for_each_possible_cpu ( cpu ) {
struct cpu_topology * cpu_topo = & cpu_topology [ cpu ] ;
cpu_topo - > thread_id = - 1 ;
2014-05-03 00:38:28 +04:00
cpu_topo - > core_id = 0 ;
2014-03-04 11:51:17 +04:00
cpu_topo - > cluster_id = - 1 ;
2014-05-03 00:38:28 +04:00
2014-03-04 11:51:17 +04:00
cpumask_clear ( & cpu_topo - > core_sibling ) ;
2014-05-03 00:38:28 +04:00
cpumask_set_cpu ( cpu , & cpu_topo - > core_sibling ) ;
2014-03-04 11:51:17 +04:00
cpumask_clear ( & cpu_topo - > thread_sibling ) ;
2014-05-03 00:38:28 +04:00
cpumask_set_cpu ( cpu , & cpu_topo - > thread_sibling ) ;
2014-03-04 11:51:17 +04:00
}
}