PageRenderTime 20ms CodeModel.GetById 8ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/sparc64/kernel/devices.c

https://bitbucket.org/evzijst/gittest
C | 144 lines | 109 code | 26 blank | 9 comment | 17 complexity | 9f93249f41277edf666316998b784ca0 MD5 | raw file
  1/* devices.c: Initial scan of the prom device tree for important
  2 *            Sparc device nodes which we need to find.
  3 *
  4 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  5 */
  6
  7#include <linux/config.h>
  8#include <linux/kernel.h>
  9#include <linux/threads.h>
 10#include <linux/init.h>
 11#include <linux/ioport.h>
 12#include <linux/string.h>
 13#include <linux/spinlock.h>
 14#include <linux/errno.h>
 15
 16#include <asm/page.h>
 17#include <asm/oplib.h>
 18#include <asm/system.h>
 19#include <asm/smp.h>
 20#include <asm/spitfire.h>
 21#include <asm/timer.h>
 22#include <asm/cpudata.h>
 23
 24/* Used to synchronize acceses to NatSemi SUPER I/O chip configure
 25 * operations in asm/ns87303.h
 26 */
 27DEFINE_SPINLOCK(ns87303_lock);
 28
 29extern void cpu_probe(void);
 30extern void central_probe(void);
 31
 32static char *cpu_mid_prop(void)
 33{
 34	if (tlb_type == spitfire)
 35		return "upa-portid";
 36	return "portid";
 37}
 38
 39static int check_cpu_node(int nd, int *cur_inst,
 40			  int (*compare)(int, int, void *), void *compare_arg,
 41			  int *prom_node, int *mid)
 42{
 43	char node_str[128];
 44
 45	prom_getstring(nd, "device_type", node_str, sizeof(node_str));
 46	if (strcmp(node_str, "cpu"))
 47		return -ENODEV;
 48
 49	if (!compare(nd, *cur_inst, compare_arg)) {
 50		if (prom_node)
 51			*prom_node = nd;
 52		if (mid)
 53			*mid = prom_getintdefault(nd, cpu_mid_prop(), 0);
 54		return 0;
 55	}
 56
 57	(*cur_inst)++;
 58
 59	return -ENODEV;
 60}
 61
 62static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
 63			 int *prom_node, int *mid)
 64{
 65	int nd, cur_inst, err;
 66
 67	nd = prom_root_node;
 68	cur_inst = 0;
 69
 70	err = check_cpu_node(nd, &cur_inst,
 71			     compare, compare_arg,
 72			     prom_node, mid);
 73	if (err == 0)
 74		return 0;
 75
 76	nd = prom_getchild(nd);
 77	while ((nd = prom_getsibling(nd)) != 0) {
 78		err = check_cpu_node(nd, &cur_inst,
 79				     compare, compare_arg,
 80				     prom_node, mid);
 81		if (err == 0)
 82			return 0;
 83	}
 84
 85	return -ENODEV;
 86}
 87
 88static int cpu_instance_compare(int nd, int instance, void *_arg)
 89{
 90	int desired_instance = (int) (long) _arg;
 91
 92	if (instance == desired_instance)
 93		return 0;
 94	return -ENODEV;
 95}
 96
 97int cpu_find_by_instance(int instance, int *prom_node, int *mid)
 98{
 99	return __cpu_find_by(cpu_instance_compare, (void *)(long)instance,
100			     prom_node, mid);
101}
102
103static int cpu_mid_compare(int nd, int instance, void *_arg)
104{
105	int desired_mid = (int) (long) _arg;
106	int this_mid;
107
108	this_mid = prom_getintdefault(nd, cpu_mid_prop(), 0);
109	if (this_mid == desired_mid)
110		return 0;
111	return -ENODEV;
112}
113
114int cpu_find_by_mid(int mid, int *prom_node)
115{
116	return __cpu_find_by(cpu_mid_compare, (void *)(long)mid,
117			     prom_node, NULL);
118}
119
120void __init device_scan(void)
121{
122	/* FIX ME FAST... -DaveM */
123	ioport_resource.end = 0xffffffffffffffffUL;
124
125	prom_printf("Booting Linux...\n");
126
127#ifndef CONFIG_SMP
128	{
129		int err, cpu_node;
130		err = cpu_find_by_instance(0, &cpu_node, NULL);
131		if (err) {
132			prom_printf("No cpu nodes, cannot continue\n");
133			prom_halt();
134		}
135		cpu_data(0).clock_tick = prom_getintdefault(cpu_node,
136							    "clock-frequency",
137							    0);
138	}
139#endif
140
141	central_probe();
142
143	cpu_probe();
144}