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

Commit 07f8e5f3 authored by David S. Miller's avatar David S. Miller
Browse files

[SPARC64]: Convert cpu_find_by_*() interface to in-kernel PROM device tree.

parent 6d307724
Loading
Loading
Loading
Loading
+57 −61
Original line number Diff line number Diff line
@@ -133,38 +133,44 @@ static const char *cpu_mid_prop(void)
	return "portid";
}

static int get_cpu_mid(int prom_node)
static int get_cpu_mid(struct device_node *dp)
{
	struct property *prop;

	if (tlb_type == hypervisor) {
		struct linux_prom64_registers reg;
		struct linux_prom64_registers *reg;
		int len;

		if (prom_getproplen(prom_node, "cpuid") == 4)
			return prom_getintdefault(prom_node, "cpuid", 0);
		prop = of_find_property(dp, "cpuid", &len);
		if (prop && len == 4)
			return *(int *) prop->value;

		prom_getproperty(prom_node, "reg", (char *) &reg, sizeof(reg));
		return (reg.phys_addr >> 32) & 0x0fffffffUL;
		prop = of_find_property(dp, "reg", NULL);
		reg = prop->value;
		return (reg[0].phys_addr >> 32) & 0x0fffffffUL;
	} else {
		const char *prop_name = cpu_mid_prop();

		return prom_getintdefault(prom_node, prop_name, 0);
		prop = of_find_property(dp, prop_name, NULL);
		if (prop)
			return *(int *) prop->value;
		return 0;
	}
}

static int check_cpu_node(int nd, int *cur_inst,
			  int (*compare)(int, int, void *), void *compare_arg,
			  int *prom_node, int *mid)
static int check_cpu_node(struct device_node *dp, int *cur_inst,
			  int (*compare)(struct device_node *, int, void *),
			  void *compare_arg,
			  struct device_node **dev_node, int *mid)
{
	char node_str[128];

	prom_getstring(nd, "device_type", node_str, sizeof(node_str));
	if (strcmp(node_str, "cpu"))
	if (strcmp(dp->type, "cpu"))
		return -ENODEV;

	if (!compare(nd, *cur_inst, compare_arg)) {
		if (prom_node)
			*prom_node = nd;
	if (!compare(dp, *cur_inst, compare_arg)) {
		if (dev_node)
			*dev_node = dp;
		if (mid)
			*mid = get_cpu_mid(nd);
			*mid = get_cpu_mid(dp);
		return 0;
	}

@@ -173,25 +179,18 @@ static int check_cpu_node(int nd, int *cur_inst,
	return -ENODEV;
}

static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
			 int *prom_node, int *mid)
static int __cpu_find_by(int (*compare)(struct device_node *, int, void *),
			 void *compare_arg,
			 struct device_node **dev_node, int *mid)
{
	int nd, cur_inst, err;
	struct device_node *dp;
	int cur_inst;

	nd = prom_root_node;
	cur_inst = 0;

	err = check_cpu_node(nd, &cur_inst,
	for_each_node_by_type(dp, "cpu") {
		int err = check_cpu_node(dp, &cur_inst,
					 compare, compare_arg,
			     prom_node, mid);
	if (err == 0)
		return 0;

	nd = prom_getchild(nd);
	while ((nd = prom_getsibling(nd)) != 0) {
		err = check_cpu_node(nd, &cur_inst,
				     compare, compare_arg,
				     prom_node, mid);
					 dev_node, mid);
		if (err == 0)
			return 0;
	}
@@ -199,7 +198,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
	return -ENODEV;
}

static int cpu_instance_compare(int nd, int instance, void *_arg)
static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg)
{
	int desired_instance = (int) (long) _arg;

@@ -208,27 +207,27 @@ static int cpu_instance_compare(int nd, int instance, void *_arg)
	return -ENODEV;
}

int cpu_find_by_instance(int instance, int *prom_node, int *mid)
int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid)
{
	return __cpu_find_by(cpu_instance_compare, (void *)(long)instance,
			     prom_node, mid);
			     dev_node, mid);
}

static int cpu_mid_compare(int nd, int instance, void *_arg)
static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg)
{
	int desired_mid = (int) (long) _arg;
	int this_mid;

	this_mid = get_cpu_mid(nd);
	this_mid = get_cpu_mid(dp);
	if (this_mid == desired_mid)
		return 0;
	return -ENODEV;
}

int cpu_find_by_mid(int mid, int *prom_node)
int cpu_find_by_mid(int mid, struct device_node **dev_node)
{
	return __cpu_find_by(cpu_mid_compare, (void *)(long)mid,
			     prom_node, NULL);
			     dev_node, NULL);
}

void __init device_scan(void)
@@ -240,50 +239,47 @@ void __init device_scan(void)

