aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonrad Eisele <konrad@gaisler.com>2009-08-16 20:13:32 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-17 21:32:10 -0400
commite63829de3d03f92cea2b26119e0aa9a7043b9913 (patch)
tree0f0bbf2f86ef8a447e9b2a298662003602650e87
parent0fd7ef1fe0e6e70c7851ce65a2eb8a8d3f49147e (diff)
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>
-rw-r--r--arch/sparc/kernel/of_device_32.c40
-rw-r--r--arch/sparc/kernel/prom_32.c33
-rw-r--r--arch/sparc/kernel/prom_common.c10
3 files changed, 81 insertions, 2 deletions
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 90396702ea2c..4c26eb59e742 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -9,6 +9,8 @@
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/of_platform.h> 11#include <linux/of_platform.h>
12#include <asm/leon.h>
13#include <asm/leon_amba.h>
12 14
13#include "of_device_common.h" 15#include "of_device_common.h"
14 16
@@ -97,6 +99,35 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
97 return IORESOURCE_MEM; 99 return IORESOURCE_MEM;
98} 100}
99 101
102 /*
103 * AMBAPP bus specific translator
104 */
105
106static int of_bus_ambapp_match(struct device_node *np)
107{
108 return !strcmp(np->name, "ambapp");
109}
110
111static 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
120static 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
126static unsigned long of_bus_ambapp_get_flags(const u32 *addr,
127 unsigned long flags)
128{
129 return IORESOURCE_MEM;
130}
100 131
101/* 132/*
102 * Array of bus specific translators 133 * Array of bus specific translators
@@ -121,6 +152,15 @@ static struct of_bus of_busses[] = {
121 .map = of_bus_default_map, 152 .map = of_bus_default_map,
122 .get_flags = of_bus_sbus_get_flags, 153 .get_flags = of_bus_sbus_get_flags,
123 }, 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,
163 },
124 /* Default */ 164 /* Default */
125 { 165 {
126 .name = "default", 166 .name = "default",
diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c
index fe43e80772db..0a37e8cfd160 100644
--- a/arch/sparc/kernel/prom_32.c
+++ b/arch/sparc/kernel/prom_32.c
@@ -24,6 +24,8 @@
24 24
25#include <asm/prom.h> 25#include <asm/prom.h>
26#include <asm/oplib.h> 26#include <asm/oplib.h>
27#include <asm/leon.h>
28#include <asm/leon_amba.h>
27 29
28#include "prom.h" 30#include "prom.h"
29 31
@@ -131,6 +133,35 @@ static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
131 regs->which_io, regs->phys_addr); 133 regs->which_io, regs->phys_addr);
132} 134}
133 135
136/* "name:vendor:device@irq,addrlo" */
137static 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
134static void __init __build_path_component(struct device_node *dp, char *tmp_buf) 165static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
135{ 166{
136 struct device_node *parent = dp->parent; 167 struct device_node *parent = dp->parent;
@@ -143,6 +174,8 @@ static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
143 return sbus_path_component(dp, tmp_buf); 174 return sbus_path_component(dp, tmp_buf);
144 if (!strcmp(parent->type, "ebus")) 175 if (!strcmp(parent->type, "ebus"))
145 return ebus_path_component(dp, tmp_buf); 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 /* "isa" is handled with platform naming */ 180 /* "isa" is handled with platform naming */
148 } 181 }
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 0fb5789d43c8..138910c67206 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -22,9 +22,12 @@
22#include <linux/of.h> 22#include <linux/of.h>
23#include <asm/prom.h> 23#include <asm/prom.h>
24#include <asm/oplib.h> 24#include <asm/oplib.h>
25#include <asm/leon.h>
25 26
26#include "prom.h" 27#include "prom.h"
27 28
29void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
30
28struct device_node *of_console_device; 31struct device_node *of_console_device;
29EXPORT_SYMBOL(of_console_device); 32EXPORT_SYMBOL(of_console_device);
30 33
@@ -161,7 +164,7 @@ static struct property * __init build_one_prop(phandle node, char *prev,
161 name = prom_nextprop(node, prev, p->name); 164 name = prom_nextprop(node, prev, p->name);
162 } 165 }
163 166
164 if (strlen(name) == 0) { 167 if (!name || strlen(name) == 0) {
165 tmp = p; 168 tmp = p;
166 return NULL; 169 return NULL;
167 } 170 }
@@ -242,7 +245,7 @@ static struct device_node * __init prom_create_node(phandle node,
242 return dp; 245 return dp;
243} 246}
244 247
245static char * __init build_full_name(struct device_node *dp) 248char * __init build_full_name(struct device_node *dp)
246{ 249{
247 int len, ourlen, plen; 250 int len, ourlen, plen;
248 char *n; 251 char *n;
@@ -289,6 +292,9 @@ static struct device_node * __init prom_build_tree(struct device_node *parent,
289 292
290 dp->child = prom_build_tree(dp, prom_getchild(node), nextp); 293 dp->child = prom_build_tree(dp, prom_getchild(node), nextp);
291 294
295 if (prom_build_more)
296 prom_build_more(dp, nextp);
297
292 node = prom_getsibling(node); 298 node = prom_getsibling(node);
293 } 299 }
294 300