aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2009-03-27 09:25:12 -0400
committerMichal Simek <monstr@monstr.eu>2009-03-27 09:25:12 -0400
commit12e8414263f47352b3fec8ba5efff160584202e0 (patch)
tree76dffeeda1d792dafb1fc056a3a88e3fe1b9696a /arch/microblaze
parent406107dacde125346c313d34534eed937eb25444 (diff)
microblaze_v8: Open firmware files
Reviewed-by: Ingo Molnar <mingo@elte.hu> Reviewed-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com> Acked-by: John Linn <john.linn@xilinx.com> Acked-by: John Williams <john.williams@petalogix.com> Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/include/asm/of_device.h45
-rw-r--r--arch/microblaze/include/asm/of_platform.h64
-rw-r--r--arch/microblaze/include/asm/prom.h313
-rw-r--r--arch/microblaze/kernel/of_device.c115
-rw-r--r--arch/microblaze/kernel/of_platform.c201
-rw-r--r--arch/microblaze/kernel/prom.c1147
-rw-r--r--arch/microblaze/kernel/prom_parse.c1025
7 files changed, 2910 insertions, 0 deletions
diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h
new file mode 100644
index 000000000000..ba917cfaefe6
--- /dev/null
+++ b/arch/microblaze/include/asm/of_device.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
3 *
4 * based on PowerPC of_device.h
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef _ASM_MICROBLAZE_OF_DEVICE_H
12#define _ASM_MICROBLAZE_OF_DEVICE_H
13#ifdef __KERNEL__
14
15#include <linux/device.h>
16#include <linux/of.h>
17
18/*
19 * The of_device is a kind of "base class" that is a superset of
20 * struct device for use by devices attached to an OF node and
21 * probed using OF properties.
22 */
23struct of_device {
24 struct device_node *node; /* to be obsoleted */
25 u64 dma_mask; /* DMA mask */
26 struct device dev; /* Generic device interface */
27};
28
29extern ssize_t of_device_get_modalias(struct of_device *ofdev,
30 char *str, ssize_t len);
31
32extern struct of_device *of_device_alloc(struct device_node *np,
33 const char *bus_id,
34 struct device *parent);
35
36extern int of_device_uevent(struct device *dev,
37 struct kobj_uevent_env *env);
38
39extern void of_device_make_bus_id(struct of_device *dev);
40
41/* This is just here during the transition */
42#include <linux/of_device.h>
43
44#endif /* __KERNEL__ */
45#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h
new file mode 100644
index 000000000000..187c0eedaece
--- /dev/null
+++ b/arch/microblaze/include/asm/of_platform.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H
12#define _ASM_MICROBLAZE_OF_PLATFORM_H
13
14/* This is just here during the transition */
15#include <linux/of_platform.h>
16
17/*
18 * The list of OF IDs below is used for matching bus types in the
19 * system whose devices are to be exposed as of_platform_devices.
20 *
21 * This is the default list valid for most platforms. This file provides
22 * functions who can take an explicit list if necessary though
23 *
24 * The search is always performed recursively looking for children of
25 * the provided device_node and recursively if such a children matches
26 * a bus type in the list
27 */
28
29static const struct of_device_id of_default_bus_ids[] = {
30 { .type = "soc", },
31 { .compatible = "soc", },
32 { .type = "plb5", },
33 { .type = "plb4", },
34 { .type = "opb", },
35 { .type = "simple", },
36 {},
37};
38
39/* Platform drivers register/unregister */
40static inline int of_register_platform_driver(struct of_platform_driver *drv)
41{
42 return of_register_driver(drv, &of_platform_bus_type);
43}
44static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
45{
46 of_unregister_driver(drv);
47}
48
49/* Platform devices and busses creation */
50extern struct of_device *of_platform_device_create(struct device_node *np,
51 const char *bus_id,
52 struct device *parent);
53/* pseudo "matches" value to not do deep probe */
54#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
55
56extern int of_platform_bus_probe(struct device_node *root,
57 const struct of_device_id *matches,
58 struct device *parent);
59
60extern struct of_device *of_find_device_by_phandle(phandle ph);
61
62extern void of_instantiate_rtc(void);
63
64#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
new file mode 100644
index 000000000000..20f7b3a926e8
--- /dev/null
+++ b/arch/microblaze/include/asm/prom.h
@@ -0,0 +1,313 @@
1/*
2 * Definitions for talking to the Open Firmware PROM on
3 * Power Macintosh computers.
4 *
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#ifndef _ASM_MICROBLAZE_PROM_H
16#define _ASM_MICROBLAZE_PROM_H
17#ifdef __KERNEL__
18
19#include <linux/types.h>
20#include <linux/proc_fs.h>
21#include <linux/platform_device.h>
22#include <asm/irq.h>
23#include <asm/atomic.h>
24
25#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
26#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
27
28#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l))
29#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
30#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
31
32/* Definitions used by the flattened device tree */
33#define OF_DT_HEADER 0xd00dfeed /* marker */
34#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
35#define OF_DT_END_NODE 0x2 /* End node */
36#define OF_DT_PROP 0x3 /* Property: name off, size, content */
37#define OF_DT_NOP 0x4 /* nop */
38#define OF_DT_END 0x9
39
40#define OF_DT_VERSION 0x10
41
42/*
43 * This is what gets passed to the kernel by prom_init or kexec
44 *
45 * The dt struct contains the device tree structure, full pathes and
46 * property contents. The dt strings contain a separate block with just
47 * the strings for the property names, and is fully page aligned and
48 * self contained in a page, so that it can be kept around by the kernel,
49 * each property name appears only once in this page (cheap compression)
50 *
51 * the mem_rsvmap contains a map of reserved ranges of physical memory,
52 * passing it here instead of in the device-tree itself greatly simplifies
53 * the job of everybody. It's just a list of u64 pairs (base/size) that
54 * ends when size is 0
55 */
56struct boot_param_header {
57 u32 magic; /* magic word OF_DT_HEADER */
58 u32 totalsize; /* total size of DT block */
59 u32 off_dt_struct; /* offset to structure */
60 u32 off_dt_strings; /* offset to strings */
61 u32 off_mem_rsvmap; /* offset to memory reserve map */
62 u32 version; /* format version */
63 u32 last_comp_version; /* last compatible version */
64 /* version 2 fields below */
65 u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
66 /* version 3 fields below */
67 u32 dt_strings_size; /* size of the DT strings block */
68 /* version 17 fields below */
69 u32 dt_struct_size; /* size of the DT structure block */
70};
71
72typedef u32 phandle;
73typedef u32 ihandle;
74
75struct property {
76 char *name;
77 int length;
78 void *value;
79 struct property *next;
80};
81
82struct device_node {
83 const char *name;
84 const char *type;
85 phandle node;
86 phandle linux_phandle;
87 char *full_name;
88
89 struct property *properties;
90 struct property *deadprops; /* removed properties */
91 struct device_node *parent;
92 struct device_node *child;
93 struct device_node *sibling;
94 struct device_node *next; /* next device of same type */
95 struct device_node *allnext; /* next in list of all nodes */
96 struct proc_dir_entry *pde; /* this node's proc directory */
97 struct kref kref;
98 unsigned long _flags;
99 void *data;
100};
101
102extern struct device_node *of_chosen;
103
104static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
105{
106 return test_bit(flag, &n->_flags);
107}
108
109static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
110{
111 set_bit(flag, &n->_flags);
112}
113
114#define HAVE_ARCH_DEVTREE_FIXUPS
115
116static inline void set_node_proc_entry(struct device_node *dn,
117 struct proc_dir_entry *de)
118{
119 dn->pde = de;
120}
121
122extern struct device_node *allnodes; /* temporary while merging */
123extern rwlock_t devtree_lock; /* temporary while merging */
124
125extern struct device_node *of_find_all_nodes(struct device_node *prev);
126extern struct device_node *of_node_get(struct device_node *node);
127extern void of_node_put(struct device_node *node);
128
129/* For scanning the flat device-tree at boot time */
130extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
131 const char *uname, int depth,
132 void *data),
133 void *data);
134extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
135 unsigned long *size);
136extern int __init
137 of_flat_dt_is_compatible(unsigned long node, const char *name);
138extern unsigned long __init of_get_flat_dt_root(void);
139
140/* For updating the device tree at runtime */
141extern void of_attach_node(struct device_node *);
142extern void of_detach_node(struct device_node *);
143
144/* Other Prototypes */
145extern void finish_device_tree(void);
146extern void unflatten_device_tree(void);
147extern int early_uartlite_console(void);
148extern void early_init_devtree(void *);
149extern int machine_is_compatible(const char *compat);
150extern void print_properties(struct device_node *node);
151extern int prom_n_intr_cells(struct device_node *np);
152extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
153extern int prom_add_property(struct device_node *np, struct property *prop);
154extern int prom_remove_property(struct device_node *np, struct property *prop);
155extern int prom_update_property(struct device_node *np,
156 struct property *newprop,
157 struct property *oldprop);
158
159extern struct resource *request_OF_resource(struct device_node *node,
160 int index, const char *name_postfix);
161extern int release_OF_resource(struct device_node *node, int index);
162
163/*
164 * OF address retreival & translation
165 */
166
167/* Helper to read a big number; size is in cells (not bytes) */
168static inline u64 of_read_number(const u32 *cell, int size)
169{
170 u64 r = 0;
171 while (size--)
172 r = (r << 32) | *(cell++);
173 return r;
174}
175
176/* Like of_read_number, but we want an unsigned long result */
177#define of_read_ulong(cell, size) of_read_number(cell, size)
178
179/* Translate an OF address block into a CPU physical address
180 */
181extern u64 of_translate_address(struct device_node *np, const u32 *addr);
182
183/* Extract an address from a device, returns the region size and
184 * the address space flags too. The PCI version uses a BAR number
185 * instead of an absolute index
186 */
187extern const u32 *of_get_address(struct device_node *dev, int index,
188 u64 *size, unsigned int *flags);
189extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
190 u64 *size, unsigned int *flags);
191
192/* Get an address as a resource. Note that if your address is
193 * a PIO address, the conversion will fail if the physical address
194 * can't be internally converted to an IO token with
195 * pci_address_to_pio(), that is because it's either called to early
196 * or it can't be matched to any host bridge IO space
197 */
198extern int of_address_to_resource(struct device_node *dev, int index,
199 struct resource *r);
200extern int of_pci_address_to_resource(struct device_node *dev, int bar,
201 struct resource *r);
202
203/* Parse the ibm,dma-window property of an OF node into the busno, phys and
204 * size parameters.
205 */
206void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
207 unsigned long *busno, unsigned long *phys, unsigned long *size);
208
209extern void kdump_move_device_tree(void);
210
211/* CPU OF node matching */
212struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
213
214/* Get the MAC address */
215extern const void *of_get_mac_address(struct device_node *np);
216
217/*
218 * OF interrupt mapping
219 */
220
221/* This structure is returned when an interrupt is mapped. The controller
222 * field needs to be put() after use
223 */
224
225#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
226
227struct of_irq {
228 struct device_node *controller; /* Interrupt controller node */
229 u32 size; /* Specifier size */
230 u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
231};
232
233/**
234 * of_irq_map_init - Initialize the irq remapper
235 * @flags: flags defining workarounds to enable
236 *
237 * Some machines have bugs in the device-tree which require certain workarounds
238 * to be applied. Call this before any interrupt mapping attempts to enable
239 * those workarounds.
240 */
241#define OF_IMAP_OLDWORLD_MAC 0x00000001
242#define OF_IMAP_NO_PHANDLE 0x00000002
243
244extern void of_irq_map_init(unsigned int flags);
245
246/**
247 * of_irq_map_raw - Low level interrupt tree parsing
248 * @parent: the device interrupt parent
249 * @intspec: interrupt specifier ("interrupts" property of the device)
250 * @ointsize: size of the passed in interrupt specifier
251 * @addr: address specifier (start of "reg" property of the device)
252 * @out_irq: structure of_irq filled by this function
253 *
254 * Returns 0 on success and a negative number on error
255 *
256 * This function is a low-level interrupt tree walking function. It
257 * can be used to do a partial walk with synthetized reg and interrupts
258 * properties, for example when resolving PCI interrupts when no device
259 * node exist for the parent.
260 *
261 */
262
263extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
264 u32 ointsize, const u32 *addr,
265 struct of_irq *out_irq);
266
267/**
268 * of_irq_map_one - Resolve an interrupt for a device
269 * @device: the device whose interrupt is to be resolved
270 * @index: index of the interrupt to resolve
271 * @out_irq: structure of_irq filled by this function
272 *
273 * This function resolves an interrupt, walking the tree, for a given
274 * device-tree node. It's the high level pendant to of_irq_map_raw().
275 * It also implements the workarounds for OldWolrd Macs.
276 */
277extern int of_irq_map_one(struct device_node *device, int index,
278 struct of_irq *out_irq);
279
280/**
281 * of_irq_map_pci - Resolve the interrupt for a PCI device
282 * @pdev: the device whose interrupt is to be resolved
283 * @out_irq: structure of_irq filled by this function
284 *
285 * This function resolves the PCI interrupt for a given PCI device. If a
286 * device-node exists for a given pci_dev, it will use normal OF tree
287 * walking. If not, it will implement standard swizzling and walk up the
288 * PCI tree until an device-node is found, at which point it will finish
289 * resolving using the OF tree walking.
290 */
291struct pci_dev;
292extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
293
294extern int of_irq_to_resource(struct device_node *dev, int index,
295 struct resource *r);
296
297/**
298 * of_iomap - Maps the memory mapped IO for a given device_node
299 * @device: the device whose io range will be mapped
300 * @index: index of the io range
301 *
302 * Returns a pointer to the mapped memory
303 */
304extern void __iomem *of_iomap(struct device_node *device, int index);
305
306/*
307 * NB: This is here while we transition from using asm/prom.h
308 * to linux/of.h
309 */
310#include <linux/of.h>
311
312#endif /* __KERNEL__ */
313#endif /* _ASM_MICROBLAZE_PROM_H */
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c
new file mode 100644
index 000000000000..717edf4ad0b4
--- /dev/null
+++ b/arch/microblaze/kernel/of_device.c
@@ -0,0 +1,115 @@
1#include <linux/string.h>
2#include <linux/kernel.h>
3#include <linux/of.h>
4#include <linux/init.h>
5#include <linux/module.h>
6#include <linux/mod_devicetable.h>
7#include <linux/slab.h>
8#include <linux/of_device.h>
9
10#include <linux/errno.h>
11
12void of_device_make_bus_id(struct of_device *dev)
13{
14 static atomic_t bus_no_reg_magic;
15 struct device_node *node = dev->node;
16 char *name = dev->dev.bus_id;
17 const u32 *reg;
18 u64 addr;
19 int magic;
20
21 /*
22 * For MMIO, get the physical address
23 */
24 reg = of_get_property(node, "reg", NULL);
25 if (reg) {
26 addr = of_translate_address(node, reg);
27 if (addr != OF_BAD_ADDR) {
28 snprintf(name, BUS_ID_SIZE,
29 "%llx.%s", (unsigned long long)addr,
30 node->name);
31 return;
32 }
33 }
34
35 /*
36 * No BusID, use the node name and add a globally incremented
37 * counter (and pray...)
38 */
39 magic = atomic_add_return(1, &bus_no_reg_magic);
40 snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
41}
42EXPORT_SYMBOL(of_device_make_bus_id);
43
44struct of_device *of_device_alloc(struct device_node *np,
45 const char *bus_id,
46 struct device *parent)
47{
48 struct of_device *dev;
49
50 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
51 if (!dev)
52 return NULL;
53
54 dev->node = of_node_get(np);
55 dev->dev.dma_mask = &dev->dma_mask;
56 dev->dev.parent = parent;
57 dev->dev.release = of_release_dev;
58 dev->dev.archdata.of_node = np;
59
60 if (bus_id)
61 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
62 else
63 of_device_make_bus_id(dev);
64
65 return dev;
66}
67EXPORT_SYMBOL(of_device_alloc);
68
69int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
70{
71 struct of_device *ofdev;
72 const char *compat;
73 int seen = 0, cplen, sl;
74
75 if (!dev)
76 return -ENODEV;
77
78 ofdev = to_of_device(dev);
79
80 if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
81 return -ENOMEM;
82
83 if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
84 return -ENOMEM;
85
86 /* Since the compatible field can contain pretty much anything
87 * it's not really legal to split it out with commas. We split it
88 * up using a number of environment variables instead. */
89
90 compat = of_get_property(ofdev->node, "compatible", &cplen);
91 while (compat && *compat && cplen > 0) {
92 if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
93 return -ENOMEM;
94
95 sl = strlen(compat) + 1;
96 compat += sl;
97 cplen -= sl;
98 seen++;
99 }
100
101 if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
102 return -ENOMEM;
103
104 /* modalias is trickier, we add it in 2 steps */
105 if (add_uevent_var(env, "MODALIAS="))
106 return -ENOMEM;
107 sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
108 sizeof(env->buf) - env->buflen);
109 if (sl >= (sizeof(env->buf) - env->buflen))
110 return -ENOMEM;
111 env->buflen += sl;
112
113 return 0;
114}
115EXPORT_SYMBOL(of_device_uevent);
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c
new file mode 100644
index 000000000000..acf4574d0f18
--- /dev/null
+++ b/arch/microblaze/kernel/of_platform.c
@@ -0,0 +1,201 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 * and Arnd Bergmann, IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#undef DEBUG
14
15#include <linux/string.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/mod_devicetable.h>
20#include <linux/slab.h>
21#include <linux/pci.h>
22#include <linux/of.h>
23#include <linux/of_device.h>
24#include <linux/of_platform.h>
25
26#include <linux/errno.h>
27#include <linux/topology.h>
28#include <asm/atomic.h>
29
30struct bus_type of_platform_bus_type = {
31 .uevent = of_device_uevent,
32};
33EXPORT_SYMBOL(of_platform_bus_type);
34
35static int __init of_bus_driver_init(void)
36{
37 return of_bus_type_init(&of_platform_bus_type, "of_platform");
38}
39postcore_initcall(of_bus_driver_init);
40
41struct of_device *of_platform_device_create(struct device_node *np,
42 const char *bus_id,
43 struct device *parent)
44{
45 struct of_device *dev;
46
47 dev = of_device_alloc(np, bus_id, parent);
48 if (!dev)
49 return NULL;
50
51 dev->dma_mask = 0xffffffffUL;
52 dev->dev.bus = &of_platform_bus_type;
53
54 /* We do not fill the DMA ops for platform devices by default.
55 * This is currently the responsibility of the platform code
56 * to do such, possibly using a device notifier
57 */
58
59 if (of_device_register(dev) != 0) {
60 of_device_free(dev);
61 return NULL;
62 }
63
64 return dev;
65}
66EXPORT_SYMBOL(of_platform_device_create);
67
68/**
69 * of_platform_bus_create - Create an OF device for a bus node and all its
70 * children. Optionally recursively instanciate matching busses.
71 * @bus: device node of the bus to instanciate
72 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
73 * disallow recursive creation of child busses
74 */
75static int of_platform_bus_create(const struct device_node *bus,
76 const struct of_device_id *matches,
77 struct device *parent)
78{
79 struct device_node *child;
80 struct of_device *dev;
81 int rc = 0;
82
83 for_each_child_of_node(bus, child) {
84 pr_debug(" create child: %s\n", child->full_name);
85 dev = of_platform_device_create(child, NULL, parent);
86 if (dev == NULL)
87 rc = -ENOMEM;
88 else if (!of_match_node(matches, child))
89 continue;
90 if (rc == 0) {
91 pr_debug(" and sub busses\n");
92 rc = of_platform_bus_create(child, matches, &dev->dev);
93 }
94 if (rc) {
95 of_node_put(child);
96 break;
97 }
98 }
99 return rc;
100}
101
102
103/**
104 * of_platform_bus_probe - Probe the device-tree for platform busses
105 * @root: parent of the first level to probe or NULL for the root of the tree
106 * @matches: match table, NULL to use the default
107 * @parent: parent to hook devices from, NULL for toplevel
108 *
109 * Note that children of the provided root are not instanciated as devices
110 * unless the specified root itself matches the bus list and is not NULL.
111 */
112
113int of_platform_bus_probe(struct device_node *root,
114 const struct of_device_id *matches,
115 struct device *parent)
116{
117 struct device_node *child;
118 struct of_device *dev;
119 int rc = 0;
120
121 if (matches == NULL)
122 matches = of_default_bus_ids;
123 if (matches == OF_NO_DEEP_PROBE)
124 return -EINVAL;
125 if (root == NULL)
126 root = of_find_node_by_path("/");
127 else
128 of_node_get(root);
129
130 pr_debug("of_platform_bus_probe()\n");
131 pr_debug(" starting at: %s\n", root->full_name);
132
133 /* Do a self check of bus type, if there's a match, create
134 * children
135 */
136 if (of_match_node(matches, root)) {
137 pr_debug(" root match, create all sub devices\n");
138 dev = of_platform_device_create(root, NULL, parent);
139 if (dev == NULL) {
140 rc = -ENOMEM;
141 goto bail;
142 }
143 pr_debug(" create all sub busses\n");
144 rc = of_platform_bus_create(root, matches, &dev->dev);
145 goto bail;
146 }
147 for_each_child_of_node(root, child) {
148 if (!of_match_node(matches, child))
149 continue;
150
151 pr_debug(" match: %s\n", child->full_name);
152 dev = of_platform_device_create(child, NULL, parent);
153 if (dev == NULL)
154 rc = -ENOMEM;
155 else
156 rc = of_platform_bus_create(child, matches, &dev->dev);
157 if (rc) {
158 of_node_put(child);
159 break;
160 }
161 }
162 bail:
163 of_node_put(root);
164 return rc;
165}
166EXPORT_SYMBOL(of_platform_bus_probe);
167
168static int of_dev_node_match(struct device *dev, void *data)
169{
170 return to_of_device(dev)->node == data;
171}
172
173struct of_device *of_find_device_by_node(struct device_node *np)
174{
175 struct device *dev;
176
177 dev = bus_find_device(&of_platform_bus_type,
178 NULL, np, of_dev_node_match);
179 if (dev)
180 return to_of_device(dev);
181 return NULL;
182}
183EXPORT_SYMBOL(of_find_device_by_node);
184
185static int of_dev_phandle_match(struct device *dev, void *data)
186{
187 phandle *ph = data;
188 return to_of_device(dev)->node->linux_phandle == *ph;
189}
190
191struct of_device *of_find_device_by_phandle(phandle ph)
192{
193 struct device *dev;
194
195 dev = bus_find_device(&of_platform_bus_type,
196 NULL, &ph, of_dev_phandle_match);
197 if (dev)
198 return to_of_device(dev);
199 return NULL;
200}
201EXPORT_SYMBOL(of_find_device_by_phandle);
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
new file mode 100644
index 000000000000..475b1fac5cfd
--- /dev/null
+++ b/arch/microblaze/kernel/prom.c
@@ -0,0 +1,1147 @@
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>
42#include <linux/pci.h>
43#include <asm/sections.h>
44#include <asm/pci-bridge.h>
45
46static int __initdata dt_root_addr_cells;
47static int __initdata dt_root_size_cells;
48
49typedef u32 cell_t;
50
51static struct boot_param_header *initial_boot_params;
52
53/* export that to outside world */
54struct device_node *of_chosen;
55
56static inline char *find_flat_dt_string(u32 offset)
57{
58 return ((char *)initial_boot_params) +
59 initial_boot_params->off_dt_strings + offset;
60}
61
62/**
63 * This function is used to scan the flattened device-tree, it is
64 * used to extract the memory informations at boot before we can
65 * unflatten the tree
66 */
67int __init of_scan_flat_dt(int (*it)(unsigned long node,
68 const char *uname, int depth,
69 void *data),
70 void *data)
71{
72 unsigned long p = ((unsigned long)initial_boot_params) +
73 initial_boot_params->off_dt_struct;
74 int rc = 0;
75 int depth = -1;
76
77 do {
78 u32 tag = *((u32 *)p);
79 char *pathp;
80
81 p += 4;
82 if (tag == OF_DT_END_NODE) {
83 depth--;
84 continue;
85 }
86 if (tag == OF_DT_NOP)
87 continue;
88 if (tag == OF_DT_END)
89 break;
90 if (tag == OF_DT_PROP) {
91 u32 sz = *((u32 *)p);
92 p += 8;
93 if (initial_boot_params->version < 0x10)
94 p = _ALIGN(p, sz >= 8 ? 8 : 4);
95 p += sz;
96 p = _ALIGN(p, 4);
97 continue;
98 }
99 if (tag != OF_DT_BEGIN_NODE) {
100 printk(KERN_WARNING "Invalid tag %x scanning flattened"
101 " device tree !\n", tag);
102 return -EINVAL;
103 }
104 depth++;
105 pathp = (char *)p;
106 p = _ALIGN(p + strlen(pathp) + 1, 4);
107 if ((*pathp) == '/') {
108 char *lp, *np;
109 for (lp = NULL, np = pathp; *np; np++)
110 if ((*np) == '/')
111 lp = np+1;
112 if (lp != NULL)
113 pathp = lp;
114 }
115 rc = it(p, pathp, depth, data);
116 if (rc != 0)
117 break;
118 } while (1);
119
120 return rc;
121}
122
123unsigned long __init of_get_flat_dt_root(void)
124{
125 unsigned long p = ((unsigned long)initial_boot_params) +
126 initial_boot_params->off_dt_struct;
127
128 while (*((u32 *)p) == OF_DT_NOP)
129 p += 4;
130 BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
131 p += 4;
132 return _ALIGN(p + strlen((char *)p) + 1, 4);
133}
134
135/**
136 * This function can be used within scan_flattened_dt callback to get
137 * access to properties
138 */
139void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
140 unsigned long *size)
141{
142 unsigned long p = node;
143
144 do {
145 u32 tag = *((u32 *)p);
146 u32 sz, noff;
147 const char *nstr;
148
149 p += 4;
150 if (tag == OF_DT_NOP)
151 continue;
152 if (tag != OF_DT_PROP)
153 return NULL;
154
155 sz = *((u32 *)p);
156 noff = *((u32 *)(p + 4));
157 p += 8;
158 if (initial_boot_params->version < 0x10)
159 p = _ALIGN(p, sz >= 8 ? 8 : 4);
160
161 nstr = find_flat_dt_string(noff);
162 if (nstr == NULL) {
163 printk(KERN_WARNING "Can't find property index"
164 " name !\n");
165 return NULL;
166 }
167 if (strcmp(name, nstr) == 0) {
168 if (size)
169 *size = sz;
170 return (void *)p;
171 }
172 p += sz;
173 p = _ALIGN(p, 4);
174 } while (1);
175}
176
177int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
178{
179 const char *cp;
180 unsigned long cplen, l;
181
182 cp = of_get_flat_dt_prop(node, "compatible", &cplen);
183 if (cp == NULL)
184 return 0;
185 while (cplen > 0) {
186 if (strncasecmp(cp, compat, strlen(compat)) == 0)
187 return 1;
188 l = strlen(cp) + 1;
189 cp += l;
190 cplen -= l;
191 }
192
193 return 0;
194}
195
196static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
197 unsigned long align)
198{
199 void *res;
200
201 *mem = _ALIGN(*mem, align);
202 res = (void *)*mem;
203 *mem += size;
204
205 return res;
206}
207
208static unsigned long __init unflatten_dt_node(unsigned long mem,
209 unsigned long *p,
210 struct device_node *dad,
211 struct device_node ***allnextpp,
212 unsigned long fpsize)
213{
214 struct device_node *np;
215 struct property *pp, **prev_pp = NULL;
216 char *pathp;
217 u32 tag;
218 unsigned int l, allocl;
219 int has_name = 0;
220 int new_format = 0;
221
222 tag = *((u32 *)(*p));
223 if (tag != OF_DT_BEGIN_NODE) {
224 printk("Weird tag at start of node: %x\n", tag);
225 return mem;
226 }
227 *p += 4;
228 pathp = (char *)*p;
229 l = allocl = strlen(pathp) + 1;
230 *p = _ALIGN(*p + l, 4);
231
232 /* version 0x10 has a more compact unit name here instead of the full
233 * path. we accumulate the full path size using "fpsize", we'll rebuild
234 * it later. We detect this because the first character of the name is
235 * not '/'.
236 */
237 if ((*pathp) != '/') {
238 new_format = 1;
239 if (fpsize == 0) {
240 /* root node: special case. fpsize accounts for path
241 * plus terminating zero. root node only has '/', so
242 * fpsize should be 2, but we want to avoid the first
243 * level nodes to have two '/' so we use fpsize 1 here
244 */
245 fpsize = 1;
246 allocl = 2;
247 } else {
248 /* account for '/' and path size minus terminal 0
249 * already in 'l'
250 */
251 fpsize += l;
252 allocl = fpsize;
253 }
254 }
255
256 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
257 __alignof__(struct device_node));
258 if (allnextpp) {
259 memset(np, 0, sizeof(*np));
260 np->full_name = ((char *)np) + sizeof(struct device_node);
261 if (new_format) {
262 char *p2 = np->full_name;
263 /* rebuild full path for new format */
264 if (dad && dad->parent) {
265 strcpy(p2, dad->full_name);
266#ifdef DEBUG
267 if ((strlen(p2) + l + 1) != allocl) {
268 pr_debug("%s: p: %d, l: %d, a: %d\n",
269 pathp, (int)strlen(p2),
270 l, allocl);
271 }
272#endif
273 p2 += strlen(p2);
274 }
275 *(p2++) = '/';
276 memcpy(p2, pathp, l);
277 } else
278 memcpy(np->full_name, pathp, l);
279 prev_pp = &np->properties;
280 **allnextpp = np;
281 *allnextpp = &np->allnext;
282 if (dad != NULL) {
283 np->parent = dad;
284 /* we temporarily use the next field as `last_child'*/
285 if (dad->next == NULL)
286 dad->child = np;
287 else
288 dad->next->sibling = np;
289 dad->next = np;
290 }
291 kref_init(&np->kref);
292 }
293 while (1) {
294 u32 sz, noff;
295 char *pname;
296
297 tag = *((u32 *)(*p));
298 if (tag == OF_DT_NOP) {
299 *p += 4;
300 continue;
301 }
302 if (tag != OF_DT_PROP)
303 break;
304 *p += 4;
305 sz = *((u32 *)(*p));
306 noff = *((u32 *)((*p) + 4));
307 *p += 8;
308 if (initial_boot_params->version < 0x10)
309 *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
310
311 pname = find_flat_dt_string(noff);
312 if (pname == NULL) {
313 printk(KERN_INFO
314 "Can't find property name in list !\n");
315 break;
316 }
317 if (strcmp(pname, "name") == 0)
318 has_name = 1;
319 l = strlen(pname) + 1;
320 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
321 __alignof__(struct property));
322 if (allnextpp) {
323 if (strcmp(pname, "linux,phandle") == 0) {
324 np->node = *((u32 *)*p);
325 if (np->linux_phandle == 0)
326 np->linux_phandle = np->node;
327 }
328 if (strcmp(pname, "ibm,phandle") == 0)
329 np->linux_phandle = *((u32 *)*p);
330 pp->name = pname;
331 pp->length = sz;
332 pp->value = (void *)*p;
333 *prev_pp = pp;
334 prev_pp = &pp->next;
335 }
336 *p = _ALIGN((*p) + sz, 4);
337 }
338 /* with version 0x10 we may not have the name property, recreate
339 * it here from the unit name if absent
340 */
341 if (!has_name) {
342 char *p1 = pathp, *ps = pathp, *pa = NULL;
343 int sz;
344
345 while (*p1) {
346 if ((*p1) == '@')
347 pa = p1;
348 if ((*p1) == '/')
349 ps = p1 + 1;
350 p1++;
351 }
352 if (pa < ps)
353 pa = p1;
354 sz = (pa - ps) + 1;
355 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
356 __alignof__(struct property));
357 if (allnextpp) {
358 pp->name = "name";
359 pp->length = sz;
360 pp->value = pp + 1;
361 *prev_pp = pp;
362 prev_pp = &pp->next;
363 memcpy(pp->value, ps, sz - 1);
364 ((char *)pp->value)[sz - 1] = 0;
365 pr_debug("fixed up name for %s -> %s\n", pathp,
366 (char *)pp->value);
367 }
368 }
369 if (allnextpp) {
370 *prev_pp = NULL;
371 np->name = of_get_property(np, "name", NULL);
372 np->type = of_get_property(np, "device_type", NULL);
373
374 if (!np->name)
375 np->name = "<NULL>";
376 if (!np->type)
377 np->type = "<NULL>";
378 }
379 while (tag == OF_DT_BEGIN_NODE) {
380 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
381 tag = *((u32 *)(*p));
382 }
383 if (tag != OF_DT_END_NODE) {
384 printk(KERN_INFO "Weird tag at end of node: %x\n", tag);
385 return mem;
386 }
387 *p += 4;
388 return mem;
389}
390
391/**
392 * unflattens the device-tree passed by the firmware, creating the
393 * tree of struct device_node. It also fills the "name" and "type"
394 * pointers of the nodes so the normal device-tree walking functions
395 * can be used (this used to be done by finish_device_tree)
396 */
397void __init unflatten_device_tree(void)
398{
399 unsigned long start, mem, size;
400 struct device_node **allnextp = &allnodes;
401
402 pr_debug(" -> unflatten_device_tree()\n");
403
404 /* First pass, scan for size */
405 start = ((unsigned long)initial_boot_params) +
406 initial_boot_params->off_dt_struct;
407 size = unflatten_dt_node(0, &start, NULL, NULL, 0);
408 size = (size | 3) + 1;
409
410 pr_debug(" size is %lx, allocating...\n", size);
411
412 /* Allocate memory for the expanded device tree */
413 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
414 mem = (unsigned long) __va(mem);
415
416 ((u32 *)mem)[size / 4] = 0xdeadbeef;
417
418 pr_debug(" unflattening %lx...\n", mem);
419
420 /* Second pass, do actual unflattening */
421 start = ((unsigned long)initial_boot_params) +
422 initial_boot_params->off_dt_struct;
423 unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
424 if (*((u32 *)start) != OF_DT_END)
425 printk(KERN_WARNING "Weird tag at end of tree: %08x\n",
426 *((u32 *)start));
427 if (((u32 *)mem)[size / 4] != 0xdeadbeef)
428 printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
429 ((u32 *)mem)[size / 4]);
430 *allnextp = NULL;
431
432 /* Get pointer to OF "/chosen" node for use everywhere */
433 of_chosen = of_find_node_by_path("/chosen");
434 if (of_chosen == NULL)
435 of_chosen = of_find_node_by_path("/chosen@0");
436
437 pr_debug(" <- unflatten_device_tree()\n");
438}
439
440#define early_init_dt_scan_drconf_memory(node) 0
441
442static int __init early_init_dt_scan_cpus(unsigned long node,
443 const char *uname, int depth,
444 void *data)
445{
446 static int logical_cpuid;
447 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
448 const u32 *intserv;
449 int i, nthreads;
450 int found = 0;
451
452 /* We are scanning "cpu" nodes only */
453 if (type == NULL || strcmp(type, "cpu") != 0)
454 return 0;
455
456 /* Get physical cpuid */
457 intserv = of_get_flat_dt_prop(node, "reg", NULL);
458 nthreads = 1;
459
460 /*
461 * Now see if any of these threads match our boot cpu.
462 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
463 */
464 for (i = 0; i < nthreads; i++) {
465 /*
466 * version 2 of the kexec param format adds the phys cpuid of
467 * booted proc.
468 */
469 if (initial_boot_params && initial_boot_params->version >= 2) {
470 if (intserv[i] ==
471 initial_boot_params->boot_cpuid_phys) {
472 found = 1;
473 break;
474 }
475 } else {
476 /*
477 * Check if it's the boot-cpu, set it's hw index now,
478 * unfortunately this format did not support booting
479 * off secondary threads.
480 */
481 if (of_get_flat_dt_prop(node,
482 "linux,boot-cpu", NULL) != NULL) {
483 found = 1;
484 break;
485 }
486 }
487
488#ifdef CONFIG_SMP
489 /* logical cpu id is always 0 on UP kernels */
490 logical_cpuid++;
491#endif
492 }
493
494 if (found) {
495 pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid,
496 intserv[i]);
497 boot_cpuid = logical_cpuid;
498 }
499
500 return 0;
501}
502
503#ifdef CONFIG_BLK_DEV_INITRD
504static void __init early_init_dt_check_for_initrd(unsigned long node)
505{
506 unsigned long l;
507 u32 *prop;
508
509 pr_debug("Looking for initrd properties... ");
510
511 prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
512 if (prop) {
513 initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
514
515 prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
516 if (prop) {
517 initrd_end = (unsigned long)
518 __va(of_read_ulong(prop, l/4));
519 initrd_below_start_ok = 1;
520 } else {
521 initrd_start = 0;
522 }
523 }
524
525 pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n",
526 initrd_start, initrd_end);
527}
528#else
529static inline void early_init_dt_check_for_initrd(unsigned long node)
530{
531}
532#endif /* CONFIG_BLK_DEV_INITRD */
533
534static int __init early_init_dt_scan_chosen(unsigned long node,
535 const char *uname, int depth, void *data)
536{
537 unsigned long l;
538 char *p;
539
540 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
541
542 if (depth != 1 ||
543 (strcmp(uname, "chosen") != 0 &&
544 strcmp(uname, "chosen@0") != 0))
545 return 0;
546
547#ifdef CONFIG_KEXEC
548 lprop = (u64 *)of_get_flat_dt_prop(node,
549 "linux,crashkernel-base", NULL);
550 if (lprop)
551 crashk_res.start = *lprop;
552
553 lprop = (u64 *)of_get_flat_dt_prop(node,
554 "linux,crashkernel-size", NULL);
555 if (lprop)
556 crashk_res.end = crashk_res.start + *lprop - 1;
557#endif
558
559 early_init_dt_check_for_initrd(node);
560
561 /* Retreive command line */
562 p = of_get_flat_dt_prop(node, "bootargs", &l);
563 if (p != NULL && l > 0)
564 strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
565
566#ifdef CONFIG_CMDLINE
567 if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
568 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
569#endif /* CONFIG_CMDLINE */
570
571 pr_debug("Command line is: %s\n", cmd_line);
572
573 /* break now */
574 return 1;
575}
576
577static int __init early_init_dt_scan_root(unsigned long node,
578 const char *uname, int depth, void *data)
579{
580 u32 *prop;
581
582 if (depth != 0)
583 return 0;
584
585 prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
586 dt_root_size_cells = (prop == NULL) ? 1 : *prop;
587 pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
588
589 prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
590 dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
591 pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
592
593 /* break now */
594 return 1;
595}
596
597static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
598{
599 cell_t *p = *cellp;
600
601 *cellp = p + s;
602 return of_read_number(p, s);
603}
604
605static int __init early_init_dt_scan_memory(unsigned long node,
606 const char *uname, int depth, void *data)
607{
608 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
609 cell_t *reg, *endp;
610 unsigned long l;
611
612 /* Look for the ibm,dynamic-reconfiguration-memory node */
613/* if (depth == 1 &&
614 strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
615 return early_init_dt_scan_drconf_memory(node);
616*/
617 /* We are scanning "memory" nodes only */
618 if (type == NULL) {
619 /*
620 * The longtrail doesn't have a device_type on the
621 * /memory node, so look for the node called /memory@0.
622 */
623 if (depth != 1 || strcmp(uname, "memory@0") != 0)
624 return 0;
625 } else if (strcmp(type, "memory") != 0)
626 return 0;
627
628 reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
629 if (reg == NULL)
630 reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
631 if (reg == NULL)
632 return 0;
633
634 endp = reg + (l / sizeof(cell_t));
635
636 pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
637 uname, l, reg[0], reg[1], reg[2], reg[3]);
638
639 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
640 u64 base, size;
641
642 base = dt_mem_next_cell(dt_root_addr_cells, &reg);
643 size = dt_mem_next_cell(dt_root_size_cells, &reg);
644
645 if (size == 0)
646 continue;
647 pr_debug(" - %llx , %llx\n", (unsigned long long)base,
648 (unsigned long long)size);
649
650 lmb_add(base, size);
651 }
652 return 0;
653}
654
655#ifdef CONFIG_PHYP_DUMP
656/**
657 * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg
658 *
659 * Function to find the largest size we need to reserve
660 * during early boot process.
661 *
662 * It either looks for boot param and returns that OR
663 * returns larger of 256 or 5% rounded down to multiples of 256MB.
664 *
665 */
666static inline unsigned long phyp_dump_calculate_reserve_size(void)
667{
668 unsigned long tmp;
669
670 if (phyp_dump_info->reserve_bootvar)
671 return phyp_dump_info->reserve_bootvar;
672
673 /* divide by 20 to get 5% of value */
674 tmp = lmb_end_of_DRAM();
675 do_div(tmp, 20);
676
677 /* round it down in multiples of 256 */
678 tmp = tmp & ~0x0FFFFFFFUL;
679
680 return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END);
681}
682
683/**
684 * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
685 *
686 * This routine may reserve memory regions in the kernel only
687 * if the system is supported and a dump was taken in last
688 * boot instance or if the hardware is supported and the
689 * scratch area needs to be setup. In other instances it returns
690 * without reserving anything. The memory in case of dump being
691 * active is freed when the dump is collected (by userland tools).
692 */
693static void __init phyp_dump_reserve_mem(void)
694{
695 unsigned long base, size;
696 unsigned long variable_reserve_size;
697
698 if (!phyp_dump_info->phyp_dump_configured) {
699 printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
700 return;
701 }
702
703 if (!phyp_dump_info->phyp_dump_at_boot) {
704 printk(KERN_INFO "Phyp-dump disabled at boot time\n");
705 return;
706 }
707
708 variable_reserve_size = phyp_dump_calculate_reserve_size();
709
710 if (phyp_dump_info->phyp_dump_is_active) {
711 /* Reserve *everything* above RMR.Area freed by userland tools*/
712 base = variable_reserve_size;
713 size = lmb_end_of_DRAM() - base;
714
715 /* XXX crashed_ram_end is wrong, since it may be beyond
716 * the memory_limit, it will need to be adjusted. */
717 lmb_reserve(base, size);
718
719 phyp_dump_info->init_reserve_start = base;
720 phyp_dump_info->init_reserve_size = size;
721 } else {
722 size = phyp_dump_info->cpu_state_size +
723 phyp_dump_info->hpte_region_size +
724 variable_reserve_size;
725 base = lmb_end_of_DRAM() - size;
726 lmb_reserve(base, size);
727 phyp_dump_info->init_reserve_start = base;
728 phyp_dump_info->init_reserve_size = size;
729 }
730}
731#else
732static inline void __init phyp_dump_reserve_mem(void) {}
733#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */
734
735#ifdef CONFIG_EARLY_PRINTK
736/* MS this is Microblaze specifig function */
737static int __init early_init_dt_scan_serial(unsigned long node,
738 const char *uname, int depth, void *data)
739{
740 unsigned long l;
741 char *p;
742 int *addr;
743
744 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
745
746/* find all serial nodes */
747 if (strncmp(uname, "serial", 6) != 0)
748 return 0;
749
750 early_init_dt_check_for_initrd(node);
751
752/* find compatible node with uartlite */
753 p = of_get_flat_dt_prop(node, "compatible", &l);
754 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
755 (strncmp(p, "xlnx,opb-uartlite", 17) != 0))
756 return 0;
757
758 addr = of_get_flat_dt_prop(node, "reg", &l);
759 return *addr; /* return address */
760}
761
762/* this function is looking for early uartlite console - Microblaze specific */
763int __init early_uartlite_console(void)
764{
765 return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
766}
767#endif
768
769void __init early_init_devtree(void *params)
770{
771 pr_debug(" -> early_init_devtree(%p)\n", params);
772
773 /* Setup flat device-tree pointer */
774 initial_boot_params = params;
775
776#ifdef CONFIG_PHYP_DUMP
777 /* scan tree to see if dump occured during last boot */
778 of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
779#endif
780
781 /* Retrieve various informations from the /chosen node of the
782 * device-tree, including the platform type, initrd location and
783 * size, TCE reserve, and more ...
784 */
785 of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
786
787 /* Scan memory nodes and rebuild LMBs */
788 lmb_init();
789 of_scan_flat_dt(early_init_dt_scan_root, NULL);
790 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
791
792 /* Save command line for /proc/cmdline and then parse parameters */
793 strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
794 parse_early_param();
795
796 lmb_analyze();
797
798 pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
799
800 pr_debug("Scanning CPUs ...\n");
801
802 /* Retreive CPU related informations from the flat tree
803 * (altivec support, boot CPU ID, ...)
804 */
805 of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
806
807 pr_debug(" <- early_init_devtree()\n");
808}
809
810/**
811 * Indicates whether the root node has a given value in its
812 * compatible property.
813 */
814int machine_is_compatible(const char *compat)
815{
816 struct device_node *root;
817 int rc = 0;
818
819 root = of_find_node_by_path("/");
820 if (root) {
821 rc = of_device_is_compatible(root, compat);
822 of_node_put(root);
823 }
824 return rc;
825}
826EXPORT_SYMBOL(machine_is_compatible);
827
828/*******
829 *
830 * New implementation of the OF "find" APIs, return a refcounted
831 * object, call of_node_put() when done. The device tree and list
832 * are protected by a rw_lock.
833 *
834 * Note that property management will need some locking as well,
835 * this isn't dealt with yet.
836 *
837 *******/
838
839/**
840 * of_find_node_by_phandle - Find a node given a phandle
841 * @handle: phandle of the node to find
842 *
843 * Returns a node pointer with refcount incremented, use
844 * of_node_put() on it when done.
845 */
846struct device_node *of_find_node_by_phandle(phandle handle)
847{
848 struct device_node *np;
849
850 read_lock(&devtree_lock);
851 for (np = allnodes; np != NULL; np = np->allnext)
852 if (np->linux_phandle == handle)
853 break;
854 of_node_get(np);
855 read_unlock(&devtree_lock);
856 return np;
857}
858EXPORT_SYMBOL(of_find_node_by_phandle);
859
860/**
861 * of_find_all_nodes - Get next node in global list
862 * @prev: Previous node or NULL to start iteration
863 * of_node_put() will be called on it
864 *
865 * Returns a node pointer with refcount incremented, use
866 * of_node_put() on it when done.
867 */
868struct device_node *of_find_all_nodes(struct device_node *prev)
869{
870 struct device_node *np;
871
872 read_lock(&devtree_lock);
873 np = prev ? prev->allnext : allnodes;
874 for (; np != NULL; np = np->allnext)
875 if (of_node_get(np))
876 break;
877 of_node_put(prev);
878 read_unlock(&devtree_lock);
879 return np;
880}
881EXPORT_SYMBOL(of_find_all_nodes);
882
883/**
884 * of_node_get - Increment refcount of a node
885 * @node: Node to inc refcount, NULL is supported to
886 * simplify writing of callers
887 *
888 * Returns node.
889 */
890struct device_node *of_node_get(struct device_node *node)
891{
892 if (node)
893 kref_get(&node->kref);
894 return node;
895}
896EXPORT_SYMBOL(of_node_get);
897
898static inline struct device_node *kref_to_device_node(struct kref *kref)
899{
900 return container_of(kref, struct device_node, kref);
901}
902
903/**
904 * of_node_release - release a dynamically allocated node
905 * @kref: kref element of the node to be released
906 *
907 * In of_node_put() this function is passed to kref_put()
908 * as the destructor.
909 */
910static void of_node_release(struct kref *kref)
911{
912 struct device_node *node = kref_to_device_node(kref);
913 struct property *prop = node->properties;
914
915 /* We should never be releasing nodes that haven't been detached. */
916 if (!of_node_check_flag(node, OF_DETACHED)) {
917 printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
918 node->full_name);
919 dump_stack();
920 kref_init(&node->kref);
921 return;
922 }
923
924 if (!of_node_check_flag(node, OF_DYNAMIC))
925 return;
926
927 while (prop) {
928 struct property *next = prop->next;
929 kfree(prop->name);
930 kfree(prop->value);
931 kfree(prop);
932 prop = next;
933
934 if (!prop) {
935 prop = node->deadprops;
936 node->deadprops = NULL;
937 }
938 }
939 kfree(node->full_name);
940 kfree(node->data);
941 kfree(node);
942}
943
944/**
945 * of_node_put - Decrement refcount of a node
946 * @node: Node to dec refcount, NULL is supported to
947 * simplify writing of callers
948 *
949 */
950void of_node_put(struct device_node *node)
951{
952 if (node)
953 kref_put(&node->kref, of_node_release);
954}
955EXPORT_SYMBOL(of_node_put);
956
957/*
958 * Plug a device node into the tree and global list.
959 */
960void of_attach_node(struct device_node *np)
961{
962 unsigned long flags;
963
964 write_lock_irqsave(&devtree_lock, flags);
965 np->sibling = np->parent->child;
966 np->allnext = allnodes;
967 np->parent->child = np;
968 allnodes = np;
969 write_unlock_irqrestore(&devtree_lock, flags);
970}
971
972/*
973 * "Unplug" a node from the device tree. The caller must hold
974 * a reference to the node. The memory associated with the node
975 * is not freed until its refcount goes to zero.
976 */
977void of_detach_node(struct device_node *np)
978{
979 struct device_node *parent;
980 unsigned long flags;
981
982 write_lock_irqsave(&devtree_lock, flags);
983
984 parent = np->parent;
985 if (!parent)
986 goto out_unlock;
987
988 if (allnodes == np)
989 allnodes = np->allnext;
990 else {
991 struct device_node *prev;
992 for (prev = allnodes;
993 prev->allnext != np;
994 prev = prev->allnext)
995 ;
996 prev->allnext = np->allnext;
997 }
998
999 if (parent->child == np)
1000 parent->child = np->sibling;
1001 else {
1002 struct device_node *prevsib;
1003 for (prevsib = np->parent->child;
1004 prevsib->sibling != np;
1005 prevsib = prevsib->sibling)
1006 ;
1007 prevsib->sibling = np->sibling;
1008 }
1009
1010 of_node_set_flag(np, OF_DETACHED);
1011
1012out_unlock:
1013 write_unlock_irqrestore(&devtree_lock, flags);
1014}
1015
1016/*
1017 * Add a property to a node
1018 */
1019int prom_add_property(struct device_node *np, struct property *prop)
1020{
1021 struct property **next;
1022 unsigned long flags;
1023
1024 prop->next = NULL;
1025 write_lock_irqsave(&devtree_lock, flags);
1026 next = &np->properties;
1027 while (*next) {
1028 if (strcmp(prop->name, (*next)->name) == 0) {
1029 /* duplicate ! don't insert it */
1030 write_unlock_irqrestore(&devtree_lock, flags);
1031 return -1;
1032 }
1033 next = &(*next)->next;
1034 }
1035 *next = prop;
1036 write_unlock_irqrestore(&devtree_lock, flags);
1037
1038#ifdef CONFIG_PROC_DEVICETREE
1039 /* try to add to proc as well if it was initialized */
1040 if (np->pde)
1041 proc_device_tree_add_prop(np->pde, prop);
1042#endif /* CONFIG_PROC_DEVICETREE */
1043
1044 return 0;
1045}
1046
1047/*
1048 * Remove a property from a node. Note that we don't actually
1049 * remove it, since we have given out who-knows-how-many pointers
1050 * to the data using get-property. Instead we just move the property
1051 * to the "dead properties" list, so it won't be found any more.
1052 */
1053int prom_remove_property(struct device_node *np, struct property *prop)
1054{
1055 struct property **next;
1056 unsigned long flags;
1057 int found = 0;
1058
1059 write_lock_irqsave(&devtree_lock, flags);
1060 next = &np->properties;
1061 while (*next) {
1062 if (*next == prop) {
1063 /* found the node */
1064 *next = prop->next;
1065 prop->next = np->deadprops;
1066 np->deadprops = prop;
1067 found = 1;
1068 break;
1069 }
1070 next = &(*next)->next;
1071 }
1072 write_unlock_irqrestore(&devtree_lock, flags);
1073
1074 if (!found)
1075 return -ENODEV;
1076
1077#ifdef CONFIG_PROC_DEVICETREE
1078 /* try to remove the proc node as well */
1079 if (np->pde)
1080 proc_device_tree_remove_prop(np->pde, prop);
1081#endif /* CONFIG_PROC_DEVICETREE */
1082
1083 return 0;
1084}
1085
1086/*
1087 * Update a property in a node. Note that we don't actually
1088 * remove it, since we have given out who-knows-how-many pointers
1089 * to the data using get-property. Instead we just move the property
1090 * to the "dead properties" list, and add the new property to the
1091 * property list
1092 */
1093int prom_update_property(struct device_node *np,
1094 struct property *newprop,
1095 struct property *oldprop)
1096{
1097 struct property **next;
1098 unsigned long flags;
1099 int found = 0;
1100
1101 write_lock_irqsave(&devtree_lock, flags);
1102 next = &np->properties;
1103 while (*next) {
1104 if (*next == oldprop) {
1105 /* found the node */
1106 newprop->next = oldprop->next;
1107 *next = newprop;
1108 oldprop->next = np->deadprops;
1109 np->deadprops = oldprop;
1110 found = 1;
1111 break;
1112 }
1113 next = &(*next)->next;
1114 }
1115 write_unlock_irqrestore(&devtree_lock, flags);
1116
1117 if (!found)
1118 return -ENODEV;
1119
1120#ifdef CONFIG_PROC_DEVICETREE
1121 /* try to add to proc as well if it was initialized */
1122 if (np->pde)
1123 proc_device_tree_update_prop(np->pde, newprop, oldprop);
1124#endif /* CONFIG_PROC_DEVICETREE */
1125
1126 return 0;
1127}
1128
1129#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
1130static struct debugfs_blob_wrapper flat_dt_blob;
1131
1132static int __init export_flat_device_tree(void)
1133{
1134 struct dentry *d;
1135
1136 flat_dt_blob.data = initial_boot_params;
1137 flat_dt_blob.size = initial_boot_params->totalsize;
1138
1139 d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
1140 of_debugfs_root, &flat_dt_blob);
1141 if (!d)
1142 return 1;
1143
1144 return 0;
1145}
1146device_initcall(export_flat_device_tree);
1147#endif
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
new file mode 100644
index 000000000000..ae0352ecd5a9
--- /dev/null
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -0,0 +1,1025 @@
1#undef DEBUG
2
3#include <linux/kernel.h>
4#include <linux/string.h>
5#include <linux/pci_regs.h>
6#include <linux/module.h>
7#include <linux/ioport.h>
8#include <linux/etherdevice.h>
9#include <asm/prom.h>
10#include <asm/pci-bridge.h>
11
12#define PRu64 "%llx"
13
14/* Max address size we deal with */
15#define OF_MAX_ADDR_CELLS 4
16#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
17 (ns) > 0)
18
19static struct of_bus *of_match_bus(struct device_node *np);
20static int __of_address_to_resource(struct device_node *dev,
21 const u32 *addrp, u64 size, unsigned int flags,
22 struct resource *r);
23
24/* Debug utility */
25#ifdef DEBUG
26static void of_dump_addr(const char *s, const u32 *addr, int na)
27{
28 printk(KERN_INFO "%s", s);
29 while (na--)
30 printk(KERN_INFO " %08x", *(addr++));
31 printk(KERN_INFO "\n");
32}
33#else
34static void of_dump_addr(const char *s, const u32 *addr, int na) { }
35#endif
36
37/* Callbacks for bus specific translators */
38struct of_bus {
39 const char *name;
40 const char *addresses;
41 int (*match)(struct device_node *parent);
42 void (*count_cells)(struct device_node *child,
43 int *addrc, int *sizec);
44 u64 (*map)(u32 *addr, const u32 *range,
45 int na, int ns, int pna);
46 int (*translate)(u32 *addr, u64 offset, int na);
47 unsigned int (*get_flags)(const u32 *addr);
48};
49
50/*
51 * Default translator (generic bus)
52 */
53
54static void of_bus_default_count_cells(struct device_node *dev,
55 int *addrc, int *sizec)
56{
57 if (addrc)
58 *addrc = of_n_addr_cells(dev);
59 if (sizec)
60 *sizec = of_n_size_cells(dev);
61}
62
63static u64 of_bus_default_map(u32 *addr, const u32 *range,
64 int na, int ns, int pna)
65{
66 u64 cp, s, da;
67
68 cp = of_read_number(range, na);
69 s = of_read_number(range + na + pna, ns);
70 da = of_read_number(addr, na);
71
72 pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
73 cp, s, da);
74
75 if (da < cp || da >= (cp + s))
76 return OF_BAD_ADDR;
77 return da - cp;
78}
79
80static int of_bus_default_translate(u32 *addr, u64 offset, int na)
81{
82 u64 a = of_read_number(addr, na);
83 memset(addr, 0, na * 4);
84 a += offset;
85 if (na > 1)
86 addr[na - 2] = a >> 32;
87 addr[na - 1] = a & 0xffffffffu;
88
89 return 0;
90}
91
92static unsigned int of_bus_default_get_flags(const u32 *addr)
93{
94 return IORESOURCE_MEM;
95}
96
97#ifdef CONFIG_PCI
98/*
99 * PCI bus specific translator
100 */
101
102static int of_bus_pci_match(struct device_node *np)
103{
104 /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
105 return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
106}
107
108static void of_bus_pci_count_cells(struct device_node *np,
109 int *addrc, int *sizec)
110{
111 if (addrc)
112 *addrc = 3;
113 if (sizec)
114 *sizec = 2;
115}
116
117static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
118{
119 u64 cp, s, da;
120
121 /* Check address type match */
122 if ((addr[0] ^ range[0]) & 0x03000000)
123 return OF_BAD_ADDR;
124
125 /* Read address values, skipping high cell */
126 cp = of_read_number(range + 1, na - 1);
127 s = of_read_number(range + na + pna, ns);
128 da = of_read_number(addr + 1, na - 1);
129
130 pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
131
132 if (da < cp || da >= (cp + s))
133 return OF_BAD_ADDR;
134 return da - cp;
135}
136
137static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
138{
139 return of_bus_default_translate(addr + 1, offset, na - 1);
140}
141
142static unsigned int of_bus_pci_get_flags(const u32 *addr)
143{
144 unsigned int flags = 0;
145 u32 w = addr[0];
146
147 switch ((w >> 24) & 0x03) {
148 case 0x01:
149 flags |= IORESOURCE_IO;
150 break;
151 case 0x02: /* 32 bits */
152 case 0x03: /* 64 bits */
153 flags |= IORESOURCE_MEM;
154 break;
155 }
156 if (w & 0x40000000)
157 flags |= IORESOURCE_PREFETCH;
158 return flags;
159}
160
161const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
162 unsigned int *flags)
163{
164 const u32 *prop;
165 unsigned int psize;
166 struct device_node *parent;
167 struct of_bus *bus;
168 int onesize, i, na, ns;
169
170 /* Get parent & match bus type */
171 parent = of_get_parent(dev);
172 if (parent == NULL)
173 return NULL;
174 bus = of_match_bus(parent);
175 if (strcmp(bus->name, "pci")) {
176 of_node_put(parent);
177 return NULL;
178 }
179 bus->count_cells(dev, &na, &ns);
180 of_node_put(parent);
181 if (!OF_CHECK_COUNTS(na, ns))
182 return NULL;
183
184 /* Get "reg" or "assigned-addresses" property */
185 prop = of_get_property(dev, bus->addresses, &psize);
186 if (prop == NULL)
187 return NULL;
188 psize /= 4;
189
190 onesize = na + ns;
191 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
192 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
193 if (size)
194 *size = of_read_number(prop + na, ns);
195 if (flags)
196 *flags = bus->get_flags(prop);
197 return prop;
198 }
199 return NULL;
200}
201EXPORT_SYMBOL(of_get_pci_address);
202
203int of_pci_address_to_resource(struct device_node *dev, int bar,
204 struct resource *r)
205{
206 const u32 *addrp;
207 u64 size;
208 unsigned int flags;
209
210 addrp = of_get_pci_address(dev, bar, &size, &flags);
211 if (addrp == NULL)
212 return -EINVAL;
213 return __of_address_to_resource(dev, addrp, size, flags, r);
214}
215EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
216
217static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
218{
219 return (((pin - 1) + slot) % 4) + 1;
220}
221
222int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
223{
224 struct device_node *dn, *ppnode;
225 struct pci_dev *ppdev;
226 u32 lspec;
227 u32 laddr[3];
228 u8 pin;
229 int rc;
230
231 /* Check if we have a device node, if yes, fallback to standard OF
232 * parsing
233 */
234 dn = pci_device_to_OF_node(pdev);
235 if (dn)
236 return of_irq_map_one(dn, 0, out_irq);
237
238 /* Ok, we don't, time to have fun. Let's start by building up an
239 * interrupt spec. we assume #interrupt-cells is 1, which is standard
240 * for PCI. If you do different, then don't use that routine.
241 */
242 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
243 if (rc != 0)
244 return rc;
245 /* No pin, exit */
246 if (pin == 0)
247 return -ENODEV;
248
249 /* Now we walk up the PCI tree */
250 lspec = pin;
251 for (;;) {
252 /* Get the pci_dev of our parent */
253 ppdev = pdev->bus->self;
254
255 /* Ouch, it's a host bridge... */
256 if (ppdev == NULL) {
257 struct pci_controller *host;
258 host = pci_bus_to_host(pdev->bus);
259 ppnode = host ? host->arch_data : NULL;
260 /* No node for host bridge ? give up */
261 if (ppnode == NULL)
262 return -EINVAL;
263 } else
264 /* We found a P2P bridge, check if it has a node */
265 ppnode = pci_device_to_OF_node(ppdev);
266
267 /* Ok, we have found a parent with a device-node, hand over to
268 * the OF parsing code.
269 * We build a unit address from the linux device to be used for
270 * resolution. Note that we use the linux bus number which may
271 * not match your firmware bus numbering.
272 * Fortunately, in most cases, interrupt-map-mask doesn't
273 * include the bus number as part of the matching.
274 * You should still be careful about that though if you intend
275 * to rely on this function (you ship a firmware that doesn't
276 * create device nodes for all PCI devices).
277 */
278 if (ppnode)
279 break;
280
281 /* We can only get here if we hit a P2P bridge with no node,
282 * let's do standard swizzling and try again
283 */
284 lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
285 pdev = ppdev;
286 }
287
288 laddr[0] = (pdev->bus->number << 16)
289 | (pdev->devfn << 8);
290 laddr[1] = laddr[2] = 0;
291 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
292}
293EXPORT_SYMBOL_GPL(of_irq_map_pci);
294#endif /* CONFIG_PCI */
295
296/*
297 * ISA bus specific translator
298 */
299
300static int of_bus_isa_match(struct device_node *np)
301{
302 return !strcmp(np->name, "isa");
303}
304
305static void of_bus_isa_count_cells(struct device_node *child,
306 int *addrc, int *sizec)
307{
308 if (addrc)
309 *addrc = 2;
310 if (sizec)
311 *sizec = 1;
312}
313
314static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
315{
316 u64 cp, s, da;
317
318 /* Check address type match */
319 if ((addr[0] ^ range[0]) & 0x00000001)
320 return OF_BAD_ADDR;
321
322 /* Read address values, skipping high cell */
323 cp = of_read_number(range + 1, na - 1);
324 s = of_read_number(range + na + pna, ns);
325 da = of_read_number(addr + 1, na - 1);
326
327 pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
328
329 if (da < cp || da >= (cp + s))
330 return OF_BAD_ADDR;
331 return da - cp;
332}
333
334static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
335{
336 return of_bus_default_translate(addr + 1, offset, na - 1);
337}
338
339static unsigned int of_bus_isa_get_flags(const u32 *addr)
340{
341 unsigned int flags = 0;
342 u32 w = addr[0];
343
344 if (w & 1)
345 flags |= IORESOURCE_IO;
346 else
347 flags |= IORESOURCE_MEM;
348 return flags;
349}
350
351/*
352 * Array of bus specific translators
353 */
354
355static struct of_bus of_busses[] = {
356#ifdef CONFIG_PCI
357 /* PCI */
358 {
359 .name = "pci",
360 .addresses = "assigned-addresses",
361 .match = of_bus_pci_match,
362 .count_cells = of_bus_pci_count_cells,
363 .map = of_bus_pci_map,
364 .translate = of_bus_pci_translate,
365 .get_flags = of_bus_pci_get_flags,
366 },
367#endif /* CONFIG_PCI */
368 /* ISA */
369 {
370 .name = "isa",
371 .addresses = "reg",
372 .match = of_bus_isa_match,
373 .count_cells = of_bus_isa_count_cells,
374 .map = of_bus_isa_map,
375 .translate = of_bus_isa_translate,
376 .get_flags = of_bus_isa_get_flags,
377 },
378 /* Default */
379 {
380 .name = "default",
381 .addresses = "reg",
382 .match = NULL,
383 .count_cells = of_bus_default_count_cells,
384 .map = of_bus_default_map,
385 .translate = of_bus_default_translate,
386 .get_flags = of_bus_default_get_flags,
387 },
388};
389
390static struct of_bus *of_match_bus(struct device_node *np)
391{
392 int i;
393
394 for (i = 0; i < ARRAY_SIZE(of_busses); i++)
395 if (!of_busses[i].match || of_busses[i].match(np))
396 return &of_busses[i];
397 BUG();
398 return NULL;
399}
400
401static int of_translate_one(struct device_node *parent, struct of_bus *bus,
402 struct of_bus *pbus, u32 *addr,
403 int na, int ns, int pna)
404{
405 const u32 *ranges;
406 unsigned int rlen;
407 int rone;
408 u64 offset = OF_BAD_ADDR;
409
410 /* Normally, an absence of a "ranges" property means we are
411 * crossing a non-translatable boundary, and thus the addresses
412 * below the current not cannot be converted to CPU physical ones.
413 * Unfortunately, while this is very clear in the spec, it's not
414 * what Apple understood, and they do have things like /uni-n or
415 * /ht nodes with no "ranges" property and a lot of perfectly
416 * useable mapped devices below them. Thus we treat the absence of
417 * "ranges" as equivalent to an empty "ranges" property which means
418 * a 1:1 translation at that level. It's up to the caller not to try
419 * to translate addresses that aren't supposed to be translated in
420 * the first place. --BenH.
421 */
422 ranges = of_get_property(parent, "ranges", (int *) &rlen);
423 if (ranges == NULL || rlen == 0) {
424 offset = of_read_number(addr, na);
425 memset(addr, 0, pna * 4);
426 pr_debug("OF: no ranges, 1:1 translation\n");
427 goto finish;
428 }
429
430 pr_debug("OF: walking ranges...\n");
431
432 /* Now walk through the ranges */
433 rlen /= 4;
434 rone = na + pna + ns;
435 for (; rlen >= rone; rlen -= rone, ranges += rone) {
436 offset = bus->map(addr, ranges, na, ns, pna);
437 if (offset != OF_BAD_ADDR)
438 break;
439 }
440 if (offset == OF_BAD_ADDR) {
441 pr_debug("OF: not found !\n");
442 return 1;
443 }
444 memcpy(addr, ranges + na, 4 * pna);
445
446 finish:
447 of_dump_addr("OF: parent translation for:", addr, pna);
448 pr_debug("OF: with offset: "PRu64"\n", offset);
449
450 /* Translate it into parent bus space */
451 return pbus->translate(addr, offset, pna);
452}
453
454/*
455 * Translate an address from the device-tree into a CPU physical address,
456 * this walks up the tree and applies the various bus mappings on the
457 * way.
458 *
459 * Note: We consider that crossing any level with #size-cells == 0 to mean
460 * that translation is impossible (that is we are not dealing with a value
461 * that can be mapped to a cpu physical address). This is not really specified
462 * that way, but this is traditionally the way IBM at least do things
463 */
464u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
465{
466 struct device_node *parent = NULL;
467 struct of_bus *bus, *pbus;
468 u32 addr[OF_MAX_ADDR_CELLS];
469 int na, ns, pna, pns;
470 u64 result = OF_BAD_ADDR;
471
472 pr_debug("OF: ** translation for device %s **\n", dev->full_name);
473
474 /* Increase refcount at current level */
475 of_node_get(dev);
476
477 /* Get parent & match bus type */
478 parent = of_get_parent(dev);
479 if (parent == NULL)
480 goto bail;
481 bus = of_match_bus(parent);
482
483 /* Cound address cells & copy address locally */
484 bus->count_cells(dev, &na, &ns);
485 if (!OF_CHECK_COUNTS(na, ns)) {
486 printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
487 dev->full_name);
488 goto bail;
489 }
490 memcpy(addr, in_addr, na * 4);
491
492 pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
493 bus->name, na, ns, parent->full_name);
494 of_dump_addr("OF: translating address:", addr, na);
495
496 /* Translate */
497 for (;;) {
498 /* Switch to parent bus */
499 of_node_put(dev);
500 dev = parent;
501 parent = of_get_parent(dev);
502
503 /* If root, we have finished */
504 if (parent == NULL) {
505 pr_debug("OF: reached root node\n");
506 result = of_read_number(addr, na);
507 break;
508 }
509
510 /* Get new parent bus and counts */
511 pbus = of_match_bus(parent);
512 pbus->count_cells(dev, &pna, &pns);
513 if (!OF_CHECK_COUNTS(pna, pns)) {
514 printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
515 dev->full_name);
516 break;
517 }
518
519 pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
520 pbus->name, pna, pns, parent->full_name);
521
522 /* Apply bus translation */
523 if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
524 break;
525
526 /* Complete the move up one level */
527 na = pna;
528 ns = pns;
529 bus = pbus;
530
531 of_dump_addr("OF: one level translation:", addr, na);
532 }
533 bail:
534 of_node_put(parent);
535 of_node_put(dev);
536
537 return result;
538}
539EXPORT_SYMBOL(of_translate_address);
540
541const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
542 unsigned int *flags)
543{
544 const u32 *prop;
545 unsigned int psize;
546 struct device_node *parent;
547 struct of_bus *bus;
548 int onesize, i, na, ns;
549
550 /* Get parent & match bus type */
551 parent = of_get_parent(dev);
552 if (parent == NULL)
553 return NULL;
554 bus = of_match_bus(parent);
555 bus->count_cells(dev, &na, &ns);
556 of_node_put(parent);
557 if (!OF_CHECK_COUNTS(na, ns))
558 return NULL;
559
560 /* Get "reg" or "assigned-addresses" property */
561 prop = of_get_property(dev, bus->addresses, (int *) &psize);
562 if (prop == NULL)
563 return NULL;
564 psize /= 4;
565
566 onesize = na + ns;
567 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
568 if (i == index) {
569 if (size)
570 *size = of_read_number(prop + na, ns);
571 if (flags)
572 *flags = bus->get_flags(prop);
573 return prop;
574 }
575 return NULL;
576}
577EXPORT_SYMBOL(of_get_address);
578
579static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
580 u64 size, unsigned int flags,
581 struct resource *r)
582{
583 u64 taddr;
584
585 if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
586 return -EINVAL;
587 taddr = of_translate_address(dev, addrp);
588 if (taddr == OF_BAD_ADDR)
589 return -EINVAL;
590 memset(r, 0, sizeof(struct resource));
591 if (flags & IORESOURCE_IO) {
592 unsigned long port;
593 port = -1; /* pci_address_to_pio(taddr); */
594 if (port == (unsigned long)-1)
595 return -EINVAL;
596 r->start = port;
597 r->end = port + size - 1;
598 } else {
599 r->start = taddr;
600 r->end = taddr + size - 1;
601 }
602 r->flags = flags;
603 r->name = dev->name;
604 return 0;
605}
606
607int of_address_to_resource(struct device_node *dev, int index,
608 struct resource *r)
609{
610 const u32 *addrp;
611 u64 size;
612 unsigned int flags;
613
614 addrp = of_get_address(dev, index, &size, &flags);
615 if (addrp == NULL)
616 return -EINVAL;
617 return __of_address_to_resource(dev, addrp, size, flags, r);
618}
619EXPORT_SYMBOL_GPL(of_address_to_resource);
620
621void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
622 unsigned long *busno, unsigned long *phys, unsigned long *size)
623{
624 const u32 *dma_window;
625 u32 cells;
626 const unsigned char *prop;
627
628 dma_window = dma_window_prop;
629
630 /* busno is always one cell */
631 *busno = *(dma_window++);
632
633 prop = of_get_property(dn, "ibm,#dma-address-cells", NULL);
634 if (!prop)
635 prop = of_get_property(dn, "#address-cells", NULL);
636
637 cells = prop ? *(u32 *)prop : of_n_addr_cells(dn);
638 *phys = of_read_number(dma_window, cells);
639
640 dma_window += cells;
641
642 prop = of_get_property(dn, "ibm,#dma-size-cells", NULL);
643 cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
644 *size = of_read_number(dma_window, cells);
645}
646
647/*
648 * Interrupt remapper
649 */
650
651static unsigned int of_irq_workarounds;
652static struct device_node *of_irq_dflt_pic;
653
654static struct device_node *of_irq_find_parent(struct device_node *child)
655{
656 struct device_node *p;
657 const phandle *parp;
658
659 if (!of_node_get(child))
660 return NULL;
661
662 do {
663 parp = of_get_property(child, "interrupt-parent", NULL);
664 if (parp == NULL)
665 p = of_get_parent(child);
666 else {
667 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
668 p = of_node_get(of_irq_dflt_pic);
669 else
670 p = of_find_node_by_phandle(*parp);
671 }
672 of_node_put(child);
673 child = p;
674 } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
675
676 return p;
677}
678
679/* This doesn't need to be called if you don't have any special workaround
680 * flags to pass
681 */
682void of_irq_map_init(unsigned int flags)
683{
684 of_irq_workarounds = flags;
685
686 /* OldWorld, don't bother looking at other things */
687 if (flags & OF_IMAP_OLDWORLD_MAC)
688 return;
689
690 /* If we don't have phandles, let's try to locate a default interrupt
691 * controller (happens when booting with BootX). We do a first match
692 * here, hopefully, that only ever happens on machines with one
693 * controller.
694 */
695 if (flags & OF_IMAP_NO_PHANDLE) {
696 struct device_node *np;
697
698 for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
699 if (of_get_property(np, "interrupt-controller", NULL)
700 == NULL)
701 continue;
702 /* Skip /chosen/interrupt-controller */
703 if (strcmp(np->name, "chosen") == 0)
704 continue;
705 /* It seems like at least one person on this planet
706 * wants to use BootX on a machine with an AppleKiwi
707 * controller which happens to pretend to be an
708 * interrupt controller too.
709 */
710 if (strcmp(np->name, "AppleKiwi") == 0)
711 continue;
712 /* I think we found one ! */
713 of_irq_dflt_pic = np;
714 break;
715 }
716 }
717
718}
719
720int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
721 const u32 *addr, struct of_irq *out_irq)
722{
723 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
724 const u32 *tmp, *imap, *imask;
725 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
726 int imaplen, match, i;
727
728 pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
729 "ointsize=%d\n",
730 parent->full_name, intspec[0], intspec[1], ointsize);
731
732 ipar = of_node_get(parent);
733
734 /* First get the #interrupt-cells property of the current cursor
735 * that tells us how to interpret the passed-in intspec. If there
736 * is none, we are nice and just walk up the tree
737 */
738 do {
739 tmp = of_get_property(ipar, "#interrupt-cells", NULL);
740 if (tmp != NULL) {
741 intsize = *tmp;
742 break;
743 }
744 tnode = ipar;
745 ipar = of_irq_find_parent(ipar);
746 of_node_put(tnode);
747 } while (ipar);
748 if (ipar == NULL) {
749 pr_debug(" -> no parent found !\n");
750 goto fail;
751 }
752
753 pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
754 ipar->full_name, intsize);
755
756 if (ointsize != intsize)
757 return -EINVAL;
758
759 /* Look for this #address-cells. We have to implement the old linux
760 * trick of looking for the parent here as some device-trees rely on it
761 */
762 old = of_node_get(ipar);
763 do {
764 tmp = of_get_property(old, "#address-cells", NULL);
765 tnode = of_get_parent(old);
766 of_node_put(old);
767 old = tnode;
768 } while (old && tmp == NULL);
769 of_node_put(old);
770 old = NULL;
771 addrsize = (tmp == NULL) ? 2 : *tmp;
772
773 pr_debug(" -> addrsize=%d\n", addrsize);
774
775 /* Now start the actual "proper" walk of the interrupt tree */
776 while (ipar != NULL) {
777 /* Now check if cursor is an interrupt-controller and if it is
778 * then we are done
779 */
780 if (of_get_property(ipar, "interrupt-controller", NULL) !=
781 NULL) {
782 pr_debug(" -> got it !\n");
783 memcpy(out_irq->specifier, intspec,
784 intsize * sizeof(u32));
785 out_irq->size = intsize;
786 out_irq->controller = ipar;
787 of_node_put(old);
788 return 0;
789 }
790
791 /* Now look for an interrupt-map */
792 imap = of_get_property(ipar, "interrupt-map", &imaplen);
793 /* No interrupt map, check for an interrupt parent */
794 if (imap == NULL) {
795 pr_debug(" -> no map, getting parent\n");
796 newpar = of_irq_find_parent(ipar);
797 goto skiplevel;
798 }
799 imaplen /= sizeof(u32);
800
801 /* Look for a mask */
802 imask = of_get_property(ipar, "interrupt-map-mask", NULL);
803
804 /* If we were passed no "reg" property and we attempt to parse
805 * an interrupt-map, then #address-cells must be 0.
806 * Fail if it's not.
807 */
808 if (addr == NULL && addrsize != 0) {
809 pr_debug(" -> no reg passed in when needed !\n");
810 goto fail;
811 }
812
813 /* Parse interrupt-map */
814 match = 0;
815 while (imaplen > (addrsize + intsize + 1) && !match) {
816 /* Compare specifiers */
817 match = 1;
818 for (i = 0; i < addrsize && match; ++i) {
819 u32 mask = imask ? imask[i] : 0xffffffffu;
820 match = ((addr[i] ^ imap[i]) & mask) == 0;
821 }
822 for (; i < (addrsize + intsize) && match; ++i) {
823 u32 mask = imask ? imask[i] : 0xffffffffu;
824 match =
825 ((intspec[i-addrsize] ^ imap[i])
826 & mask) == 0;
827 }
828 imap += addrsize + intsize;
829 imaplen -= addrsize + intsize;
830
831 pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
832
833 /* Get the interrupt parent */
834 if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
835 newpar = of_node_get(of_irq_dflt_pic);
836 else
837 newpar =
838 of_find_node_by_phandle((phandle)*imap);
839 imap++;
840 --imaplen;
841
842 /* Check if not found */
843 if (newpar == NULL) {
844 pr_debug(" -> imap parent not found !\n");
845 goto fail;
846 }
847
848 /* Get #interrupt-cells and #address-cells of new
849 * parent
850 */
851 tmp = of_get_property(newpar, "#interrupt-cells", NULL);
852 if (tmp == NULL) {
853 pr_debug(" -> parent lacks "
854 "#interrupt-cells!\n");
855 goto fail;
856 }
857 newintsize = *tmp;
858 tmp = of_get_property(newpar, "#address-cells", NULL);
859 newaddrsize = (tmp == NULL) ? 0 : *tmp;
860
861 pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
862 newintsize, newaddrsize);
863
864 /* Check for malformed properties */
865 if (imaplen < (newaddrsize + newintsize))
866 goto fail;
867
868 imap += newaddrsize + newintsize;
869 imaplen -= newaddrsize + newintsize;
870
871 pr_debug(" -> imaplen=%d\n", imaplen);
872 }
873 if (!match)
874 goto fail;
875
876 of_node_put(old);
877 old = of_node_get(newpar);
878 addrsize = newaddrsize;
879 intsize = newintsize;
880 intspec = imap - intsize;
881 addr = intspec - addrsize;
882
883skiplevel:
884 /* Iterate again with new parent */
885 pr_debug(" -> new parent: %s\n",
886 newpar ? newpar->full_name : "<>");
887 of_node_put(ipar);
888 ipar = newpar;
889 newpar = NULL;
890 }
891fail:
892 of_node_put(ipar);
893 of_node_put(old);
894 of_node_put(newpar);
895
896 return -EINVAL;
897}
898EXPORT_SYMBOL_GPL(of_irq_map_raw);
899
900int of_irq_map_one(struct device_node *device,
901 int index, struct of_irq *out_irq)
902{
903 struct device_node *p;
904 const u32 *intspec, *tmp, *addr;
905 u32 intsize, intlen;
906 int res;
907
908 pr_debug("of_irq_map_one: dev=%s, index=%d\n",
909 device->full_name, index);
910
911 /* Get the interrupts property */
912 intspec = of_get_property(device, "interrupts", (int *) &intlen);
913 if (intspec == NULL)
914 return -EINVAL;
915 intlen /= sizeof(u32);
916
917 pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
918
919 /* Get the reg property (if any) */
920 addr = of_get_property(device, "reg", NULL);
921
922 /* Look for the interrupt parent. */
923 p = of_irq_find_parent(device);
924 if (p == NULL)
925 return -EINVAL;
926
927 /* Get size of interrupt specifier */
928 tmp = of_get_property(p, "#interrupt-cells", NULL);
929 if (tmp == NULL) {
930 of_node_put(p);
931 return -EINVAL;
932 }
933 intsize = *tmp;
934
935 pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
936
937 /* Check index */
938 if ((index + 1) * intsize > intlen)
939 return -EINVAL;
940
941 /* Get new specifier and map it */
942 res = of_irq_map_raw(p, intspec + index * intsize, intsize,
943 addr, out_irq);
944 of_node_put(p);
945 return res;
946}
947EXPORT_SYMBOL_GPL(of_irq_map_one);
948
949/**
950 * Search the device tree for the best MAC address to use. 'mac-address' is
951 * checked first, because that is supposed to contain to "most recent" MAC
952 * address. If that isn't set, then 'local-mac-address' is checked next,
953 * because that is the default address. If that isn't set, then the obsolete
954 * 'address' is checked, just in case we're using an old device tree.
955 *
956 * Note that the 'address' property is supposed to contain a virtual address of
957 * the register set, but some DTS files have redefined that property to be the
958 * MAC address.
959 *
960 * All-zero MAC addresses are rejected, because those could be properties that
961 * exist in the device tree, but were not set by U-Boot. For example, the
962 * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
963 * addresses. Some older U-Boots only initialized 'local-mac-address'. In
964 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
965 * but is all zeros.
966*/
967const void *of_get_mac_address(struct device_node *np)
968{
969 struct property *pp;
970
971 pp = of_find_property(np, "mac-address", NULL);
972 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
973 return pp->value;
974
975 pp = of_find_property(np, "local-mac-address", NULL);
976 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
977 return pp->value;
978
979 pp = of_find_property(np, "address", NULL);
980 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
981 return pp->value;
982
983 return NULL;
984}
985EXPORT_SYMBOL(of_get_mac_address);
986
987int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
988{
989 struct of_irq out_irq;
990 int irq;
991 int res;
992
993 res = of_irq_map_one(dev, index, &out_irq);
994
995 /* Get irq for the device */
996 if (res) {
997 pr_debug("IRQ not found... code = %d", res);
998 return NO_IRQ;
999 }
1000 /* Assuming single interrupt controller... */
1001 irq = out_irq.specifier[0];
1002
1003 pr_debug("IRQ found = %d", irq);
1004
1005 /* Only dereference the resource if both the
1006 * resource and the irq are valid. */
1007 if (r && irq != NO_IRQ) {
1008 r->start = r->end = irq;
1009 r->flags = IORESOURCE_IRQ;
1010 }
1011
1012 return irq;
1013}
1014EXPORT_SYMBOL_GPL(of_irq_to_resource);
1015
1016void __iomem *of_iomap(struct device_node *np, int index)
1017{
1018 struct resource res;
1019
1020 if (of_address_to_resource(np, index, &res))
1021 return NULL;
1022
1023 return ioremap(res.start, 1 + res.end - res.start);
1024}
1025EXPORT_SYMBOL(of_iomap);