162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_POWERPC_TOPOLOGY_H
362306a36Sopenharmony_ci#define _ASM_POWERPC_TOPOLOGY_H
462306a36Sopenharmony_ci#ifdef __KERNEL__
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci
762306a36Sopenharmony_cistruct device;
862306a36Sopenharmony_cistruct device_node;
962306a36Sopenharmony_cistruct drmem_lmb;
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifdef CONFIG_NUMA
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/*
1462306a36Sopenharmony_ci * If zone_reclaim_mode is enabled, a RECLAIM_DISTANCE of 10 will mean that
1562306a36Sopenharmony_ci * all zones on all nodes will be eligible for zone_reclaim().
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci#define RECLAIM_DISTANCE 10
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <asm/mmzone.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define cpumask_of_node(node) ((node) == -1 ?				\
2262306a36Sopenharmony_ci			       cpu_all_mask :				\
2362306a36Sopenharmony_ci			       node_to_cpumask_map[node])
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistruct pci_bus;
2662306a36Sopenharmony_ci#ifdef CONFIG_PCI
2762306a36Sopenharmony_ciextern int pcibus_to_node(struct pci_bus *bus);
2862306a36Sopenharmony_ci#else
2962306a36Sopenharmony_cistatic inline int pcibus_to_node(struct pci_bus *bus)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	return -1;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci#endif
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define cpumask_of_pcibus(bus)	(pcibus_to_node(bus) == -1 ?		\
3662306a36Sopenharmony_ci				 cpu_all_mask :				\
3762306a36Sopenharmony_ci				 cpumask_of_node(pcibus_to_node(bus)))
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ciint cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc);
4062306a36Sopenharmony_ciextern int __node_distance(int, int);
4162306a36Sopenharmony_ci#define node_distance(a, b) __node_distance(a, b)
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciextern void __init dump_numa_cpu_topology(void);
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciextern int sysfs_add_device_to_node(struct device *dev, int nid);
4662306a36Sopenharmony_ciextern void sysfs_remove_device_from_node(struct device *dev, int nid);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic inline void update_numa_cpu_lookup_table(unsigned int cpu, int node)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	numa_cpu_lookup_table[cpu] = node;
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline int early_cpu_to_node(int cpu)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	int nid;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	nid = numa_cpu_lookup_table[cpu];
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	/*
6062306a36Sopenharmony_ci	 * Fall back to node 0 if nid is unset (it should be, except bugs).
6162306a36Sopenharmony_ci	 * This allows callers to safely do NODE_DATA(early_cpu_to_node(cpu)).
6262306a36Sopenharmony_ci	 */
6362306a36Sopenharmony_ci	return (nid < 0) ? 0 : nid;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciint of_drconf_to_nid_single(struct drmem_lmb *lmb);
6762306a36Sopenharmony_civoid update_numa_distance(struct device_node *node);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ciextern void map_cpu_to_node(int cpu, int node);
7062306a36Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU
7162306a36Sopenharmony_ciextern void unmap_cpu_from_node(unsigned long cpu);
7262306a36Sopenharmony_ci#endif /* CONFIG_HOTPLUG_CPU */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#else
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistatic inline int early_cpu_to_node(int cpu) { return 0; }
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistatic inline void dump_numa_cpu_topology(void) {}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic inline int sysfs_add_device_to_node(struct device *dev, int nid)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	return 0;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic inline void sysfs_remove_device_from_node(struct device *dev,
8662306a36Sopenharmony_ci						int nid)
8762306a36Sopenharmony_ci{
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistatic inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic inline int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	return 0;
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic inline int of_drconf_to_nid_single(struct drmem_lmb *lmb)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	return first_online_node;
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic inline void update_numa_distance(struct device_node *node) {}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#ifdef CONFIG_SMP
10562306a36Sopenharmony_cistatic inline void map_cpu_to_node(int cpu, int node) {}
10662306a36Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU
10762306a36Sopenharmony_cistatic inline void unmap_cpu_from_node(unsigned long cpu) {}
10862306a36Sopenharmony_ci#endif /* CONFIG_HOTPLUG_CPU */
10962306a36Sopenharmony_ci#endif /* CONFIG_SMP */
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci#endif /* CONFIG_NUMA */
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
11462306a36Sopenharmony_civoid find_and_update_cpu_nid(int cpu);
11562306a36Sopenharmony_ciextern int cpu_to_coregroup_id(int cpu);
11662306a36Sopenharmony_ci#else
11762306a36Sopenharmony_cistatic inline void find_and_update_cpu_nid(int cpu) {}
11862306a36Sopenharmony_cistatic inline int cpu_to_coregroup_id(int cpu)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci#ifdef CONFIG_SMP
12162306a36Sopenharmony_ci	return cpu_to_core_id(cpu);
12262306a36Sopenharmony_ci#else
12362306a36Sopenharmony_ci	return 0;
12462306a36Sopenharmony_ci#endif
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci#include <asm-generic/topology.h>
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci#ifdef CONFIG_SMP
13262306a36Sopenharmony_ci#include <asm/cputable.h>
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci#ifdef CONFIG_PPC64
13562306a36Sopenharmony_ci#include <asm/smp.h>
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#define topology_physical_package_id(cpu)	(cpu_to_chip_id(cpu))
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#define topology_sibling_cpumask(cpu)	(per_cpu(cpu_sibling_map, cpu))
14062306a36Sopenharmony_ci#define topology_core_cpumask(cpu)	(per_cpu(cpu_core_map, cpu))
14162306a36Sopenharmony_ci#define topology_core_id(cpu)		(cpu_to_core_id(cpu))
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#endif
14462306a36Sopenharmony_ci#endif
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci#ifdef CONFIG_HOTPLUG_SMT
14762306a36Sopenharmony_ci#include <linux/cpu_smt.h>
14862306a36Sopenharmony_ci#include <asm/cputhreads.h>
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic inline bool topology_is_primary_thread(unsigned int cpu)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	return cpu == cpu_first_thread_sibling(cpu);
15362306a36Sopenharmony_ci}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic inline bool topology_smt_thread_allowed(unsigned int cpu)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	return cpu_thread_in_core(cpu) < cpu_smt_num_threads;
15862306a36Sopenharmony_ci}
15962306a36Sopenharmony_ci#endif
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci#endif /* __KERNEL__ */
16262306a36Sopenharmony_ci#endif	/* _ASM_POWERPC_TOPOLOGY_H */
163