Commit e63829de3d03f92cea2b26119e0aa9a7043b9913
Committed by
David S. Miller
1 parent
0fd7ef1fe0
Exists in
master
and in
7 other branches
sparc,leon: Added support for AMBAPP bus.
The device is a AMBA bus if it is a child of prom node "ambapp" (AMBA plug and play). Two functions leon_trans_init() and leon_node_init() (defined in sparc/kernel/leon_kernel.c) are called in the prom_build_tree() path if CONFIG_SPARC_LEON is defined. leon_node_init() will build up the device tree using AMBA plug and play. Also: a extra check was addes to prom_common.c:build_one_prop() in case a rom-node is undefined which can happen for SPARC-LEON because it creates only a minimum nodes to emulate sparc behaviour. Signed-off-by: Konrad Eisele <konrad@gaisler.com> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 3 changed files with 81 additions and 2 deletions Side-by-side Diff
arch/sparc/kernel/of_device_32.c
... | ... | @@ -9,6 +9,8 @@ |
9 | 9 | #include <linux/irq.h> |
10 | 10 | #include <linux/of_device.h> |
11 | 11 | #include <linux/of_platform.h> |
12 | +#include <asm/leon.h> | |
13 | +#include <asm/leon_amba.h> | |
12 | 14 | |
13 | 15 | #include "of_device_common.h" |
14 | 16 | |
15 | 17 | |
... | ... | @@ -97,7 +99,36 @@ |
97 | 99 | return IORESOURCE_MEM; |
98 | 100 | } |
99 | 101 | |
102 | + /* | |
103 | + * AMBAPP bus specific translator | |
104 | + */ | |
100 | 105 | |
106 | +static int of_bus_ambapp_match(struct device_node *np) | |
107 | +{ | |
108 | + return !strcmp(np->name, "ambapp"); | |
109 | +} | |
110 | + | |
111 | +static void of_bus_ambapp_count_cells(struct device_node *child, | |
112 | + int *addrc, int *sizec) | |
113 | +{ | |
114 | + if (addrc) | |
115 | + *addrc = 1; | |
116 | + if (sizec) | |
117 | + *sizec = 1; | |
118 | +} | |
119 | + | |
120 | +static int of_bus_ambapp_map(u32 *addr, const u32 *range, | |
121 | + int na, int ns, int pna) | |
122 | +{ | |
123 | + return of_bus_default_map(addr, range, na, ns, pna); | |
124 | +} | |
125 | + | |
126 | +static unsigned long of_bus_ambapp_get_flags(const u32 *addr, | |
127 | + unsigned long flags) | |
128 | +{ | |
129 | + return IORESOURCE_MEM; | |
130 | +} | |
131 | + | |
101 | 132 | /* |
102 | 133 | * Array of bus specific translators |
103 | 134 | */ |
... | ... | @@ -120,6 +151,15 @@ |
120 | 151 | .count_cells = of_bus_sbus_count_cells, |
121 | 152 | .map = of_bus_default_map, |
122 | 153 | .get_flags = of_bus_sbus_get_flags, |
154 | + }, | |
155 | + /* AMBA */ | |
156 | + { | |
157 | + .name = "ambapp", | |
158 | + .addr_prop_name = "reg", | |
159 | + .match = of_bus_ambapp_match, | |
160 | + .count_cells = of_bus_ambapp_count_cells, | |
161 | + .map = of_bus_ambapp_map, | |
162 | + .get_flags = of_bus_ambapp_get_flags, | |
123 | 163 | }, |
124 | 164 | /* Default */ |
125 | 165 | { |
arch/sparc/kernel/prom_32.c
... | ... | @@ -24,6 +24,8 @@ |
24 | 24 | |
25 | 25 | #include <asm/prom.h> |
26 | 26 | #include <asm/oplib.h> |
27 | +#include <asm/leon.h> | |
28 | +#include <asm/leon_amba.h> | |
27 | 29 | |
28 | 30 | #include "prom.h" |
29 | 31 | |
... | ... | @@ -131,6 +133,35 @@ |
131 | 133 | regs->which_io, regs->phys_addr); |
132 | 134 | } |
133 | 135 | |
136 | +/* "name:vendor:device@irq,addrlo" */ | |
137 | +static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf) | |
138 | +{ | |
139 | + struct amba_prom_registers *regs; unsigned int *intr; | |
140 | + unsigned int *device, *vendor; | |
141 | + struct property *prop; | |
142 | + | |
143 | + prop = of_find_property(dp, "reg", NULL); | |
144 | + if (!prop) | |
145 | + return; | |
146 | + regs = prop->value; | |
147 | + prop = of_find_property(dp, "interrupts", NULL); | |
148 | + if (!prop) | |
149 | + return; | |
150 | + intr = prop->value; | |
151 | + prop = of_find_property(dp, "vendor", NULL); | |
152 | + if (!prop) | |
153 | + return; | |
154 | + vendor = prop->value; | |
155 | + prop = of_find_property(dp, "device", NULL); | |
156 | + if (!prop) | |
157 | + return; | |
158 | + device = prop->value; | |
159 | + | |
160 | + sprintf(tmp_buf, "%s:%d:%d@%x,%x", | |
161 | + dp->name, *vendor, *device, | |
162 | + *intr, regs->phys_addr); | |
163 | +} | |
164 | + | |
134 | 165 | static void __init __build_path_component(struct device_node *dp, char *tmp_buf) |
135 | 166 | { |
136 | 167 | struct device_node *parent = dp->parent; |
... | ... | @@ -143,6 +174,8 @@ |
143 | 174 | return sbus_path_component(dp, tmp_buf); |
144 | 175 | if (!strcmp(parent->type, "ebus")) |
145 | 176 | return ebus_path_component(dp, tmp_buf); |
177 | + if (!strcmp(parent->type, "ambapp")) | |
178 | + return ambapp_path_component(dp, tmp_buf); | |
146 | 179 | |
147 | 180 | /* "isa" is handled with platform naming */ |
148 | 181 | } |
arch/sparc/kernel/prom_common.c
... | ... | @@ -22,9 +22,12 @@ |
22 | 22 | #include <linux/of.h> |
23 | 23 | #include <asm/prom.h> |
24 | 24 | #include <asm/oplib.h> |
25 | +#include <asm/leon.h> | |
25 | 26 | |
26 | 27 | #include "prom.h" |
27 | 28 | |
29 | +void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); | |
30 | + | |
28 | 31 | struct device_node *of_console_device; |
29 | 32 | EXPORT_SYMBOL(of_console_device); |
30 | 33 | |
... | ... | @@ -161,7 +164,7 @@ |
161 | 164 | name = prom_nextprop(node, prev, p->name); |
162 | 165 | } |
163 | 166 | |
164 | - if (strlen(name) == 0) { | |
167 | + if (!name || strlen(name) == 0) { | |
165 | 168 | tmp = p; |
166 | 169 | return NULL; |
167 | 170 | } |
... | ... | @@ -242,7 +245,7 @@ |
242 | 245 | return dp; |
243 | 246 | } |
244 | 247 | |
245 | -static char * __init build_full_name(struct device_node *dp) | |
248 | +char * __init build_full_name(struct device_node *dp) | |
246 | 249 | { |
247 | 250 | int len, ourlen, plen; |
248 | 251 | char *n; |
... | ... | @@ -288,6 +291,9 @@ |
288 | 291 | dp->full_name = build_full_name(dp); |
289 | 292 | |
290 | 293 | dp->child = prom_build_tree(dp, prom_getchild(node), nextp); |
294 | + | |
295 | + if (prom_build_more) | |
296 | + prom_build_more(dp, nextp); | |
291 | 297 | |
292 | 298 | node = prom_getsibling(node); |
293 | 299 | } |