* [PATCH 1/2] pci: Fix bus resource assignment on 32 bits with 64b resources
From: Benjamin Herrenschmidt @ 2007-12-10 6:32 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linuxppc-dev, linux-pci, linux-kernel
The current pci_assign_unassigned_resources() code doesn't work properly
on 32 bits platforms with 64 bits resources. The main reason is the use
of unsigned long in various places instead of resource_size_t.
This fixes it, along with some tricks to avoid casting to 64 bits on
platforms that don't need it in every printk around.
This is a pre-requisite for making powerpc use the generic code instead of
its own half-useful implementation.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This version now uses casts as Greg asked for and adds proper setup
of the prefetchable base & limit "upper" registers when using 64 bits
resources.
(and builds ... sorry about that)
drivers/pci/setup-bus.c | 64 ++++++++++++++++++++++++++++++------------------
include/linux/pci.h | 4 +--
2 files changed, 42 insertions(+), 26 deletions(-)
Index: linux-work/drivers/pci/setup-bus.c
===================================================================
--- linux-work.orig/drivers/pci/setup-bus.c 2007-12-10 17:16:44.000000000 +1100
+++ linux-work/drivers/pci/setup-bus.c 2007-12-10 17:21:53.000000000 +1100
@@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *b
* The IO resource is allocated a range twice as large as it
* would normally need. This allows us to set both IO regs.
*/
- printk(" IO window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
@@ -99,8 +100,9 @@ void pci_setup_cardbus(struct pci_bus *b
pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]);
if (bus->resource[1]->flags & IORESOURCE_IO) {
- printk(" IO window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
@@ -109,8 +111,9 @@ void pci_setup_cardbus(struct pci_bus *b
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_MEM) {
- printk(" PREFETCH window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
@@ -119,8 +122,9 @@ void pci_setup_cardbus(struct pci_bus *b
pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]);
if (bus->resource[3]->flags & IORESOURCE_MEM) {
- printk(" MEM window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -145,7 +149,7 @@ pci_setup_bridge(struct pci_bus *bus)
{
struct pci_dev *bridge = bus->self;
struct pci_bus_region region;
- u32 l, io_upper16;
+ u32 l, bu, lu, io_upper16;
DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
@@ -159,7 +163,8 @@ pci_setup_bridge(struct pci_bus *bus)
/* Set up upper 16 bits of I/O base/limit. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
DBG(KERN_INFO " IO window: %04lx-%04lx\n",
- region.start, region.end);
+ (unsigned long)region.start,
+ (unsigned long)region.end);
}
else {
/* Clear upper 16 bits of I/O base/limit. */
@@ -180,8 +185,9 @@ pci_setup_bridge(struct pci_bus *bus)
if (bus->resource[1]->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- DBG(KERN_INFO " MEM window: %08lx-%08lx\n",
- region.start, region.end);
+ DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
}
else {
l = 0x0000fff0;
@@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus)
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
/* Set up PREF base/limit. */
+ bu = lu = 0;
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n",
- region.start, region.end);
+#ifdef CONFIG_RESOURCES_64BIT
+ bu = region.start >> 32;
+ lu = region.end >> 32;
+#endif
+ DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n",
+ (unsigned long long)region.start,
+ (unsigned long long)region.end);
}
else {
l = 0x0000fff0;
@@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus)
}
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
- /* Clear out the upper 32 bits of PREF base. */
- pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
+ /* Set the upper 32 bits of PREF base & limit. */
+ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+ pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
}
@@ -323,8 +336,8 @@ static void pbus_size_io(struct pci_bus
static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
{
struct pci_dev *dev;
- unsigned long min_align, align, size;
- unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */
+ resource_size_t min_align, align, size;
+ resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order;
struct resource *b_res = find_free_bus_resource(bus, type);
@@ -340,7 +353,7 @@ static int pbus_size_mem(struct pci_bus
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
- unsigned long r_size;
+ resource_size_t r_size;
if (r->parent || (r->flags & mask) != type)
continue;
@@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus
order = __ffs(align) - 20;
if (order > 11) {
printk(KERN_WARNING "PCI: region %s/%d "
- "too large: %llx-%llx\n",
+ "too large: 0x%016llx-0x%016llx\n",
pci_name(dev), i,
- (unsigned long long)r->start,
- (unsigned long long)r->end);
+ (unsigned long long)r->start,
+ (unsigned long long)r->end);
r->flags = 0;
continue;
}
@@ -372,8 +385,11 @@ static int pbus_size_mem(struct pci_bus
align = 0;
min_align = 0;
for (order = 0; order <= max_order; order++) {
- unsigned long align1 = 1UL << (order + 20);
-
+#ifdef CONFIG_RESOURCES_64BIT
+ resource_size_t align1 = 1ULL << (order + 20);
+#else
+ resource_size_t align1 = 1U << (order + 20);
+#endif
if (!align)
min_align = align1;
else if (ALIGN(align + min_align, min_align) < align1)
Index: linux-work/include/linux/pci.h
===================================================================
--- linux-work.orig/include/linux/pci.h 2007-12-10 17:16:44.000000000 +1100
+++ linux-work/include/linux/pci.h 2007-12-10 17:16:46.000000000 +1100
@@ -314,8 +314,8 @@ struct pci_raw_ops {
extern struct pci_raw_ops *raw_pci_ops;
struct pci_bus_region {
- unsigned long start;
- unsigned long end;
+ resource_size_t start;
+ resource_size_t end;
};
struct pci_dynids {
^ permalink raw reply
* Re: [PATCH] pci: Fix bus resource assignment on 32 bits with 64b resources
From: Benjamin Herrenschmidt @ 2007-12-10 6:19 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linuxppc-dev, linux-pci, linux-kernel
In-Reply-To: <20071210061559.2E3DDDDE02@ozlabs.org>
On Mon, 2007-12-10 at 17:15 +1100, Benjamin Herrenschmidt wrote:
> The current pci_assign_unassigned_resources() code doesn't work properly
> on 32 bits platforms with 64 bits resources. The main reason is the use
> of unsigned long in various places instead of resource_size_t.
>
> This fixes it, along with some tricks to avoid casting to 64 bits on
> platforms that don't need it in every printk around.
>
> This is a pre-requisite for making powerpc use the generic code instead of
> its own half-useful implementation.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> This version now uses casts as Greg asked for and adds proper setup
> of the prefetchable base & limit "upper" registers when using 64 bits
> resources.
Crap ! Ignore it. I forgot to quilt ref again... won't build.
Sending it again, with a separate patch fixing a warning in setup-res.c
that isn't directly related to the changes to setup-bus.c
Cheers,
Ben.
^ permalink raw reply
* [PATCH] pci: Fix bus resource assignment on 32 bits with 64b resources
From: Benjamin Herrenschmidt @ 2007-12-10 6:15 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linuxppc-dev, linux-pci, linux-kernel
The current pci_assign_unassigned_resources() code doesn't work properly
on 32 bits platforms with 64 bits resources. The main reason is the use
of unsigned long in various places instead of resource_size_t.
This fixes it, along with some tricks to avoid casting to 64 bits on
platforms that don't need it in every printk around.
This is a pre-requisite for making powerpc use the generic code instead of
its own half-useful implementation.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This version now uses casts as Greg asked for and adds proper setup
of the prefetchable base & limit "upper" registers when using 64 bits
resources.
drivers/pci/setup-bus.c | 59 +++++++++++++++++++++++++++++-------------------
include/linux/pci.h | 4 +--
2 files changed, 38 insertions(+), 25 deletions(-)
Index: linux-work/drivers/pci/setup-bus.c
===================================================================
--- linux-work.orig/drivers/pci/setup-bus.c 2007-12-10 16:56:51.000000000 +1100
+++ linux-work/drivers/pci/setup-bus.c 2007-12-10 17:12:27.000000000 +1100
@@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *b
* The IO resource is allocated a range twice as large as it
* would normally need. This allows us to set both IO regs.
*/
- printk(" IO window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
@@ -99,8 +100,9 @@ void pci_setup_cardbus(struct pci_bus *b
pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]);
if (bus->resource[1]->flags & IORESOURCE_IO) {
- printk(" IO window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
@@ -109,8 +111,9 @@ void pci_setup_cardbus(struct pci_bus *b
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_MEM) {
- printk(" PREFETCH window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
@@ -119,8 +122,9 @@ void pci_setup_cardbus(struct pci_bus *b
pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]);
if (bus->resource[3]->flags & IORESOURCE_MEM) {
- printk(" MEM window: %08lx-%08lx\n",
- region.start, region.end);
+ printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -145,7 +149,7 @@ pci_setup_bridge(struct pci_bus *bus)
{
struct pci_dev *bridge = bus->self;
struct pci_bus_region region;
- u32 l, io_upper16;
+ u32 l, bu, lu, io_upper16;
DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
@@ -159,7 +163,8 @@ pci_setup_bridge(struct pci_bus *bus)
/* Set up upper 16 bits of I/O base/limit. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
DBG(KERN_INFO " IO window: %04lx-%04lx\n",
- region.start, region.end);
+ (unsigned long)region.start,
+ (unsigned long)region.end);
}
else {
/* Clear upper 16 bits of I/O base/limit. */
@@ -180,8 +185,9 @@ pci_setup_bridge(struct pci_bus *bus)
if (bus->resource[1]->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- DBG(KERN_INFO " MEM window: %08lx-%08lx\n",
- region.start, region.end);
+ DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
+ (unsigned long)region.start,
+ (unsigned long)region.end);
}
else {
l = 0x0000fff0;
@@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus)
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
/* Set up PREF base/limit. */
+ bu = lu = 0;
pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n",
- region.start, region.end);
+#ifdef CONFIG_RESOURCES_64BIT
+ bu = region.start >> 32;
+ lu = region.end >> 32;
+#endif
+ DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n",
+ (unsigned long long)region.start,
+ (unsigned long long)region.end);
}
else {
l = 0x0000fff0;
@@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus)
}
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
- /* Clear out the upper 32 bits of PREF base. */
- pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
+ /* Set the upper 32 bits of PREF base & limit. */
+ pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+ pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
}
@@ -323,8 +336,8 @@ static void pbus_size_io(struct pci_bus
static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
{
struct pci_dev *dev;
- unsigned long min_align, align, size;
- unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */
+ resource_size_t min_align, align, size;
+ resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order;
struct resource *b_res = find_free_bus_resource(bus, type);
@@ -340,7 +353,7 @@ static int pbus_size_mem(struct pci_bus
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
- unsigned long r_size;
+ resource_size_t r_size;
if (r->parent || (r->flags & mask) != type)
continue;
@@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus
order = __ffs(align) - 20;
if (order > 11) {
printk(KERN_WARNING "PCI: region %s/%d "
- "too large: %llx-%llx\n",
+ "too large: 0x%016llx-0x%016llx\n",
pci_name(dev), i,
- (unsigned long long)r->start,
- (unsigned long long)r->end);
+ (unsigned long long)r->start,
+ (unsigned long long)r->end);
r->flags = 0;
continue;
}
@@ -372,7 +385,7 @@ static int pbus_size_mem(struct pci_bus
align = 0;
min_align = 0;
for (order = 0; order <= max_order; order++) {
- unsigned long align1 = 1UL << (order + 20);
+ resource_size_t align1 = RESOURCE_ORDER(order + 20);
if (!align)
min_align = align1;
Index: linux-work/include/linux/pci.h
===================================================================
--- linux-work.orig/include/linux/pci.h 2007-12-10 16:56:51.000000000 +1100
+++ linux-work/include/linux/pci.h 2007-12-10 16:57:20.000000000 +1100
@@ -314,8 +314,8 @@ struct pci_raw_ops {
extern struct pci_raw_ops *raw_pci_ops;
struct pci_bus_region {
- unsigned long start;
- unsigned long end;
+ resource_size_t start;
+ resource_size_t end;
};
struct pci_dynids {
^ permalink raw reply
* RE: Xilinx ML310 Linux 2.6 PCI bridge
From: Stephen Neuendorffer @ 2007-12-10 5:46 UTC (permalink / raw)
To: Grant Likely, Jean-Samuel Chenard; +Cc: linuxppc-embedded
In-Reply-To: <fa686aa40712091223x3efb1143kfd81277890fb74ae@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2337 bytes --]
I would strongly recommend not spending a huge amount of time on the ml310. The University program board is dirt cheap for universities, very well supported under Linux, using either secretlab.ca or git.xilinx.com and you won't spend your time getting PCI to place and route correctly, followed by figuring out how to get Linux to talk to it nicely.
If your lab can afford a bee2, then you should be able to afford one (or better yet, several) xupv2p's to go with it.
http://www.xilinx.com/univ/xupv2p.html
Steve
-----Original Message-----
From: linuxppc-embedded-bounces+stephen=neuendorffer.name@ozlabs.org on behalf of Grant Likely
Sent: Sun 12/9/2007 12:23 PM
To: Jean-Samuel Chenard
Cc: linuxppc-embedded@ozlabs.org
Subject: Re: Xilinx ML310 Linux 2.6 PCI bridge
On 12/9/07, Jean-Samuel Chenard <jsamch@macs.ece.mcgill.ca> wrote:
> On Dec 9, 2007 1:18 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> > On 12/8/07, Jean-Samuel Chenard <jsamch@macs.ece.mcgill.ca> wrote:
> > > Thanks to the valuable information provided by this discussion group and
> > > particularly by Grant Likely from Secret Lab Technologies, I was able to
> > > setup and run Linux 2.6 on my ML-310 development platform.
> >
> > Congratulations. If you had to make any changes to get it to work
> > then please send me your patches.
>
> Thank you for the quick reply.
No problem.
>
> I will directly update Secret Lab's Wiki pages. Those pages are the
> ones that got me going really quickly, so I will add a few of my
> observations directly on your pages so everyone can benefit.
Much appreciated; thank you!
> My real target is the control FPGA on a BEE2 box
> (http://bee2.eecs.berkeley.edu) and on that particular setup, the
> control FPGA is directly connected to an LXT971A Ethernet PHY, so I'll
> use the ethernet MAC from Xilinx.
Cool platform. Yes, you should have much better luck with the EMAC
core. The driver needs some work to be acceptable for mainline, but
it should be functional.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
[-- Attachment #2: Type: text/html, Size: 3247 bytes --]
^ permalink raw reply
* Re: [PATCH 18/25] powerpc: Base support for 440GX Taishan eval board
From: Benjamin Herrenschmidt @ 2007-12-10 5:39 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071206211758.6f086161@zod.rchland.ibm.com>
powerpc: Base support for 440GX Taishan eval board
From: Hugh Blemings <hugh@blemings.org>
Signed-off-by: Hugh Blemings <hugh@blemings.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This needs a bit of cleanup still, probably not to be merged as-is
just yet (like using mtdcri/mfdcri for CPR access).
Index: linux-work/arch/powerpc/boot/dcr.h
===================================================================
--- linux-work.orig/arch/powerpc/boot/dcr.h 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/boot/dcr.h 2007-12-10 15:56:56.000000000 +1100
@@ -139,4 +139,31 @@ static const unsigned long sdram_bxcr[]
#define DCRN_405_CPC0_CR0 0xb1
#define DCRN_405_CPC0_CR1 0xb2
+
+/* 440GX Clock control etc */
+
+
+#define DCRN_CPR0_CLKUPD 0x020
+#define DCRN_CPR0_PLLC 0x040
+#define DCRN_CPR0_PLLD 0x060
+#define DCRN_CPR0_PRIMAD 0x080
+#define DCRN_CPR0_PRIMBD 0x0a0
+#define DCRN_CPR0_OPBD 0x0c0
+#define DCRN_CPR0_PERD 0x0e0
+#define DCRN_CPR0_MALD 0x100
+
+/* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */
+
+#define DCRN_CPR0_CFGADDR 0xc
+#define DCRN_CPR0_CFGDATA 0xd
+
+#define CPR0_READ(offset) ({\
+ mtdcr(DCRN_CPR0_CFGADDR, offset); \
+ mfdcr(DCRN_CPR0_CFGDATA); })
+#define CPR0_WRITE(offset, data) ({\
+ mtdcr(DCRN_CPR0_CFGADDR, offset); \
+ mtdcr(DCRN_CPR0_CFGDATA, data); })
+
+
+
#endif /* _PPC_BOOT_DCR_H_ */
Index: linux-work/arch/powerpc/boot/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/boot/Makefile 2007-12-10 15:54:23.000000000 +1100
+++ linux-work/arch/powerpc/boot/Makefile 2007-12-10 15:56:56.000000000 +1100
@@ -37,8 +37,10 @@ BOOTCFLAGS += -I$(obj) -I$(srctree)/$(ob
$(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
+
zlib := inffast.c inflate.c inftrees.c
zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
zliblinuxheader := zlib.h zconf.h zutil.h
@@ -56,7 +58,7 @@ src-plat := of.c cuboot-52xx.c cuboot-83
cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \
- fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c
+ fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c cuboot-taishan.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -160,6 +162,7 @@ image-$(CONFIG_EBONY) += treeImage.ebo
image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo
image-$(CONFIG_SEQUOIA) += cuImage.sequoia
image-$(CONFIG_WALNUT) += treeImage.walnut
+image-$(CONFIG_TAISHAN) += cuImage.taishan
endif
# For 32-bit powermacs, build the COFF and miboot images
Index: linux-work/arch/powerpc/Kconfig.debug
===================================================================
--- linux-work.orig/arch/powerpc/Kconfig.debug 2007-12-10 15:54:22.000000000 +1100
+++ linux-work/arch/powerpc/Kconfig.debug 2007-12-10 15:56:56.000000000 +1100
@@ -225,7 +225,8 @@ config PPC_EARLY_DEBUG_44x
depends on 44x
help
Select this to enable early debugging for IBM 44x chips via the
- inbuilt serial port.
+ inbuilt serial port. If you enable this, ensure you set
+ PPC_EARLY_DEBUG_44x_PHYSLOW below to suit your target board.
config PPC_EARLY_DEBUG_40x
bool "Early serial debugging for IBM/AMCC 40x CPUs"
@@ -250,6 +251,9 @@ config PPC_EARLY_DEBUG_44x_PHYSLOW
hex "Low 32 bits of early debug UART physical address"
depends on PPC_EARLY_DEBUG_44x
default "0x40000200"
+ help
+ You probably want 0x40000200 for ebony boards and
+ 0x40000300 for taishan
config PPC_EARLY_DEBUG_44x_PHYSHIGH
hex "EPRN of early debug UART physical address"
Index: linux-work/arch/powerpc/platforms/44x/Kconfig
===================================================================
--- linux-work.orig/arch/powerpc/platforms/44x/Kconfig 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/platforms/44x/Kconfig 2007-12-10 16:36:44.000000000 +1100
@@ -22,6 +22,15 @@ config SEQUOIA
help
This option enables support for the AMCC PPC440EPX evaluation board.
+config TAISHAN
+ bool "Taishan"
+ depends on 44x
+ default n
+ select 440GX
+ help
+ This option enables support for the AMCC PPC440GX "Taishan"
+ evaluation board.
+
#config LUAN
# bool "Luan"
# depends on 44x
@@ -58,6 +67,10 @@ config 440GP
config 440GX
bool
+ select IBM_NEW_EMAC_EMAC4
+ select IBM_NEW_EMAC_RGMII
+ select IBM_NEW_EMAC_ZMII #test only
+ select IBM_NEW_EMAC_TAH #test only
config 440SP
bool
Index: linux-work/arch/powerpc/platforms/44x/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/platforms/44x/Makefile 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/platforms/44x/Makefile 2007-12-10 15:56:56.000000000 +1100
@@ -1,4 +1,5 @@
obj-$(CONFIG_44x) := misc_44x.o
obj-$(CONFIG_EBONY) += ebony.o
+obj-$(CONFIG_TAISHAN) += taishan.o
obj-$(CONFIG_BAMBOO) += bamboo.o
obj-$(CONFIG_SEQUOIA) += sequoia.o
Index: linux-work/arch/powerpc/platforms/44x/taishan.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/platforms/44x/taishan.c 2007-12-10 16:37:07.000000000 +1100
@@ -0,0 +1,74 @@
+/*
+ * Taishan board specific routines based off ebony.c code
+ * original copyrights below
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003-2005 Zultys Technologies
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * Modified from ebony.c for taishan:
+ * Copyright 2007 Hugh Blemings <hugh@au.ibm.com>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/pci-bridge.h>
+
+#include "44x.h"
+
+static struct of_device_id taishan_of_bus[] = {
+ { .compatible = "ibm,plb4", },
+ { .compatible = "ibm,opb", },
+ { .compatible = "ibm,ebc", },
+ {},
+};
+
+static int __init taishan_device_probe(void)
+{
+ if (!machine_is(taishan))
+ return 0;
+
+ of_platform_bus_probe(NULL, taishan_of_bus, NULL);
+
+ return 0;
+}
+device_initcall(taishan_device_probe);
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init taishan_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "amcc,taishan"))
+ return 0;
+
+ return 1;
+}
+
+define_machine(taishan) {
+ .name = "Taishan",
+ .probe = taishan_probe,
+ .progress = udbg_progress,
+ .init_IRQ = uic_init_tree,
+ .get_irq = uic_get_irq,
+ .restart = ppc44x_reset_system,
+ .calibrate_decr = generic_calibrate_decr,
+};
Index: linux-work/arch/powerpc/boot/dts/taishan.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/boot/dts/taishan.dts 2007-12-10 16:38:54.000000000 +1100
@@ -0,0 +1,375 @@
+/*
+ * Device Tree Source for IBM/AMCC Taishan
+ *
+ * Copyright 2007 IBM Corp.
+ * Hugh Blemings <hugh@au.ibm.com> based off code by
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ model = "amcc,taishan";
+ compatible = "amcc,taishan";
+ dcr-parent = <&/cpus/PowerPC,440GX@0>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,440GX@0 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <2FAF0800>; // 800MHz
+ timebase-frequency = <0>; // Filled in by zImage
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <8000>; /* 32 kB */
+ d-cache-size = <8000>; /* 32 kB */
+ dcr-controller;
+ dcr-access-method = "native";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0>; // Filled in by zImage
+ };
+
+
+ UICB0: interrupt-controller-base {
+ compatible = "ibm,uic-440gx", "ibm,uic";
+ interrupt-controller;
+ cell-index = <3>;
+ dcr-reg = <200 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ };
+
+
+ UIC0: interrupt-controller0 {
+ compatible = "ibm,uic-440gx", "ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0c0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <01 4 00 4>; /* cascade - first non-critical */
+ interrupt-parent = <&UICB0>;
+
+ };
+
+ UIC1: interrupt-controller1 {
+ compatible = "ibm,uic-440gx", "ibm,uic";
+ interrupt-controller;
+ cell-index = <1>;
+ dcr-reg = <0d0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <03 4 02 4>; /* cascade */
+ interrupt-parent = <&UICB0>;
+ };
+
+ UIC2: interrupt-controller2 {
+ compatible = "ibm,uic-440gx", "ibm,uic";
+ interrupt-controller;
+ cell-index = <2>; /* was 1 */
+ dcr-reg = <210 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <05 4 04 4>; /* cascade */
+ interrupt-parent = <&UICB0>;
+ };
+
+
+ CPC0: cpc {
+ compatible = "ibm,cpc-440gp";
+ dcr-reg = <0b0 003 0e0 010>;
+ // FIXME: anything else?
+ };
+
+ plb {
+ compatible = "ibm,plb-440gx", "ibm,plb4";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <9896800>; // 160MHz
+
+ SDRAM0: memory-controller {
+ compatible = "ibm,sdram-440gp";
+ dcr-reg = <010 2>;
+ // FIXME: anything else?
+ };
+
+ SRAM0: sram {
+ compatible = "ibm,sram-440gp";
+ dcr-reg = <020 8 00a 1>;
+ };
+
+ DMA0: dma {
+ // FIXME: ???
+ compatible = "ibm,dma-440gp";
+ dcr-reg = <100 027>;
+ };
+
+ MAL0: mcmal {
+ compatible = "ibm,mcmal-440gx", "ibm,mcmal2";
+ dcr-reg = <180 62>;
+ num-tx-chans = <4>;
+ num-rx-chans = <4>;
+ interrupt-parent = <&MAL0>;
+ interrupts = <0 1 2 3 4>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
+ /*RXEOB*/ 1 &UIC0 b 4
+ /*SERR*/ 2 &UIC1 0 4
+ /*TXDE*/ 3 &UIC1 1 4
+ /*RXDE*/ 4 &UIC1 2 4>;
+ interrupt-map-mask = <ffffffff>;
+ };
+
+ POB0: opb {
+ compatible = "ibm,opb-440gx", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* Wish there was a nicer way of specifying a full 32-bit
+ range */
+ ranges = <00000000 1 00000000 80000000
+ 80000000 1 80000000 80000000>;
+ dcr-reg = <090 00b>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <7 4>;
+ clock-frequency = <4C4B400>; // 80MHz
+
+
+ EBC0: ebc {
+ compatible = "ibm,ebc-440gx", "ibm,ebc";
+ dcr-reg = <012 2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-frequency = <4C4B400>; // 80MHz
+
+ /* ranges property is supplied by zImage
+ * based on firmware's configuration of the
+ * EBC bridge */
+
+ interrupts = <5 4>;
+ interrupt-parent = <&UIC1>;
+
+ /* TODO: Add other EBC devices */
+ };
+
+
+
+ UART0: serial@40000200 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <40000200 8>;
+ virtual-reg = <e0000200>;
+ clock-frequency = <A8C000>;
+ current-speed = <1C200>; /* 115200 */
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
+
+ UART1: serial@40000300 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <40000300 8>;
+ virtual-reg = <e0000300>;
+ clock-frequency = <A8C000>;
+ current-speed = <1C200>; /* 115200 */
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
+
+ IIC0: i2c@40000400 {
+ /* FIXME */
+ device_type = "i2c";
+ compatible = "ibm,iic-440gp", "ibm,iic";
+ reg = <40000400 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <2 4>;
+ };
+ IIC1: i2c@40000500 {
+ /* FIXME */
+ device_type = "i2c";
+ compatible = "ibm,iic-440gp", "ibm,iic";
+ reg = <40000500 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <3 4>;
+ };
+
+ GPIO0: gpio@40000700 {
+ /* FIXME */
+ compatible = "ibm,gpio-440gp";
+ reg = <40000700 20>;
+ };
+
+ ZMII0: emac-zmii@40000780 {
+ device_type = "zgmii-interface";
+ compatible = "ibm,zmii-440gx", "ibm,zmii";
+ reg = <40000780 c>;
+ };
+
+ RGMII0: emac-rgmii@40000790 {
+ device_type = "rgmii-interface";
+ compatible = "ibm,rgmii";
+ reg = <40000790 8>;
+ };
+
+
+ EMAC0: ethernet@40000800 {
+ unused = <1>;
+ linux,network-index = <2>;
+ device_type = "network";
+ compatible = "ibm,emac-440gx", "ibm,emac4";
+ interrupt-parent = <&UIC1>;
+ interrupts = <1c 4 1d 4>;
+ reg = <40000800 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <0>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000001>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <0>;
+ };
+ EMAC1: ethernet@40000900 {
+ unused = <1>;
+ linux,network-index = <3>;
+ device_type = "network";
+ compatible = "ibm,emac-440gx", "ibm,emac4";
+ interrupt-parent = <&UIC1>;
+ interrupts = <1e 4 1f 4>;
+ reg = <40000900 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <1>;
+ mal-rx-channel = <1>;
+ cell-index = <1>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000001>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <1>;
+ };
+
+ EMAC2: ethernet@40000c00 {
+ linux,network-index = <0>;
+ device_type = "network";
+ compatible = "ibm,emac-440gx", "ibm,emac4";
+ interrupt-parent = <&UIC2>;
+ interrupts = <0 4 1 4>;
+ reg = <40000c00 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <2>;
+ mal-rx-channel = <2>;
+ cell-index = <2>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rgmii";
+ phy-map = <00000001>;
+ rgmii-device = <&RGMII0>;
+ rgmii-channel = <0>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <2>;
+ };
+
+ EMAC3: ethernet@40000e00 {
+ linux,network-index = <1>;
+ device_type = "network";
+ compatible = "ibm,emac-440gx", "ibm,emac4";
+ interrupt-parent = <&UIC2>;
+ interrupts = <2 4 3 4>;
+ reg = <40000e00 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <3>;
+ mal-rx-channel = <3>;
+ cell-index = <3>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rgmii";
+ phy-map = <00000003>;
+ rgmii-device = <&RGMII0>;
+ rgmii-channel = <1>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <3>;
+ };
+
+
+ GPT0: gpt@40000a00 {
+ /* FIXME */
+ reg = <40000a00 d4>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <12 4 13 4 14 4 15 4 16 4>;
+ };
+
+ };
+
+ PCIX0: pci@20ec00000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix";
+ primary;
+ large-inbound-windows;
+ enable-msi-hole;
+ reg = <2 0ec00000 8 /* Config space access */
+ 0 0 0 /* no IACK cycles */
+ 2 0ed00000 4 /* Special cycles */
+ 2 0ec80000 100 /* Internal registers */
+ 2 0ec80100 fc>; /* Internal messaging registers */
+
+ /* Outbound ranges, one memory and one IO,
+ * later cannot be changed
+ */
+ ranges = <02000000 0 80000000 00000003 80000000 0 80000000
+ 01000000 0 00000000 00000002 08000000 0 00010000>;
+
+ /* Inbound 2GB range starting at 0 */
+ dma-ranges = <42000000 0 0 0 0 0 80000000>;
+
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 1 */
+ 0800 0 0 1 &UIC0 17 8
+ 0800 0 0 2 &UIC0 18 8
+ 0800 0 0 3 &UIC0 19 8
+ 0800 0 0 4 &UIC0 1a 8
+
+ /* IDSEL 2 */
+ 1000 0 0 1 &UIC0 18 8
+ 1000 0 0 2 &UIC0 19 8
+ 1000 0 0 3 &UIC0 1a 8
+ 1000 0 0 4 &UIC0 17 8
+ >;
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/plb/opb/serial@40000300";
+ };
+};
Index: linux-work/arch/powerpc/boot/cuboot-taishan.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/boot/cuboot-taishan.c 2007-12-10 15:56:56.000000000 +1100
@@ -0,0 +1,56 @@
+/*
+ * Old U-boot compatibility for Taishan
+ *
+ * Author: Hugh Blemings <hugh@au.ibm.com>
+ *
+ * Copyright 2007 Hugh Blemings, IBM Corporation.
+ * Based on cuboot-ebony.c which is:
+ * Copyright 2007 David Gibson, IBM Corporation.
+ * Based on cuboot-83xx.c, which is:
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "cuboot.h"
+#include "reg.h"
+#include "dcr.h"
+#include "4xx.h"
+
+#define TARGET_44x
+#include "ppcboot.h"
+
+static bd_t bd;
+
+BSS_STACK(4096);
+
+static void taishan_fixups(void)
+{
+ /* FIXME: sysclk should be derived by reading the FPGA
+ registers */
+ unsigned long sysclk = 33000000;
+
+ /* 440EP Clock logic is all but identical to 440GX
+ so we just use that code for now at least */
+ ibm440ep_fixup_clocks(sysclk, 6 * 1843200);
+
+ ibm4xx_fixup_memsize();
+
+ dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
+
+ ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ CUBOOT_INIT();
+
+ platform_ops.fixups = taishan_fixups;
+ ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ serial_console_init();
+}
^ permalink raw reply
* Re: [PATCH 23/25] powerpc: Rework 4xx clock probing in boot wrapper
From: Benjamin Herrenschmidt @ 2007-12-10 5:43 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071206212744.7257f1a2@zod.rchland.ibm.com>
On Thu, 2007-12-06 at 21:27 -0600, Josh Boyer wrote:
> On Thu, 06 Dec 2007 19:00:22 +1100
> Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> > Index: linux-work/arch/powerpc/boot/reg.h
> > ===================================================================
> > --- linux-work.orig/arch/powerpc/boot/reg.h 2007-12-03 14:26:09.000000000 +1100
> > +++ linux-work/arch/powerpc/boot/reg.h 2007-12-03 14:26:09.000000000 +1100
> > @@ -24,6 +24,14 @@ static inline u32 mfpvr(void)
> > : "=r" (rval)); rval; })
> > #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
> >
> > +#define __stringify_1(x) #x
> > +#define __stringify(x) __stringify_1(x)
> > +
> > +#define mfspr(rn) ({unsigned long rval; \
> > + asm volatile("mfspr %0," __stringify(rn) \
> > + : "=r" (rval)); rval; })
> > +#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
> > +
>
> You felt like duplicating this? It was added in the previous patch. :)
Want a new patch or can you just remove that bit ?
Ben.
^ permalink raw reply
* Re: [PATCH 19/25] powerpc: Wire up PCI on Bamboo board
From: Benjamin Herrenschmidt @ 2007-12-10 5:40 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071206211906.2e1c099f@zod.rchland.ibm.com>
powerpc: Wire up PCI on Bamboo board
This adds the device-tree bits & call to ppc4xx_pci_find_bridges()
to make PCI work on the Bamboo board
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Index: linux-work/arch/powerpc/boot/dts/bamboo.dts
===================================================================
--- linux-work.orig/arch/powerpc/boot/dts/bamboo.dts 2007-12-10 15:56:59.000000000 +1100
+++ linux-work/arch/powerpc/boot/dts/bamboo.dts 2007-12-10 16:39:51.000000000 +1100
@@ -239,10 +239,48 @@
zmii-channel = <1>;
};
};
+
+ PCI0: pci@ec000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb440ep-pci", "ibm,plb-pci";
+ primary;
+ reg = <0 eec00000 8 /* Config space access */
+ 0 eed80000 4 /* IACK */
+ 0 eed80000 4 /* Special cycle */
+ 0 ef480000 40>; /* Internal registers */
+
+ /* Outbound ranges, one memory and one IO,
+ * later cannot be changed. Chip supports a second
+ * IO range but we don't use it for now
+ */
+ ranges = <02000000 0 a0000000 0 a0000000 0 20000000
+ 01000000 0 00000000 0 e8000000 0 00010000>;
+
+ /* Inbound 2GB range starting at 0 */
+ dma-ranges = <42000000 0 0 0 0 0 80000000>;
+
+ /* Bamboo has all 4 IRQ pins tied together per slot */
+ interrupt-map-mask = <f800 0 0 0>;
+ interrupt-map = <
+ /* IDSEL 1 */
+ 0800 0 0 0 &UIC0 1c 8
+
+ /* IDSEL 2 */
+ 1000 0 0 0 &UIC0 1b 8
+
+ /* IDSEL 3 */
+ 1800 0 0 0 &UIC0 1a 8
+
+ /* IDSEL 4 */
+ 2000 0 0 0 &UIC0 19 8
+ >;
+ };
};
chosen {
linux,stdout-path = "/plb/opb/serial@ef600300";
- bootargs = "console=ttyS0,115200";
};
};
^ permalink raw reply
* RE: [PATCH] Fix rounding bug in emulation for double floatoperating
From: Liu Yu @ 2007-12-10 5:25 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20071210045616.GC29611@localhost.localdomain>
=20
> -----Original Message-----
> From: David Gibson [mailto:david@gibson.dropbear.id.au]=20
> Sent: Monday, December 10, 2007 12:56 PM
> To: Liu Yu
> Cc: linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH] Fix rounding bug in emulation for double=20
> floatoperating
>=20
>=20
> On Mon, Dec 10, 2007 at 01:00:52PM +0800, Liu Yu wrote:
> >=20
> > This patch fixes rounding bug in emulation for double float=20
> operating on PowerPC platform.
> >=20
> > When pack double float operand, it need to truncate the=20
> tail due to the limited precision.
> > If the truncated part is not zero, the last bit of work bit=20
> (totally 3 bits) need to '|' 1.
> >=20
> > This patch is completed in _FP_FRAC_SRS_2(X,N,sz)=20
> (arch/powerpc/math-emu/op-2.h).
> > Originally the code leftwards rotates the operand to just keep the=20
> > truncated part, then check whether it is zero. However, the=20
> number it=20
> > rotates is not correct when N is not smaller than=20
> _FP_W_TYPE_SIZE, and it will cause the work bit '|' 1 in the=20
> improper case.
> >=20
> > This patch fixes this issue.
> >=20
> > Signed-off-by: Liu Yu <b13201@freescale.com>
>=20
> Wow someone deciphered the hideous macro hell of the math=20
> emulation code enough to fix a bug. I don't suppose you'd=20
> care to fix the millions of warnings that the math-emu code=20
> generates...?
Oh, I don't like macro define either. But it's really a bug...
^ permalink raw reply
* Re: [PATCH 16/25] powerpc: EP405 boards support for arch/powerpc
From: Benjamin Herrenschmidt @ 2007-12-10 4:56 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071206210550.520e5131@zod.rchland.ibm.com>
powerpc: EP405 boards support for arch/powerpc
Brings EP405 support to arch/powerpc. The IRQ routing for the CPLD
comes from a device-tree property, PCI is working to the point where
I can see the video card, USB device, and south bridge.
This should work with both EP405 and EP405PC.
I've not totally figured out how IRQs are wired on this hardware
though, thus at this stage, expect only USB interrupts working,
pretty much the same as what arch/ppc did.
Also, the flash, nvram, rtc and temp control still have to be wired.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Note about IRQ routing: The doc is very obscure in that area.
I _think_ the SB interrupt on the CPLD is actually the Windond's
8259 output and the NB interrupt is the PCI_A...PCI_D mux in
there (which can be implemented as a cascaded controller) but
I haven't sorted that out yet. If anybody from Embedded Planet
is around, I could use some advice there.
If my deductions are correct, then we would need to wire up the
8259 driver to SB, which should be trivial provided I stick the
windbond bridge in the device-tree, or at least part of it,
and probably implement a cascaded controller for the PCI IRQ
A...D mux thingy, which should also be trivial.
Note also that it tends to lockup during the transition from
the boot wrapper to the kernel, before udbg is started. I didn't
have a RiscWatch at hand so I haven't yet been able to track that
down. It's random though, quite weird. Maybe some stale TLB entries
or cache content that isn't cleared properly...
Index: linux-work/arch/powerpc/boot/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/boot/Makefile 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/boot/Makefile 2007-12-10 15:54:23.000000000 +1100
@@ -56,7 +56,7 @@ src-plat := of.c cuboot-52xx.c cuboot-83
cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \
- fixed-head.S ep88xc.c cuboot-hpc2.c
+ fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -150,6 +150,7 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImag
ifneq ($(CONFIG_DEVICE_TREE),"")
image-$(CONFIG_PPC_8xx) += cuImage.8xx
image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc
+image-$(CONFIG_EP405) += zImage.ep405
image-$(CONFIG_8260) += cuImage.pq2
image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx
image-$(CONFIG_PPC_83xx) += cuImage.83xx
Index: linux-work/arch/powerpc/boot/ep405.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/boot/ep405.c 2007-12-10 15:54:23.000000000 +1100
@@ -0,0 +1,74 @@
+/*
+ * Embedded Planet EP405 with PlanetCore firmware
+ *
+ * (c) Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp,\
+ *
+ * Based on ep88xc.c by
+ *
+ * Scott Wood <scottwood@freescale.com>
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "planetcore.h"
+#include "dcr.h"
+#include "4xx.h"
+#include "io.h"
+
+static char *table;
+static u64 mem_size;
+
+static void platform_fixups(void)
+{
+ u64 val;
+ void *nvrtc;
+
+ dt_fixup_memory(0, mem_size);
+ planetcore_set_mac_addrs(table);
+
+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) {
+ printf("No PlanetCore crystal frequency key.\r\n");
+ return;
+ }
+ ibm405gp_fixup_clocks(val, 0xa8c000);
+ ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
+ ibm4xx_fixup_ebc_ranges("/plb/ebc");
+
+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_KB_NVRAM, &val)) {
+ printf("No PlanetCore NVRAM size key.\r\n");
+ return;
+ }
+ nvrtc = finddevice("/plb/ebc/nvrtc@4,200000");
+ if (nvrtc != NULL) {
+ u32 reg[3] = { 4, 0x200000, 0};
+ getprop(nvrtc, "reg", reg, 3);
+ reg[2] = (val << 10) & 0xffffffff;
+ setprop(nvrtc, "reg", reg, 3);
+ }
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ table = (char *)r3;
+ planetcore_prepare_table(table);
+
+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size))
+ return;
+
+ mem_size *= 1024 * 1024;
+ simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
+
+ ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+
+ planetcore_set_stdout_path(table);
+
+ serial_console_init();
+ platform_ops.fixups = platform_fixups;
+}
Index: linux-work/arch/powerpc/boot/dts/ep405.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/boot/dts/ep405.dts 2007-12-10 15:55:04.000000000 +1100
@@ -0,0 +1,221 @@
+/*
+ * Device Tree Source for EP405
+ *
+ * Copyright 2007 IBM Corp.
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "ep405";
+ compatible = "ep405";
+ dcr-parent = <&/cpus/PowerPC,405GP@0>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,405GP@0 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <bebc200>; /* Filled in by zImage */
+ timebase-frequency = <0>; /* Filled in by zImage */
+ i-cache-line-size = <20>;
+ d-cache-line-size = <20>;
+ i-cache-size = <4000>;
+ d-cache-size = <4000>;
+ dcr-controller;
+ dcr-access-method = "native";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0>; /* Filled in by zImage */
+ };
+
+ UIC0: interrupt-controller {
+ compatible = "ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0c0 9>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ };
+
+ plb {
+ compatible = "ibm,plb3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <0>; /* Filled in by zImage */
+
+ SDRAM0: memory-controller {
+ compatible = "ibm,sdram-405gp";
+ dcr-reg = <010 2>;
+ };
+
+ MAL: mcmal {
+ compatible = "ibm,mcmal-405gp", "ibm,mcmal";
+ dcr-reg = <180 62>;
+ num-tx-chans = <1>;
+ num-rx-chans = <1>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <
+ b 4 /* TXEOB */
+ c 4 /* RXEOB */
+ a 4 /* SERR */
+ d 4 /* TXDE */
+ e 4 /* RXDE */>;
+ };
+
+ POB0: opb {
+ compatible = "ibm,opb-405gp", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <ef600000 ef600000 a00000>;
+ dcr-reg = <0a0 5>;
+ clock-frequency = <0>; /* Filled in by zImage */
+
+ UART0: serial@ef600300 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <ef600300 8>;
+ virtual-reg = <ef600300>;
+ clock-frequency = <0>; /* Filled in by zImage */
+ current-speed = <2580>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
+
+ UART1: serial@ef600400 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <ef600400 8>;
+ virtual-reg = <ef600400>;
+ clock-frequency = <0>; /* Filled in by zImage */
+ current-speed = <2580>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
+
+ IIC: i2c@ef600500 {
+ compatible = "ibm,iic-405gp", "ibm,iic";
+ reg = <ef600500 11>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <2 4>;
+ };
+
+ GPIO: gpio@ef600700 {
+ compatible = "ibm,gpio-405gp";
+ reg = <ef600700 20>;
+ };
+
+ EMAC: ethernet@ef600800 {
+ linux,network-index = <0>;
+ device_type = "network";
+ compatible = "ibm,emac-405gp", "ibm,emac";
+ interrupt-parent = <&UIC0>;
+ interrupts = <
+ f 4 /* Ethernet */
+ 9 4 /* Ethernet Wake Up */>;
+ local-mac-address = [000000000000]; /* Filled in by zImage */
+ reg = <ef600800 70>;
+ mal-device = <&MAL>;
+ mal-tx-channel = <0>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000000>;
+ };
+
+ };
+
+ EBC0: ebc {
+ compatible = "ibm,ebc-405gp", "ibm,ebc";
+ dcr-reg = <012 2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+
+ /* The ranges property is supplied by the bootwrapper
+ * and is based on the firmware's configuration of the
+ * EBC bridge
+ */
+ clock-frequency = <0>; /* Filled in by zImage */
+
+ /* NVRAM and RTC */
+ nvrtc@4,200000 {
+ compatible = "ds1742";
+ reg = <4 200000 0>; /* size fixed up by zImage */
+ };
+
+ /* "BCSR" CPLD contains a PCI irq controller */
+ bcsr@4,0 {
+ compatible = "ep405-bcsr";
+ reg = <4 0 10>;
+ interrupt-controller;
+ /* Routing table */
+ irq-routing = [ 00 /* SYSERR */
+ 01 /* STTM */
+ 01 /* RTC */
+ 01 /* FENET */
+ 02 /* NB PCIIRQ mux ? */
+ 03 /* SB Winbond 8259 ? */
+ 04 /* Serial Ring */
+ 05 /* USB (ep405pc) */
+ 06 /* XIRQ 0 */
+ 06 /* XIRQ 1 */
+ 06 /* XIRQ 2 */
+ 06 /* XIRQ 3 */
+ 06 /* XIRQ 4 */
+ 06 /* XIRQ 5 */
+ 06 /* XIRQ 6 */
+ 07]; /* Reserved */
+ };
+ };
+
+ PCI0: pci@ec000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb405gp-pci", "ibm,plb-pci";
+ primary;
+ reg = <eec00000 8 /* Config space access */
+ eed80000 4 /* IACK */
+ eed80000 4 /* Special cycle */
+ ef480000 40>; /* Internal registers */
+
+ /* Outbound ranges, one memory and one IO,
+ * later cannot be changed. Chip supports a second
+ * IO range but we don't use it for now
+ */
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e8000000 0 00010000>;
+
+ /* Inbound 2GB range starting at 0 */
+ dma-ranges = <42000000 0 0 0 0 80000000>;
+
+ /* That's all I know about IRQs on that thing ... */
+ interrupt-map-mask = <f800 0 0 0>;
+ interrupt-map = <
+ /* USB */
+ 7000 0 0 0 &UIC0 1e 8 /* IRQ5 */
+ >;
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/plb/opb/serial@ef600300";
+ };
+};
Index: linux-work/arch/powerpc/boot/4xx.c
===================================================================
--- linux-work.orig/arch/powerpc/boot/4xx.c 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/boot/4xx.c 2007-12-10 15:54:23.000000000 +1100
@@ -179,13 +179,16 @@ void ibm40x_dbcr_reset(void)
#define EMAC_RESET 0x20000000
void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
{
- /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't do this for us */
+ /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't
+ * do this for us
+ */
if (emac0)
*emac0 = EMAC_RESET;
if (emac1)
*emac1 = EMAC_RESET;
mtdcr(DCRN_MAL0_CFG, MAL_RESET);
+ while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET) {};
}
/* Read 4xx EBC bus bridge registers to get mappings of the peripheral
@@ -298,3 +301,53 @@ void ibm440ep_fixup_clocks(unsigned int
dt_fixup_clock("/plb/opb/serial@ef600500", uart0);
dt_fixup_clock("/plb/opb/serial@ef600600", uart0);
}
+
+void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
+{
+ u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
+ u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
+ u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
+ u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
+ u32 fwdv, fbdv, cbdv, opdv, epdv, udiv;
+
+ fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
+ fbdv = (pllmr & 0x1e000000) >> 25;
+ cbdv = ((pllmr & 0x00060000) >> 17) + 1;
+ opdv = ((pllmr & 0x00018000) >> 15) + 1;
+ epdv = ((pllmr & 0x00001800) >> 13) + 2;
+ udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
+
+ m = fwdv * fbdv * cbdv;
+
+ cpu = sysclk * m / fwdv;
+ plb = cpu / cbdv;
+ opb = plb / opdv;
+ ebc = plb / epdv;
+
+ if (cpc0_cr0 & 0x80) {
+ /* uart0 uses the external clock */
+ uart0 = ser_clk;
+ } else {
+ uart0 = cpu / udiv;
+ }
+
+ if (cpc0_cr0 & 0x40) {
+ /* uart1 uses the external clock */
+ uart1 = ser_clk;
+ } else {
+ uart1 = cpu / udiv;
+ }
+
+ /* setup the timebase clock to tick at the cpu frequency */
+ cpc0_cr1 = cpc0_cr1 & ~0x00800000;
+ mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
+ tb = cpu;
+
+ dt_fixup_cpu_clocks(cpu, tb, 0);
+ dt_fixup_clock("/plb", plb);
+ dt_fixup_clock("/plb/opb", opb);
+ dt_fixup_clock("/plb/ebc", ebc);
+ dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
+ dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
+}
+
Index: linux-work/arch/powerpc/boot/treeboot-walnut.c
===================================================================
--- linux-work.orig/arch/powerpc/boot/treeboot-walnut.c 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/boot/treeboot-walnut.c 2007-12-10 15:54:23.000000000 +1100
@@ -20,55 +20,6 @@
BSS_STACK(4096);
-void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
-{
- u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
- u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
- u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
- u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
- u32 fwdv, fbdv, cbdv, opdv, epdv, udiv;
-
- fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
- fbdv = (pllmr & 0x1e000000) >> 25;
- cbdv = ((pllmr & 0x00060000) >> 17) + 1;
- opdv = ((pllmr & 0x00018000) >> 15) + 1;
- epdv = ((pllmr & 0x00001800) >> 13) + 2;
- udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
-
- m = fwdv * fbdv * cbdv;
-
- cpu = sysclk * m / fwdv;
- plb = cpu / cbdv;
- opb = plb / opdv;
- ebc = plb / epdv;
-
- if (cpc0_cr0 & 0x80) {
- /* uart0 uses the external clock */
- uart0 = ser_clk;
- } else {
- uart0 = cpu / udiv;
- }
-
- if (cpc0_cr0 & 0x40) {
- /* uart1 uses the external clock */
- uart1 = ser_clk;
- } else {
- uart1 = cpu / udiv;
- }
-
- /* setup the timebase clock to tick at the cpu frequency */
- cpc0_cr1 = cpc0_cr1 & ~0x00800000;
- mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
- tb = cpu;
-
- dt_fixup_cpu_clocks(cpu, tb, 0);
- dt_fixup_clock("/plb", plb);
- dt_fixup_clock("/plb/opb", opb);
- dt_fixup_clock("/plb/ebc", ebc);
- dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
- dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
-}
-
static void walnut_flashsel_fixup(void)
{
void *devp, *sram;
Index: linux-work/arch/powerpc/platforms/40x/Kconfig
===================================================================
--- linux-work.orig/arch/powerpc/platforms/40x/Kconfig 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/platforms/40x/Kconfig 2007-12-10 15:54:23.000000000 +1100
@@ -14,20 +14,13 @@
# help
# This option enables support for the CPCI405 board.
-#config EP405
-# bool "EP405/EP405PC"
-# depends on 40x
-# default n
-# select 405GP
-# help
-# This option enables support for the EP405/EP405PC boards.
-
-#config EP405PC
-# bool "EP405PC Support"
-# depends on EP405
-# default y
-# help
-# This option enables support for the extra features of the EP405PC board.
+config EP405
+ bool "EP405/EP405PC"
+ depends on 40x
+ default n
+ select 405GP
+ help
+ This option enables support for the EP405/EP405PC boards.
config KILAUEA
bool "Kilauea"
Index: linux-work/arch/powerpc/platforms/40x/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/platforms/40x/Makefile 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/platforms/40x/Makefile 2007-12-10 15:54:23.000000000 +1100
@@ -1,3 +1,4 @@
obj-$(CONFIG_KILAUEA) += kilauea.o
obj-$(CONFIG_WALNUT) += walnut.o
obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o
+obj-$(CONFIG_EP405) += ep405.o
Index: linux-work/arch/powerpc/platforms/40x/ep405.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/platforms/40x/ep405.c 2007-12-10 15:55:38.000000000 +1100
@@ -0,0 +1,124 @@
+/*
+ * Architecture- / platform-specific boot-time initialization code for
+ * IBM PowerPC 4xx based boards. Adapted from original
+ * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ * <dan@net4x.com>.
+ *
+ * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 IBM Corporation
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * Adapted to EP405 by Ben. Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * TODO: Wire up the PCI IRQ mux and the southbridge interrupts
+ *
+ * 2002 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/pci-bridge.h>
+
+static struct device_node *bcsr_node;
+static void __iomem *bcsr_regs;
+
+/* BCSR registers */
+#define BCSR_ID 0
+#define BCSR_PCI_CTRL 1
+#define BCSR_FLASH_NV_POR_CTRL 2
+#define BCSR_FENET_UART_CTRL 3
+#define BCSR_PCI_IRQ 4
+#define BCSR_XIRQ_SELECT 5
+#define BCSR_XIRQ_ROUTING 6
+#define BCSR_XIRQ_STATUS 7
+#define BCSR_XIRQ_STATUS2 8
+#define BCSR_SW_STAT_LED_CTRL 9
+#define BCSR_GPIO_IRQ_PAR_CTRL 10
+/* there's more, can't be bothered typing them tho */
+
+
+static struct of_device_id ep405_of_bus[] = {
+ { .compatible = "ibm,plb3", },
+ { .compatible = "ibm,opb", },
+ { .compatible = "ibm,ebc", },
+ {},
+};
+
+static int __init ep405_device_probe(void)
+{
+ if (!machine_is(ep405))
+ return 0;
+
+ of_platform_bus_probe(NULL, ep405_of_bus, NULL);
+
+ return 0;
+}
+device_initcall(ep405_device_probe);
+
+static void __init ep405_init_bcsr(void)
+{
+ const u8 *irq_routing;
+ int i;
+
+ /* Find the bloody thing & map it */
+ bcsr_node = of_find_compatible_node(NULL, NULL, "ep405-bcsr");
+ if (bcsr_node == NULL) {
+ printk(KERN_ERR "EP405 BCSR not found !\n");
+ return;
+ }
+ bcsr_regs = of_iomap(bcsr_node, 0);
+ if (bcsr_regs == NULL) {
+ printk(KERN_ERR "EP405 BCSR failed to map !\n");
+ return;
+ }
+
+ /* Get the irq-routing property and apply the routing to the CPLD */
+ irq_routing = of_get_property(bcsr_node, "irq-routing", NULL);
+ if (irq_routing == NULL)
+ return;
+ for (i = 0; i < 16; i++) {
+ u8 irq = irq_routing[i];
+ out_8(bcsr_regs + BCSR_XIRQ_SELECT, i);
+ out_8(bcsr_regs + BCSR_XIRQ_ROUTING, irq);
+ }
+ in_8(bcsr_regs + BCSR_XIRQ_SELECT);
+ mb();
+ out_8(bcsr_regs + BCSR_GPIO_IRQ_PAR_CTRL, 0xfe);
+}
+
+static void __init ep405_setup_arch(void)
+{
+ /* Find & init the BCSR CPLD */
+ ep405_init_bcsr();
+}
+
+static int __init ep405_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ep405"))
+ return 0;
+
+ return 1;
+}
+
+define_machine(ep405) {
+ .name = "EP405",
+ .probe = ep405_probe,
+ .setup_arch = ep405_setup_arch,
+ .progress = udbg_progress,
+ .init_IRQ = uic_init_tree,
+ .get_irq = uic_get_irq,
+ .calibrate_decr = generic_calibrate_decr,
+};
Index: linux-work/arch/powerpc/boot/4xx.h
===================================================================
--- linux-work.orig/arch/powerpc/boot/4xx.h 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/boot/4xx.h 2007-12-10 15:54:23.000000000 +1100
@@ -18,5 +18,6 @@ void ibm40x_dbcr_reset(void);
void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1);
void ibm4xx_fixup_ebc_ranges(const char *ebc);
void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk);
+void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk);
#endif /* _POWERPC_BOOT_4XX_H_ */
Index: linux-work/arch/powerpc/boot/wrapper
===================================================================
--- linux-work.orig/arch/powerpc/boot/wrapper 2007-12-10 15:52:04.000000000 +1100
+++ linux-work/arch/powerpc/boot/wrapper 2007-12-10 15:54:23.000000000 +1100
@@ -163,7 +163,7 @@ ps3)
ksection=.kernel:vmlinux.bin
isection=.kernel:initrd
;;
-ep88xc)
+ep88xc|ep405)
platformo="$object/fixed-head.o $object/$platform.o"
binary=y
;;
Index: linux-work/arch/powerpc/configs/ep405_defconfig
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/configs/ep405_defconfig 2007-12-10 15:54:23.000000000 +1100
@@ -0,0 +1,951 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24-rc2
+# Wed Nov 21 16:44:30 2007
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_EP405=y
+# CONFIG_KILAUEA is not set
+# CONFIG_WALNUT is not set
+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
+CONFIG_405GP=y
+CONFIG_IBM405_ERR77=y
+CONFIG_IBM405_ERR51=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPM2 is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_MATH_EMULATION is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_HIBERNATION_UP_POSSIBLE=y
+CONFIG_SECCOMP=y
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="ep405.dts"
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
^ permalink raw reply
* Re: [PATCH] Fix rounding bug in emulation for double float operating
From: David Gibson @ 2007-12-10 4:56 UTC (permalink / raw)
To: Liu Yu; +Cc: linuxppc-dev
In-Reply-To: <11972628522442-git-send-email-b13201@freescale.com>
On Mon, Dec 10, 2007 at 01:00:52PM +0800, Liu Yu wrote:
>
> This patch fixes rounding bug in emulation for double float operating on PowerPC platform.
>
> When pack double float operand, it need to truncate the tail due to the limited precision.
> If the truncated part is not zero, the last bit of work bit (totally 3 bits) need to '|' 1.
>
> This patch is completed in _FP_FRAC_SRS_2(X,N,sz) (arch/powerpc/math-emu/op-2.h).
> Originally the code leftwards rotates the operand to just keep the truncated part,
> then check whether it is zero. However, the number it rotates is not correct when
> N is not smaller than _FP_W_TYPE_SIZE, and it will cause the work bit '|' 1 in the improper case.
>
> This patch fixes this issue.
>
> Signed-off-by: Liu Yu <b13201@freescale.com>
Wow someone deciphered the hideous macro hell of the math emulation
code enough to fix a bug. I don't suppose you'd care to fix the
millions of warnings that the math-emu code generates...?
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 8/25] powerpc: Improve support for 4xx indirect DCRs
From: Benjamin Herrenschmidt @ 2007-12-10 4:54 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071206201913.498185e6@zod.rchland.ibm.com>
powerpc: Improve support for 4xx indirect DCRs
Accessing indirect DCRs is done via a pair of address/data DCRs.
Such accesses are thus inherently racy, vs. interrupts, preemption
and possibly SMP if 4xx SMP cores are ever used.
This updates the mfdcri/mtdcri macros in dcr-native.h (which were
so far unused) to use a spinlock.
In addition, add some common definitions to a new dcr-regs.h file.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Index: linux-work/include/asm-powerpc/dcr-native.h
===================================================================
--- linux-work.orig/include/asm-powerpc/dcr-native.h 2007-12-10 15:52:26.000000000 +1100
+++ linux-work/include/asm-powerpc/dcr-native.h 2007-12-10 15:53:36.000000000 +1100
@@ -22,6 +22,8 @@
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
+#include <linux/spinlock.h>
+
typedef struct {
unsigned int base;
} dcr_host_t;
@@ -55,20 +57,28 @@ do { \
} while (0)
/* R/W of indirect DCRs make use of standard naming conventions for DCRs */
-#define mfdcri(base, reg) \
-({ \
- mtdcr(base ## _CFGADDR, base ## _ ## reg); \
- mfdcr(base ## _CFGDATA); \
+extern spinlock_t dcr_ind_lock;
+
+#define mfdcri(base, reg) \
+({ \
+ unsigned long flags; \
+ unsigned int val; \
+ spin_lock_irqsave(&dcr_ind_lock, flags); \
+ mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \
+ val = mfdcr(DCRN_ ## base ## _CONFIG_DATA); \
+ spin_unlock_irqrestore(&dcr_ind_lock, flags); \
+ val; \
})
-#define mtdcri(base, reg, data) \
-do { \
- mtdcr(base ## _CFGADDR, base ## _ ## reg); \
- mtdcr(base ## _CFGDATA, data); \
+#define mtdcri(base, reg, data) \
+do { \
+ unsigned long flags; \
+ spin_lock_irqsave(&dcr_ind_lock, flags); \
+ mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \
+ mtdcr(DCRN_ ## base ## _CONFIG_DATA, data); \
+ spin_unlock_irqrestore(&dcr_ind_lock, flags); \
} while (0)
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_DCR_NATIVE_H */
-
-
Index: linux-work/include/asm-powerpc/dcr-regs.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/include/asm-powerpc/dcr-regs.h 2007-12-10 15:53:33.000000000 +1100
@@ -0,0 +1,71 @@
+/*
+ * Common DCR / SDR / CPR register definitions used on various IBM/AMCC
+ * 4xx processors
+ *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp
+ * <benh@kernel.crashing.org>
+ *
+ * Mostly lifted from asm-ppc/ibm4xx.h by
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ */
+
+#ifndef __DCR_REGS_H__
+#define __DCR_REGS_H__
+
+/*
+ * Most DCRs used for controlling devices such as the MAL, DMA engine,
+ * etc... are obtained for the device tree.
+ *
+ * The definitions in this files are fixed DCRs and indirect DCRs that
+ * are commonly used outside of specific drivers or refer to core
+ * common registers that may occasionally have to be tweaked outside
+ * of the driver main register set
+ */
+
+/* CPRs (440GX and 440SP/440SPe) */
+#define DCRN_CPR0_CONFIG_ADDR 0xc
+#define DCRN_CPR0_CONFIG_DATA 0xd
+
+/* SDRs (440GX and 440SP/440SPe) */
+#define DCRN_SDR0_CONFIG_ADDR 0xe
+#define DCRN_SDR0_CONFIG_DATA 0xf
+
+#define SDR0_PFC0 0x4100
+#define SDR0_PFC1 0x4101
+#define SDR0_PFC1_EPS 0x1c00000
+#define SDR0_PFC1_EPS_SHIFT 22
+#define SDR0_PFC1_RMII 0x02000000
+#define SDR0_MFR 0x4300
+#define SDR0_MFR_TAH0 0x80000000 /* TAHOE0 Enable */
+#define SDR0_MFR_TAH1 0x40000000 /* TAHOE1 Enable */
+#define SDR0_MFR_PCM 0x10000000 /* PPC440GP irq compat mode */
+#define SDR0_MFR_ECS 0x08000000 /* EMAC int clk */
+#define SDR0_MFR_T0TXFL 0x00080000
+#define SDR0_MFR_T0TXFH 0x00040000
+#define SDR0_MFR_T1TXFL 0x00020000
+#define SDR0_MFR_T1TXFH 0x00010000
+#define SDR0_MFR_E0TXFL 0x00008000
+#define SDR0_MFR_E0TXFH 0x00004000
+#define SDR0_MFR_E0RXFL 0x00002000
+#define SDR0_MFR_E0RXFH 0x00001000
+#define SDR0_MFR_E1TXFL 0x00000800
+#define SDR0_MFR_E1TXFH 0x00000400
+#define SDR0_MFR_E1RXFL 0x00000200
+#define SDR0_MFR_E1RXFH 0x00000100
+#define SDR0_MFR_E2TXFL 0x00000080
+#define SDR0_MFR_E2TXFH 0x00000040
+#define SDR0_MFR_E2RXFL 0x00000020
+#define SDR0_MFR_E2RXFH 0x00000010
+#define SDR0_MFR_E3TXFL 0x00000008
+#define SDR0_MFR_E3TXFH 0x00000004
+#define SDR0_MFR_E3RXFL 0x00000002
+#define SDR0_MFR_E3RXFH 0x00000001
+#define SDR0_UART0 0x0120
+#define SDR0_UART1 0x0121
+#define SDR0_UART2 0x0122
+#define SDR0_UART3 0x0123
+#define SDR0_CUST0 0x4000
+
+#endif /* __DCR_REGS_H__ */
^ permalink raw reply
* [PATCH] Fix rounding bug in emulation for double float operating
From: Liu Yu @ 2007-12-10 5:00 UTC (permalink / raw)
To: linuxppc-dev
This patch fixes rounding bug in emulation for double float operating on PowerPC platform.
When pack double float operand, it need to truncate the tail due to the limited precision.
If the truncated part is not zero, the last bit of work bit (totally 3 bits) need to '|' 1.
This patch is completed in _FP_FRAC_SRS_2(X,N,sz) (arch/powerpc/math-emu/op-2.h).
Originally the code leftwards rotates the operand to just keep the truncated part,
then check whether it is zero. However, the number it rotates is not correct when
N is not smaller than _FP_W_TYPE_SIZE, and it will cause the work bit '|' 1 in the improper case.
This patch fixes this issue.
Signed-off-by: Liu Yu <b13201@freescale.com>
---
arch/powerpc/math-emu/op-2.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/math-emu/op-2.h b/arch/powerpc/math-emu/op-2.h
index b9b06b4..7d6f17c 100644
--- a/arch/powerpc/math-emu/op-2.h
+++ b/arch/powerpc/math-emu/op-2.h
@@ -59,7 +59,8 @@
else \
{ \
X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \
- (((X##_f1 << (sz - (N))) | X##_f0) != 0)); \
+ (((X##_f1 << (2 * _FP_W_TYPE_SIZE - (N))) | \
+ X##_f0) != 0)); \
X##_f1 = 0; \
} \
} while (0)
--
1.5.2
^ permalink raw reply related
* [PATCH 19/19] [POWERPC] pci_controller->arch_data really is a struct device_node *
From: Stephen Rothwell @ 2007-12-10 3:33 UTC (permalink / raw)
To: benh; +Cc: ppc-dev
In-Reply-To: <1197185271.6572.41.camel@pasglop>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
This version also renames the arch_data field to dn.
arch/powerpc/kernel/isa-bridge.c | 2 +-
arch/powerpc/kernel/pci-common.c | 4 ++--
arch/powerpc/kernel/pci_32.c | 10 +++++-----
arch/powerpc/kernel/pci_64.c | 8 +++-----
arch/powerpc/kernel/pci_dn.c | 2 +-
arch/powerpc/kernel/prom_parse.c | 2 +-
arch/powerpc/kernel/rtas_pci.c | 2 +-
arch/powerpc/platforms/82xx/pq2.c | 2 +-
arch/powerpc/platforms/85xx/mpc85xx_ds.c | 2 +-
arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 2 +-
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 2 +-
arch/powerpc/platforms/cell/io-workarounds.c | 4 ++--
arch/powerpc/platforms/celleb/io-workarounds.c | 4 ++--
arch/powerpc/platforms/celleb/pci.c | 2 +-
arch/powerpc/platforms/maple/pci.c | 2 +-
arch/powerpc/platforms/powermac/pci.c | 6 +++---
arch/powerpc/platforms/pseries/iommu.c | 2 +-
include/asm-powerpc/pci-bridge.h | 5 +++--
18 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
index 965bfcc..ee172aa 100644
--- a/arch/powerpc/kernel/isa-bridge.c
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -145,7 +145,7 @@ void __init isa_bridge_find_early(struct pci_controller *hose)
for_each_node_by_type(np, "isa") {
/* Look for our hose being a parent */
for (parent = of_get_parent(np); parent;) {
- if (parent == hose->arch_data) {
+ if (parent == hose->dn) {
of_node_put(parent);
break;
}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index e0d4a2a..8f80591 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -65,7 +65,7 @@ struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
phb->global_number = global_phb_number++;
list_add_tail(&phb->list_node, &hose_list);
spin_unlock(&hose_spinlock);
- phb->arch_data = dev;
+ phb->dn = dev;
phb->is_dynamic = mem_init_done;
#ifdef CONFIG_PPC64
if (dev) {
@@ -140,7 +140,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
while(node) {
struct pci_controller *hose, *tmp;
list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
- if (hose->arch_data == node)
+ if (hose->dn == node)
return hose;
node = node->parent;
}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index e1151b5..20a1192 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -661,8 +661,8 @@ pcibios_make_OF_bus_map(void)
/* For each hose, we begin searching bridges */
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- struct device_node* node;
- node = (struct device_node *)hose->arch_data;
+ struct device_node* node = hose->dn;
+
if (!node)
continue;
make_one_node_map(node, hose->first_busno);
@@ -741,7 +741,7 @@ static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
struct pci_controller *hose = pci_bus_to_host(bus);
if (hose == NULL)
return NULL;
- return of_node_get(hose->arch_data);
+ return of_node_get(hose->dn);
}
/* not a root bus, we need to get our parent */
@@ -811,9 +811,9 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
return -ENODEV;
/* Make sure it's really a PCI device */
hose = pci_find_hose_for_OF_device(node);
- if (!hose || !hose->arch_data)
+ if (!hose || !hose->dn)
return -ENODEV;
- if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
+ if (!scan_OF_pci_childs(hose->dn->child,
find_OF_pci_device_filter, (void *)node))
return -ENODEV;
reg = of_get_property(node, "reg", NULL);
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index acf1219..bf06926 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -458,7 +458,7 @@ EXPORT_SYMBOL(of_scan_pci_bridge);
void __devinit scan_phb(struct pci_controller *hose)
{
struct pci_bus *bus;
- struct device_node *node = hose->arch_data;
+ struct device_node *node = hose->dn;
int i, mode;
struct resource *res;
@@ -612,8 +612,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
if (hose->io_base_alloc == 0)
return 0;
- DBG("IO unmapping for PHB %s\n",
- ((struct device_node *)hose->arch_data)->full_name);
+ DBG("IO unmapping for PHB %s\n", hose->dn->full_name);
DBG(" alloc=0x%p\n", hose->io_base_alloc);
/* This is a PHB, we fully unmap the IO area */
@@ -672,8 +671,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
hose->io_base_virt = (void __iomem *)(area->addr +
hose->io_base_phys - phys_page);
- DBG("IO mapping for PHB %s\n",
- ((struct device_node *)hose->arch_data)->full_name);
+ DBG("IO mapping for PHB %s\n", hose->dn->full_name);
DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
DBG(" size=0x%016lx (alloc=0x%016lx)\n",
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index b483903..85d4d89 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -133,7 +133,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
*/
void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
{
- struct device_node * dn = (struct device_node *) phb->arch_data;
+ struct device_node *dn = phb->dn;
struct pci_dn *pdn;
/* PHB nodes themselves must not match */
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index b5c96af..6bdfaf3 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -273,7 +273,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
#else
struct pci_controller *host;
host = pci_bus_to_host(pdev->bus);
- ppnode = host ? host->arch_data : NULL;
+ ppnode = host ? host->dn : NULL;
#endif
/* No node for host bridge ? give up */
if (ppnode == NULL)
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 21f14e5..3650eb5 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -260,7 +260,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
int __devinit rtas_setup_phb(struct pci_controller *phb)
{
- struct device_node *dev = phb->arch_data;
+ struct device_node *dev = phb->dn;
if (is_python(dev))
python_countermeasures(dev);
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
index a497cba..11d1db8 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -59,7 +59,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
if (!hose)
return;
- hose->arch_data = np;
+ hose->dn = np;
setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0);
pci_process_bridge_OF_ranges(hose, np, 1);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 59c121a..bdb3d0b 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -123,7 +123,7 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
struct device_node* node;
struct resource rsrc;
- node = (struct device_node *)hose->arch_data;
+ node = hose->dn;
of_address_to_resource(node, 0, &rsrc);
if ((rsrc.start & 0xfffff) == primary_phb_addr) {
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 6390895..c6d2f48 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -124,7 +124,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
static void __devinit final_uli5288(struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
- struct device_node *hosenode = hose ? hose->arch_data : NULL;
+ struct device_node *hosenode = hose ? hose->dn : NULL;
struct of_irq oirq;
int virq, pin = 2;
u32 laddr[3];
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 32a531a..14f4e52 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -116,7 +116,7 @@ static int mpc86xx_exclude_device(struct pci_controller *hose,
struct device_node* node;
struct resource rsrc;
- node = (struct device_node *)hose->arch_data;
+ node = hose->dn;
of_address_to_resource(node, 0, &rsrc);
if ((rsrc.start & 0xfffff) == 0x8000) {
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 9d7c2ef..b86076e 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -238,7 +238,7 @@ static void __init spider_pci_setup_chip(struct spider_pci_bus *bus)
static void __init spider_pci_add_one(struct pci_controller *phb)
{
struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count];
- struct device_node *np = phb->arch_data;
+ struct device_node *np = phb->dn;
struct resource rsrc;
void __iomem *regs;
@@ -317,7 +317,7 @@ static int __init spider_pci_workaround_init(void)
* update this code to cope with dynamically added busses
*/
list_for_each_entry(phb, &hose_list, list_node) {
- struct device_node *np = phb->arch_data;
+ struct device_node *np = phb->dn;
const char *model = of_get_property(np, "model", NULL);
/* If no model property or name isn't exactly "pci", skip */
diff --git a/arch/powerpc/platforms/celleb/io-workarounds.c b/arch/powerpc/platforms/celleb/io-workarounds.c
index 32b9cec..b939c0e 100644
--- a/arch/powerpc/platforms/celleb/io-workarounds.c
+++ b/arch/powerpc/platforms/celleb/io-workarounds.c
@@ -222,7 +222,7 @@ void __init celleb_pci_add_one(struct pci_controller *phb,
void (*dummy_read)(struct pci_controller *))
{
struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
- struct device_node *np = phb->arch_data;
+ struct device_node *np = phb->dn;
if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
printk(KERN_ERR "Too many pci bridges, workarounds"
@@ -262,7 +262,7 @@ int __init celleb_pci_workaround_init(void)
}
list_for_each_entry(phb, &hose_list, list_node) {
- node = phb->arch_data;
+ node = phb->dn;
match = of_match_node(celleb_pci_workaround_match, node);
if (match) {
diff --git a/arch/powerpc/platforms/celleb/pci.c b/arch/powerpc/platforms/celleb/pci.c
index 13ec4a6..5d399e0 100644
--- a/arch/powerpc/platforms/celleb/pci.c
+++ b/arch/powerpc/platforms/celleb/pci.c
@@ -480,7 +480,7 @@ static struct of_device_id celleb_phb_match[] __initdata = {
int __init celleb_setup_phb(struct pci_controller *phb)
{
- struct device_node *dev = phb->arch_data;
+ struct device_node *dev = phb->dn;
const struct of_device_id *match;
int (*setup_func)(struct device_node *, struct pci_controller *);
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 771ed0c..3ffa0ac 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -558,7 +558,7 @@ void __init maple_pci_init(void)
* safe assumptions hopefully.
*/
if (u3_agp) {
- struct device_node *np = u3_agp->arch_data;
+ struct device_node *np = u3_agp->dn;
PCI_DN(np)->busno = 0xf0;
for (np = np->child; np; np = np->sibling)
PCI_DN(np)->busno = 0xf0;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index ec49099..778c249 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -319,7 +319,7 @@ static int u3_ht_skip_device(struct pci_controller *hose,
if (bus->self)
busdn = pci_device_to_OF_node(bus->self);
else
- busdn = hose->arch_data;
+ busdn = hose->dn;
for (dn = busdn->child; dn; dn = dn->sibling)
if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn)
break;
@@ -778,7 +778,7 @@ static void __init setup_u4_pcie(struct pci_controller* hose)
static void __init setup_u3_ht(struct pci_controller* hose)
{
- struct device_node *np = (struct device_node *)hose->arch_data;
+ struct device_node *np = hose->dn;
struct pci_controller *other = NULL;
int i, cur;
@@ -1032,7 +1032,7 @@ void __init pmac_pci_init(void)
* future though
*/
if (u3_agp) {
- struct device_node *np = u3_agp->arch_data;
+ struct device_node *np = u3_agp->dn;
PCI_DN(np)->busno = 0xf0;
for (np = np->child; np; np = np->sibling)
PCI_DN(np)->busno = 0xf0;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index ebb9313..a65c763 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -251,7 +251,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
const unsigned long *basep;
const u32 *sizep;
- node = (struct device_node *)phb->arch_data;
+ node = phb->dn;
basep = of_get_property(node, "linux,tce-base", NULL);
sizep = of_get_property(node, "linux,tce-size", NULL);
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index beb09b5..6b81e22 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -11,6 +11,8 @@
#include <linux/list.h>
#include <linux/ioport.h>
+struct device_node;
+
/*
* Structure of a PCI controller (host bridge)
*/
@@ -20,7 +22,7 @@ struct pci_controller {
#ifdef CONFIG_PPC64
int node;
#endif
- void *arch_data;
+ struct device_node *dn;
struct list_head list_node;
struct device *parent;
@@ -130,7 +132,6 @@ extern void __init update_bridge_resource(struct pci_dev *dev,
* by device_node->data.
*/
struct iommu_table;
-struct device_node;
struct pci_dn {
int busno; /* pci bus number */
--
1.5.3.7
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply related
* [PATCH 3/3] Kill flatdevtree.c
From: David Gibson @ 2007-12-10 3:28 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <20071210032343.GB29611@localhost.localdomain>
Now that earlier patches have switched the bootwrapper to using libfdt
for device tree manipulation, this patch removes the now unused
flatdevtree.c and related files.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
arch/powerpc/boot/Makefile | 2
arch/powerpc/boot/flatdevtree.c | 1036 -----------------------------------
arch/powerpc/boot/flatdevtree.h | 113 ---
arch/powerpc/boot/flatdevtree_misc.c | 79 --
arch/powerpc/boot/main.c | 1
arch/powerpc/boot/ops.h | 1
6 files changed, 1 insertion(+), 1231 deletions(-)
Index: working-2.6/arch/powerpc/boot/Makefile
===================================================================
--- working-2.6.orig/arch/powerpc/boot/Makefile 2007-12-10 13:24:45.000000000 +1100
+++ working-2.6/arch/powerpc/boot/Makefile 2007-12-10 13:26:57.000000000 +1100
@@ -47,7 +47,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
-src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
+src-wlib := string.S crt0.S stdio.c main.c \
$(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
Index: working-2.6/arch/powerpc/boot/flatdevtree.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/flatdevtree.c 2007-10-22 13:55:50.000000000 +1000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,1036 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright Pantelis Antoniou 2006
- * Copyright (C) IBM Corporation 2006
- *
- * Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
- * Hollis Blanchard <hollisb@us.ibm.com>
- * Mark A. Greer <mgreer@mvista.com>
- * Paul Mackerras <paulus@samba.org>
- */
-
-#include <string.h>
-#include <stddef.h>
-#include "flatdevtree.h"
-#include "flatdevtree_env.h"
-
-#define _ALIGN(x, al) (((x) + (al) - 1) & ~((al) - 1))
-
-static char *ft_root_node(struct ft_cxt *cxt)
-{
- return cxt->rgn[FT_STRUCT].start;
-}
-
-/* Routines for keeping node ptrs returned by ft_find_device current */
-/* First entry not used b/c it would return 0 and be taken as NULL/error */
-static void *ft_get_phandle(struct ft_cxt *cxt, char *node)
-{
- unsigned int i;
-
- if (!node)
- return NULL;
-
- for (i = 1; i < cxt->nodes_used; i++) /* already there? */
- if (cxt->node_tbl[i] == node)
- return (void *)i;
-
- if (cxt->nodes_used < cxt->node_max) {
- cxt->node_tbl[cxt->nodes_used] = node;
- return (void *)cxt->nodes_used++;
- }
-
- return NULL;
-}
-
-static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle)
-{
- unsigned int i = (unsigned int)phandle;
-
- if (i < cxt->nodes_used)
- return cxt->node_tbl[i];
- return NULL;
-}
-
-static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift)
-{
- unsigned int i;
-
- if (shift == 0)
- return;
-
- for (i = 1; i < cxt->nodes_used; i++)
- if (cxt->node_tbl[i] < addr)
- cxt->node_tbl[i] += shift;
-}
-
-static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift)
-{
- unsigned int i;
-
- if (shift == 0)
- return;
-
- for (i = 1; i < cxt->nodes_used; i++)
- if (cxt->node_tbl[i] >= addr)
- cxt->node_tbl[i] += shift;
-}
-
-/* Struct used to return info from ft_next() */
-struct ft_atom {
- u32 tag;
- const char *name;
- void *data;
- u32 size;
-};
-
-/* Set ptrs to current one's info; return addr of next one */
-static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret)
-{
- u32 sz;
-
- if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size)
- return NULL;
-
- ret->tag = be32_to_cpu(*(u32 *) p);
- p += 4;
-
- switch (ret->tag) { /* Tag */
- case OF_DT_BEGIN_NODE:
- ret->name = p;
- ret->data = (void *)(p - 4); /* start of node */
- p += _ALIGN(strlen(p) + 1, 4);
- break;
- case OF_DT_PROP:
- ret->size = sz = be32_to_cpu(*(u32 *) p);
- ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4));
- ret->data = (void *)(p + 8);
- p += 8 + _ALIGN(sz, 4);
- break;
- case OF_DT_END_NODE:
- case OF_DT_NOP:
- break;
- case OF_DT_END:
- default:
- p = NULL;
- break;
- }
-
- return p;
-}
-
-#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8)
-#define EXPAND_INCR 1024 /* alloc this much extra when expanding */
-
-/* Copy the tree to a newly-allocated region and put things in order */
-static int ft_reorder(struct ft_cxt *cxt, int nextra)
-{
- unsigned long tot;
- enum ft_rgn_id r;
- char *p, *pend;
- int stroff;
-
- tot = HDR_SIZE + EXPAND_INCR;
- for (r = FT_RSVMAP; r <= FT_STRINGS; ++r)
- tot += cxt->rgn[r].size;
- if (nextra > 0)
- tot += nextra;
- tot = _ALIGN(tot, 8);
-
- if (!cxt->realloc)
- return 0;
- p = cxt->realloc(NULL, tot);
- if (!p)
- return 0;
-
- memcpy(p, cxt->bph, sizeof(struct boot_param_header));
- /* offsets get fixed up later */
-
- cxt->bph = (struct boot_param_header *)p;
- cxt->max_size = tot;
- pend = p + tot;
- p += HDR_SIZE;
-
- memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size);
- cxt->rgn[FT_RSVMAP].start = p;
- p += cxt->rgn[FT_RSVMAP].size;
-
- memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size);
- ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
- p - cxt->rgn[FT_STRUCT].start);
- cxt->p += p - cxt->rgn[FT_STRUCT].start;
- cxt->rgn[FT_STRUCT].start = p;
-
- p = pend - cxt->rgn[FT_STRINGS].size;
- memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size);
- stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start;
- cxt->rgn[FT_STRINGS].start = p;
- cxt->str_anchor = p + stroff;
-
- cxt->isordered = 1;
- return 1;
-}
-
-static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r)
-{
- if (r > FT_RSVMAP)
- return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size;
- return (char *)cxt->bph + HDR_SIZE;
-}
-
-static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r)
-{
- if (r < FT_STRINGS)
- return cxt->rgn[r + 1].start;
- return (char *)cxt->bph + cxt->max_size;
-}
-
-/*
- * See if we can expand region rgn by nextra bytes by using up
- * free space after or before the region.
- */
-static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
- int nextra)
-{
- char *p = *pp;
- char *rgn_start, *rgn_end;
-
- rgn_start = cxt->rgn[rgn].start;
- rgn_end = rgn_start + cxt->rgn[rgn].size;
- if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) {
- /* move following stuff */
- if (p < rgn_end) {
- if (nextra < 0)
- memmove(p, p - nextra, rgn_end - p + nextra);
- else
- memmove(p + nextra, p, rgn_end - p);
- if (rgn == FT_STRUCT)
- ft_node_update_after(cxt, p, nextra);
- }
- cxt->rgn[rgn].size += nextra;
- if (rgn == FT_STRINGS)
- /* assumes strings only added at beginning */
- cxt->str_anchor += nextra;
- return 1;
- }
- if (prev_end(cxt, rgn) <= rgn_start - nextra) {
- /* move preceding stuff */
- if (p > rgn_start) {
- memmove(rgn_start - nextra, rgn_start, p - rgn_start);
- if (rgn == FT_STRUCT)
- ft_node_update_before(cxt, p, -nextra);
- }
- *pp -= nextra;
- cxt->rgn[rgn].start -= nextra;
- cxt->rgn[rgn].size += nextra;
- return 1;
- }
- return 0;
-}
-
-static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
- int nextra)
-{
- unsigned long size, ssize, tot;
- char *str, *next;
- enum ft_rgn_id r;
-
- if (!cxt->isordered) {
- unsigned long rgn_off = *pp - cxt->rgn[rgn].start;
-
- if (!ft_reorder(cxt, nextra))
- return 0;
-
- *pp = cxt->rgn[rgn].start + rgn_off;
- }
- if (ft_shuffle(cxt, pp, rgn, nextra))
- return 1;
-
- /* See if there is space after the strings section */
- ssize = cxt->rgn[FT_STRINGS].size;
- if (cxt->rgn[FT_STRINGS].start + ssize
- < (char *)cxt->bph + cxt->max_size) {
- /* move strings up as far as possible */
- str = (char *)cxt->bph + cxt->max_size - ssize;
- cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
- memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
- cxt->rgn[FT_STRINGS].start = str;
- /* enough space now? */
- if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra))
- return 1;
- }
-
- /* how much total free space is there following this region? */
- tot = 0;
- for (r = rgn; r < FT_STRINGS; ++r) {
- char *r_end = cxt->rgn[r].start + cxt->rgn[r].size;
- tot += next_start(cxt, rgn) - r_end;
- }
-
- /* cast is to shut gcc up; we know nextra >= 0 */
- if (tot < (unsigned int)nextra) {
- /* have to reallocate */
- char *newp, *new_start;
- int shift;
-
- if (!cxt->realloc)
- return 0;
- size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8);
- newp = cxt->realloc(cxt->bph, size);
- if (!newp)
- return 0;
- cxt->max_size = size;
- shift = newp - (char *)cxt->bph;
-
- if (shift) { /* realloc can return same addr */
- cxt->bph = (struct boot_param_header *)newp;
- ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
- shift);
- for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
- new_start = cxt->rgn[r].start + shift;
- cxt->rgn[r].start = new_start;
- }
- *pp += shift;
- cxt->str_anchor += shift;
- }
-
- /* move strings up to the end */
- str = newp + size - ssize;
- cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
- memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
- cxt->rgn[FT_STRINGS].start = str;
-
- if (ft_shuffle(cxt, pp, rgn, nextra))
- return 1;
- }
-
- /* must be FT_RSVMAP and we need to move FT_STRUCT up */
- if (rgn == FT_RSVMAP) {
- next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
- + nextra;
- ssize = cxt->rgn[FT_STRUCT].size;
- if (next + ssize >= cxt->rgn[FT_STRINGS].start)
- return 0; /* "can't happen" */
- memmove(next, cxt->rgn[FT_STRUCT].start, ssize);
- ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra);
- cxt->rgn[FT_STRUCT].start = next;
-
- if (ft_shuffle(cxt, pp, rgn, nextra))
- return 1;
- }
-
- return 0; /* "can't happen" */
-}
-
-static void ft_put_word(struct ft_cxt *cxt, u32 v)
-{
- *(u32 *) cxt->p = cpu_to_be32(v);
- cxt->p += 4;
-}
-
-static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz)
-{
- unsigned long sza = _ALIGN(sz, 4);
-
- /* zero out the alignment gap if necessary */
- if (sz < sza)
- *(u32 *) (cxt->p + sza - 4) = 0;
-
- /* copy in the data */
- memcpy(cxt->p, data, sz);
-
- cxt->p += sza;
-}
-
-char *ft_begin_node(struct ft_cxt *cxt, const char *name)
-{
- unsigned long nlen = strlen(name) + 1;
- unsigned long len = 8 + _ALIGN(nlen, 4);
- char *ret;
-
- if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
- return NULL;
-
- ret = cxt->p;
-
- ft_put_word(cxt, OF_DT_BEGIN_NODE);
- ft_put_bin(cxt, name, strlen(name) + 1);
-
- return ret;
-}
-
-void ft_end_node(struct ft_cxt *cxt)
-{
- ft_put_word(cxt, OF_DT_END_NODE);
-}
-
-void ft_nop(struct ft_cxt *cxt)
-{
- if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4))
- ft_put_word(cxt, OF_DT_NOP);
-}
-
-#define NO_STRING 0x7fffffff
-
-static int lookup_string(struct ft_cxt *cxt, const char *name)
-{
- char *p, *end;
-
- p = cxt->rgn[FT_STRINGS].start;
- end = p + cxt->rgn[FT_STRINGS].size;
- while (p < end) {
- if (strcmp(p, (char *)name) == 0)
- return p - cxt->str_anchor;
- p += strlen(p) + 1;
- }
-
- return NO_STRING;
-}
-
-/* lookup string and insert if not found */
-static int map_string(struct ft_cxt *cxt, const char *name)
-{
- int off;
- char *p;
-
- off = lookup_string(cxt, name);
- if (off != NO_STRING)
- return off;
- p = cxt->rgn[FT_STRINGS].start;
- if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1))
- return NO_STRING;
- strcpy(p, name);
- return p - cxt->str_anchor;
-}
-
-int ft_prop(struct ft_cxt *cxt, const char *name, const void *data,
- unsigned int sz)
-{
- int off, len;
-
- off = map_string(cxt, name);
- if (off == NO_STRING)
- return -1;
-
- len = 12 + _ALIGN(sz, 4);
- if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
- return -1;
-
- ft_put_word(cxt, OF_DT_PROP);
- ft_put_word(cxt, sz);
- ft_put_word(cxt, off);
- ft_put_bin(cxt, data, sz);
- return 0;
-}
-
-int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
-{
- return ft_prop(cxt, name, str, strlen(str) + 1);
-}
-
-int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
-{
- u32 v = cpu_to_be32((u32) val);
-
- return ft_prop(cxt, name, &v, 4);
-}
-
-/* Calculate the size of the reserved map */
-static unsigned long rsvmap_size(struct ft_cxt *cxt)
-{
- struct ft_reserve *res;
-
- res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start;
- while (res->start || res->len)
- ++res;
- return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start;
-}
-
-/* Calculate the size of the struct region by stepping through it */
-static unsigned long struct_size(struct ft_cxt *cxt)
-{
- char *p = cxt->rgn[FT_STRUCT].start;
- char *next;
- struct ft_atom atom;
-
- /* make check in ft_next happy */
- if (cxt->rgn[FT_STRUCT].size == 0)
- cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p;
-
- while ((next = ft_next(cxt, p, &atom)) != NULL)
- p = next;
- return p + 4 - cxt->rgn[FT_STRUCT].start;
-}
-
-/* add `adj' on to all string offset values in the struct area */
-static void adjust_string_offsets(struct ft_cxt *cxt, int adj)
-{
- char *p = cxt->rgn[FT_STRUCT].start;
- char *next;
- struct ft_atom atom;
- int off;
-
- while ((next = ft_next(cxt, p, &atom)) != NULL) {
- if (atom.tag == OF_DT_PROP) {
- off = be32_to_cpu(*(u32 *) (p + 8));
- *(u32 *) (p + 8) = cpu_to_be32(off + adj);
- }
- p = next;
- }
-}
-
-/* start construction of the flat OF tree from scratch */
-void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
- void *(*realloc_fn) (void *, unsigned long))
-{
- struct boot_param_header *bph = blob;
- char *p;
- struct ft_reserve *pres;
-
- /* clear the cxt */
- memset(cxt, 0, sizeof(*cxt));
-
- cxt->bph = bph;
- cxt->max_size = max_size;
- cxt->realloc = realloc_fn;
- cxt->isordered = 1;
-
- /* zero everything in the header area */
- memset(bph, 0, sizeof(*bph));
-
- bph->magic = cpu_to_be32(OF_DT_HEADER);
- bph->version = cpu_to_be32(0x10);
- bph->last_comp_version = cpu_to_be32(0x10);
-
- /* start pointers */
- cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE;
- cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve);
- pres = (struct ft_reserve *)p;
- cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve);
- cxt->rgn[FT_STRUCT].size = 4;
- cxt->rgn[FT_STRINGS].start = blob + max_size;
- cxt->rgn[FT_STRINGS].size = 0;
-
- /* init rsvmap and struct */
- pres->start = 0;
- pres->len = 0;
- *(u32 *) p = cpu_to_be32(OF_DT_END);
-
- cxt->str_anchor = blob;
-}
-
-/* open up an existing blob to be examined or modified */
-int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
- unsigned int max_find_device,
- void *(*realloc_fn) (void *, unsigned long))
-{
- struct boot_param_header *bph = blob;
-
- /* can't cope with version < 16 */
- if (be32_to_cpu(bph->version) < 16)
- return -1;
-
- /* clear the cxt */
- memset(cxt, 0, sizeof(*cxt));
-
- /* alloc node_tbl to track node ptrs returned by ft_find_device */
- ++max_find_device;
- cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *));
- if (!cxt->node_tbl)
- return -1;
- memset(cxt->node_tbl, 0, max_find_device * sizeof(char *));
- cxt->node_max = max_find_device;
- cxt->nodes_used = 1; /* don't use idx 0 b/c looks like NULL */
-
- cxt->bph = bph;
- cxt->max_size = max_size;
- cxt->realloc = realloc_fn;
-
- cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap);
- cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt);
- cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct);
- cxt->rgn[FT_STRUCT].size = struct_size(cxt);
- cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
- cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
-
- cxt->p = cxt->rgn[FT_STRUCT].start;
- cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
-
- return 0;
-}
-
-/* add a reserver physical area to the rsvmap */
-int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
-{
- char *p;
- struct ft_reserve *pres;
-
- p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
- - sizeof(struct ft_reserve);
- if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve)))
- return -1;
-
- pres = (struct ft_reserve *)p;
- pres->start = cpu_to_be64(physaddr);
- pres->len = cpu_to_be64(size);
-
- return 0;
-}
-
-void ft_begin_tree(struct ft_cxt *cxt)
-{
- cxt->p = ft_root_node(cxt);
-}
-
-void ft_end_tree(struct ft_cxt *cxt)
-{
- struct boot_param_header *bph = cxt->bph;
- char *p, *oldstr, *str, *endp;
- unsigned long ssize;
- int adj;
-
- if (!cxt->isordered)
- return; /* we haven't touched anything */
-
- /* adjust string offsets */
- oldstr = cxt->rgn[FT_STRINGS].start;
- adj = cxt->str_anchor - oldstr;
- if (adj)
- adjust_string_offsets(cxt, adj);
-
- /* make strings end on 8-byte boundary */
- ssize = cxt->rgn[FT_STRINGS].size;
- endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start
- + cxt->rgn[FT_STRUCT].size + ssize, 8);
- str = endp - ssize;
-
- /* move strings down to end of structs */
- memmove(str, oldstr, ssize);
- cxt->str_anchor = str;
- cxt->rgn[FT_STRINGS].start = str;
-
- /* fill in header fields */
- p = (char *)bph;
- bph->totalsize = cpu_to_be32(endp - p);
- bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p);
- bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p);
- bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p);
- bph->dt_strings_size = cpu_to_be32(ssize);
-}
-
-void *ft_find_device(struct ft_cxt *cxt, const void *top, const char *srch_path)
-{
- char *node;
-
- if (top) {
- node = ft_node_ph2node(cxt, top);
- if (node == NULL)
- return NULL;
- } else {
- node = ft_root_node(cxt);
- }
-
- node = ft_find_descendent(cxt, node, srch_path);
- return ft_get_phandle(cxt, node);
-}
-
-void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path)
-{
- struct ft_atom atom;
- char *p;
- const char *cp, *q;
- int cl;
- int depth = -1;
- int dmatch = 0;
- const char *path_comp[FT_MAX_DEPTH];
-
- cp = srch_path;
- cl = 0;
- p = top;
-
- while ((p = ft_next(cxt, p, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- ++depth;
- if (depth != dmatch)
- break;
- cxt->genealogy[depth] = atom.data;
- cxt->genealogy[depth + 1] = NULL;
- if (depth && !(strncmp(atom.name, cp, cl) == 0
- && (atom.name[cl] == '/'
- || atom.name[cl] == '\0'
- || atom.name[cl] == '@')))
- break;
- path_comp[dmatch] = cp;
- /* it matches so far, advance to next path component */
- cp += cl;
- /* skip slashes */
- while (*cp == '/')
- ++cp;
- /* we're done if this is the end of the string */
- if (*cp == 0)
- return atom.data;
- /* look for end of this component */
- q = strchr(cp, '/');
- if (q)
- cl = q - cp;
- else
- cl = strlen(cp);
- ++dmatch;
- break;
- case OF_DT_END_NODE:
- if (depth == 0)
- return NULL;
- if (dmatch > depth) {
- --dmatch;
- cl = cp - path_comp[dmatch] - 1;
- cp = path_comp[dmatch];
- while (cl > 0 && cp[cl - 1] == '/')
- --cl;
- }
- --depth;
- break;
- }
- }
- return NULL;
-}
-
-void *__ft_get_parent(struct ft_cxt *cxt, void *node)
-{
- int d;
- struct ft_atom atom;
- char *p;
-
- for (d = 0; cxt->genealogy[d] != NULL; ++d)
- if (cxt->genealogy[d] == node)
- return d > 0 ? cxt->genealogy[d - 1] : NULL;
-
- /* have to do it the hard way... */
- p = ft_root_node(cxt);
- d = 0;
- while ((p = ft_next(cxt, p, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- cxt->genealogy[d] = atom.data;
- if (node == atom.data) {
- /* found it */
- cxt->genealogy[d + 1] = NULL;
- return d > 0 ? cxt->genealogy[d - 1] : NULL;
- }
- ++d;
- break;
- case OF_DT_END_NODE:
- --d;
- break;
- }
- }
- return NULL;
-}
-
-void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
-{
- void *node = ft_node_ph2node(cxt, phandle);
- if (node == NULL)
- return NULL;
-
- node = __ft_get_parent(cxt, node);
- return ft_get_phandle(cxt, node);
-}
-
-static const void *__ft_get_prop(struct ft_cxt *cxt, void *node,
- const char *propname, unsigned int *len)
-{
- struct ft_atom atom;
- int depth = 0;
-
- while ((node = ft_next(cxt, node, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- ++depth;
- break;
-
- case OF_DT_PROP:
- if (depth != 1 || strcmp(atom.name, propname))
- break;
-
- if (len)
- *len = atom.size;
-
- return atom.data;
-
- case OF_DT_END_NODE:
- if (--depth <= 0)
- return NULL;
- }
- }
-
- return NULL;
-}
-
-int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
- void *buf, const unsigned int buflen)
-{
- const void *data;
- unsigned int size;
-
- void *node = ft_node_ph2node(cxt, phandle);
- if (!node)
- return -1;
-
- data = __ft_get_prop(cxt, node, propname, &size);
- if (data) {
- unsigned int clipped_size = min(size, buflen);
- memcpy(buf, data, clipped_size);
- return size;
- }
-
- return -1;
-}
-
-void *__ft_find_node_by_prop_value(struct ft_cxt *cxt, void *prev,
- const char *propname, const char *propval,
- unsigned int proplen)
-{
- struct ft_atom atom;
- char *p = ft_root_node(cxt);
- char *next;
- int past_prev = prev ? 0 : 1;
- int depth = -1;
-
- while ((next = ft_next(cxt, p, &atom)) != NULL) {
- const void *data;
- unsigned int size;
-
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- depth++;
-
- if (prev == p) {
- past_prev = 1;
- break;
- }
-
- if (!past_prev || depth < 1)
- break;
-
- data = __ft_get_prop(cxt, p, propname, &size);
- if (!data || size != proplen)
- break;
- if (memcmp(data, propval, size))
- break;
-
- return p;
-
- case OF_DT_END_NODE:
- if (depth-- == 0)
- return NULL;
-
- break;
- }
-
- p = next;
- }
-
- return NULL;
-}
-
-void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
- const char *propname, const char *propval,
- int proplen)
-{
- void *node = NULL;
-
- if (prev) {
- node = ft_node_ph2node(cxt, prev);
-
- if (!node)
- return NULL;
- }
-
- node = __ft_find_node_by_prop_value(cxt, node, propname,
- propval, proplen);
- return ft_get_phandle(cxt, node);
-}
-
-int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
- const void *buf, const unsigned int buflen)
-{
- struct ft_atom atom;
- void *node;
- char *p, *next;
- int nextra;
-
- node = ft_node_ph2node(cxt, phandle);
- if (node == NULL)
- return -1;
-
- next = ft_next(cxt, node, &atom);
- if (atom.tag != OF_DT_BEGIN_NODE)
- /* phandle didn't point to a node */
- return -1;
- p = next;
-
- while ((next = ft_next(cxt, p, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE: /* properties must go before subnodes */
- case OF_DT_END_NODE:
- /* haven't found the property, insert here */
- cxt->p = p;
- return ft_prop(cxt, propname, buf, buflen);
- case OF_DT_PROP:
- if (strcmp(atom.name, propname))
- break;
- /* found an existing property, overwrite it */
- nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4);
- cxt->p = atom.data;
- if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT,
- nextra))
- return -1;
- *(u32 *) (cxt->p - 8) = cpu_to_be32(buflen);
- ft_put_bin(cxt, buf, buflen);
- return 0;
- }
- p = next;
- }
- return -1;
-}
-
-int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
-{
- struct ft_atom atom;
- void *node;
- char *p, *next;
- int size;
-
- node = ft_node_ph2node(cxt, phandle);
- if (node == NULL)
- return -1;
-
- p = node;
- while ((next = ft_next(cxt, p, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- case OF_DT_END_NODE:
- return -1;
- case OF_DT_PROP:
- if (strcmp(atom.name, propname))
- break;
- /* found the property, remove it */
- size = 12 + -_ALIGN(atom.size, 4);
- cxt->p = p;
- if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size))
- return -1;
- return 0;
- }
- p = next;
- }
- return -1;
-}
-
-void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name)
-{
- struct ft_atom atom;
- char *p, *next, *ret;
- int depth = 0;
-
- if (parent) {
- p = ft_node_ph2node(cxt, parent);
- if (!p)
- return NULL;
- } else {
- p = ft_root_node(cxt);
- }
-
- while ((next = ft_next(cxt, p, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- ++depth;
- if (depth == 1 && strcmp(atom.name, name) == 0)
- /* duplicate node name, return error */
- return NULL;
- break;
- case OF_DT_END_NODE:
- --depth;
- if (depth > 0)
- break;
- /* end of node, insert here */
- cxt->p = p;
- ret = ft_begin_node(cxt, name);
- ft_end_node(cxt);
- return ft_get_phandle(cxt, ret);
- }
- p = next;
- }
- return NULL;
-}
-
-/* Returns the start of the path within the provided buffer, or NULL on
- * error.
- */
-char *ft_get_path(struct ft_cxt *cxt, const void *phandle,
- char *buf, int len)
-{
- const char *path_comp[FT_MAX_DEPTH];
- struct ft_atom atom;
- char *p, *next, *pos;
- int depth = 0, i;
- void *node;
-
- node = ft_node_ph2node(cxt, phandle);
- if (node == NULL)
- return NULL;
-
- p = ft_root_node(cxt);
-
- while ((next = ft_next(cxt, p, &atom)) != NULL) {
- switch (atom.tag) {
- case OF_DT_BEGIN_NODE:
- path_comp[depth++] = atom.name;
- if (p == node)
- goto found;
-
- break;
-
- case OF_DT_END_NODE:
- if (--depth == 0)
- return NULL;
- }
-
- p = next;
- }
-
-found:
- pos = buf;
- for (i = 1; i < depth; i++) {
- int this_len;
-
- if (len <= 1)
- return NULL;
-
- *pos++ = '/';
- len--;
-
- strncpy(pos, path_comp[i], len);
-
- if (pos[len - 1] != 0)
- return NULL;
-
- this_len = strlen(pos);
- len -= this_len;
- pos += this_len;
- }
-
- return buf;
-}
Index: working-2.6/arch/powerpc/boot/flatdevtree.h
===================================================================
--- working-2.6.orig/arch/powerpc/boot/flatdevtree.h 2007-10-22 13:55:50.000000000 +1000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,113 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef FLATDEVTREE_H
-#define FLATDEVTREE_H
-
-#include "flatdevtree_env.h"
-
-/* Definitions used by the flattened device tree */
-#define OF_DT_HEADER 0xd00dfeed /* marker */
-#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
-#define OF_DT_END_NODE 0x2 /* End node */
-#define OF_DT_PROP 0x3 /* Property: name off, size, content */
-#define OF_DT_NOP 0x4 /* nop */
-#define OF_DT_END 0x9
-
-#define OF_DT_VERSION 0x10
-
-struct boot_param_header {
- u32 magic; /* magic word OF_DT_HEADER */
- u32 totalsize; /* total size of DT block */
- u32 off_dt_struct; /* offset to structure */
- u32 off_dt_strings; /* offset to strings */
- u32 off_mem_rsvmap; /* offset to memory reserve map */
- u32 version; /* format version */
- u32 last_comp_version; /* last compatible version */
- /* version 2 fields below */
- u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
- /* version 3 fields below */
- u32 dt_strings_size; /* size of the DT strings block */
-};
-
-struct ft_reserve {
- u64 start;
- u64 len;
-};
-
-struct ft_region {
- char *start;
- unsigned long size;
-};
-
-enum ft_rgn_id {
- FT_RSVMAP,
- FT_STRUCT,
- FT_STRINGS,
- FT_N_REGION
-};
-
-#define FT_MAX_DEPTH 50
-
-struct ft_cxt {
- struct boot_param_header *bph;
- int max_size; /* maximum size of tree */
- int isordered; /* everything in standard order */
- void *(*realloc)(void *, unsigned long);
- char *str_anchor;
- char *p; /* current insertion point in structs */
- struct ft_region rgn[FT_N_REGION];
- void *genealogy[FT_MAX_DEPTH+1];
- char **node_tbl;
- unsigned int node_max;
- unsigned int nodes_used;
-};
-
-char *ft_begin_node(struct ft_cxt *cxt, const char *name);
-void ft_end_node(struct ft_cxt *cxt);
-
-void ft_begin_tree(struct ft_cxt *cxt);
-void ft_end_tree(struct ft_cxt *cxt);
-
-void ft_nop(struct ft_cxt *cxt);
-int ft_prop(struct ft_cxt *cxt, const char *name,
- const void *data, unsigned int sz);
-int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
-int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
-void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
- void *(*realloc_fn)(void *, unsigned long));
-int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
- unsigned int max_find_device,
- void *(*realloc_fn)(void *, unsigned long));
-int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
-
-void ft_dump_blob(const void *bphp);
-void ft_merge_blob(struct ft_cxt *cxt, void *blob);
-void *ft_find_device(struct ft_cxt *cxt, const void *top,
- const char *srch_path);
-void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path);
-int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
- void *buf, const unsigned int buflen);
-int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
- const void *buf, const unsigned int buflen);
-void *ft_get_parent(struct ft_cxt *cxt, const void *phandle);
-void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
- const char *propname, const char *propval,
- int proplen);
-void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name);
-char *ft_get_path(struct ft_cxt *cxt, const void *phandle, char *buf, int len);
-
-#endif /* FLATDEVTREE_H */
Index: working-2.6/arch/powerpc/boot/flatdevtree_misc.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/flatdevtree_misc.c 2007-10-22 13:55:50.000000000 +1000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,79 +0,0 @@
-/*
- * This file does the necessary interface mapping between the bootwrapper
- * device tree operations and the interface provided by shared source
- * files flatdevicetree.[ch].
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * 2006 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <stddef.h>
-#include "flatdevtree.h"
-#include "ops.h"
-
-static struct ft_cxt cxt;
-
-static void *fdtm_finddevice(const char *name)
-{
- return ft_find_device(&cxt, NULL, name);
-}
-
-static int fdtm_getprop(const void *phandle, const char *propname,
- void *buf, const int buflen)
-{
- return ft_get_prop(&cxt, phandle, propname, buf, buflen);
-}
-
-static int fdtm_setprop(const void *phandle, const char *propname,
- const void *buf, const int buflen)
-{
- return ft_set_prop(&cxt, phandle, propname, buf, buflen);
-}
-
-static void *fdtm_get_parent(const void *phandle)
-{
- return ft_get_parent(&cxt, phandle);
-}
-
-static void *fdtm_create_node(const void *phandle, const char *name)
-{
- return ft_create_node(&cxt, phandle, name);
-}
-
-static void *fdtm_find_node_by_prop_value(const void *prev,
- const char *propname,
- const char *propval,
- int proplen)
-{
- return ft_find_node_by_prop_value(&cxt, prev, propname,
- propval, proplen);
-}
-
-static unsigned long fdtm_finalize(void)
-{
- ft_end_tree(&cxt);
- return (unsigned long)cxt.bph;
-}
-
-static char *fdtm_get_path(const void *phandle, char *buf, int len)
-{
- return ft_get_path(&cxt, phandle, buf, len);
-}
-
-int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device)
-{
- dt_ops.finddevice = fdtm_finddevice;
- dt_ops.getprop = fdtm_getprop;
- dt_ops.setprop = fdtm_setprop;
- dt_ops.get_parent = fdtm_get_parent;
- dt_ops.create_node = fdtm_create_node;
- dt_ops.find_node_by_prop_value = fdtm_find_node_by_prop_value;
- dt_ops.finalize = fdtm_finalize;
- dt_ops.get_path = fdtm_get_path;
-
- return ft_open(&cxt, dt_blob, max_size, max_find_device,
- platform_ops.realloc);
-}
Index: working-2.6/arch/powerpc/boot/main.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/main.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/main.c 2007-12-10 13:26:24.000000000 +1100
@@ -16,7 +16,6 @@
#include "stdio.h"
#include "ops.h"
#include "gunzip_util.h"
-#include "flatdevtree.h"
#include "reg.h"
static struct gunzip_state gzstate;
Index: working-2.6/arch/powerpc/boot/ops.h
===================================================================
--- working-2.6.orig/arch/powerpc/boot/ops.h 2007-12-10 13:24:45.000000000 +1100
+++ working-2.6/arch/powerpc/boot/ops.h 2007-12-10 13:26:24.000000000 +1100
@@ -79,7 +79,6 @@ struct loader_info {
extern struct loader_info loader_info;
void start(void);
-int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
void fdt_init(void *blob);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
^ permalink raw reply
* [PATCH 2/3] Use embedded libfdt in the bootwrapper
From: David Gibson @ 2007-12-10 3:28 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <20071210032343.GB29611@localhost.localdomain>
This patch incorporates libfdt (from the source embedded in an earlier
patch) into the wrapper.a library used by the bootwrapper. This
includes adding a libfdt_env.h file, which the libfdt sources need in
order to integrate into the bootwrapper environment, and a
libfdt-wrapper.c which provides glue to connect the bootwrapper's
abstract device tree callbacks to the libfdt functions.
In addition, this patch changes the various wrapper and platform files
to use libfdt functions instead of the older flatdevtree.c library.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
arch/powerpc/boot/Makefile | 6 -
arch/powerpc/boot/bamboo.c | 2
arch/powerpc/boot/cuboot-52xx.c | 2
arch/powerpc/boot/cuboot-83xx.c | 2
arch/powerpc/boot/cuboot-85xx.c | 2
arch/powerpc/boot/cuboot-8xx.c | 2
arch/powerpc/boot/cuboot-hpc2.c | 2
arch/powerpc/boot/cuboot-pq2.c | 2
arch/powerpc/boot/cuboot-sequoia.c | 2
arch/powerpc/boot/ebony.c | 2
arch/powerpc/boot/ep88xc.c | 2
arch/powerpc/boot/holly.c | 2
arch/powerpc/boot/libfdt-wrapper.c | 182 ++++++++++++++++++++++++++++++++++++
arch/powerpc/boot/libfdt_env.h | 17 +++
arch/powerpc/boot/ops.h | 1
arch/powerpc/boot/prpmc2800.c | 3
arch/powerpc/boot/ps3.c | 2
arch/powerpc/boot/treeboot-walnut.c | 2
18 files changed, 219 insertions(+), 16 deletions(-)
Index: working-2.6/arch/powerpc/boot/Makefile
===================================================================
--- working-2.6.orig/arch/powerpc/boot/Makefile 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/Makefile 2007-12-10 12:01:56.000000000 +1100
@@ -33,7 +33,7 @@ ifeq ($(call cc-option-yn, -fstack-prote
BOOTCFLAGS += -fno-stack-protector
endif
-BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
+BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
$(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
@@ -46,7 +46,9 @@ zliblinuxheader := zlib.h zconf.h zutil.
$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
+src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
+ $(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
@@ -101,8 +103,10 @@ quiet_cmd_bootar = BOOTAR $@
cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE
+ $(Q)mkdir -p $(dir $@)
$(call if_changed_dep,bootcc)
$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE
+ $(Q)mkdir -p $(dir $@)
$(call if_changed_dep,bootas)
$(obj)/wrapper.a: $(obj-wlib) FORCE
Index: working-2.6/arch/powerpc/boot/libfdt_env.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt_env.h 2007-12-10 12:01:10.000000000 +1100
@@ -0,0 +1,17 @@
+#ifndef _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
+#define _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
+
+#include <types.h>
+#include <string.h>
+
+typedef u32 uint32_t;
+typedef u64 uint64_t;
+
+#define fdt16_to_cpu(x) (x)
+#define cpu_to_fdt16(x) (x)
+#define fdt32_to_cpu(x) (x)
+#define cpu_to_fdt32(x) (x)
+#define fdt64_to_cpu(x) (x)
+#define cpu_to_fdt64(x) (x)
+
+#endif /* _ARCH_POWERPC_BOOT_LIBFDT_ENV_H */
Index: working-2.6/arch/powerpc/boot/bamboo.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/bamboo.c 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/bamboo.c 2007-12-10 12:01:10.000000000 +1100
@@ -42,6 +42,6 @@ void bamboo_init(void *mac0, void *mac1)
platform_ops.exit = ibm44x_dbcr_reset;
bamboo_mac0 = mac0;
bamboo_mac1 = mac1;
- ft_init(_dtb_start, 0, 32);
+ fdt_init(_dtb_start);
serial_console_init();
}
Index: working-2.6/arch/powerpc/boot/cuboot-52xx.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-52xx.c 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-52xx.c 2007-12-10 12:01:10.000000000 +1100
@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, uns
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = platform_fixups;
}
Index: working-2.6/arch/powerpc/boot/cuboot-83xx.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-83xx.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-83xx.c 2007-12-10 12:01:10.000000000 +1100
@@ -52,7 +52,7 @@ void platform_init(unsigned long r3, uns
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = platform_fixups;
}
Index: working-2.6/arch/powerpc/boot/cuboot-85xx.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-85xx.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-85xx.c 2007-12-10 12:01:10.000000000 +1100
@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, uns
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = platform_fixups;
}
Index: working-2.6/arch/powerpc/boot/cuboot-8xx.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-8xx.c 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-8xx.c 2007-12-10 12:01:10.000000000 +1100
@@ -41,7 +41,7 @@ void platform_init(unsigned long r3, uns
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = platform_fixups;
}
Index: working-2.6/arch/powerpc/boot/cuboot-hpc2.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-hpc2.c 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-hpc2.c 2007-12-10 12:01:10.000000000 +1100
@@ -42,7 +42,7 @@ void platform_init(unsigned long r3, uns
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = platform_fixups;
}
Index: working-2.6/arch/powerpc/boot/cuboot-pq2.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-pq2.c 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-pq2.c 2007-12-10 12:01:10.000000000 +1100
@@ -255,7 +255,7 @@ void platform_init(unsigned long r3, uns
unsigned long r6, unsigned long r7)
{
CUBOOT_INIT();
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
platform_ops.fixups = pq2_platform_fixups;
}
Index: working-2.6/arch/powerpc/boot/cuboot-sequoia.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/cuboot-sequoia.c 2007-10-22 13:55:49.000000000 +1000
+++ working-2.6/arch/powerpc/boot/cuboot-sequoia.c 2007-12-10 12:01:10.000000000 +1100
@@ -51,6 +51,6 @@ void platform_init(unsigned long r3, uns
CUBOOT_INIT();
platform_ops.fixups = sequoia_fixups;
platform_ops.exit = ibm44x_dbcr_reset;
- ft_init(_dtb_start, 0, 32);
+ fdt_init(_dtb_start);
serial_console_init();
}
Index: working-2.6/arch/powerpc/boot/ebony.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/ebony.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/ebony.c 2007-12-10 12:01:10.000000000 +1100
@@ -146,6 +146,6 @@ void ebony_init(void *mac0, void *mac1)
platform_ops.exit = ibm44x_dbcr_reset;
ebony_mac0 = mac0;
ebony_mac1 = mac1;
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
}
Index: working-2.6/arch/powerpc/boot/ep88xc.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/ep88xc.c 2007-10-22 13:55:50.000000000 +1000
+++ working-2.6/arch/powerpc/boot/ep88xc.c 2007-12-10 12:01:10.000000000 +1100
@@ -45,7 +45,7 @@ void platform_init(unsigned long r3, uns
mem_size *= 1024 * 1024;
simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
planetcore_set_stdout_path(table);
Index: working-2.6/arch/powerpc/boot/holly.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/holly.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/holly.c 2007-12-10 12:01:10.000000000 +1100
@@ -28,6 +28,6 @@ void platform_init(unsigned long r3, uns
u32 heapsize = 0x8000000 - (u32)_end; /* 128M */
simple_alloc_init(_end, heapsize, 32, 64);
- ft_init(_dtb_start, 0, 4);
+ fdt_init(_dtb_start);
serial_console_init();
}
Index: working-2.6/arch/powerpc/boot/libfdt-wrapper.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt-wrapper.c 2007-12-10 12:01:10.000000000 +1100
@@ -0,0 +1,182 @@
+/*
+ * This file does the necessary interface mapping between the bootwrapper
+ * device tree operations and the interface provided by shared source
+ * files flatdevicetree.[ch].
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <page.h>
+#include <libfdt.h>
+#include "ops.h"
+
+#define DEBUG 0
+#define BAD_ERROR(err) (((err) < 0) \
+ && ((err) != -FDT_ERR_NOTFOUND) \
+ && ((err) != -FDT_ERR_EXISTS))
+
+#define check_err(err) \
+ ({ \
+ if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \
+ printf("%s():%d %s\n\r", __FUNCTION__, __LINE__, \
+ fdt_strerror(err)); \
+ if (BAD_ERROR(err)) \
+ exit(); \
+ (err < 0) ? -1 : 0; \
+ })
+
+#define offset_devp(off) \
+ ({ \
+ int offset = (off); \
+ check_err(offset) ? NULL : (void *)(offset+1); \
+ })
+
+#define devp_offset(devp) (((int)(devp))-1)
+
+static void *fdt;
+static void *buf; /* = NULL */
+
+#define EXPAND_GRANULARITY 1024
+
+static void expand_buf(int minexpand)
+{
+ int size = fdt_totalsize(fdt);
+ int rc;
+
+ size = _ALIGN(size + minexpand, EXPAND_GRANULARITY);
+ buf = platform_ops.realloc(buf, size);
+ if (!buf)
+ fatal("Couldn't find %d bytes to expand device tree\n\r", size);
+ rc = fdt_open_into(fdt, buf, size);
+ if (rc != 0)
+ fatal("Couldn't expand fdt into new buffer: %s\n\r",
+ fdt_strerror(rc));
+
+ fdt = buf;
+}
+
+static void *fdt_wrapper_finddevice(const char *path)
+{
+ return offset_devp(fdt_path_offset(fdt, path));
+}
+
+static int fdt_wrapper_getprop(const void *devp, const char *name,
+ void *buf, const int buflen)
+{
+ const void *p;
+ int len;
+
+ p = fdt_getprop(fdt, devp_offset(devp), name, &len);
+ if (!p)
+ return check_err(len);
+ memcpy(buf, p, min(len, buflen));
+ return len;
+}
+
+static int fdt_wrapper_setprop(const void *devp, const char *name,
+ const void *buf, const int len)
+{
+ int rc;
+
+ rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
+ if (rc == -FDT_ERR_NOSPACE) {
+ expand_buf(len + 16);
+ rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
+ }
+
+ return check_err(rc);
+}
+
+static void *fdt_wrapper_get_parent(const void *devp)
+{
+ return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
+}
+
+static void *fdt_wrapper_create_node(const void *devp, const char *name)
+{
+ int offset;
+
+ offset = fdt_add_subnode(fdt, devp_offset(devp), name);
+ if (offset == -FDT_ERR_NOSPACE) {
+ expand_buf(strlen(name) + 16);
+ offset = fdt_add_subnode(fdt, devp_offset(devp), name);
+ }
+
+ return offset_devp(offset);
+}
+
+static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
+ const char *name,
+ const char *val,
+ int len)
+{
+ return offset_devp(fdt_node_offset_by_prop_value(fdt, devp_offset(prev),
+ name, val, len));
+}
+
+static char *fdt_wrapper_get_path(const void *devp, char *buf, int len)
+{
+ int rc;
+
+ rc = fdt_get_path(fdt, devp_offset(devp), buf, len);
+ if (check_err(rc))
+ return NULL;
+ return buf;
+}
+
+static unsigned long fdt_wrapper_finalize(void)
+{
+ int rc;
+
+ rc = fdt_pack(fdt);
+ if (rc != 0)
+ fatal("Couldn't pack flat tree: %s\n\r",
+ fdt_strerror(rc));
+ return (unsigned long)fdt;
+}
+
+void fdt_init(void *blob)
+{
+ int err;
+
+ dt_ops.finddevice = fdt_wrapper_finddevice;
+ dt_ops.getprop = fdt_wrapper_getprop;
+ dt_ops.setprop = fdt_wrapper_setprop;
+ dt_ops.get_parent = fdt_wrapper_get_parent;
+ dt_ops.create_node = fdt_wrapper_create_node;
+ dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
+ dt_ops.get_path = fdt_wrapper_get_path;
+ dt_ops.finalize = fdt_wrapper_finalize;
+
+ /* Make sure the dt blob is the right version and so forth */
+ fdt = blob;
+ err = fdt_open_into(fdt, fdt, fdt_totalsize(blob));
+ if (err == -FDT_ERR_NOSPACE) {
+ int bufsize = fdt_totalsize(fdt) + 4;
+ buf = malloc(bufsize);
+ err = fdt_open_into(fdt, buf, bufsize);
+ }
+
+ if (err != 0)
+ fatal("fdt_init(): %s\n\r", fdt_strerror(err));
+
+ if (buf)
+ fdt = buf;
+}
Index: working-2.6/arch/powerpc/boot/ops.h
===================================================================
--- working-2.6.orig/arch/powerpc/boot/ops.h 2007-10-22 13:55:50.000000000 +1000
+++ working-2.6/arch/powerpc/boot/ops.h 2007-12-10 12:01:10.000000000 +1100
@@ -80,6 +80,7 @@ extern struct loader_info loader_info;
void start(void);
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
+void fdt_init(void *blob);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
int mpsc_console_init(void *devp, struct serial_console_data *scdp);
Index: working-2.6/arch/powerpc/boot/prpmc2800.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/prpmc2800.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/prpmc2800.c 2007-12-10 12:01:10.000000000 +1100
@@ -547,8 +547,7 @@ void platform_init(unsigned long r3, uns
if (!dtb)
exit();
memmove(dtb, _dtb_start, dt_size);
- if (ft_init(dtb, dt_size, 16))
- exit();
+ fdt_init(dtb);
bridge_base = mv64x60_get_bridge_base();
Index: working-2.6/arch/powerpc/boot/ps3.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/ps3.c 2007-10-02 14:55:34.000000000 +1000
+++ working-2.6/arch/powerpc/boot/ps3.c 2007-12-10 12:01:10.000000000 +1100
@@ -131,7 +131,7 @@ void platform_init(void)
printf("\n-- PS3 bootwrapper --\n");
simple_alloc_init(_end, heapsize, 32, 64);
- ft_init(_dtb_start, 0, 4);
+ fdt_init(_dtb_start);
chosen = finddevice("/chosen");
Index: working-2.6/arch/powerpc/boot/treeboot-walnut.c
===================================================================
--- working-2.6.orig/arch/powerpc/boot/treeboot-walnut.c 2007-12-10 10:52:43.000000000 +1100
+++ working-2.6/arch/powerpc/boot/treeboot-walnut.c 2007-12-10 12:01:10.000000000 +1100
@@ -128,6 +128,6 @@ void platform_init(void)
simple_alloc_init(_end, avail_ram, 32, 32);
platform_ops.fixups = walnut_fixups;
platform_ops.exit = ibm40x_dbcr_reset;
- ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ fdt_init(_dtb_start);
serial_console_init();
}
^ permalink raw reply
* [PATCH 1/3] Merge libfdt upstream source
From: David Gibson @ 2007-12-10 3:28 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <20071210032343.GB29611@localhost.localdomain>
This large patch incorporates a copy of dtc libfdt into the kernel
source, in arch/powerpc/boot/libfdt. This patch only imports the
upstream sources verbatim, later patches are needed to actually link
it into the kernel Makefiles.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
arch/powerpc/boot/libfdt/Makefile.libfdt | 14
10 files changed, 2568 insertions(+)
---
arch/powerpc/boot/libfdt/Makefile.libfdt | 14
arch/powerpc/boot/libfdt/fdt.c | 156 ++++++
arch/powerpc/boot/libfdt/fdt.h | 60 ++
arch/powerpc/boot/libfdt/fdt_ro.c | 583 +++++++++++++++++++++++
arch/powerpc/boot/libfdt/fdt_rw.c | 447 +++++++++++++++++
arch/powerpc/boot/libfdt/fdt_strerror.c | 96 +++
arch/powerpc/boot/libfdt/fdt_sw.c | 258 ++++++++++
arch/powerpc/boot/libfdt/fdt_wip.c | 144 +++++
arch/powerpc/boot/libfdt/libfdt.h | 721 +++++++++++++++++++++++++++++
arch/powerpc/boot/libfdt/libfdt_internal.h | 89 +++
10 files changed, 2568 insertions(+)
Index: working-2.6/arch/powerpc/boot/libfdt/Makefile.libfdt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/Makefile.libfdt 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,14 @@
+# Makefile.libfdt
+#
+# This is not a complete Makefile of itself. Instead, it is designed to
+# be easily embeddable into other systems of Makefiles.
+#
+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
+LIBFDT_INCLUDES = fdt.h libfdt.h
+LIBFDT_EXTRA = libfdt_internal.h
+LIBFDT_LIB = libfdt/libfdt.a
+
+LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
+
+$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
+
Index: working-2.6/arch/powerpc/boot/libfdt/fdt.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt.c 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,156 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_check_header(const void *fdt)
+{
+ if (fdt_magic(fdt) == FDT_MAGIC) {
+ /* Complete tree */
+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ } else if (fdt_magic(fdt) == SW_MAGIC) {
+ /* Unfinished sequential-write blob */
+ if (fdt_size_dt_struct(fdt) == 0)
+ return -FDT_ERR_BADSTATE;
+ } else {
+ return -FDT_ERR_BADMAGIC;
+ }
+
+ return 0;
+}
+
+const void *fdt_offset_ptr(const void *fdt, int offset, int len)
+{
+ const void *p;
+
+ if (fdt_version(fdt) >= 0x11)
+ if (((offset + len) < offset)
+ || ((offset + len) > fdt_size_dt_struct(fdt)))
+ return NULL;
+
+ p = _fdt_offset_ptr(fdt, offset);
+
+ if (p + len < p)
+ return NULL;
+ return p;
+}
+
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
+{
+ const uint32_t *tagp, *lenp;
+ uint32_t tag;
+ const char *p;
+
+ if (offset % FDT_TAGSIZE)
+ return -1;
+
+ tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
+ if (! tagp)
+ return FDT_END; /* premature end */
+ tag = fdt32_to_cpu(*tagp);
+ offset += FDT_TAGSIZE;
+
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ /* skip name */
+ do {
+ p = fdt_offset_ptr(fdt, offset++, 1);
+ } while (p && (*p != '\0'));
+ if (! p)
+ return FDT_END;
+ break;
+ case FDT_PROP:
+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+ if (! lenp)
+ return FDT_END;
+ /* skip name offset, length and value */
+ offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
+ break;
+ }
+
+ if (nextoffset)
+ *nextoffset = ALIGN(offset, FDT_TAGSIZE);
+
+ return tag;
+}
+
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+{
+ int len = strlen(s) + 1;
+ const char *last = strtab + tabsize - len;
+ const char *p;
+
+ for (p = strtab; p <= last; p++)
+ if (memeq(p, s, len))
+ return p;
+ return NULL;
+}
+
+int fdt_move(const void *fdt, void *buf, int bufsize)
+{
+ int err = fdt_check_header(fdt);
+
+ if (err)
+ return err;
+
+ if (fdt_totalsize(fdt) > bufsize)
+ return -FDT_ERR_NOSPACE;
+
+ memmove(buf, fdt, fdt_totalsize(fdt));
+ return 0;
+}
Index: working-2.6/arch/powerpc/boot/libfdt/fdt.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt.h 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,60 @@
+#ifndef _FDT_H
+#define _FDT_H
+
+#ifndef __ASSEMBLY__
+
+struct fdt_header {
+ uint32_t magic; /* magic word FDT_MAGIC */
+ uint32_t totalsize; /* total size of DT block */
+ uint32_t off_dt_struct; /* offset to structure */
+ uint32_t off_dt_strings; /* offset to strings */
+ uint32_t off_mem_rsvmap; /* offset to memory reserve map */
+ uint32_t version; /* format version */
+ uint32_t last_comp_version; /* last compatible version */
+
+ /* version 2 fields below */
+ uint32_t boot_cpuid_phys; /* Which physical CPU id we're
+ booting on */
+ /* version 3 fields below */
+ uint32_t size_dt_strings; /* size of the strings block */
+
+ /* version 17 fields below */
+ uint32_t size_dt_struct; /* size of the structure block */
+};
+
+struct fdt_reserve_entry {
+ uint64_t address;
+ uint64_t size;
+};
+
+struct fdt_node_header {
+ uint32_t tag;
+ char name[0];
+};
+
+struct fdt_property {
+ uint32_t tag;
+ uint32_t len;
+ uint32_t nameoff;
+ char data[0];
+};
+
+#endif /* !__ASSEMBLY */
+
+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
+#define FDT_TAGSIZE sizeof(uint32_t)
+
+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
+#define FDT_END_NODE 0x2 /* End node */
+#define FDT_PROP 0x3 /* Property: name off,
+ size, content */
+#define FDT_NOP 0x4 /* nop */
+#define FDT_END 0x9
+
+#define FDT_V1_SIZE (7*sizeof(uint32_t))
+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))
+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))
+#define FDT_V16_SIZE FDT_V3_SIZE
+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))
+
+#endif /* _FDT_H */
Index: working-2.6/arch/powerpc/boot/libfdt/fdt_ro.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt_ro.c 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,583 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+#define CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = fdt_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+static int nodename_eq(const void *fdt, int offset,
+ const char *s, int len)
+{
+ const char *p = fdt_offset_ptr(fdt, offset, len+1);
+
+ if (! p)
+ /* short match */
+ return 0;
+
+ if (memcmp(p, s, len) != 0)
+ return 0;
+
+ if (p[len] == '\0')
+ return 1;
+ else if (!memchr(s, '@', len) && (p[len] == '@'))
+ return 1;
+ else
+ return 0;
+}
+
+const char *fdt_string(const void *fdt, int stroffset)
+{
+ return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+}
+
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
+{
+ CHECK_HEADER(fdt);
+ *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
+ *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+ return 0;
+}
+
+int fdt_num_mem_rsv(const void *fdt)
+{
+ int i = 0;
+
+ while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+ i++;
+ return i;
+}
+
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ const char *name, int namelen)
+{
+ int level = 0;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ CHECK_HEADER(fdt);
+
+ tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_END:
+ return -FDT_ERR_TRUNCATED;
+
+ case FDT_BEGIN_NODE:
+ level++;
+ if (level != 1)
+ continue;
+ if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
+ /* Found it! */
+ return offset;
+ break;
+
+ case FDT_END_NODE:
+ level--;
+ break;
+
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (level >= 0);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+int fdt_subnode_offset(const void *fdt, int parentoffset,
+ const char *name)
+{
+ return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_path_offset(const void *fdt, const char *path)
+{
+ const char *end = path + strlen(path);
+ const char *p = path;
+ int offset = 0;
+
+ CHECK_HEADER(fdt);
+
+ if (*path != '/')
+ return -FDT_ERR_BADPATH;
+
+ while (*p) {
+ const char *q;
+
+ while (*p == '/')
+ p++;
+ if (! *p)
+ return offset;
+ q = strchr(p, '/');
+ if (! q)
+ q = end;
+
+ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
+ if (offset < 0)
+ return offset;
+
+ p = q;
+ }
+
+ return offset;
+}
+
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
+{
+ const struct fdt_node_header *nh;
+ int err;
+
+ if ((err = fdt_check_header(fdt)) != 0)
+ goto fail;
+
+ err = -FDT_ERR_BADOFFSET;
+ nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
+ if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
+ goto fail;
+
+ if (len)
+ *len = strlen(nh->name);
+
+ return nh->name;
+
+ fail:
+ if (len)
+ *len = err;
+ return NULL;
+}
+
+const struct fdt_property *fdt_get_property(const void *fdt,
+ int nodeoffset,
+ const char *name, int *lenp)
+{
+ uint32_t tag;
+ const struct fdt_property *prop;
+ int namestroff;
+ int offset, nextoffset;
+ int err;
+
+ if ((err = fdt_check_header(fdt)) != 0)
+ goto fail;
+
+ err = -FDT_ERR_BADOFFSET;
+ if (nodeoffset % FDT_TAGSIZE)
+ goto fail;
+
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ goto fail;
+
+ do {
+ offset = nextoffset;
+
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ switch (tag) {
+ case FDT_END:
+ err = -FDT_ERR_TRUNCATED;
+ goto fail;
+
+ case FDT_BEGIN_NODE:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ case FDT_PROP:
+ err = -FDT_ERR_BADSTRUCTURE;
+ prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
+ if (! prop)
+ goto fail;
+ namestroff = fdt32_to_cpu(prop->nameoff);
+ if (streq(fdt_string(fdt, namestroff), name)) {
+ /* Found it! */
+ int len = fdt32_to_cpu(prop->len);
+ prop = fdt_offset_ptr(fdt, offset,
+ sizeof(*prop)+len);
+ if (! prop)
+ goto fail;
+
+ if (lenp)
+ *lenp = len;
+
+ return prop;
+ }
+ break;
+
+ default:
+ err = -FDT_ERR_BADSTRUCTURE;
+ goto fail;
+ }
+ } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
+
+ err = -FDT_ERR_NOTFOUND;
+ fail:
+ if (lenp)
+ *lenp = err;
+ return NULL;
+}
+
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property(fdt, nodeoffset, name, lenp);
+ if (! prop)
+ return NULL;
+
+ return prop->data;
+}
+
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
+{
+ const uint32_t *php;
+ int len;
+
+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof(*php)))
+ return 0;
+
+ return fdt32_to_cpu(*php);
+}
+
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
+{
+ uint32_t tag;
+ int p = 0, overflow = 0;
+ int offset, nextoffset, namelen;
+ const char *name;
+
+ CHECK_HEADER(fdt);
+
+ tag = fdt_next_tag(fdt, 0, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ if (buflen < 2)
+ return -FDT_ERR_NOSPACE;
+ buf[0] = '/';
+ p = 1;
+
+ while (nextoffset <= nodeoffset) {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ switch (tag) {
+ case FDT_END:
+ return -FDT_ERR_BADOFFSET;
+
+ case FDT_BEGIN_NODE:
+ name = fdt_get_name(fdt, offset, &namelen);
+ if (!name)
+ return namelen;
+ if (overflow || ((p + namelen + 1) > buflen)) {
+ overflow++;
+ break;
+ }
+ memcpy(buf + p, name, namelen);
+ p += namelen;
+ buf[p++] = '/';
+ break;
+
+ case FDT_END_NODE:
+ if (overflow) {
+ overflow--;
+ break;
+ }
+ do {
+ p--;
+ } while (buf[p-1] != '/');
+ break;
+
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ }
+
+ if (overflow)
+ return -FDT_ERR_NOSPACE;
+
+ if (p > 1) /* special case so that root path is "/", not "" */
+ p--;
+ buf[p] = '\0';
+ return p;
+}
+
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth)
+{
+ int level = -1;
+ uint32_t tag;
+ int offset, nextoffset = 0;
+ int supernodeoffset = -FDT_ERR_INTERNAL;
+
+ CHECK_HEADER(fdt);
+
+ if (supernodedepth < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ switch (tag) {
+ case FDT_END:
+ return -FDT_ERR_BADOFFSET;
+
+ case FDT_BEGIN_NODE:
+ level++;
+ if (level == supernodedepth)
+ supernodeoffset = offset;
+ break;
+
+ case FDT_END_NODE:
+ level--;
+ break;
+
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (offset < nodeoffset);
+
+ if (nodedepth)
+ *nodedepth = level;
+
+ if (supernodedepth > level)
+ return -FDT_ERR_NOTFOUND;
+ return supernodeoffset;
+}
+
+int fdt_node_depth(const void *fdt, int nodeoffset)
+{
+ int nodedepth;
+ int err;
+
+ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
+ if (err)
+ return (err < 0) ? err : -FDT_ERR_INTERNAL;
+ return nodedepth;
+}
+
+int fdt_parent_offset(const void *fdt, int nodeoffset)
+{
+ int nodedepth = fdt_node_depth(fdt, nodeoffset);
+
+ if (nodedepth < 0)
+ return nodedepth;
+ return fdt_supernode_atdepth_offset(fdt, nodeoffset,
+ nodedepth - 1, NULL);
+}
+
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen)
+{
+ uint32_t tag;
+ int offset, nextoffset;
+ const void *val;
+ int len;
+
+ CHECK_HEADER(fdt);
+
+ if (startoffset >= 0) {
+ tag = fdt_next_tag(fdt, startoffset, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+ } else {
+ nextoffset = 0;
+ }
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_getprop(), then if that didn't
+ * find what we want, we scan over them again making our way
+ * to the next node. Still it's the easiest to implement
+ * approach; performance can come later. */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ val = fdt_getprop(fdt, offset, propname, &len);
+ if (val
+ && (len == proplen)
+ && (memcmp(val, propval, len) == 0))
+ return offset;
+ break;
+
+ case FDT_PROP:
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (tag != FDT_END);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
+{
+ if ((phandle == 0) || (phandle == -1))
+ return -FDT_ERR_BADPHANDLE;
+ phandle = cpu_to_fdt32(phandle);
+ return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
+ &phandle, sizeof(phandle));
+}
+
+int _stringlist_contains(const void *strlist, int listlen, const char *str)
+{
+ int len = strlen(str);
+ const void *p;
+
+ while (listlen >= len) {
+ if (memcmp(str, strlist, len+1) == 0)
+ return 1;
+ p = memchr(strlist, '\0', listlen);
+ if (!p)
+ return 0; /* malformed strlist.. */
+ listlen -= (p-strlist) + 1;
+ strlist = p + 1;
+ }
+ return 0;
+}
+
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+ const char *compatible)
+{
+ const void *prop;
+ int len;
+
+ prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
+ if (!prop)
+ return len;
+ if (_stringlist_contains(prop, len, compatible))
+ return 0;
+ else
+ return 1;
+}
+
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+ const char *compatible)
+{
+ uint32_t tag;
+ int offset, nextoffset;
+ int err;
+
+ CHECK_HEADER(fdt);
+
+ if (startoffset >= 0) {
+ tag = fdt_next_tag(fdt, startoffset, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+ } else {
+ nextoffset = 0;
+ }
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_node_check_compatible(), then if
+ * that didn't find what we want, we scan over them again
+ * making our way to the next node. Still it's the easiest to
+ * implement approach; performance can come later. */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ err = fdt_node_check_compatible(fdt, offset,
+ compatible);
+ if ((err < 0)
+ && (err != -FDT_ERR_NOTFOUND))
+ return err;
+ else if (err == 0)
+ return offset;
+ break;
+
+ case FDT_PROP:
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (tag != FDT_END);
+
+ return -FDT_ERR_NOTFOUND;
+}
Index: working-2.6/arch/powerpc/boot/libfdt/fdt_rw.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt_rw.c 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,447 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _blocks_misordered(const void *fdt,
+ int mem_rsv_size, int struct_size)
+{
+ return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
+ || (fdt_off_dt_struct(fdt) <
+ (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
+ || (fdt_off_dt_strings(fdt) <
+ (fdt_off_dt_struct(fdt) + struct_size))
+ || (fdt_totalsize(fdt) <
+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+}
+
+static int rw_check_header(void *fdt)
+{
+ int err;
+
+ if ((err = fdt_check_header(fdt)))
+ return err;
+ if (fdt_version(fdt) < 17)
+ return -FDT_ERR_BADVERSION;
+ if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+ fdt_size_dt_struct(fdt)))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_version(fdt) > 17)
+ fdt_set_version(fdt, 17);
+
+ return 0;
+}
+
+#define RW_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = rw_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+static inline int _blob_data_size(void *fdt)
+{
+ return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+}
+
+static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
+{
+ void *end = fdt + _blob_data_size(fdt);
+
+ if (((p + oldlen) < p) || ((p + oldlen) > end))
+ return -FDT_ERR_BADOFFSET;
+ if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
+ return -FDT_ERR_NOSPACE;
+ memmove(p + newlen, p + oldlen, end - p - oldlen);
+ return 0;
+}
+
+static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+ int oldn, int newn)
+{
+ int delta = (newn - oldn) * sizeof(*p);
+ int err;
+ err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+ if (err)
+ return err;
+ fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _blob_splice_struct(void *fdt, void *p,
+ int oldlen, int newlen)
+{
+ int delta = newlen - oldlen;
+ int err;
+
+ if ((err = _blob_splice(fdt, p, oldlen, newlen)))
+ return err;
+
+ fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _blob_splice_string(void *fdt, int newlen)
+{
+ void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+ int err;
+
+ if ((err = _blob_splice(fdt, p, 0, newlen)))
+ return err;
+
+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
+ return 0;
+}
+
+static int _find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
+ const char *p;
+ char *new;
+ int len = strlen(s) + 1;
+ int err;
+
+ p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
+ if (p)
+ /* found it */
+ return (p - strtab);
+
+ new = strtab + fdt_size_dt_strings(fdt);
+ err = _blob_splice_string(fdt, len);
+ if (err)
+ return err;
+
+ memcpy(new, s, len);
+ return (new - strtab);
+}
+
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int err;
+
+ if ((err = rw_check_header(fdt)))
+ return err;
+
+ re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
+ err = _blob_splice_mem_rsv(fdt, re, 0, 1);
+ if (err)
+ return err;
+
+ re->address = cpu_to_fdt64(address);
+ re->size = cpu_to_fdt64(size);
+ return 0;
+}
+
+int fdt_del_mem_rsv(void *fdt, int n)
+{
+ struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+ int err;
+
+ if ((err = rw_check_header(fdt)))
+ return err;
+ if (n >= fdt_num_mem_rsv(fdt))
+ return -FDT_ERR_NOTFOUND;
+
+ err = _blob_splice_mem_rsv(fdt, re, 1, 0);
+ if (err)
+ return err;
+ return 0;
+}
+
+static int _resize_property(void *fdt, int nodeoffset, const char *name, int len,
+ struct fdt_property **prop)
+{
+ int oldlen;
+ int err;
+
+ *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (! (*prop))
+ return oldlen;
+
+ if ((err = _blob_splice_struct(fdt, (*prop)->data,
+ ALIGN(oldlen, FDT_TAGSIZE),
+ ALIGN(len, FDT_TAGSIZE))))
+ return err;
+
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
+ struct fdt_property **prop)
+{
+ uint32_t tag;
+ int proplen;
+ int nextoffset;
+ int namestroff;
+ int err;
+
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+
+ namestroff = _find_add_string(fdt, name);
+ if (namestroff < 0)
+ return namestroff;
+
+ *prop = _fdt_offset_ptr_w(fdt, nextoffset);
+ proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE);
+
+ err = _blob_splice_struct(fdt, *prop, 0, proplen);
+ if (err)
+ return err;
+
+ (*prop)->tag = cpu_to_fdt32(FDT_PROP);
+ (*prop)->nameoff = cpu_to_fdt32(namestroff);
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err;
+
+ if ((err = rw_check_header(fdt)))
+ return err;
+
+ err = _resize_property(fdt, nodeoffset, name, len, &prop);
+ if (err == -FDT_ERR_NOTFOUND)
+ err = _add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+
+ memcpy(prop->data, val, len);
+ return 0;
+}
+
+int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len, proplen;
+
+ RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+ if (! prop)
+ return len;
+
+ proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE);
+ return _blob_splice_struct(fdt, prop, proplen, 0);
+}
+
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen)
+{
+ struct fdt_node_header *nh;
+ int offset, nextoffset;
+ int nodelen;
+ int err;
+ uint32_t tag;
+ uint32_t *endtag;
+
+ RW_CHECK_HEADER(fdt);
+
+ offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
+ if (offset >= 0)
+ return -FDT_ERR_EXISTS;
+ else if (offset != -FDT_ERR_NOTFOUND)
+ return offset;
+
+ /* Try to place the new node after the parent's properties */
+ fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ } while (tag == FDT_PROP);
+
+ nh = _fdt_offset_ptr_w(fdt, offset);
+ nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE;
+
+ err = _blob_splice_struct(fdt, nh, 0, nodelen);
+ if (err)
+ return err;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE));
+ memcpy(nh->name, name, namelen);
+ endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE);
+ *endtag = cpu_to_fdt32(FDT_END_NODE);
+
+ return offset;
+}
+
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+ return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_del_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ RW_CHECK_HEADER(fdt);
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
+ endoffset - nodeoffset, 0);
+}
+
+static void _packblocks(const void *fdt, void *buf,
+ int mem_rsv_size, int struct_size)
+{
+ int mem_rsv_off, struct_off, strings_off;
+
+ mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8);
+ struct_off = mem_rsv_off + mem_rsv_size;
+ strings_off = struct_off + struct_size;
+
+ memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
+ fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
+
+ memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
+ fdt_set_off_dt_struct(buf, struct_off);
+ fdt_set_size_dt_struct(buf, struct_size);
+
+ memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
+ fdt_size_dt_strings(fdt));
+ fdt_set_off_dt_strings(buf, strings_off);
+ fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
+}
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize)
+{
+ int err;
+ int mem_rsv_size, struct_size;
+ int newsize;
+ void *tmp;
+
+ err = fdt_check_header(fdt);
+ if (err)
+ return err;
+
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+
+ if (fdt_version(fdt) >= 17) {
+ struct_size = fdt_size_dt_struct(fdt);
+ } else {
+ struct_size = 0;
+ while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
+ ;
+ }
+
+ if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+ /* no further work necessary */
+ err = fdt_move(fdt, buf, bufsize);
+ if (err)
+ return err;
+ fdt_set_version(buf, 17);
+ fdt_set_size_dt_struct(buf, struct_size);
+ fdt_set_totalsize(buf, bufsize);
+ return 0;
+ }
+
+ /* Need to reorder */
+ newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+ + struct_size + fdt_size_dt_strings(fdt);
+
+ if (bufsize < newsize)
+ return -FDT_ERR_NOSPACE;
+
+ if (((buf + newsize) <= fdt)
+ || (buf >= (fdt + fdt_totalsize(fdt)))) {
+ tmp = buf;
+ } else {
+ tmp = (void *)fdt + fdt_totalsize(fdt);
+ if ((tmp + newsize) > (buf + bufsize))
+ return -FDT_ERR_NOSPACE;
+ }
+
+ _packblocks(fdt, tmp, mem_rsv_size, struct_size);
+ memmove(buf, tmp, newsize);
+
+ fdt_set_magic(buf, FDT_MAGIC);
+ fdt_set_totalsize(buf, bufsize);
+ fdt_set_version(buf, 17);
+ fdt_set_last_comp_version(buf, 16);
+ fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
+
+ return 0;
+}
+
+int fdt_pack(void *fdt)
+{
+ int mem_rsv_size;
+ int err;
+
+ err = rw_check_header(fdt);
+ if (err)
+ return err;
+
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+ _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+ fdt_set_totalsize(fdt, _blob_data_size(fdt));
+
+ return 0;
+}
Index: working-2.6/arch/powerpc/boot/libfdt/fdt_strerror.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt_strerror.c 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,96 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+struct errtabent {
+ const char *str;
+};
+
+#define ERRTABENT(val) \
+ [(val)] = { .str = #val, }
+
+static struct errtabent errtable[] = {
+ ERRTABENT(FDT_ERR_NOTFOUND),
+ ERRTABENT(FDT_ERR_EXISTS),
+ ERRTABENT(FDT_ERR_NOSPACE),
+
+ ERRTABENT(FDT_ERR_BADOFFSET),
+ ERRTABENT(FDT_ERR_BADPATH),
+ ERRTABENT(FDT_ERR_BADSTATE),
+
+ ERRTABENT(FDT_ERR_TRUNCATED),
+ ERRTABENT(FDT_ERR_BADMAGIC),
+ ERRTABENT(FDT_ERR_BADVERSION),
+ ERRTABENT(FDT_ERR_BADSTRUCTURE),
+ ERRTABENT(FDT_ERR_BADLAYOUT),
+};
+#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0]))
+
+const char *fdt_strerror(int errval)
+{
+ if (errval > 0)
+ return "<valid offset/length>";
+ else if (errval == 0)
+ return "<no error>";
+ else if (errval > -ERRTABSIZE) {
+ const char *s = errtable[-errval].str;
+
+ if (s)
+ return s;
+ }
+
+ return "<unknown error>";
+}
Index: working-2.6/arch/powerpc/boot/libfdt/fdt_sw.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt_sw.c 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,258 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int check_header_sw(void *fdt)
+{
+ if (fdt_magic(fdt) != SW_MAGIC)
+ return -FDT_ERR_BADMAGIC;
+ return 0;
+}
+
+static void *grab_space(void *fdt, int len)
+{
+ int offset = fdt_size_dt_struct(fdt);
+ int spaceleft;
+
+ spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
+ - fdt_size_dt_strings(fdt);
+
+ if ((offset + len < offset) || (offset + len > spaceleft))
+ return NULL;
+
+ fdt_set_size_dt_struct(fdt, offset + len);
+ return fdt_offset_ptr_w(fdt, offset, len);
+}
+
+int fdt_create(void *buf, int bufsize)
+{
+ void *fdt = buf;
+
+ if (bufsize < sizeof(struct fdt_header))
+ return -FDT_ERR_NOSPACE;
+
+ memset(buf, 0, bufsize);
+
+ fdt_set_magic(fdt, SW_MAGIC);
+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_totalsize(fdt, bufsize);
+
+ fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header),
+ sizeof(struct fdt_reserve_entry)));
+ fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
+ fdt_set_off_dt_strings(fdt, bufsize);
+
+ return 0;
+}
+
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int err = check_header_sw(fdt);
+ int offset;
+
+ if (err)
+ return err;
+ if (fdt_size_dt_struct(fdt))
+ return -FDT_ERR_BADSTATE;
+
+ offset = fdt_off_dt_struct(fdt);
+ if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
+ return -FDT_ERR_NOSPACE;
+
+ re = (struct fdt_reserve_entry *)(fdt + offset);
+ re->address = cpu_to_fdt64(addr);
+ re->size = cpu_to_fdt64(size);
+
+ fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
+
+ return 0;
+}
+
+int fdt_finish_reservemap(void *fdt)
+{
+ return fdt_add_reservemap_entry(fdt, 0, 0);
+}
+
+int fdt_begin_node(void *fdt, const char *name)
+{
+ struct fdt_node_header *nh;
+ int err = check_header_sw(fdt);
+ int namelen = strlen(name) + 1;
+
+ if (err)
+ return err;
+
+ nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
+ if (! nh)
+ return -FDT_ERR_NOSPACE;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memcpy(nh->name, name, namelen);
+ return 0;
+}
+
+int fdt_end_node(void *fdt)
+{
+ uint32_t *en;
+ int err = check_header_sw(fdt);
+
+ if (err)
+ return err;
+
+ en = grab_space(fdt, FDT_TAGSIZE);
+ if (! en)
+ return -FDT_ERR_NOSPACE;
+
+ *en = cpu_to_fdt32(FDT_END_NODE);
+ return 0;
+}
+
+static int find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_totalsize(fdt);
+ const char *p;
+ int strtabsize = fdt_size_dt_strings(fdt);
+ int len = strlen(s) + 1;
+ int struct_top, offset;
+
+ p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
+ if (p)
+ return p - strtab;
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ if (fdt_totalsize(fdt) + offset < struct_top)
+ return 0; /* no more room :( */
+
+ memcpy(strtab + offset, s, len);
+ fdt_set_size_dt_strings(fdt, strtabsize + len);
+ return offset;
+}
+
+int fdt_property(void *fdt, const char *name, const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err = check_header_sw(fdt);
+ int nameoff;
+
+ if (err)
+ return err;
+
+ nameoff = find_add_string(fdt, name);
+ if (nameoff == 0)
+ return -FDT_ERR_NOSPACE;
+
+ prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE));
+ if (! prop)
+ return -FDT_ERR_NOSPACE;
+
+ prop->tag = cpu_to_fdt32(FDT_PROP);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ prop->len = cpu_to_fdt32(len);
+ memcpy(prop->data, val, len);
+ return 0;
+}
+
+int fdt_finish(void *fdt)
+{
+ int err = check_header_sw(fdt);
+ char *p = (char *)fdt;
+ uint32_t *end;
+ int oldstroffset, newstroffset;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ if (err)
+ return err;
+
+ /* Add terminator */
+ end = grab_space(fdt, sizeof(*end));
+ if (! end)
+ return -FDT_ERR_NOSPACE;
+ *end = cpu_to_fdt32(FDT_END);
+
+ /* Relocate the string table */
+ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
+ newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
+ fdt_set_off_dt_strings(fdt, newstroffset);
+
+ /* Walk the structure, correcting string offsets */
+ offset = 0;
+ while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
+ if (tag == FDT_PROP) {
+ struct fdt_property *prop =
+ fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
+ int nameoff;
+
+ if (! prop)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ nameoff = fdt32_to_cpu(prop->nameoff);
+ nameoff += fdt_size_dt_strings(fdt);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ }
+ offset = nextoffset;
+ }
+
+ /* Finally, adjust the header */
+ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
+ fdt_set_magic(fdt, FDT_MAGIC);
+ return 0;
+}
Index: working-2.6/arch/powerpc/boot/libfdt/fdt_wip.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/fdt_wip.c 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,144 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ void *propval;
+ int proplen;
+
+ propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
+ if (! propval)
+ return proplen;
+
+ if (proplen != len)
+ return -FDT_ERR_NOSPACE;
+
+ memcpy(propval, val, len);
+ return 0;
+}
+
+static void nop_region(void *start, int len)
+{
+ uint32_t *p;
+
+ for (p = start; (void *)p < (start + len); p++)
+ *p = cpu_to_fdt32(FDT_NOP);
+}
+
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+ if (! prop)
+ return len;
+
+ nop_region(prop, len + sizeof(*prop));
+
+ return 0;
+}
+
+int _fdt_node_end_offset(void *fdt, int nodeoffset)
+{
+ int level = 0;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_END:
+ return offset;
+
+ case FDT_BEGIN_NODE:
+ level++;
+ break;
+
+ case FDT_END_NODE:
+ level--;
+ break;
+
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (level >= 0);
+
+ return nextoffset;
+}
+
+int fdt_nop_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset);
+ return 0;
+}
Index: working-2.6/arch/powerpc/boot/libfdt/libfdt.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/libfdt.h 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,721 @@
+#ifndef _LIBFDT_H
+#define _LIBFDT_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <libfdt_env.h>
+#include <fdt.h>
+
+#define FDT_FIRST_SUPPORTED_VERSION 0x10
+#define FDT_LAST_SUPPORTED_VERSION 0x11
+
+/* Error codes: informative error codes */
+#define FDT_ERR_NOTFOUND 1
+ /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
+#define FDT_ERR_EXISTS 2
+ /* FDT_ERR_EXISTS: Attemped to create a node or property which
+ * already exists */
+#define FDT_ERR_NOSPACE 3
+ /* FDT_ERR_NOSPACE: Operation needed to expand the device
+ * tree, but its buffer did not have sufficient space to
+ * contain the expanded tree. Use fdt_open_into() to move the
+ * device tree to a buffer with more space. */
+
+/* Error codes: codes for bad parameters */
+#define FDT_ERR_BADOFFSET 4
+ /* FDT_ERR_BADOFFSET: Function was passed a structure block
+ * offset which is out-of-bounds, or which points to an
+ * unsuitable part of the structure for the operation. */
+#define FDT_ERR_BADPATH 5
+ /* FDT_ERR_BADPATH: Function was passed a badly formatted path
+ * (e.g. missing a leading / for a function which requires an
+ * absolute path) */
+#define FDT_ERR_BADPHANDLE 6
+ /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
+ * value. phandle values of 0 and -1 are not permitted. */
+#define FDT_ERR_BADSTATE 7
+ /* FDT_ERR_BADSTATE: Function was passed an incomplete device
+ * tree created by the sequential-write functions, which is
+ * not sufficiently complete for the requested operation. */
+
+/* Error codes: codes for bad device tree blobs */
+#define FDT_ERR_TRUNCATED 8
+ /* FDT_ERR_TRUNCATED: Structure block of the given device tree
+ * ends without an FDT_END tag. */
+#define FDT_ERR_BADMAGIC 9
+ /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
+ * device tree at all - it is missing the flattened device
+ * tree magic number. */
+#define FDT_ERR_BADVERSION 10
+ /* FDT_ERR_BADVERSION: Given device tree has a version which
+ * can't be handled by the requested operation. For
+ * read-write functions, this may mean that fdt_open_into() is
+ * required to convert the tree to the expected version. */
+#define FDT_ERR_BADSTRUCTURE 11
+ /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
+ * structure block or other serious error (e.g. misnested
+ * nodes, or subnodes preceding properties). */
+#define FDT_ERR_BADLAYOUT 12
+ /* FDT_ERR_BADLAYOUT: For read-write functions, the given
+ * device tree has it's sub-blocks in an order that the
+ * function can't handle (memory reserve map, then structure,
+ * then strings). Use fdt_open_into() to reorganize the tree
+ * into a form suitable for the read-write operations. */
+
+/* "Can't happen" error indicating a bug in libfdt */
+#define FDT_ERR_INTERNAL 13
+ /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
+ * Should never be returned, if it is, it indicates a bug in
+ * libfdt itself. */
+
+#define FDT_ERR_MAX 13
+
+/**********************************************************************/
+/* Low-level functions (you probably don't need these) */
+/**********************************************************************/
+
+const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
+static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
+{
+ return (void *)fdt_offset_ptr(fdt, offset, checklen);
+}
+
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
+
+/**********************************************************************/
+/* General functions */
+/**********************************************************************/
+
+#define fdt_get_header(fdt, field) \
+ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
+#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
+#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
+#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
+#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
+#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
+#define fdt_version(fdt) (fdt_get_header(fdt, version))
+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
+#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
+
+#define __fdt_set_hdr(name) \
+ static inline void fdt_set_##name(void *fdt, uint32_t val) \
+ { \
+ struct fdt_header *fdth = fdt; \
+ fdth->name = cpu_to_fdt32(val); \
+ }
+__fdt_set_hdr(magic);
+__fdt_set_hdr(totalsize);
+__fdt_set_hdr(off_dt_struct);
+__fdt_set_hdr(off_dt_strings);
+__fdt_set_hdr(off_mem_rsvmap);
+__fdt_set_hdr(version);
+__fdt_set_hdr(last_comp_version);
+__fdt_set_hdr(boot_cpuid_phys);
+__fdt_set_hdr(size_dt_strings);
+__fdt_set_hdr(size_dt_struct);
+#undef __fdt_set_hdr
+
+/**
+ * fdt_check_header - sanity check a device tree or possible device tree
+ * @fdt: pointer to data which might be a flattened device tree
+ *
+ * fdt_check_header() checks that the given buffer contains what
+ * appears to be a flattened device tree with sane information in its
+ * header.
+ *
+ * returns:
+ * 0, if the buffer appears to contain a valid device tree
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings, as above
+ */
+int fdt_check_header(const void *fdt);
+
+/**
+ * fdt_move - move a device tree around in memory
+ * @fdt: pointer to the device tree to move
+ * @buf: pointer to memory where the device is to be moved
+ * @bufsize: size of the memory space at buf
+ *
+ * fdt_move() relocates, if possible, the device tree blob located at
+ * fdt to the buffer at buf of size bufsize. The buffer may overlap
+ * with the existing device tree blob at fdt. Therefore,
+ * fdt_move(fdt, fdt, fdt_totalsize(fdt))
+ * should always succeed.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_move(const void *fdt, void *buf, int bufsize);
+
+/**********************************************************************/
+/* Read-only functions */
+/**********************************************************************/
+
+/**
+ * fdt_string - retreive a string from the strings block of a device tree
+ * @fdt: pointer to the device tree blob
+ * @stroffset: offset of the string within the strings block (native endian)
+ *
+ * fdt_string() retrieves a pointer to a single string from the
+ * strings block of the device tree blob at fdt.
+ *
+ * returns:
+ * a pointer to the string, on success
+ * NULL, if stroffset is out of bounds
+ */
+const char *fdt_string(const void *fdt, int stroffset);
+
+/**
+ * fdt_num_mem_rsv - retreive the number of memory reserve map entries
+ * @fdt: pointer to the device tree blob
+ *
+ * Returns the number of entries in the device tree blob's memory
+ * reservation map. This does not include the terminating 0,0 entry
+ * or any other (0,0) entries reserved for expansion.
+ *
+ * returns:
+ * the number of entries
+ */
+int fdt_num_mem_rsv(const void *fdt);
+
+/**
+ * fdt_get_mem_rsv - retreive one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: pointers to 64-bit variables
+ *
+ * On success, *address and *size will contain the address and size of
+ * the n-th reserve map entry from the device tree blob, in
+ * native-endian format.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
+
+/**
+ * fdt_subnode_offset_namelen - find a subnode based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_subnode_offset(), but only examine the first
+ * namelen characters of name for matching the subnode name. This is
+ * useful for finding subnodes based on a portion of a larger string,
+ * such as a full path.
+ */
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ const char *name, int namelen);
+/**
+ * fdt_subnode_offset - find a subnode of a given node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_subnode_offset() finds a subnode of the node at structure block
+ * offset parentoffset with the given name. name may include a unit
+ * address, in which case fdt_subnode_offset() will find the subnode
+ * with that unit address, or the unit address may be omitted, in
+ * which case fdt_subnode_offset() will find an arbitrary subnode
+ * whose name excluding unit address matches the given name.
+ *
+ * returns:
+ * structure block offset of the requested subnode (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
+
+/**
+ * fdt_path_offset - find a tree node by its full path
+ * @fdt: pointer to the device tree blob
+ * @path: full path of the node to locate
+ *
+ * fdt_path_offset() finds a node of a given path in the device tree.
+ * Each path component may omit the unit address portion, but the
+ * results of this are undefined if any such path component is
+ * ambiguous (that is if there are multiple nodes at the relevant
+ * level matching the given component, differentiated only by unit
+ * address).
+ *
+ * returns:
+ * structure block offset of the node with the requested path (>=0), on success
+ * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
+ * -FDT_ERR_NOTFOUND, if the requested node does not exist
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_path_offset(const void *fdt, const char *path);
+
+/**
+ * fdt_get_name - retreive the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the starting node
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_name() retrieves the name (including unit address) of the
+ * device tree node at structure block offset nodeoffset. If lenp is
+ * non-NULL, the length of this name is also returned, in the integer
+ * pointed to by lenp.
+ *
+ * returns:
+ * pointer to the node's name, on success
+ * If lenp is non-NULL, *lenp contains the length of that name (>=0)
+ * NULL, on error
+ * if lenp is non-NULL *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
+
+/**
+ * fdt_get_property - find a given property in a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property() retrieves a pointer to the fdt_property
+ * structure within the device tree blob corresponding to the property
+ * named 'name' of the node at offset nodeoffset. If lenp is
+ * non-NULL, the length of the property value also returned, in the
+ * integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_NOTFOUND, node does not have named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
+ const char *name,
+ int *lenp)
+{
+ return (struct fdt_property *)fdt_get_property(fdt, nodeoffset,
+ name, lenp);
+}
+
+/**
+ * fdt_getprop - retrieve the value of a given property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop() retrieves a pointer to the value of the property
+ * named 'name' of the node at offset nodeoffset (this will be a
+ * pointer to within the device blob itself, not a copy of the value).
+ * If lenp is non-NULL, the length of the property value also
+ * returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_NOTFOUND, node does not have named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ return (void *)fdt_getprop(fdt, nodeoffset, name, lenp);
+}
+
+/**
+ * fdt_get_phandle - retreive the phandle of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the node
+ *
+ * fdt_get_phandle() retrieves the phandle of the device tree node at
+ * structure block offset nodeoffset.
+ *
+ * returns:
+ * the phandle of the node at nodeoffset, on succes (!= 0, != -1)
+ * 0, if the node has no phandle, or another error occurs
+ */
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_get_path - determine the full path of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose path to find
+ * @buf: character buffer to contain the returned path (will be overwritten)
+ * @buflen: size of the character buffer at buf
+ *
+ * fdt_get_path() computes the full path of the node at offset
+ * nodeoffset, and records that path in the buffer at buf.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * 0, on success
+ * buf contains the absolute path of the node at
+ * nodeoffset, as a NUL-terminated string.
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
+ * characters and will not fit in the given buffer.
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
+
+/**
+ * fdt_supernode_atdepth_offset - find a specific ancestor of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ * @supernodedepth: depth of the ancestor to find
+ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_supernode_atdepth_offset() finds an ancestor of the given node
+ * at a specific depth from the root (where the root itself has depth
+ * 0, its immediate subnodes depth 1 and so forth). So
+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
+ * will always return 0, the offset of the root node. If the node at
+ * nodeoffset has depth D, then:
+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
+ * will return nodeoffset itself.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+
+ * structure block offset of the node at node offset's ancestor
+ * of depth supernodedepth (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth);
+
+/**
+ * fdt_node_depth - find the depth of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_node_depth() finds the depth of a given node. The root node
+ * has depth 0, its immediate subnodes depth 1 and so forth.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * depth of the node at nodeoffset (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_depth(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_parent_offset - find the parent of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_parent_offset() locates the parent node of a given node (that
+ * is, it finds the offset of the node which contains the node at
+ * nodeoffset as a subnode).
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset, *twice*.
+ *
+ * returns:
+ * stucture block offset of the parent of the node at nodeoffset
+ * (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_parent_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_node_offset_by_prop_value - find nodes with a given property value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @propname: property name to check
+ * @propval: property value to search for
+ * @proplen: length of the value in propval
+ *
+ * fdt_node_offset_by_prop_value() returns the offset of the first
+ * node after startoffset, which has a property named propname whose
+ * value is of length proplen and has value equal to propval; or if
+ * startoffset is -1, the very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
+ * propval, proplen);
+ * while (offset != -FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
+ * propval, proplen);
+ * }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0, >startoffset),
+ * on success
+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ * tree after startoffset
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen);
+
+/**
+ * fdt_node_offset_by_phandle - find the node with a given phandle
+ * @fdt: pointer to the device tree blob
+ * @phandle: phandle value
+ *
+ * fdt_node_offset_by_prop_value() returns the offset of the node
+ * which has the given phandle value. If there is more than one node
+ * in the tree with the given phandle (an invalid tree), results are
+ * undefined.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0), on success
+ * -FDT_ERR_NOTFOUND, no node with that phandle exists
+ * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
+
+/**
+ * fdt_node_check_compatible: check a node's compatible property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @compatible: string to match against
+ *
+ *
+ * fdt_node_check_compatible() returns 0 if the given node contains a
+ * 'compatible' property with the given string as one of its elements,
+ * it returns non-zero otherwise, or on error.
+ *
+ * returns:
+ * 0, if the node has a 'compatible' property listing the given string
+ * 1, if the node has a 'compatible' property, but it does not list
+ * the given string
+ * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+ const char *compatible);
+
+/**
+ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @compatible: 'compatible' string to match against
+ *
+ * fdt_node_offset_by_compatible() returns the offset of the first
+ * node after startoffset, which has a 'compatible' property which
+ * lists the given compatible string; or if startoffset is -1, the
+ * very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
+ * while (offset != -FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
+ * }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0, >startoffset),
+ * on success
+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ * tree after startoffset
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+ const char *compatible);
+
+/**********************************************************************/
+/* Write-in-place functions */
+/**********************************************************************/
+
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+int fdt_nop_node(void *fdt, int nodeoffset);
+
+/**********************************************************************/
+/* Sequential write functions */
+/**********************************************************************/
+
+int fdt_create(void *buf, int bufsize);
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
+int fdt_finish_reservemap(void *fdt);
+int fdt_begin_node(void *fdt, const char *name);
+int fdt_property(void *fdt, const char *name, const void *val, int len);
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_property(fdt, name, &val, sizeof(val));
+}
+#define fdt_property_string(fdt, name, str) \
+ fdt_property(fdt, name, str, strlen(str)+1)
+int fdt_end_node(void *fdt);
+int fdt_finish(void *fdt);
+
+/**********************************************************************/
+/* Read-write functions */
+/**********************************************************************/
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize);
+int fdt_pack(void *fdt);
+
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
+int fdt_del_mem_rsv(void *fdt, int n);
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+#define fdt_setprop_string(fdt, nodeoffset, name, str) \
+ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen);
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+int fdt_del_node(void *fdt, int nodeoffset);
+
+/**********************************************************************/
+/* Debugging / informational functions */
+/**********************************************************************/
+
+const char *fdt_strerror(int errval);
+
+#endif /* _LIBFDT_H */
Index: working-2.6/arch/powerpc/boot/libfdt/libfdt_internal.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/arch/powerpc/boot/libfdt/libfdt_internal.h 2007-12-10 14:20:16.000000000 +1100
@@ -0,0 +1,89 @@
+#ifndef _LIBFDT_INTERNAL_H
+#define _LIBFDT_INTERNAL_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <fdt.h>
+
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a)))
+
+#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
+#define streq(p, q) (strcmp((p), (q)) == 0)
+
+uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
+int _fdt_node_end_offset(void *fdt, int nodeoffset);
+
+static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+{
+ return fdt + fdt_off_dt_struct(fdt) + offset;
+}
+
+static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+{
+ return (void *)_fdt_offset_ptr(fdt, offset);
+}
+
+static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+{
+ const struct fdt_reserve_entry *rsv_table =
+ fdt + fdt_off_mem_rsvmap(fdt);
+
+ return rsv_table + n;
+}
+static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+{
+ return (void *)_fdt_mem_rsv(fdt, n);
+}
+
+#define SW_MAGIC (~FDT_MAGIC)
+
+#endif /* _LIBFDT_INTERNAL_H */
^ permalink raw reply
* [0/3] Merge libfdt into the bootwrapper
From: David Gibson @ 2007-12-10 3:23 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Since there's still argument about what to do with dtc w.r.t. the
kernel, for now here's a cut down series which merges libfdt into the
powerpc bootwrapper.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* looking for ibook users
From: Benjamin Herrenschmidt @ 2007-12-10 1:37 UTC (permalink / raw)
To: linuxppc-dev
Hi !
If you have an ibook in linux and your dmesg contains something like:
"Apple USB OHCI xxxx:xx:xx disabled by firmware"
Can you contact me privately ? I'm about to make some change that could
cause problems with those unless I find somebody to test and make sure
it's allright.
Thanks !
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 18/25] powerpc: Base support for 440GX Taishan eval board
From: Josh Boyer @ 2007-12-10 1:29 UTC (permalink / raw)
To: benh; +Cc: Olof Johansson, linuxppc-dev, Stephen, Rothwell
In-Reply-To: <1197230313.6563.0.camel@pasglop>
On Mon, 10 Dec 2007 06:58:33 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> On Sun, 2007-12-09 at 11:24 -0600, Olof Johansson wrote:
> > On Sun, Dec 09, 2007 at 06:01:55PM +1100, Benjamin Herrenschmidt wrote:
> >
> > > Ah yeah, indeed. I'll fix these. (BTW. Could you CC Hugh next time as
> > > he's the author).
> >
> > I didn't see him Cc:d on the patch submission, and I'm guessing Josh did
> > a reply-all. Seems as if the mailing list manager strips Cc fields of
> > people already subscribed to the list, I've seen it before.
>
> Yeah, my script for mailing quilt series doesn't do the selective CC
> thingy... Bah, mpe wrote it, I suppose I can either nag him to fix it or
> start learning perl :-)
Or you could just use 'quilt mail' ...
josh
^ permalink raw reply
* FSL device-trees i8259 bugs (and others too !)
From: Benjamin Herrenschmidt @ 2007-12-10 0:35 UTC (permalink / raw)
To: linuxppc-dev list; +Cc: Kumar Gala
Hi !
I've been looking into making the 8259 driver properly apply the sense
setting to the chip. We'll probably need that for PReP and I was looking
into some issues with legacy IDE controllers flipping between legacy and
native mode since that changes the IRQ as well (legacy mode is rising
edge, while native mode is level low).
A bit of grepp'ing in arch/powerpc/boot/dts/ seems to show however that
this will break a few things in FSL land though.
First, let's quickly pass on mpc8555cds.dts which seems to have a
totally bogus 8259 node... Nodes below a PCI bridge are supposed to be
PCI devices. This isn't one, and that may cause problems in the long
run.
Then, it seems that mpc8544ds, mpc8572ds and mpc8641_hpcn all declare
interrupt maps that point to the 8259 as the parent controller... and
set the sense of all PCI interrupts to 2, which for an 8259 means
falling edge... Doesn't seem correct to me. PCI interrupts are level
low.
There might be more of such things, so if your platform uses an 8259,
please double check your IRQ sense encoding. Remember, for 8259, the
encoding is specified in the OF ISA spec and is:
0 = level low
1 = level high
2 = falling edge
3 = rising edge
Of course, Pegasos is broken, as usual, but I'll do quirks for it.
Cheers,
Ben.
^ permalink raw reply
* Test, please ignore
From: Stephen Rothwell @ 2007-12-09 23:56 UTC (permalink / raw)
To: ppc-dev; +Cc: sfr
[-- Attachment #1: Type: text/plain, Size: 141 bytes --]
Just a test of the CC munging.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* CC munging
From: Stephen Rothwell @ 2007-12-09 23:53 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 526 bytes --]
Hi all,
Mailman has an option that strips people's addresses from the CC list of
emails if they are also members of the list. The default for the per
user option is on.
I have now changed the default for new users to not do this stripping.
Current users can change their own setting by going to
https://ozlabs.org/listinfo/linuxppc-embedded and changing the "Avoid
duplicate copies of messages?" option.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* CC munging by mailman lists (Was: Re: [PATCH 18/25] powerpc: Base support for 440GX Taishan eval board)
From: Stephen Rothwell @ 2007-12-09 23:43 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20071209172404.GA26651@lixom.net>
[-- Attachment #1: Type: text/plain, Size: 787 bytes --]
On Sun, 9 Dec 2007 11:24:04 -0600 Olof Johansson <olof@lixom.net> wrote:
>
> I didn't see him Cc:d on the patch submission, and I'm guessing Josh did
> a reply-all. Seems as if the mailing list manager strips Cc fields of
> people already subscribed to the list, I've seen it before.
Ok, this is a per user setting with the default for new users set to
attempt to strip the user from the CC header if they are a member of the
list.
I have now changed the default for new users to not do this stripping.
Current users can change their own setting by going to
https://ozlabs.org/listinfo/linuxppc-dev and changing the "Avoid
duplicate copies of messages?" option.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH 4/4] Convert pfc8563 i2c driver from old style to new style
From: Jon Smirl @ 2007-12-09 23:36 UTC (permalink / raw)
To: i2c, linuxppc-dev
In-Reply-To: <20071209233648.2327.14584.stgit@terra.home>
Convert pfc8563 i2c driver from old style to new style. The
driver is also modified to support device tree names via the
i2c mod alias mechanism.
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
drivers/rtc/rtc-pcf8563.c | 110 ++++++++++++---------------------------------
1 files changed, 30 insertions(+), 80 deletions(-)
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 0242d80..7da2cd0 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -25,10 +25,6 @@
* located at 0x51 will pass the validation routine due to
* the way the registers are implemented.
*/
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Module parameters */
-I2C_CLIENT_INSMOD;
#define PCF8563_REG_ST1 0x00 /* status */
#define PCF8563_REG_ST2 0x01
@@ -72,9 +68,6 @@ struct pcf8563 {
int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
};
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8563_detach(struct i2c_client *client);
-
/*
* In the routines that deal directly with the pcf8563 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -257,98 +250,55 @@ static const struct rtc_class_ops pcf8563_rtc_ops = {
.set_time = pcf8563_rtc_set_time,
};
-static int pcf8563_attach(struct i2c_adapter *adapter)
+static int pcf8563_remove(struct i2c_client *client)
{
- return i2c_probe(adapter, &addr_data, pcf8563_probe);
+ struct rtc_device *rtc = i2c_get_clientdata(client);
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+
+ return 0;
}
+static struct i2c_device_id pcf8563_id[] = {
+ {"rtc-pcf8563", 0},
+ {"pcf8563", 0},
+ {"philips,pcf8563", 0},
+ {"rtc8564", 0},
+ {"epson,rtc8564", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, pcf8563_id);
+
+static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id);
+
static struct i2c_driver pcf8563_driver = {
.driver = {
- .name = "pcf8563",
+ .name = "rtc-pcf8563",
},
.id = I2C_DRIVERID_PCF8563,
- .attach_adapter = &pcf8563_attach,
- .detach_client = &pcf8563_detach,
+ .probe = &pcf8563_probe,
+ .remove = &pcf8563_remove,
+ .id_table = pcf8563_id,
};
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
+static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct pcf8563 *pcf8563;
- struct i2c_client *client;
+ int result;
struct rtc_device *rtc;
- int err = 0;
-
- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
- err = -ENODEV;
- goto exit;
- }
-
- if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- client = &pcf8563->client;
- client->addr = address;
- client->driver = &pcf8563_driver;
- client->adapter = adapter;
-
- strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
-
- /* Verify the chip is really an PCF8563 */
- if (kind < 0) {
- if (pcf8563_validate_client(client) < 0) {
- err = -ENODEV;
- goto exit_kfree;
- }
- }
-
- /* Inform the i2c layer */
- if ((err = i2c_attach_client(client)))
- goto exit_kfree;
-
- dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
+ result = pcf8563_validate_client(client);
+ if (result)
+ return result;
rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
&pcf8563_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(rtc)) {
- err = PTR_ERR(rtc);
- goto exit_detach;
- }
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
return 0;
-
-exit_detach:
- i2c_detach_client(client);
-
-exit_kfree:
- kfree(pcf8563);
-
-exit:
- return err;
-}
-
-static int pcf8563_detach(struct i2c_client *client)
-{
- struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
- int err;
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- kfree(pcf8563);
-
- return 0;
}
static int __init pcf8563_init(void)
^ permalink raw reply related
* [PATCH 0/4] Series to add device tree naming to i2c
From: Jon Smirl @ 2007-12-09 23:36 UTC (permalink / raw)
To: i2c, linuxppc-dev
New verision, addresses whitespace issues
The following series implements standard linux module aliasing for i2c modules
It then converts the mpc i2c driver from being a platform driver to an open
firmware one. I2C device names are picked up from the device tree. Module
aliasing is used to translate from device tree names into to linux kernel
names. Several i2c drivers are updated to use the new aliasing.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox