Commit e63829de3d03f92cea2b26119e0aa9a7043b9913

Authored by Konrad Eisele
Committed by David S. Miller
1 parent 0fd7ef1fe0

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 }