Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1cb9d1a authored by David Miller's avatar David Miller Committed by Grant Likely
Browse files

of: Make cpu node handling more portable.



Use for_each_node_by_type() to iterate all cpu nodes in the
system.

Provide and overridable function arch_find_n_match_cpu_physical_id,
which sees if the given device node matches 'cpu' and if so sets
'*thread' when non-NULL to the cpu thread number within the core.

The default implementation behaves the same as the existing code.

Add a sparc64 implementation.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Tested-by: default avatarSudeep KarkadaNagesha <Sudeep.KarkadaNagesha@arm.com>
Signed-off-by: default avatarGrant Likely <grant.likely@linaro.org>
parent 444c91e5
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -373,6 +373,59 @@ static const char *get_mid_prop(void)
	return (tlb_type == spitfire ? "upa-portid" : "portid");
}

bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
				       int cpu, unsigned int *thread)
{
	const char *mid_prop = get_mid_prop();
	int this_cpu_id;

	/* On hypervisor based platforms we interrogate the 'reg'
	 * property.  On everything else we look for a 'upa-portis',
	 * 'portid', or 'cpuid' property.
	 */

	if (tlb_type == hypervisor) {
		struct property *prop = of_find_property(cpun, "reg", NULL);
		u32 *regs;

		if (!prop) {
			pr_warn("CPU node missing reg property\n");
			return false;
		}
		regs = prop->value;
		this_cpu_id = regs[0] & 0x0fffffff;
	} else {
		this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);

		if (this_cpu_id < 0) {
			mid_prop = "cpuid";
			this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
		}
		if (this_cpu_id < 0) {
			pr_warn("CPU node missing cpu ID property\n");
			return false;
		}
	}
	if (this_cpu_id == cpu) {
		if (thread) {
			int proc_id = cpu_data(cpu).proc_id;

			/* On sparc64, the cpu thread information is obtained
			 * either from OBP or the machine description.  We've
			 * actually probed this information already long before
			 * this interface gets called so instead of interrogating
			 * both the OF node and the MDESC again, just use what
			 * we discovered already.
			 */
			if (proc_id < 0)
				proc_id = 0;
			*thread = proc_id;
		}
		return true;
	}
	return false;
}

static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
{
	struct device_node *dp;
+28 −17
Original line number Diff line number Diff line
@@ -280,6 +280,31 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
	return false;
}

/*
 * arch_find_n_match_cpu_physical_id - See if the given device node is
 * for the cpu corresponding to logical cpu 'cpu'.  Return true if so,
 * else false.  If 'thread' is non-NULL, the local thread number within the
 * core is returned in it.
 */
bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
					      int cpu, unsigned int *thread)
{
	/* Check for non-standard "ibm,ppc-interrupt-server#s" property
	 * for thread ids on PowerPC. If it doesn't exist fallback to
	 * standard "reg" property.
	 */
	if (IS_ENABLED(CONFIG_PPC) &&
	    __of_find_n_match_cpu_property(cpun,
					   "ibm,ppc-interrupt-server#s",
					   cpu, thread))
		return true;

	if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
		return true;

	return false;
}

/**
 * of_get_cpu_node - Get device node associated with the given logical CPU
 *
@@ -300,24 +325,10 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
 */
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
{
	struct device_node *cpun, *cpus;
	struct device_node *cpun;

	cpus = of_find_node_by_path("/cpus");
	if (!cpus)
		return NULL;

	for_each_child_of_node(cpus, cpun) {
		if (of_node_cmp(cpun->type, "cpu"))
			continue;
		/* Check for non-standard "ibm,ppc-interrupt-server#s" property
		 * for thread ids on PowerPC. If it doesn't exist fallback to
		 * standard "reg" property.
		 */
		if (IS_ENABLED(CONFIG_PPC) &&
			__of_find_n_match_cpu_property(cpun,
				"ibm,ppc-interrupt-server#s", cpu, thread))
			return cpun;
		if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
	for_each_node_by_type(cpun, "cpu") {
		if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
			return cpun;
	}
	return NULL;
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/cpumask.h>

struct device;
struct device_node;

struct cpu {
	int node_id;		/* The node which contains the CPU */
@@ -29,6 +30,8 @@ extern int register_cpu(struct cpu *cpu, int num);
extern struct device *get_cpu_device(unsigned cpu);
extern bool cpu_is_hotpluggable(unsigned cpu);
extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);
extern bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
					      int cpu, unsigned int *thread);

extern int cpu_add_dev_attr(struct device_attribute *attr);
extern void cpu_remove_dev_attr(struct device_attribute *attr);