From patchwork Tue Jun 23 09:13:50 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konrad Eisele X-Patchwork-Id: 29048 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 56188B711C for ; Tue, 23 Jun 2009 19:11:38 +1000 (EST) Received: by ozlabs.org (Postfix) id 48001DDDD4; Tue, 23 Jun 2009 19:11:38 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id CCCA6DDDE1 for ; Tue, 23 Jun 2009 19:11:37 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757269AbZFWJKp (ORCPT ); Tue, 23 Jun 2009 05:10:45 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1758138AbZFWJKp (ORCPT ); Tue, 23 Jun 2009 05:10:45 -0400 Received: from mail168c2.megamailservers.com ([69.49.111.68]:43172 "EHLO mail168c2.megamailservers.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757269AbZFWJKo (ORCPT ); Tue, 23 Jun 2009 05:10:44 -0400 X-Authenticated-User: konrad.gaisler.com Received: from localhost.localdomain (c-10a5e155.260-1-64736c10.cust.bredbandsbolaget.se [85.225.165.16]) (authenticated bits=0) by mail168c2.megamailservers.com (8.13.6/8.13.1) with ESMTP id n5N9AIeP009016; Tue, 23 Jun 2009 05:10:27 -0400 From: konrad@gaisler.com To: sparclinux@vger.kernel.org Cc: sam@ravnborg.org, julian.calaby@gmail.com, davem@davemloft.net, Konrad Eisele Subject: [PATCH 4/5] sparc,leon: Added support for AMBAPP bus. Date: Tue, 23 Jun 2009 11:13:50 +0200 Message-Id: <1245748431-26756-4-git-send-email-konrad@gaisler.com> X-Mailer: git-send-email 1.6.3.2 In-Reply-To: <4A409C4E.6090007@gaisler.com> References: <4A409C4E.6090007@gaisler.com> Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org From: Konrad Eisele 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 --- arch/sparc/kernel/of_device_32.c | 40 ++++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/prom_32.c | 33 +++++++++++++++++++++++++++++++ arch/sparc/kernel/prom_common.c | 10 +++++++- 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 9039670..4c26eb5 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #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", diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c index fe43e80..0a37e8c 100644 --- a/arch/sparc/kernel/prom_32.c +++ b/arch/sparc/kernel/prom_32.c @@ -24,6 +24,8 @@ #include #include +#include +#include #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 */ } diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 0fb5789..138910c 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -22,9 +22,12 @@ #include #include #include +#include #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); }