Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e63829de authored by Konrad Eisele's avatar Konrad Eisele Committed by David S. Miller
Browse files

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: default avatarKonrad Eisele <konrad@gaisler.com>
Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0fd7ef1f
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@
#include <linux/irq.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <asm/leon.h>
#include <asm/leon_amba.h>

#include "of_device_common.h"

@@ -97,6 +99,35 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
	return IORESOURCE_MEM;
}

 /*
 * AMBAPP bus specific translator
 */

static int of_bus_ambapp_match(struct device_node *np)
{
	return !strcmp(np->name, "ambapp");
}

static void of_bus_ambapp_count_cells(struct device_node *child,
				      int *addrc, int *sizec)
{
	if (addrc)
		*addrc = 1;
	if (sizec)
		*sizec = 1;
}

static int of_bus_ambapp_map(u32 *addr, const u32 *range,
			     int na, int ns, int pna)
{
	return of_bus_default_map(addr, range, na, ns, pna);
}

static unsigned long of_bus_ambapp_get_flags(const u32 *addr,
					     unsigned long flags)
{
	return IORESOURCE_MEM;
}

/*
 * Array of bus specific translators
@@ -121,6 +152,15 @@ static struct of_bus of_busses[] = {
		.map = of_bus_default_map,
		.get_flags = of_bus_sbus_get_flags,
	},
	/* AMBA */
	{
		.name = "ambapp",
		.addr_prop_name = "reg",
		.match = of_bus_ambapp_match,
		.count_cells = of_bus_ambapp_count_cells,
		.map = of_bus_ambapp_map,
		.get_flags = of_bus_ambapp_get_flags,
	},
	/* Default */
	{
		.name = "default",
+33 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@

#include <asm/prom.h>
#include <asm/oplib.h>
#include <asm/leon.h>
#include <asm/leon_amba.h>

#include "prom.h"

@@ -131,6 +133,35 @@ static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
		regs->which_io, regs->phys_addr);
}

/* "name:vendor:device@irq,addrlo" */
static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
{
	struct amba_prom_registers *regs; unsigned int *intr;
	unsigned int *device, *vendor;
	struct property *prop;

	prop = of_find_property(dp, "reg", NULL);
	if (!prop)
		return;
	regs = prop->value;
	prop = of_find_property(dp, "interrupts", NULL);
	if (!prop)
		return;
	intr = prop->value;
	prop = of_find_property(dp, "vendor", NULL);
	if (!prop)
		return;
	vendor = prop->value;
	prop = of_find_property(dp, "device", NULL);
	if (!prop)
		return;
	device = prop->value;

	sprintf(tmp_buf, "%s:%d:%d@%x,%x",
		dp->name, *vendor, *device,
		*intr, regs->phys_addr);
}

static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
{
	struct device_node *parent = dp->parent;
@@ -143,6 +174,8 @@ static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
			return sbus_path_component(dp, tmp_buf);
		if (!strcmp(parent->type, "ebus"))
			return ebus_path_component(dp, tmp_buf);
		if (!strcmp(parent->type, "ambapp"))
			return ambapp_path_component(dp, tmp_buf);

		/* "isa" is handled with platform naming */
	}
+8 −2
Original line number Diff line number Diff line
@@ -22,9 +22,12 @@
#include <linux/of.h>
#include <asm/prom.h>
#include <asm/oplib.h>
#include <asm/leon.h>

#include "prom.h"

void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);

struct device_node *of_console_device;
EXPORT_SYMBOL(of_console_device);

@@ -161,7 +164,7 @@ static struct property * __init build_one_prop(phandle node, char *prev,
			name = prom_nextprop(node, prev, p->name);
		}

		if (strlen(name) == 0) {
		if (!name || strlen(name) == 0) {
			tmp = p;
			return NULL;
		}
@@ -242,7 +245,7 @@ static struct device_node * __init prom_create_node(phandle node,
	return dp;
}

static char * __init build_full_name(struct device_node *dp)
char * __init build_full_name(struct device_node *dp)
{
	int len, ourlen, plen;
	char *n;
@@ -289,6 +292,9 @@ static struct device_node * __init prom_build_tree(struct device_node *parent,

		dp->child = prom_build_tree(dp, prom_getchild(node), nextp);

		if (prom_build_more)
			prom_build_more(dp, nextp);

		node = prom_getsibling(node);
	}