of: merge of_attach_node() & of_detach_node()
[deliverable/linux.git] / arch / microblaze / kernel / prom.c
CommitLineData
12e84142
MS
1/*
2 * Procedures for creating, accessing and interpreting the device tree.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <stdarg.h>
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/init.h>
20#include <linux/threads.h>
21#include <linux/spinlock.h>
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/stringify.h>
25#include <linux/delay.h>
26#include <linux/initrd.h>
27#include <linux/bitops.h>
28#include <linux/module.h>
29#include <linux/kexec.h>
30#include <linux/debugfs.h>
31#include <linux/irq.h>
32#include <linux/lmb.h>
33
34#include <asm/prom.h>
35#include <asm/page.h>
36#include <asm/processor.h>
37#include <asm/irq.h>
38#include <linux/io.h>
39#include <asm/system.h>
40#include <asm/mmu.h>
41#include <asm/pgtable.h>
12e84142
MS
42#include <asm/sections.h>
43#include <asm/pci-bridge.h>
44
12e84142
MS
45/* export that to outside world */
46struct device_node *of_chosen;
47
12e84142
MS
48#define early_init_dt_scan_drconf_memory(node) 0
49
86e03221 50void __init early_init_dt_scan_chosen_arch(unsigned long node)
12e84142 51{
86e03221 52 /* No Microblaze specific code here */
12e84142
MS
53}
54
12e84142
MS
55static int __init early_init_dt_scan_memory(unsigned long node,
56 const char *uname, int depth, void *data)
57{
58 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
0f0b56c3 59 __be32 *reg, *endp;
12e84142
MS
60 unsigned long l;
61
62 /* Look for the ibm,dynamic-reconfiguration-memory node */
63/* if (depth == 1 &&
64 strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
65 return early_init_dt_scan_drconf_memory(node);
66*/
67 /* We are scanning "memory" nodes only */
68 if (type == NULL) {
69 /*
70 * The longtrail doesn't have a device_type on the
71 * /memory node, so look for the node called /memory@0.
72 */
73 if (depth != 1 || strcmp(uname, "memory@0") != 0)
74 return 0;
75 } else if (strcmp(type, "memory") != 0)
76 return 0;
77
0f0b56c3 78 reg = (__be32 *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
12e84142 79 if (reg == NULL)
0f0b56c3 80 reg = (__be32 *)of_get_flat_dt_prop(node, "reg", &l);
12e84142
MS
81 if (reg == NULL)
82 return 0;
83
0f0b56c3 84 endp = reg + (l / sizeof(__be32));
12e84142
MS
85
86 pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
87 uname, l, reg[0], reg[1], reg[2], reg[3]);
88
89 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
90 u64 base, size;
91
92 base = dt_mem_next_cell(dt_root_addr_cells, &reg);
93 size = dt_mem_next_cell(dt_root_size_cells, &reg);
94
95 if (size == 0)
96 continue;
97 pr_debug(" - %llx , %llx\n", (unsigned long long)base,
98 (unsigned long long)size);
99
100 lmb_add(base, size);
101 }
102 return 0;
103}
104
12e84142
MS
105#ifdef CONFIG_EARLY_PRINTK
106/* MS this is Microblaze specifig function */
107static int __init early_init_dt_scan_serial(unsigned long node,
108 const char *uname, int depth, void *data)
109{
110 unsigned long l;
111 char *p;
112 int *addr;
113
114 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
115
116/* find all serial nodes */
117 if (strncmp(uname, "serial", 6) != 0)
118 return 0;
119
120 early_init_dt_check_for_initrd(node);
121
122/* find compatible node with uartlite */
123 p = of_get_flat_dt_prop(node, "compatible", &l);
124 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
125 (strncmp(p, "xlnx,opb-uartlite", 17) != 0))
126 return 0;
127
128 addr = of_get_flat_dt_prop(node, "reg", &l);
129 return *addr; /* return address */
130}
131
132/* this function is looking for early uartlite console - Microblaze specific */
133int __init early_uartlite_console(void)
134{
135 return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
136}
137#endif
138
139void __init early_init_devtree(void *params)
140{
141 pr_debug(" -> early_init_devtree(%p)\n", params);
142
143 /* Setup flat device-tree pointer */
144 initial_boot_params = params;
145
12e84142
MS
146 /* Retrieve various informations from the /chosen node of the
147 * device-tree, including the platform type, initrd location and
148 * size, TCE reserve, and more ...
149 */
150 of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
151
152 /* Scan memory nodes and rebuild LMBs */
153 lmb_init();
154 of_scan_flat_dt(early_init_dt_scan_root, NULL);
155 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
156
157 /* Save command line for /proc/cmdline and then parse parameters */
158 strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
159 parse_early_param();
160
161 lmb_analyze();
162
163 pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
164
12e84142
MS
165 pr_debug(" <- early_init_devtree()\n");
166}
167
12e84142
MS
168/*******
169 *
170 * New implementation of the OF "find" APIs, return a refcounted
171 * object, call of_node_put() when done. The device tree and list
172 * are protected by a rw_lock.
173 *
174 * Note that property management will need some locking as well,
175 * this isn't dealt with yet.
176 *
177 *******/
178
179/**
180 * of_find_node_by_phandle - Find a node given a phandle
181 * @handle: phandle of the node to find
182 *
183 * Returns a node pointer with refcount incremented, use
184 * of_node_put() on it when done.
185 */
186struct device_node *of_find_node_by_phandle(phandle handle)
187{
188 struct device_node *np;
189
190 read_lock(&devtree_lock);
191 for (np = allnodes; np != NULL; np = np->allnext)
6016a363 192 if (np->phandle == handle)
12e84142
MS
193 break;
194 of_node_get(np);
195 read_unlock(&devtree_lock);
196 return np;
197}
198EXPORT_SYMBOL(of_find_node_by_phandle);
199
12e84142
MS
200#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
201static struct debugfs_blob_wrapper flat_dt_blob;
202
203static int __init export_flat_device_tree(void)
204{
205 struct dentry *d;
206
207 flat_dt_blob.data = initial_boot_params;
208 flat_dt_blob.size = initial_boot_params->totalsize;
209
210 d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
211 of_debugfs_root, &flat_dt_blob);
212 if (!d)
213 return 1;
214
215 return 0;
216}
217device_initcall(export_flat_device_tree);
218#endif
This page took 0.11519 seconds and 5 git commands to generate.