#ifndef CONFIG_SMP
	{
		int err, cpu_node, def;
		struct device_node *dp;
		int err, def;

		err = cpu_find_by_instance(0, &cpu_node, NULL);
		err = cpu_find_by_instance(0, &dp, NULL);
		if (err) {
			prom_printf("No cpu nodes, cannot continue\n");
			prom_halt();
		}
		cpu_data(0).clock_tick = prom_getintdefault(cpu_node,
							    "clock-frequency",
							    0);
		cpu_data(0).clock_tick =
			of_getintprop_default(dp, "clock-frequency", 0);

		def = ((tlb_type == hypervisor) ?
		       (8 * 1024) :
		       (16 * 1024));
		cpu_data(0).dcache_size = prom_getintdefault(cpu_node,
		cpu_data(0).dcache_size = of_getintprop_default(dp,
								"dcache-size",
								def);

		def = 32;
		cpu_data(0).dcache_line_size =
			prom_getintdefault(cpu_node, "dcache-line-size",
					   def);
			of_getintprop_default(dp, "dcache-line-size", def);

		def = 16 * 1024;
		cpu_data(0).icache_size = prom_getintdefault(cpu_node,
		cpu_data(0).icache_size = of_getintprop_default(dp,
								"icache-size",
								def);

		def = 32;
		cpu_data(0).icache_line_size =
			prom_getintdefault(cpu_node, "icache-line-size",
					   def);
			of_getintprop_default(dp, "icache-line-size", def);

		def = ((tlb_type == hypervisor) ?
		       (3 * 1024 * 1024) :
		       (4 * 1024 * 1024));
		cpu_data(0).ecache_size = prom_getintdefault(cpu_node,
		cpu_data(0).ecache_size = of_getintprop_default(dp,
								"ecache-size",
								def);

		def = 64;
		cpu_data(0).ecache_line_size =
			prom_getintdefault(cpu_node, "ecache-line-size",
					   def);
			of_getintprop_default(dp, "ecache-line-size", def);
		printk("CPU[0]: Caches "
		       "D[sz(%d):line_sz(%d)] "
		       "I[sz(%d):line_sz(%d)] "
+3 −6
Original line number Diff line number Diff line
@@ -1455,16 +1455,13 @@ void sabre_init(struct device_node *dp, char *model_name)
				hummingbird_p = 1;
		}
		if (!hummingbird_p) {
			char compat[64];
			int cpu_node;
			struct device_node *dp;

			/* Of course, Sun has to encode things a thousand
			 * different ways, inconsistently.
			 */
			cpu_find_by_instance(0, &cpu_node, NULL);
			if (prom_getproperty(cpu_node, "name",
					     compat, sizeof(compat)) > 0 &&
			    !strcmp(compat, "SUNW,UltraSPARC-IIe"))
			cpu_find_by_instance(0, &dp, NULL);
			if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
				hummingbird_p = 1;
		}
	}
+22 −19
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <asm/starfire.h>
#include <asm/tlb.h>
#include <asm/sections.h>
#include <asm/prom.h>

extern void calibrate_delay(void);

@@ -76,41 +77,42 @@ void smp_bogo(struct seq_file *m)

void __init smp_store_cpu_info(int id)
{
	int cpu_node, def;
	struct device_node *dp;
	int def;

	/* multiplier and counter set by
	   smp_setup_percpu_timer()  */
	cpu_data(id).udelay_val			= loops_per_jiffy;

	cpu_find_by_mid(id, &cpu_node);
	cpu_data(id).clock_tick = prom_getintdefault(cpu_node,
						     "clock-frequency", 0);
	cpu_find_by_mid(id, &dp);
	cpu_data(id).clock_tick =
		of_getintprop_default(dp, "clock-frequency", 0);

	def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024));
	cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size",
						      def);
	cpu_data(id).dcache_size =
		of_getintprop_default(dp, "dcache-size", def);

	def = 32;
	cpu_data(id).dcache_line_size =
		prom_getintdefault(cpu_node, "dcache-line-size", def);
		of_getintprop_default(dp, "dcache-line-size", def);

	def = 16 * 1024;
	cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size",
						      def);
	cpu_data(id).icache_size =
		of_getintprop_default(dp, "icache-size", def);

	def = 32;
	cpu_data(id).icache_line_size =
		prom_getintdefault(cpu_node, "icache-line-size", def);
		of_getintprop_default(dp, "icache-line-size", def);

	def = ((tlb_type == hypervisor) ?
	       (3 * 1024 * 1024) :
	       (4 * 1024 * 1024));
	cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size",
						      def);
	cpu_data(id).ecache_size =
		of_getintprop_default(dp, "ecache-size", def);

	def = 64;
	cpu_data(id).ecache_line_size =
		prom_getintdefault(cpu_node, "ecache-line-size", def);
		of_getintprop_default(dp, "ecache-line-size", def);

	printk("CPU[%d]: Caches "
	       "D[sz(%d):line_sz(%d)] "
@@ -342,10 +344,10 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu)

		prom_startcpu_cpuid(cpu, entry, cookie);
	} else {
		int cpu_node;
		struct device_node *dp;

		cpu_find_by_mid(cpu, &cpu_node);
		prom_startcpu(cpu_node, entry, cookie);
		cpu_find_by_mid(cpu, &dp);
		prom_startcpu(dp->node, entry, cookie);
	}

	for (timeout = 0; timeout < 5000000; timeout++) {
@@ -1289,7 +1291,8 @@ int setup_profiling_timer(unsigned int multiplier)

static void __init smp_tune_scheduling(void)
{
	int instance, node;
	struct device_node *dp;
	int instance;
	unsigned int def, smallest = ~0U;

	def = ((tlb_type == hypervisor) ?
@@ -1297,10 +1300,10 @@ static void __init smp_tune_scheduling(void)
	       (4 * 1024 * 1024));

	instance = 0;
	while (!cpu_find_by_instance(instance, &node, NULL)) {
	while (!cpu_find_by_instance(instance, &dp, NULL)) {
		unsigned int val;

		val = prom_getintdefault(node, "ecache-size", def);
		val = of_getintprop_default(dp, "ecache-size", def);
		if (val < smallest)
			smallest = val;

+9 −7
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#include <asm/sections.h>
#include <asm/cpudata.h>
#include <asm/uaccess.h>
#include <asm/prom.h>

DEFINE_SPINLOCK(mostek_lock);
DEFINE_SPINLOCK(rtc_lock);
@@ -983,12 +984,14 @@ void __init clock_probe(void)
/* This is gets the master TICK_INT timer going. */
static unsigned long sparc64_init_timers(void)
{
	struct device_node *dp;
	struct property *prop;
	unsigned long clock;
	int node;
#ifdef CONFIG_SMP
	extern void smp_tick_init(void);
#endif

	dp = of_find_node_by_path("/");
	if (tlb_type == spitfire) {
		unsigned long ver, manuf, impl;

@@ -999,18 +1002,17 @@ static unsigned long sparc64_init_timers(void)
		if (manuf == 0x17 && impl == 0x13) {
			/* Hummingbird, aka Ultra-IIe */
			tick_ops = &hbtick_operations;
			node = prom_root_node;
			clock = prom_getint(node, "stick-frequency");
			prop = of_find_property(dp, "stick-frequency", NULL);
		} else {
			tick_ops = &tick_operations;
			cpu_find_by_instance(0, &node, NULL);
			clock = prom_getint(node, "clock-frequency");
			cpu_find_by_instance(0, &dp, NULL);
			prop = of_find_property(dp, "clock-frequency", NULL);
		}
	} else {
		tick_ops = &stick_operations;
		node = prom_root_node;
		clock = prom_getint(node, "stick-frequency");
		prop = of_find_property(dp, "stick-frequency", NULL);
	}
	clock = *(unsigned int *) prop->value;
	timer_tick_offset = clock / HZ;

#ifdef CONFIG_SMP
+10 −8
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
#include <asm/prom.h>

ATOMIC_NOTIFIER_HEAD(sparc64die_chain);

@@ -807,7 +808,8 @@ extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector
void __init cheetah_ecache_flush_init(void)
{
	unsigned long largest_size, smallest_linesize, order, ver;
	int node, i, instance;
	struct device_node *dp;
	int i, instance, sz;

	/* Scan all cpu device tree nodes, note two values:
	 * 1) largest E-cache size
@@ -817,14 +819,14 @@ void __init cheetah_ecache_flush_init(void)
	smallest_linesize = ~0UL;

	instance = 0;
	while (!cpu_find_by_instance(instance, &node, NULL)) {
	while (!cpu_find_by_instance(instance, &dp, NULL)) {
		unsigned long val;

		val = prom_getintdefault(node, "ecache-size",
		val = of_getintprop_default(dp, "ecache-size",
					    (2 * 1024 * 1024));
		if (val > largest_size)
			largest_size = val;
		val = prom_getintdefault(node, "ecache-line-size", 64);
		val = of_getintprop_default(dp, "ecache-line-size", 64);
		if (val < smallest_linesize)
			smallest_linesize = val;
		instance++;
@@ -849,16 +851,16 @@ void __init cheetah_ecache_flush_init(void)
	}

	/* Now allocate error trap reporting scoreboard. */
	node = NR_CPUS * (2 * sizeof(struct cheetah_err_info));
	sz = NR_CPUS * (2 * sizeof(struct cheetah_err_info));
	for (order = 0; order < MAX_ORDER; order++) {
		if ((PAGE_SIZE << order) >= node)
		if ((PAGE_SIZE << order) >= sz)
			break;
	}
	cheetah_error_log = (struct cheetah_err_info *)
		__get_free_pages(GFP_KERNEL, order);
	if (!cheetah_error_log) {
		prom_printf("cheetah_ecache_flush_init: Failed to allocate "
			    "error logging scoreboard (%d bytes).\n", node);
			    "error logging scoreboard (%d bytes).\n", sz);
		prom_halt();
	}
	memset(cheetah_error_log, 0, PAGE_SIZE << order);
Loading