From marek.belisko at open-nandra.com  Wed Dec  1 05:22:36 2010
From: marek.belisko at open-nandra.com (Marek Belisko)
Date: Wed,  1 Dec 2010 11:22:36 +0100
Subject: [PATCH] arm: mini2440: Add memory size.
Message-ID: <1291198956-20628-1-git-send-email-marek.belisko@open-nandra.com>

MINI240 board has available always 64M of memory so add
size to memory device structure.

Signed-off-by: Marek Belisko <marek.belisko at open-nandra.com>
---
 arch/arm/boards/mini2440/mini2440.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
index a673a5d..9639176 100644
--- a/arch/arm/boards/mini2440/mini2440.c
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -47,6 +47,7 @@ static struct memory_platform_data ram_pdata = {
 static struct device_d sdram_dev = {
 	.name		= "mem",
 	.map_base	= CS6_BASE,
+	.size		= 64 * 1024 * 1024,
 	.platform_data	= &ram_pdata,
 };
 
-- 
1.7.1



From of at flatfrog.com  Thu Dec  2 09:20:21 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Thu, 2 Dec 2010 15:20:21 +0100
Subject: Barebox on a 3730
Message-ID: <4CF7AB25.3010604@flatfrog.com>

Hi,

We have successfully used Barebox as bootloader on one of our own boards 
with an OMAP 3530.  Same board, but with a 3730 instead (and a few 
auxiliary components changed) I'm getting completely garbled output on 
the serial port.  I tried changing the baud rate from 115200 to 38400 
and 19200 to no avail.

Anyone here rambooted a 3730 with barebox?  (Just to rule out that I 
need to do any software changes.)

When setting the board in boot mode "60" is printed on the serial port 
by the boot ROM, the same way "40W" was printed by the 3530 so it's not 
like the serial port isn't working at all.  I can bootstrap via either 
USB or serial port.  We're using the omap3530_beagle_per_uart_defconfig.


Thanks,
Orjan

-- 
Orjan Friberg
FlatFrog Laboratories AB


From of at flatfrog.com  Thu Dec  2 10:06:43 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Thu, 2 Dec 2010 16:06:43 +0100
Subject: Barebox on a 3730
In-Reply-To: <4CF7AB25.3010604@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
Message-ID: <4CF7B603.6090407@flatfrog.com>

On 2010-12-02 15:20, Orjan Friberg wrote:
> Anyone here rambooted a 3730 with barebox?  (Just to rule out that I
> need to do any software changes.)

I do have an BeagleBoard xM but it seems the user button doesn't affect 
the boot sequence like it did on the original BeagleBoard, so I don't 
have any other hardware to try this on.

> When setting the board in boot mode "60" is printed on the serial port

... with "60" being "\x36\x30" in printable characters.  I did a hexdump 
of the garbled output and its basically a lot of 0xc0 with 0x00 
sprinkled in between.

I'd appreciate any clue as to what's happening.

Thanks,
Orjan

-- 
Orjan Friberg
FlatFrog Laboratories AB


From marek.belisko at gmail.com  Thu Dec  2 10:13:00 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Thu, 2 Dec 2010 16:13:00 +0100
Subject: Barebox on a 3730
In-Reply-To: <4CF7AB25.3010604@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
Message-ID: <AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>

Hi,

On Thu, Dec 2, 2010 at 3:20 PM, Orjan Friberg <of at flatfrog.com> wrote:
> Hi,
>
> We have successfully used Barebox as bootloader on one of our own boards
> with an OMAP 3530. ?Same board, but with a 3730 instead (and a few auxiliary
> components changed) I'm getting completely garbled output on the serial
> port. ?I tried changing the baud rate from 115200 to 38400 and 19200 to no
> avail.
Not have omap3530 or other but have same issue with different board type.
Problem was with clock setup for serial. Just an idea check if clock is correct
according data sheet. Maybe 37xx differs from 35xx ;)
>
> Anyone here rambooted a 3730 with barebox? ?(Just to rule out that I need to
> do any software changes.)
>
> When setting the board in boot mode "60" is printed on the serial port by
> the boot ROM, the same way "40W" was printed by the 3530 so it's not like
> the serial port isn't working at all. ?I can bootstrap via either USB or
> serial port. ?We're using the omap3530_beagle_per_uart_defconfig.
>
>
> Thanks,
> Orjan
>
> --
> Orjan Friberg
> FlatFrog Laboratories AB
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From of at flatfrog.com  Thu Dec  2 11:39:44 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Thu, 2 Dec 2010 17:39:44 +0100
Subject: Barebox on a 3730
In-Reply-To: <AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
References: <4CF7AB25.3010604@flatfrog.com>
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
Message-ID: <4CF7CBD0.7080609@flatfrog.com>

On 2010-12-02 16:13, Belisko Marek wrote:
> Not have omap3530 or other but have same issue with different board type.
> Problem was with clock setup for serial. Just an idea check if clock is correct
> according data sheet. Maybe 37xx differs from 35xx ;)

Clocking looks like it should be the same but just out of curiosity, 
what issue did you have with the clock setup?  (What was bad, how did it 
manifest itself.)

I haven't found any 3530 vs. 3730 diffs in the uart configuration in 
u-boot or linux (though there is a silicon errata fix in the latest 
linux-omap-2.6 kernel related to not reading from an empty FIFO).

But then again, they could potentially both be relying on the first 
stage bootloader setting things upp correctly (and then not touching it).


Thanks,
Orjan

-- 
Orjan Friberg
FlatFrog Laboratories AB


From premi at ti.com  Thu Dec  2 11:43:09 2010
From: premi at ti.com (Premi, Sanjeev)
Date: Thu, 2 Dec 2010 22:13:09 +0530
Subject: Barebox on a 3730
In-Reply-To: <AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
References: <4CF7AB25.3010604@flatfrog.com>,
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
Message-ID: <B85A65D85D7EB246BE421B3FB0FBB5930247466DBA@dbde02.ent.ti.com>

_______________________________________
From: barebox-bounces at lists.infradead.org [barebox-bounces at lists.infradead.org] On Behalf Of Belisko Marek [marek.belisko at gmail.com]
Sent: Thursday, December 02, 2010 8:43 PM
To: Orjan Friberg
Cc: barebox at lists.infradead.org
Subject: Re: Barebox on a 3730

Hi,

On Thu, Dec 2, 2010 at 3:20 PM, Orjan Friberg <of at flatfrog.com> wrote:
> Hi,
>
> We have successfully used Barebox as bootloader on one of our own boards
> with an OMAP 3530.  Same board, but with a 3730 instead (and a few auxiliary
> components changed) I'm getting completely garbled output on the serial
> port.  I tried changing the baud rate from 115200 to 38400 and 19200 to no
> avail.
Not have omap3530 or other but have same issue with different board type.
Problem was with clock setup for serial. Just an idea check if clock is correct
according data sheet. Maybe 37xx differs from 35xx ;)

[sp] Yes. There is a difference between the 35x and 37x clock settings.

>
> Anyone here rambooted a 3730 with barebox?  (Just to rule out that I need to
> do any software changes.)

[sp] If the support does exist yet - changes are necessary.

[sp] How urgent is your need? I could make a patch - but you may have
      to wait for couple of days.

>
> When setting the board in boot mode "60" is printed on the serial port by
> the boot ROM, the same way "40W" was printed by the 3530 so it's not like
> the serial port isn't working at all.  I can bootstrap via either USB or
> serial port.  We're using the omap3530_beagle_per_uart_defconfig.


From of at flatfrog.com  Thu Dec  2 12:19:14 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Thu, 2 Dec 2010 18:19:14 +0100
Subject: Barebox on a 3730
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB5930247466DBA@dbde02.ent.ti.com>
References: <4CF7AB25.3010604@flatfrog.com>,
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247466DBA@dbde02.ent.ti.com>
Message-ID: <4CF7D512.9090908@flatfrog.com>

On 2010-12-02 17:43, Premi, Sanjeev wrote:
> [sp] How urgent is your need? I could make a patch - but you may have
>        to wait for couple of days.

Well, that would be great.  I'd be happy to help out if I can.

-- 
Orjan Friberg
FlatFrog Laboratories AB


From plagnioj at jcrosoft.com  Thu Dec  2 12:52:02 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu, 2 Dec 2010 18:52:02 +0100
Subject: [PATCH 0/12] cfi_flash: improvment
In-Reply-To: <20101129205350.GZ6017@pengutronix.de>
References: <20101126194353.GH26540@game.jcrosoft.org>
	<20101129205350.GZ6017@pengutronix.de>
Message-ID: <20101202175202.GC4450@game.jcrosoft.org>

Hi,

	update without the __raw_

please pull
The following changes since commit 4a7f56056d6aa12a0449f03eb038e4d2bf7fdd49:

  scripts: Adapt checkpatch.pl for barebox. (2010-11-29 21:56:05 +0100)

are available in the git repository at:
  git://git.jcrosoft.org/barebox.git cfi

Jean-Christophe PLAGNIOL-VILLARD (12):
      cfi_flash: move intel real protect flash support to cfi_flash_intel.c
      cfi_flash: add Atmel real protect flash support
      cfi_flash: move flash_read_uchar from inline to noinline
      cfi_flash: use amd and standard reset flash command at probing
      cfi_flash: synchronize command offsets with Linux CFI driver
      cfi_flash: update manufacturer id flash support
      cfi_flash: Introduce read and write accessors
      cfi_flash: Read whole QRY structure in one go
      cfi_flash: do not reset flash when probe fails
      cfi_flash: move reset command assigment to specific chipset init function
      cfi_flash: introduce flash cmdset fixup
      cfi_flash_amd: Add manufacturer-specific fixups

 drivers/nor/cfi_flash.c       |  303 +++++++++++++++++++----------------------
 drivers/nor/cfi_flash.h       |  120 +++++++++++++----
 drivers/nor/cfi_flash_amd.c   |  172 ++++++++++++++++++++----
 drivers/nor/cfi_flash_intel.c |   52 ++++++--
 4 files changed, 420 insertions(+), 227 deletions(-)

Best Regards,
J.
On 21:53 Mon 29 Nov     , Sascha Hauer wrote:
> Hi J,
> 
> On Fri, Nov 26, 2010 at 08:43:53PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > Hi,
> > 
> > 	the following patch series improve the current flash
> > 	by adding the atmel flash supportm fixing some issues and factorising
> > 	more the code
> > 
> > 	Found during the adding of the at91rm9200ek
> > 
> > please pull
> > The following changes since commit 53dbaf3fc7b8371ed1e24ef96715e41d60b8ebc3:
> > 
> >   Merge branch 'master' into next (2010-11-19 09:35:15 +0100)
> 
> Nice. I like this series.
> 
> Can we use readl/writel instead? The __raw_ versions do not exist on
> architectures other than ARM.
> 
> Sascha
> 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From premi at ti.com  Thu Dec  2 13:34:59 2010
From: premi at ti.com (Premi, Sanjeev)
Date: Fri, 3 Dec 2010 00:04:59 +0530
Subject: Barebox on a 3730
In-Reply-To: <4CF7CBD0.7080609@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<4CF7CBD0.7080609@flatfrog.com>
Message-ID: <B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>

> -----Original Message-----
> From: barebox-bounces at lists.infradead.org 
> [mailto:barebox-bounces at lists.infradead.org] On Behalf Of 
> Orjan Friberg
> Sent: Thursday, December 02, 2010 10:10 PM
> To: Belisko Marek
> Cc: barebox at lists.infradead.org
> Subject: Re: Barebox on a 3730
> 
> On 2010-12-02 16:13, Belisko Marek wrote:
> > Not have omap3530 or other but have same issue with 
> different board type.
> > Problem was with clock setup for serial. Just an idea check 
> if clock is correct
> > according data sheet. Maybe 37xx differs from 35xx ;)
> 
> Clocking looks like it should be the same but just out of curiosity, 
> what issue did you have with the clock setup?  (What was bad, 
> how did it 
> manifest itself.)
> 
> I haven't found any 3530 vs. 3730 diffs in the uart configuration in 
> u-boot or linux (though there is a silicon errata fix in the latest 
> linux-omap-2.6 kernel related to not reading from an empty FIFO).
> 
Look for the AM37x TRM here:
http://focus.ti.com/docs/prod/folders/print/am3715.html

> But then again, they could potentially both be relying on the first 
> stage bootloader setting things upp correctly (and then not 
> touching it).
> 
> 
> Thanks,
> Orjan
> 
> -- 
> Orjan Friberg
> FlatFrog Laboratories AB
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

From of at flatfrog.com  Fri Dec  3 02:23:50 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Fri, 3 Dec 2010 08:23:50 +0100
Subject: Barebox on a 3730
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>
References: <4CF7AB25.3010604@flatfrog.com>	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<4CF7CBD0.7080609@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>
Message-ID: <4CF89B06.3070209@flatfrog.com>

On 2010-12-02 19:34, Premi, Sanjeev wrote:
>> I haven't found any 3530 vs. 3730 diffs in the uart configuration in
>> u-boot or linux (though there is a silicon errata fix in the latest
>> linux-omap-2.6 kernel related to not reading from an empty FIFO).
>>
> Look for the AM37x TRM here:
> http://focus.ti.com/docs/prod/folders/print/am3715.html

Any specific section you were thinking of?  I did look in the UART 
section of the TRM before and established that it was still driven by a 
48 MHz clock.

-- 
Orjan Friberg
FlatFrog Laboratories AB


From marek.belisko at gmail.com  Fri Dec  3 02:33:08 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 3 Dec 2010 08:33:08 +0100
Subject: Barebox on a 3730
In-Reply-To: <4CF89B06.3070209@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<4CF7CBD0.7080609@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>
	<4CF89B06.3070209@flatfrog.com>
Message-ID: <AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>

On Fri, Dec 3, 2010 at 8:23 AM, Orjan Friberg <of at flatfrog.com> wrote:
> On 2010-12-02 19:34, Premi, Sanjeev wrote:
>>>
>>> I haven't found any 3530 vs. 3730 diffs in the uart configuration in
>>> u-boot or linux (though there is a silicon errata fix in the latest
>>> linux-omap-2.6 kernel related to not reading from an empty FIFO).
>>>
>> Look for the AM37x TRM here:
>> http://focus.ti.com/docs/prod/folders/print/am3715.html
>
> Any specific section you were thinking of? ?I did look in the UART section
> of the TRM before and established that it was still driven by a 48 MHz
> clock.
Yes clock for UART is also 48Mhz. I think difference is how to setup main clock
which will be then also used for UART. Just quessing you have latest beagleboard
revision which have 3730?
>
> --
> Orjan Friberg
> FlatFrog Laboratories AB
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From of at flatfrog.com  Fri Dec  3 03:08:34 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Fri, 3 Dec 2010 09:08:34 +0100
Subject: Barebox on a 3730
In-Reply-To: <AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
References: <4CF7AB25.3010604@flatfrog.com>	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>	<4CF7CBD0.7080609@flatfrog.com>	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>	<4CF89B06.3070209@flatfrog.com>
	<AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
Message-ID: <4CF8A582.8080003@flatfrog.com>

On 2010-12-03 08:33, Belisko Marek wrote:
> Yes clock for UART is also 48Mhz. I think difference is how to setup main clock
> which will be then also used for UART. Just quessing you have latest beagleboard
> revision which have 3730?

The board I'm trying to RAM boot with barebox is our own design, but I'd 
be happy to try it on a BeagleBoard xM if there's a way (mine is an A2 
revision).

I'll take a look at arch/arm/mach-omap/omap3_clock.c.

Thanks,
Orjan

-- 
Orjan Friberg
FlatFrog Laboratories AB


From of at flatfrog.com  Fri Dec  3 04:11:48 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Fri, 3 Dec 2010 10:11:48 +0100
Subject: Barebox on a 3730
In-Reply-To: <4CF8A582.8080003@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>	<4CF7CBD0.7080609@flatfrog.com>	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>	<4CF89B06.3070209@flatfrog.com>	<AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
	<4CF8A582.8080003@flatfrog.com>
Message-ID: <4CF8B454.1080202@flatfrog.com>

On 2010-12-03 09:08, Orjan Friberg wrote:
> I'll take a look at arch/arm/mach-omap/omap3_clock.c.

Ok, that stuff looks like it's a bit out of my league.  I guess you'd 
need to read the TRM very carefully and/or have a JTAG debugger handy to 
get it right.

Sanjeev, if you're able to make a patch I'd be grateful.

(On a related note, is everyone using MMC for bootstrapping?  I'm 
finding very little related to rambooting the 35x or 37x.)

-- 
Orjan Friberg
FlatFrog Laboratories AB


From premi at ti.com  Fri Dec  3 07:30:44 2010
From: premi at ti.com (Premi, Sanjeev)
Date: Fri, 3 Dec 2010 18:00:44 +0530
Subject: Barebox on a 3730
In-Reply-To: <4CF8B454.1080202@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<4CF7CBD0.7080609@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>
	<4CF89B06.3070209@flatfrog.com>
	<AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
	<4CF8A582.8080003@flatfrog.com> <4CF8B454.1080202@flatfrog.com>
Message-ID: <B85A65D85D7EB246BE421B3FB0FBB5930247B9A952@dbde02.ent.ti.com>

 

> -----Original Message-----
> From: Orjan Friberg [mailto:of at flatfrog.com] 
> Sent: Friday, December 03, 2010 2:42 PM
> To: Belisko Marek; Premi, Sanjeev
> Cc: barebox at lists.infradead.org
> Subject: Re: Barebox on a 3730
> 
> On 2010-12-03 09:08, Orjan Friberg wrote:
> > I'll take a look at arch/arm/mach-omap/omap3_clock.c.
> 
> Ok, that stuff looks like it's a bit out of my league.  I guess you'd 
> need to read the TRM very carefully and/or have a JTAG 
> debugger handy to 
> get it right.
> 
> Sanjeev, if you're able to make a patch I'd be grateful.

Just started to refresh the repo. I do hope I can get it done
over this weekend...
Haven't looked at barebox sources for quite long; will give
my best shot...

> 
> (On a related note, is everyone using MMC for bootstrapping?  I'm 
> finding very little related to rambooting the 35x or 37x.)
> 
> -- 
> Orjan Friberg
> FlatFrog Laboratories AB
> 

From jbe at pengutronix.de  Fri Dec  3 08:59:50 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Fri, 3 Dec 2010 14:59:50 +0100
Subject: [PATCH] STM/MCI: Fix wrong register bit
Message-ID: <201012031459.50684.jbe@pengutronix.de>


Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/stm378x.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: barebox-git/drivers/mci/stm378x.c
===================================================================
--- barebox-git.orig/drivers/mci/stm378x.c
+++ barebox-git/drivers/mci/stm378x.c
@@ -52,7 +52,7 @@
 # define SSP_CTRL0_SFTRST (1 << 31)
 # define SSP_CTRL0_CLKGATE (1 << 30)
 # define SSP_CTRL0_RUN (1 << 29)
-# define SSP_CTRL0_LOCK_CS (1 << 29)
+# define SSP_CTRL0_LOCK_CS (1 << 27)
 # define SSP_CTRL0_READ (1 << 25)
 # define SSP_CTRL0_IGNORE_CRC (1 << 26)
 # define SSP_CTRL0_DATA_XFER (1 << 24)

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Fri Dec  3 10:34:30 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 3 Dec 2010 16:34:30 +0100
Subject: v2010.12.0
Message-ID: <20101203153430.GP6017@pengutronix.de>

Release day! v2010.12.0 This time with quite a lot of changes.

Sascha

The following changes since commit d1209136e304faab8616f75a347bf2d02d283468:

  Release v2010.11.0 (2010-11-02 17:55:58 +0100)

are available in the git repository at:
  git://git.pengutronix.de/git/barebox.git ..BRANCH.NOT.VERIFIED..

Eric B?nard (17):
      eukrea_cpuimx27: update board support
      imx/clocksource: enable GPT1 before using it on CPUIMX25
      mx25: add MMC clock support
      MX25: fix IOMUX for ESDHC1 pins
      mci-core: add more tested SD Cards
      epautoconf: fix compile error
      eukrea_cpuimx25: update board support
      imx35-regs: add defines for USB and SD
      speed-imx35: add support for SDHC1
      iomux-mx35: fox IOMUX for SDHC1's pins
      eukrea_cpuimx35: update board support
      fsl_udc: fix warning
      i.MX25 & 35 usb config bits : create mach/usb.h
      armlinux: pass INIRTD tag to the kernel
      eukrea's boards: unify kernel partition's size
      cpuimx35: fix warning
      eukrea_cpuimx35: fix flash header

Jean-Christophe PLAGNIOL-VILLARD (10):
      defaultenv: introduce CONFIG_DEFAULT_ENVIRONMENT_GENERIC to enable it
      commands/crc32: add compare 2 files crc
      defaultenv/update: merge update_rootfs and update_kernel
      defaultenv/update: add check crc32 options
      defaultenv: add xmodem support for update
      defaultenv: add update_barebox to update barebox easly via tftp or xmodem
      nhk8815: use defaultenv
      linux16: fix cmd_tbl_t as struct command
      x86: add 64bit host build support
      x86: fix out of tree build support

Juergen Beisert (21):
      x-functions do not return in case of failure.
      Make the disk driver less noisy
      Don't use a sector buffer on stack
      Don't try to guess the size of a disk if its size value is already given
      Add MCI card support to barebox
      Add i.MX23 MCI card support
      Add S3C2440 MCI card support
      mci: mark 'old Canon SD 16 MiB' as working
      Add the basic files for the i.MX23/i.MX28 familiy of CPUs
      Add the driver for the i.MX23 debug UART
      Add the i.MX23-EVK platform (WIP)
      Add the i.MX23 based Chumby platform (WIP)
      Switch the i.MX27's PLL in a safe manner
      Make the clock calculation easier to read and correct
      Glue i.MX23 and MCI support
      Adapt the i.MX23 MCI driver to the v2 i.MX23 patch series
      Spend the ChumbyOne a persistant environment memory on MCI card
      Adapt the defconfig for a full blown ChumbyOne support
      Add GPIO support and GPIO setup features to the S3C processors
      Add some help using the gpio commands at runtime
      Fix a simple typo to less confusing the user

Marek Belisko (6):
      Add basic support for mini2440 dev board.
      mini2440: Fix compilation error.
      serial_s3c24x0: Add missing brackets.
      fs: Fix bug found by sparse.
      drivers: mci: Fix compilation warning.
      arm: mini2440: Add memory size.

Robert Schwebel (54):
      reset_cpu: unify declaration
      Doxyfile: enable quiet output
      Doxyfile: remove obsolete boards directory
      Doxyfile: add exclude rules
      Doxyfile: remove non-existing directories
      Doxyfile: remove unused features
      Doxyfile: enable assembler files
      doc: let doxygen find some assembler functions
      doc: remove nonexisting command
      doc: remove reference to non-existing documentation
      doc: eliminate nonexisting reference
      doc: add missing quoting
      doc: mark code explicitely
      doc: avoid that doxygen parses magic in command.h
      doc: fix wrongly named parameter
      doc: fix parameter name in mci-core
      doc: silence doxygen warnings
      devinfo: use subtree only with devinfo
      sandbox: use devfs functions only if defined
      digest: align menu
      parser: use debug macros
      doc: add macros to unify command help with doxygen
      doc: add documentation for 'bmp'
      doc: add documentation for 'clear'
      doc: add documentation for 'crc32'
      doc: add documentation for 'dfu'
      doc: unify documentation for 'ls'
      doc: unify documentation for 'cat'
      doc: unify documentation for 'cd'
      doc: add documentation for 'echo'
      doc: unify documentation for 'edit'
      doc: add documentation for 'bootm'
      doc: unify documentation for 'addpart'
      doc: unify documentation for 'cp'
      doc: unify documentation for 'delpart'
      doc: rework user manual
      doc: unify documentation for 'devinfo'
      doc: unify documentation for 'erase'
      doc: rework and unify documentation for gpio commands
      doc: unify documentation for 'export'
      doc: unify documentation for 'tftp'
      doc: remove obsolete link method for arch specification
      doc: unify documentation for 'loadenv'
      doc: remove ..., confuses doxygen
      doc: unify documentation for 'mount'
      doc: unify documentation for 'printenv'
      doc: unify documentation for 'protect' and 'unprotect'
      doc: unify documentation for 'saveenv'
      doc: unify documentation for 'setenv'
      doc: remove sh from command documentation
      doc: unify documentation for 'linux16'
      doc: put CPUIMX35 into the right chapter
      doc: put babage board into the right chapter
      doc: put cupid into the right chapter

Sascha Hauer (87):
      hush: pass context around in shell
      hush: fix nasty memory leak in hush
      hush: implement getopt builtin
      i.MX27: Add mmc clock support in order to add an i.MX MCI driver
      mci: Add i.MX27/31 driver
      ARM pca100: Add mci support
      i.MX27: Add support for SDHC pins
      mci: Add i.MX esdhc support
      mci: print error code on failure
      spi i.MX: add spi version namespace to register defines
      spi i.MX: redirect functions to version specific functions
      spi i.MX: Add i.MX51 support
      Move mfd drivers to drivers/mfd
      move include files for mfd drivers to include/mfd
      mfd mc13892: Add spi support
      mfd mc13892: support reading the revision
      mci: handle SD cards < 2.0 correctly
      mci: align write buffer if necessary
      defaultenv: handle disk partitions
      imx_serial: Add mx51 support
      ARM mmu: Call __mmu_cache_flush instead of hardcoded v4/v5 only function
      ARM i.MX: Add basic i.MX51 support
      ARM i.MX51: Add babbage board support
      Merge branch 'getopt' into next
      Merge branch 'mx51' into next
      image: remove confusing image_check_* functions
      defaultenv: do not overwrite bootargs variable
      glob: sparse fixes
      fnmatch:sparse fixes
      readline: sparse fixes
      edit: sparse fixes
      command.h: sparse fixes
      crc32: sparse fixes
      copy_file: sparse fixes
      commands/mem.c: sparse fixes
      dlmalloc: sparse fixes
      console: sparse fixes
      notifier: sparse fixes
      fec_imx: sparse fixes
      imx gpio: sparse fixes
      imx clocksource: sparse fixes
      armlinux: sparse fixes
      arch/arm/cpu/cpu.c: sparse fixes
      cache-l2x0: sparse fixes
      speed-imx35: sparse fixes
      imx_dump_clocks: sparse fixes
      i.MX serial: sparse fixes
      i.MX remove wdog registers from header files
      hush: sparse fixes
      ramfs: sparse fixes
      common/env.c: sparse fixes
      version_string: sparse fixes
      imx-nand: sparse fixes
      ping: make locally used functions static
      arm div0: sparse fixes
      edit: make locally used variable static
      common/environment.c: sparse fixes
      commands/mem.c: make locally used function static
      bootm: sparse fixes
      net: make locally used functions static
      lib/driver.c: sparse fixes
      remove dead ldiv code
      common/memsize.c: add missing include
      i.MX speed: add missing include
      libbb: sparse fixes
      remove strange flush_cache functions
      pcm043: fix compiler warning
      arm interrupts.c: sparse fixes
      process_escape_sequence: Add missing include
      ARM pca100: Use a flash bbt
      i.MX nand: optimize nand boot code for size
      mci-core: add multiple block support
      i.MX51: Fix mmcclk rate
      i.MX esdctl: Add register bits from redboot
      i.MX35 regs: Add watchdog base
      fb: i.MX IPU: remove unnecessary printf
      fb: i.MX IPU: move fb_info initialization to a single function
      fb: i.MX IPU: fold mx3fb_set_par into its only user
      mci: align data for commands
      ARM: Add Garz+Fricke Cupid board support
      defaultenv: fix mtdparts
      ARM: Add defconfig for Garz+Fricke cupid board
      ARM i.MX27: remove duplicated defines
      Merge branch 'next'
      fb: set id for framebuffer device correctly
      Merge branch 'x86' of git://git.jcrosoft.org/barebox
      Release v2010.12.0

 Documentation/barebox-main.dox                     |  232 +---
 Documentation/boards.dox                           |    6 +
 Documentation/building.dox                         |   60 +
 Documentation/commands.dox                         |   30 +-
 Documentation/developers_manual.dox                |    1 -
 Documentation/first_steps.dox                      |   61 +
 Documentation/users_manual.dox                     |   14 +-
 Doxyfile                                           |   27 +-
 Makefile                                           |    2 +-
 arch/arm/Kconfig                                   |    6 +
 arch/arm/Makefile                                  |    6 +
 arch/arm/boards/chumby_falconwing/Makefile         |    1 +
 .../cache.c => boards/chumby_falconwing/config.h}  |   21 +-
 arch/arm/boards/chumby_falconwing/env/bin/boot     |   38 +
 arch/arm/boards/chumby_falconwing/env/bin/init     |   15 +
 arch/arm/boards/chumby_falconwing/env/config       |   36 +
 arch/arm/boards/chumby_falconwing/falconwing.c     |  350 +++++
 arch/arm/boards/eukrea_cpuimx25/env/bin/init       |    2 +
 arch/arm/boards/eukrea_cpuimx25/env/config         |    2 +-
 arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c  |   95 ++-
 arch/arm/boards/eukrea_cpuimx25/lowlevel.c         |   64 +-
 arch/arm/boards/eukrea_cpuimx27/env/bin/boot       |   12 +-
 arch/arm/boards/eukrea_cpuimx27/env/bin/init       |   10 +
 arch/arm/boards/eukrea_cpuimx27/env/config         |   11 +-
 arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c  |    5 +-
 arch/arm/boards/eukrea_cpuimx35/env/bin/init       |    4 +-
 arch/arm/boards/eukrea_cpuimx35/env/config         |    2 +-
 arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c  |   90 ++-
 arch/arm/boards/eukrea_cpuimx35/flash_header.c     |   29 +-
 arch/arm/boards/eukrea_cpuimx35/lowlevel.c         |   20 +-
 arch/arm/boards/freescale-mx23-evk/Makefile        |    2 +
 arch/arm/boards/freescale-mx23-evk/config.h        |   16 +
 arch/arm/boards/freescale-mx23-evk/mx23-evk.c      |   96 ++
 arch/arm/boards/freescale-mx25-3-stack/3stack.c    |    2 +-
 arch/arm/boards/freescale-mx35-3-stack/3stack.c    |    6 +-
 arch/arm/boards/freescale-mx51-pdk/Makefile        |    3 +
 arch/arm/boards/freescale-mx51-pdk/board.c         |  318 +++++
 .../cache.c => boards/freescale-mx51-pdk/config.h} |   26 +-
 arch/arm/boards/freescale-mx51-pdk/env/config      |   52 +
 arch/arm/boards/freescale-mx51-pdk/flash_header.c  |   85 ++
 arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S |  216 ++++
 arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox    |    4 +
 arch/arm/boards/freescale-mx51-pdk/spi.c           |  340 +++++
 arch/arm/boards/guf-cupid/Makefile                 |   24 +
 arch/arm/boards/guf-cupid/board.c                  |  426 ++++++
 .../arm/{lib/cache.c => boards/guf-cupid/config.h} |   23 +-
 arch/arm/boards/guf-cupid/cupid.dox                |    9 +
 arch/arm/boards/guf-cupid/env/config               |   56 +
 arch/arm/boards/guf-cupid/lowlevel.c               |  349 +++++
 arch/arm/boards/mini2440/Makefile                  |    2 +
 arch/arm/boards/mini2440/config.h                  |   50 +
 .../boards/{nhk8815 => mini2440}/env/bin/_update   |    4 +-
 arch/arm/boards/mini2440/env/bin/boot              |   40 +
 arch/arm/boards/mini2440/env/bin/hush_hack         |    1 +
 arch/arm/boards/{nhk8815 => mini2440}/env/bin/init |   12 +-
 arch/arm/boards/mini2440/env/bin/update_kernel     |   13 +
 arch/arm/boards/mini2440/env/bin/update_root       |   13 +
 arch/arm/boards/mini2440/env/config                |   27 +
 arch/arm/boards/mini2440/mini2440.c                |  140 ++
 arch/arm/boards/nhk8815/env/bin/boot               |   38 -
 .../boards/nhk8815/env/bin/update_barebox_xmodem   |   19 -
 arch/arm/boards/nhk8815/env/bin/update_kernel      |    8 -
 arch/arm/boards/nhk8815/env/bin/update_root        |    8 -
 arch/arm/boards/nhk8815/env/config                 |   44 +-
 arch/arm/boards/pcm038/Makefile                    |    2 +-
 arch/arm/boards/pcm038/lowlevel.c                  |    7 +
 arch/arm/boards/pcm038/pcm038.c                    |   65 +-
 arch/arm/boards/pcm038/pll.h                       |   70 +
 arch/arm/boards/pcm038/pll_init.S                  |   48 -
 arch/arm/boards/pcm043/pcm043.c                    |    4 +-
 arch/arm/boards/phycard-i.MX27/pca100.c            |   16 +
 arch/arm/configs/chumbyone_defconfig               |   29 +
 arch/arm/configs/cupid_defconfig                   |   56 +
 arch/arm/configs/eukrea_cpuimx25_defconfig         |   12 +-
 arch/arm/configs/eukrea_cpuimx35_defconfig         |   14 +-
 arch/arm/configs/freescale_mx51_babbage_defconfig  |   43 +
 arch/arm/configs/imx23evk_defconfig                |   24 +
 arch/arm/configs/mini2440_defconfig                |  251 ++++
 arch/arm/configs/neso_defconfig                    |    3 +-
 arch/arm/configs/nhk8815_defconfig                 |    5 +-
 arch/arm/configs/pca100_defconfig                  |    3 +-
 arch/arm/configs/pcm037_defconfig                  |    3 +-
 arch/arm/configs/pcm038_defconfig                  |    3 +-
 arch/arm/configs/pcm043_defconfig                  |    3 +-
 arch/arm/cpu/cache-l2x0.c                          |    2 +-
 arch/arm/cpu/cpu.c                                 |    1 +
 arch/arm/cpu/interrupts.c                          |   10 +-
 arch/arm/cpu/mmu.c                                 |    6 +-
 arch/arm/lib/Makefile                              |    1 -
 arch/arm/lib/armlinux.c                            |   35 +-
 arch/arm/lib/div0.c                                |    5 +-
 arch/arm/mach-at91/at91sam926x_time.c              |    2 +-
 arch/arm/mach-ep93xx/clocksource.c                 |    2 +-
 arch/arm/mach-imx/Kconfig                          |   35 +-
 arch/arm/mach-imx/Makefile                         |    1 +
 arch/arm/mach-imx/clocksource.c                    |   31 +-
 arch/arm/mach-imx/gpio.c                           |   15 +-
 arch/arm/mach-imx/imx51.c                          |   51 +
 arch/arm/mach-imx/include/mach/clock-imx51.h       |  696 ++++++++++
 arch/arm/mach-imx/include/mach/clock.h             |    3 +
 arch/arm/mach-imx/include/mach/esdctl.h            |   88 ++
 arch/arm/mach-imx/include/mach/generic.h           |    6 +
 arch/arm/mach-imx/include/mach/imx-nand.h          |    4 +-
 arch/arm/mach-imx/include/mach/imx-regs.h          |    2 +
 arch/arm/mach-imx/include/mach/imx1-regs.h         |    8 -
 arch/arm/mach-imx/include/mach/imx21-regs.h        |    8 -
 arch/arm/mach-imx/include/mach/imx27-regs.h        |   16 -
 arch/arm/mach-imx/include/mach/imx31-regs.h        |   10 -
 arch/arm/mach-imx/include/mach/imx35-regs.h        |   14 +-
 arch/arm/mach-imx/include/mach/imx51-regs.h        |  124 ++
 arch/arm/mach-imx/include/mach/iomux-mx25.h        |   12 +-
 arch/arm/mach-imx/include/mach/iomux-mx27.h        |    6 +
 arch/arm/mach-imx/include/mach/iomux-mx35.h        |   12 +-
 arch/arm/mach-imx/include/mach/iomux-mx51.h        |  330 +++++
 arch/arm/mach-imx/include/mach/iomux-v3.h          |   10 +-
 arch/arm/mach-imx/include/mach/usb.h               |   14 +
 arch/arm/mach-imx/speed-imx25.c                    |   10 +-
 arch/arm/mach-imx/speed-imx27.c                    |    5 +
 arch/arm/mach-imx/speed-imx35.c                    |   21 +-
 arch/arm/mach-imx/speed-imx51.c                    |  190 +++
 arch/arm/mach-imx/speed.c                          |    1 +
 arch/arm/mach-omap/arch-omap.dox                   |    6 +-
 arch/arm/mach-omap/omap3_generic.c                 |    4 +-
 arch/arm/mach-s3c24xx/Kconfig                      |    9 +
 arch/arm/mach-s3c24xx/Makefile                     |    2 +-
 arch/arm/mach-s3c24xx/gpio-s3c24x0.c               |  169 +++
 .../cache.c => mach-s3c24xx/include/mach/gpio.h}   |   27 +-
 arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h |  426 ++++++
 .../mach-s3c24xx/include/mach/mci.h}               |   50 +-
 arch/arm/mach-stm/Kconfig                          |   48 +
 arch/arm/mach-stm/Makefile                         |    2 +
 arch/arm/mach-stm/clocksource-imx23.c              |   82 ++
 arch/arm/{lib/cache.c => mach-stm/imx23.c}         |   25 +-
 .../{lib/cache.c => mach-stm/include/mach/clock.h} |   28 +-
 .../cache.c => mach-stm/include/mach/generic.h}    |   22 +-
 .../{lib/cache.c => mach-stm/include/mach/gpio.h}  |   23 +-
 .../cache.c => mach-stm/include/mach/imx-regs.h}   |   23 +-
 arch/arm/mach-stm/include/mach/imx23-regs.h        |   41 +
 arch/arm/mach-stm/include/mach/iomux-imx23.h       |  424 ++++++
 .../{lib/cache.c => mach-stm/include/mach/mci.h}   |   30 +-
 arch/arm/mach-stm/iomux-imx23.c                    |  117 ++
 arch/arm/mach-stm/reset-imx23.c                    |   61 +
 arch/arm/mach-stm/speed-imx23.c                    |  280 ++++
 arch/blackfin/lib/cpu.c                            |    2 +-
 arch/m68k/lib/m68k-linuxboot.c                     |    2 +-
 arch/m68k/mach-mcfv4e/mcf_reset_cpu.c              |    2 +-
 arch/ppc/lib/Makefile                              |    1 -
 arch/ppc/lib/ppclinux.c                            |    2 +-
 arch/ppc/mach-mpc5xxx/cpu.c                        |    2 +-
 arch/sandbox/board/hostfile.c                      |    2 +
 arch/sandbox/os/common.c                           |    7 +-
 arch/x86/Makefile                                  |    3 +-
 arch/x86/boards/x86_generic/generic_pc.c           |    2 +-
 arch/x86/boot/boot_hdisk.S                         |    2 -
 arch/x86/boot/boot_main.S                          |    2 -
 arch/x86/boot/pmjump.S                             |    2 -
 arch/x86/lib/memory16.S                            |    2 -
 arch/x86/lib/traveler.S                            |    3 -
 arch/x86/mach-x86.dox                              |    2 +-
 commands/Kconfig                                   |    5 +
 commands/bmp.c                                     |   27 +-
 commands/bootm.c                                   |   48 +-
 commands/cat.c                                     |   19 +-
 commands/cd.c                                      |   17 +-
 commands/clear.c                                   |    5 +
 commands/cp.c                                      |   30 +-
 commands/crc.c                                     |  124 ++-
 commands/dfu.c                                     |   28 +-
 commands/echo.c                                    |   17 +
 commands/edit.c                                    |   42 +-
 commands/export.c                                  |   14 +-
 commands/flash.c                                   |  100 +-
 commands/gpio.c                                    |   93 ++-
 commands/linux16.c                                 |   27 +-
 commands/loadb.c                                   |    1 -
 commands/loadenv.c                                 |   34 +-
 commands/loads.c                                   |    1 -
 commands/ls.c                                      |    9 +-
 commands/mem.c                                     |    2 +-
 commands/mount.c                                   |   78 +-
 commands/partition.c                               |   75 +-
 commands/printenv.c                                |   30 +-
 commands/saveenv.c                                 |   31 +-
 commands/setenv.c                                  |   30 +-
 commands/version.c                                 |    1 -
 common/Kconfig                                     |   23 +
 common/Makefile                                    |   10 +-
 common/console.c                                   |    8 +-
 common/dlmalloc.c                                  |   41 +-
 common/env.c                                       |    2 +-
 common/environment.c                               |    2 +-
 common/hush.c                                      |  137 ++-
 common/image.c                                     |    7 +-
 common/kallsyms.c                                  |    4 +
 common/memsize.c                                   |    1 +
 common/parser.c                                    |   51 +-
 defaultenv/bin/_update                             |   30 +-
 defaultenv/bin/_update_help                        |   12 +
 defaultenv/bin/boot                                |    4 +-
 defaultenv/bin/init                                |    7 +-
 defaultenv/bin/update                              |   65 +
 defaultenv/bin/update_kernel                       |   15 -
 defaultenv/bin/update_rootfs                       |   16 -
 drivers/Kconfig                                    |    2 +
 drivers/Makefile                                   |    2 +
 drivers/ata/disk_drive.c                           |   51 +-
 drivers/i2c/Kconfig                                |   16 -
 drivers/i2c/Makefile                               |    6 -
 drivers/i2c/mc13892.c                              |  164 ---
 drivers/mci/Kconfig                                |   64 +
 drivers/mci/Makefile                               |    5 +
 drivers/mci/imx-esdhc.c                            |  512 ++++++++
 drivers/mci/imx-esdhc.h                            |  164 +++
 drivers/mci/imx.c                                  |  520 ++++++++
 drivers/mci/mci-core.c                             | 1360 ++++++++++++++++++++
 drivers/mci/s3c.c                                  |  817 ++++++++++++
 drivers/mci/stm378x.c                              |  699 ++++++++++
 drivers/mfd/Kconfig                                |   28 +
 drivers/mfd/Makefile                               |    6 +
 drivers/{i2c => mfd}/lp3972.c                      |    0
 drivers/{spi => mfd}/mc13783.c                     |    0
 drivers/mfd/mc13892.c                              |  327 +++++
 drivers/{i2c => mfd}/mc34704.c                     |    2 +-
 drivers/{i2c => mfd}/mc9sdz60.c                    |    2 +-
 drivers/{i2c => mfd}/twl4030.c                     |    2 +-
 drivers/mtd/nand/Kconfig                           |   16 +
 drivers/mtd/nand/nand_imx.c                        |  196 ++-
 drivers/net/fec_imx.c                              |    8 +-
 drivers/net/fec_imx.h                              |    6 +-
 drivers/serial/Kconfig                             |    5 +
 drivers/serial/Makefile                            |    1 +
 drivers/serial/serial_imx.c                        |   92 +-
 drivers/serial/serial_s3c24x0.c                    |    2 +-
 drivers/serial/stm-serial.c                        |  202 +++
 drivers/spi/Kconfig                                |   12 +-
 drivers/spi/Makefile                               |    2 -
 drivers/spi/imx_spi.c                              |  347 ++++-
 drivers/usb/gadget/fsl_udc.c                       |    3 +-
 drivers/usb/host/ehci-omap.c                       |    2 +-
 drivers/usb/otg/twl4030.c                          |    2 +-
 drivers/video/fb.c                                 |    1 +
 drivers/video/imx-ipu-fb.c                         |   92 +-
 fs/fs.c                                            |    2 +-
 fs/ramfs.c                                         |    2 +-
 include/asm-generic/barebox.lds.h                  |    2 +-
 include/cache.h                                    |    1 -
 include/command.h                                  |   20 +-
 include/common.h                                   |    4 +
 include/image.h                                    |   56 +-
 include/mci.h                                      |  239 ++++
 include/{i2c => mfd}/lp3972.h                      |    0
 include/{i2c => mfd}/mc13892.h                     |   28 +
 include/{i2c => mfd}/mc34704.h                     |    0
 include/{i2c => mfd}/mc9sdz60.h                    |    0
 include/{i2c => mfd}/twl4030.h                     |    0
 include/notifier.h                                 |    1 +
 lib/Kconfig                                        |    2 +-
 lib/Makefile                                       |    1 -
 lib/copy_file.c                                    |    2 +
 lib/crc32.c                                        |    2 +-
 lib/driver.c                                       |   88 +-
 lib/fnmatch.c                                      |    5 +-
 lib/glob.c                                         |   36 +-
 lib/ldiv.c                                         |   55 -
 lib/libbb.c                                        |    2 +-
 lib/parameter.c                                    |    2 +-
 lib/process_escape_sequence.c                      |    1 +
 lib/readline.c                                     |    6 +-
 net/net.c                                          |    4 +-
 net/ping.c                                         |    4 +-
 net/tftp.c                                         |   49 +-
 scripts/doxy_filter.awk                            |  103 ++
 scripts/mkimage.c                                  |    2 +-
 scripts/setupmbr/setupmbr.c                        |    4 +-
 274 files changed, 13938 insertions(+), 1955 deletions(-)
 create mode 100644 Documentation/building.dox
 create mode 100644 Documentation/first_steps.dox
 create mode 100644 arch/arm/boards/chumby_falconwing/Makefile
 copy arch/arm/{lib/cache.c => boards/chumby_falconwing/config.h} (64%)
 create mode 100644 arch/arm/boards/chumby_falconwing/env/bin/boot
 create mode 100644 arch/arm/boards/chumby_falconwing/env/bin/init
 create mode 100644 arch/arm/boards/chumby_falconwing/env/config
 create mode 100644 arch/arm/boards/chumby_falconwing/falconwing.c
 create mode 100644 arch/arm/boards/freescale-mx23-evk/Makefile
 create mode 100644 arch/arm/boards/freescale-mx23-evk/config.h
 create mode 100644 arch/arm/boards/freescale-mx23-evk/mx23-evk.c
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/Makefile
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/board.c
 copy arch/arm/{lib/cache.c => boards/freescale-mx51-pdk/config.h} (58%)
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/env/config
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/flash_header.c
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/lowlevel_init.S
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/mx51-pdk.dox
 create mode 100644 arch/arm/boards/freescale-mx51-pdk/spi.c
 create mode 100644 arch/arm/boards/guf-cupid/Makefile
 create mode 100644 arch/arm/boards/guf-cupid/board.c
 copy arch/arm/{lib/cache.c => boards/guf-cupid/config.h} (65%)
 create mode 100644 arch/arm/boards/guf-cupid/cupid.dox
 create mode 100644 arch/arm/boards/guf-cupid/env/config
 create mode 100644 arch/arm/boards/guf-cupid/lowlevel.c
 create mode 100644 arch/arm/boards/mini2440/Makefile
 create mode 100644 arch/arm/boards/mini2440/config.h
 rename arch/arm/boards/{nhk8815 => mini2440}/env/bin/_update (90%)
 create mode 100644 arch/arm/boards/mini2440/env/bin/boot
 create mode 100644 arch/arm/boards/mini2440/env/bin/hush_hack
 rename arch/arm/boards/{nhk8815 => mini2440}/env/bin/init (55%)
 create mode 100644 arch/arm/boards/mini2440/env/bin/update_kernel
 create mode 100644 arch/arm/boards/mini2440/env/bin/update_root
 create mode 100644 arch/arm/boards/mini2440/env/config
 create mode 100644 arch/arm/boards/mini2440/mini2440.c
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/boot
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_barebox_xmodem
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_kernel
 delete mode 100644 arch/arm/boards/nhk8815/env/bin/update_root
 create mode 100644 arch/arm/boards/pcm038/pll.h
 delete mode 100644 arch/arm/boards/pcm038/pll_init.S
 create mode 100644 arch/arm/configs/chumbyone_defconfig
 create mode 100644 arch/arm/configs/cupid_defconfig
 create mode 100644 arch/arm/configs/freescale_mx51_babbage_defconfig
 create mode 100644 arch/arm/configs/imx23evk_defconfig
 create mode 100644 arch/arm/configs/mini2440_defconfig
 create mode 100644 arch/arm/mach-imx/include/mach/clock-imx51.h
 create mode 100644 arch/arm/mach-imx/include/mach/imx51-regs.h
 create mode 100644 arch/arm/mach-imx/include/mach/iomux-mx51.h
 create mode 100644 arch/arm/mach-imx/include/mach/usb.h
 create mode 100644 arch/arm/mach-imx/speed-imx51.c
 create mode 100644 arch/arm/mach-s3c24xx/gpio-s3c24x0.c
 copy arch/arm/{lib/cache.c => mach-s3c24xx/include/mach/gpio.h} (65%)
 create mode 100644 arch/arm/mach-s3c24xx/include/mach/iomux-s3c24x0.h
 rename arch/{ppc/lib/cache.c => arm/mach-s3c24xx/include/mach/mci.h} (50%)
 create mode 100644 arch/arm/mach-stm/Kconfig
 create mode 100644 arch/arm/mach-stm/Makefile
 create mode 100644 arch/arm/mach-stm/clocksource-imx23.c
 copy arch/arm/{lib/cache.c => mach-stm/imx23.c} (66%)
 copy arch/arm/{lib/cache.c => mach-stm/include/mach/clock.h} (61%)
 copy arch/arm/{lib/cache.c => mach-stm/include/mach/generic.h} (65%)
 copy arch/arm/{lib/cache.c => mach-stm/include/mach/gpio.h} (65%)
 copy arch/arm/{lib/cache.c => mach-stm/include/mach/imx-regs.h} (65%)
 create mode 100644 arch/arm/mach-stm/include/mach/imx23-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx23.h
 rename arch/arm/{lib/cache.c => mach-stm/include/mach/mci.h} (57%)
 create mode 100644 arch/arm/mach-stm/iomux-imx23.c
 create mode 100644 arch/arm/mach-stm/reset-imx23.c
 create mode 100644 arch/arm/mach-stm/speed-imx23.c
 create mode 100644 defaultenv/bin/_update_help
 create mode 100644 defaultenv/bin/update
 delete mode 100644 defaultenv/bin/update_kernel
 delete mode 100644 defaultenv/bin/update_rootfs
 delete mode 100644 drivers/i2c/mc13892.c
 create mode 100644 drivers/mci/Kconfig
 create mode 100644 drivers/mci/Makefile
 create mode 100644 drivers/mci/imx-esdhc.c
 create mode 100644 drivers/mci/imx-esdhc.h
 create mode 100644 drivers/mci/imx.c
 create mode 100644 drivers/mci/mci-core.c
 create mode 100644 drivers/mci/s3c.c
 create mode 100644 drivers/mci/stm378x.c
 create mode 100644 drivers/mfd/Kconfig
 create mode 100644 drivers/mfd/Makefile
 rename drivers/{i2c => mfd}/lp3972.c (100%)
 rename drivers/{spi => mfd}/mc13783.c (100%)
 create mode 100644 drivers/mfd/mc13892.c
 rename drivers/{i2c => mfd}/mc34704.c (99%)
 rename drivers/{i2c => mfd}/mc9sdz60.c (99%)
 rename drivers/{i2c => mfd}/twl4030.c (99%)
 create mode 100644 drivers/serial/stm-serial.c
 create mode 100644 include/mci.h
 rename include/{i2c => mfd}/lp3972.h (100%)
 rename include/{i2c => mfd}/mc13892.h (82%)
 rename include/{i2c => mfd}/mc34704.h (100%)
 rename include/{i2c => mfd}/mc9sdz60.h (100%)
 rename include/{i2c => mfd}/twl4030.h (100%)
 delete mode 100644 lib/ldiv.c
 create mode 100644 scripts/doxy_filter.awk
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From u.kleine-koenig at pengutronix.de  Sun Dec  5 05:50:28 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Sun, 5 Dec 2010 11:50:28 +0100
Subject: [PATCH] STM/MCI: Fix wrong register bit
In-Reply-To: <201012031459.50684.jbe@pengutronix.de>
References: <201012031459.50684.jbe@pengutronix.de>
Message-ID: <20101205105028.GD10693@pengutronix.de>

On Fri, Dec 03, 2010 at 02:59:50PM +0100, Juergen Beisert wrote:
> 
Maybe add something like: "The define isn't used up to now, so the wrong
offset didn't stick out before.  For the same reason this fix isn't
critical." to the changelog?

Uwe
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
>  drivers/mci/stm378x.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> Index: barebox-git/drivers/mci/stm378x.c
> ===================================================================
> --- barebox-git.orig/drivers/mci/stm378x.c
> +++ barebox-git/drivers/mci/stm378x.c
> @@ -52,7 +52,7 @@
>  # define SSP_CTRL0_SFTRST (1 << 31)
>  # define SSP_CTRL0_CLKGATE (1 << 30)
>  # define SSP_CTRL0_RUN (1 << 29)
> -# define SSP_CTRL0_LOCK_CS (1 << 29)
> +# define SSP_CTRL0_LOCK_CS (1 << 27)
>  # define SSP_CTRL0_READ (1 << 25)
>  # define SSP_CTRL0_IGNORE_CRC (1 << 26)
>  # define SSP_CTRL0_DATA_XFER (1 << 24)

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From premi at ti.com  Sun Dec  5 21:40:28 2010
From: premi at ti.com (Premi, Sanjeev)
Date: Mon, 6 Dec 2010 08:10:28 +0530
Subject: Barebox on a 3730
In-Reply-To: <4CF8B454.1080202@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<4CF7CBD0.7080609@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>
	<4CF89B06.3070209@flatfrog.com>
	<AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
	<4CF8A582.8080003@flatfrog.com> <4CF8B454.1080202@flatfrog.com>
Message-ID: <B85A65D85D7EB246BE421B3FB0FBB5930247B9AC02@dbde02.ent.ti.com>

> -----Original Message-----
> From: Orjan Friberg [mailto:of at flatfrog.com] 
> Sent: Friday, December 03, 2010 2:42 PM
> To: Belisko Marek; Premi, Sanjeev
> Cc: barebox at lists.infradead.org
> Subject: Re: Barebox on a 3730
> 
> On 2010-12-03 09:08, Orjan Friberg wrote:
> > I'll take a look at arch/arm/mach-omap/omap3_clock.c.
> 
> Ok, that stuff looks like it's a bit out of my league.  I guess you'd 
> need to read the TRM very carefully and/or have a JTAG 
> debugger handy to 
> get it right.
> 
> Sanjeev, if you're able to make a patch I'd be grateful.
> 
Looks like I got into more than I could chew for a weekend!

I found many things missing in the process of creating the
patch; and ended with a big lst of 'dirty' patches. I will
be able to try them on the EVM today; but clean-up can take
another day.

If I can get the board to boot, I can send the patches to
you off-the-list for you to get started while I clean-up;
...if helps you.

~sanjeev

> (On a related note, is everyone using MMC for bootstrapping?  I'm 
> finding very little related to rambooting the 35x or 37x.)
> 
> -- 
> Orjan Friber
> FlatFrog Laboratories AB
> 

From of at flatfrog.com  Mon Dec  6 05:34:58 2010
From: of at flatfrog.com (Orjan Friberg)
Date: Mon, 6 Dec 2010 11:34:58 +0100
Subject: Barebox on a 3730
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB5930247B9AC02@dbde02.ent.ti.com>
References: <4CF7AB25.3010604@flatfrog.com>	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>	<4CF7CBD0.7080609@flatfrog.com>	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>	<4CF89B06.3070209@flatfrog.com>	<AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
	<4CF8A582.8080003@flatfrog.com> <4CF8B454.1080202@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9AC02@dbde02.ent.ti.com>
Message-ID: <4CFCBC52.9010701@flatfrog.com>

On 2010-12-06 03:40, Premi, Sanjeev wrote:
> If I can get the board to boot, I can send the patches to
> you off-the-list for you to get started while I clean-up;
> ...if helps you.

Please do, I'd be happy to give it a spin.

Thanks,
Orjan

-- 
Orjan Friberg
FlatFrog Laboratories AB


From premi at ti.com  Mon Dec  6 08:35:02 2010
From: premi at ti.com (Premi, Sanjeev)
Date: Mon, 6 Dec 2010 19:05:02 +0530
Subject: Barebox on a 3730
In-Reply-To: <4CFCBC52.9010701@flatfrog.com>
References: <4CF7AB25.3010604@flatfrog.com>
	<AANLkTimHbFqqTZ3_oqWCTg+dYHuKA2jHqWCymmy++qTO@mail.gmail.com>
	<4CF7CBD0.7080609@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9A457@dbde02.ent.ti.com>
	<4CF89B06.3070209@flatfrog.com>
	<AANLkTineUQPxVixwGswwxvBdZhxrqvmZ8=+rv3QynZ=8@mail.gmail.com>
	<4CF8A582.8080003@flatfrog.com> <4CF8B454.1080202@flatfrog.com>
	<B85A65D85D7EB246BE421B3FB0FBB5930247B9AC02@dbde02.ent.ti.com>
	<4CFCBC52.9010701@flatfrog.com>
Message-ID: <B85A65D85D7EB246BE421B3FB0FBB5930247C46649@dbde02.ent.ti.com>

Just fixed the issue. give me 30 mins and I will send you zip of patches to apply on latest master.

~sanjeev 

> -----Original Message-----
> From: Orjan Friberg [mailto:of at flatfrog.com] 
> Sent: Monday, December 06, 2010 4:05 PM
> To: Premi, Sanjeev
> Cc: Belisko Marek; barebox at lists.infradead.org
> Subject: Re: Barebox on a 3730
> 
> On 2010-12-06 03:40, Premi, Sanjeev wrote:
> > If I can get the board to boot, I can send the patches to
> > you off-the-list for you to get started while I clean-up;
> > ...if helps you.
> 
> Please do, I'd be happy to give it a spin.
> 
> Thanks,
> Orjan
> 
> -- 
> Orjan Friberg
> FlatFrog Laboratories AB
> 

From marc at cpdesign.com.au  Thu Dec  9 22:37:44 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 10 Dec 2010 14:37:44 +1100
Subject: [PATCH] arm: update mach-types
Message-ID: <1291952264-3363-1-git-send-email-marc@cpdesign.com.au>

Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
---
 arch/arm/tools/mach-types |  385 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 372 insertions(+), 13 deletions(-)

diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 32d7833..43dbb8e 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Mon May 24 21:27:47 2010
+# Last update: Fri Dec 10 03:31:36 2010
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -1319,7 +1319,7 @@ mistral			MACH_MISTRAL		MISTRAL			1315
 msm			MACH_MSM		MSM			1316
 ct5910			MACH_CT5910		CT5910			1317
 ct5912			MACH_CT5912		CT5912			1318
-argonst_foundation	MACH_HYNET_INE		HYNET_INE		1319
+argonst_mp		MACH_HYNET_INE		HYNET_INE		1319
 hynet_app		MACH_HYNET_APP		HYNET_APP		1320
 msm7200			MACH_MSM7200		MSM7200			1321
 msm7600			MACH_MSM7600		MSM7600			1322
@@ -1877,7 +1877,7 @@ ued			MACH_UED		UED			1885
 esiblade		MACH_ESIBLADE		ESIBLADE		1886
 eye02			MACH_EYE02		EYE02			1887
 imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
-sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
+p87_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
 kixvp435		MACH_KIXVP435		KIXVP435		1890
 kixnp435		MACH_KIXNP435		KIXNP435		1891
 africa			MACH_AFRICA		AFRICA			1892
@@ -1994,7 +1994,7 @@ spark			MACH_SPARK		SPARK			2002
 benzina			MACH_BENZINA		BENZINA			2003
 blaze			MACH_BLAZE		BLAZE			2004
 linkstation_ls_hgl	MACH_LINKSTATION_LS_HGL	LINKSTATION_LS_HGL	2005
-htckovsky		MACH_HTCVENUS		HTCVENUS		2006
+htckovsky		MACH_HTCKOVSKY		HTCKOVSKY		2006
 sony_prs505		MACH_SONY_PRS505	SONY_PRS505		2007
 hanlin_v3		MACH_HANLIN_V3		HANLIN_V3		2008
 sapphira		MACH_SAPPHIRA		SAPPHIRA		2009
@@ -2321,7 +2321,7 @@ mx31txtr		MACH_MX31TXTR		MX31TXTR		2332
 u380			MACH_U380		U380			2333
 oamp3_hualu		MACH_HUALU_BOARD	HUALU_BOARD		2334
 npcmx50			MACH_NPCMX50		NPCMX50			2335
-mx51_lange51		MACH_MX51_LANGE51	MX51_LANGE51		2336
+mx51_efikamx		MACH_MX51_EFIKAMX	MX51_EFIKAMX		2336
 mx51_lange52		MACH_MX51_LANGE52	MX51_LANGE52		2337
 riom			MACH_RIOM		RIOM			2338
 comcas			MACH_COMCAS		COMCAS			2339
@@ -2355,7 +2355,7 @@ at91sam9263cs		MACH_AT91SAM9263CS	AT91SAM9263CS		2366
 csb732			MACH_CSB732		CSB732			2367
 u8500			MACH_U8500		U8500			2368
 huqiu			MACH_HUQIU		HUQIU			2369
-mx51_kunlun		MACH_MX51_KUNLUN	MX51_KUNLUN		2370
+mx51_efikasb		MACH_MX51_EFIKASB	MX51_EFIKASB		2370
 pmt1g			MACH_PMT1G		PMT1G			2371
 htcelf			MACH_HTCELF		HTCELF			2372
 armadillo420		MACH_ARMADILLO420	ARMADILLO420		2373
@@ -2446,7 +2446,7 @@ siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1		2458
 siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459
 sm3k			MACH_SM3K		SM3K			2460
 acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461
-sst61vc010_dev		MACH_SST61VC010_DEV	SST61VC010_DEV		2462
+p87_dev			MACH_SST61VC010_DEV	SST61VC010_DEV		2462
 glittertind		MACH_GLITTERTIND	GLITTERTIND		2463
 omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
 omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
@@ -2561,7 +2561,7 @@ magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573
 emxx			MACH_EMXX		EMXX			2574
 outlaw			MACH_OUTLAW		OUTLAW			2575
 riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
-riot_vox		MACH_RIOT_VOX		RIOT_VOX		2577
+riot_gx2		MACH_RIOT_VOX		RIOT_VOX		2577
 riot_x37		MACH_RIOT_X37		RIOT_X37		2578
 mega25mx		MACH_MEGA25MX		MEGA25MX		2579
 benzina2		MACH_BENZINA2		BENZINA2		2580
@@ -2591,7 +2591,7 @@ wzl6410i		MACH_WZL6410I		WZL6410I		2603
 spacecom1		MACH_SPACECOM1		SPACECOM1		2604
 pingu920		MACH_PINGU920		PINGU920		2605
 bravoc			MACH_BRAVOC		BRAVOC			2606
-cybo2440		MACH_CYBO2440		CYBO2440		2607
+mydev			MACH_CYBO2440		CYBO2440		2607
 vdssw			MACH_VDSSW		VDSSW			2608
 romulus			MACH_ROMULUS		ROMULUS			2609
 omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
@@ -2609,7 +2609,7 @@ fujitsu_tvstbsoc1	MACH_FUJITSU_TVSTBSOC1	FUJITSU_TVSTBSOC1	2621
 lexikon			MACH_LEXIKON		LEXIKON			2622
 mini2440v2		MACH_MINI2440V2		MINI2440V2		2623
 icontrol		MACH_ICONTROL		ICONTROL		2624
-sheevad			MACH_SHEEVAD		SHEEVAD			2625
+gplugd			MACH_SHEEVAD		SHEEVAD			2625
 qsd8x50a_st1_1		MACH_QSD8X50A_ST1_1	QSD8X50A_ST1_1		2626
 qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
 bee			MACH_BEE		BEE			2628
@@ -2622,7 +2622,7 @@ kraken			MACH_KRAKEN		KRAKEN			2634
 gw2388			MACH_GW2388		GW2388			2635
 jadecpu			MACH_JADECPU		JADECPU			2636
 carlisle		MACH_CARLISLE		CARLISLE		2637
-lux_sf9			MACH_LUX_SFT9		LUX_SFT9		2638
+lux_sf9			MACH_LUX_SF9		LUX_SF9			2638
 nemid_tb		MACH_NEMID_TB		NEMID_TB		2639
 terrier			MACH_TERRIER		TERRIER			2640
 turbot			MACH_TURBOT		TURBOT			2641
@@ -2683,7 +2683,7 @@ lkevm			MACH_LKEVM		LKEVM			2695
 mw6410			MACH_MW6410		MW6410			2696
 terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
 cpu8000e		MACH_CPU8000E		CPU8000E		2698
-catania			MACH_CATANIA		CATANIA			2699
+catania_s		MACH_CATANIA		CATANIA			2699
 tokyo			MACH_TOKYO		TOKYO			2700
 msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
 msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
@@ -2812,7 +2812,7 @@ p565			MACH_P565		P565			2824
 acer_a4			MACH_ACER_A4		ACER_A4			2825
 davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
 eshare			MACH_ESHARE		ESHARE			2827
-hw_omapl138_europa	MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828
+omapl138_europa		MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828
 wlbargn			MACH_WLBARGN		WLBARGN			2829
 bm170			MACH_BM170		BM170			2830
 netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
@@ -2859,3 +2859,362 @@ autobot			MACH_AUTOBOT		AUTOBOT			2871
 coconut			MACH_COCONUT		COCONUT			2872
 durian			MACH_DURIAN		DURIAN			2873
 cayenne			MACH_CAYENNE		CAYENNE			2874
+fuji			MACH_FUJI		FUJI			2875
+synology_6282		MACH_SYNOLOGY_6282	SYNOLOGY_6282		2876
+em1sy			MACH_EM1SY		EM1SY			2877
+m502			MACH_M502		M502			2878
+matrix518		MACH_MATRIX518		MATRIX518		2879
+tiny_gurnard		MACH_TINY_GURNARD	TINY_GURNARD		2880
+spear1310		MACH_SPEAR1310		SPEAR1310		2881
+bv07			MACH_BV07		BV07			2882
+mxt_td61		MACH_MXT_TD61		MXT_TD61		2883
+openrd_ultimate		MACH_OPENRD_ULTIMATE	OPENRD_ULTIMATE		2884
+devixp			MACH_DEVIXP		DEVIXP			2885
+miccpt			MACH_MICCPT		MICCPT			2886
+mic256			MACH_MIC256		MIC256			2887
+as1167			MACH_AS1167		AS1167			2888
+omap3_ibiza		MACH_OMAP3_IBIZA	OMAP3_IBIZA		2889
+u5500			MACH_U5500		U5500			2890
+davinci_picto		MACH_DAVINCI_PICTO	DAVINCI_PICTO		2891
+mecha			MACH_MECHA		MECHA			2892
+bubba3			MACH_BUBBA3		BUBBA3			2893
+pupitre			MACH_PUPITRE		PUPITRE			2894
+tegra_harmony		MACH_TEGRA_HARMONY	TEGRA_HARMONY		2895
+tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896
+tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897
+simplenet		MACH_SIMPLENET		SIMPLENET		2898
+ec4350tbm		MACH_EC4350TBM		EC4350TBM		2899
+pec_tc			MACH_PEC_TC		PEC_TC			2900
+pec_hc2			MACH_PEC_HC2		PEC_HC2			2901
+esl_mobilis_a		MACH_ESL_MOBILIS_A	ESL_MOBILIS_A		2902
+esl_mobilis_b		MACH_ESL_MOBILIS_B	ESL_MOBILIS_B		2903
+esl_wave_a		MACH_ESL_WAVE_A		ESL_WAVE_A		2904
+esl_wave_b		MACH_ESL_WAVE_B		ESL_WAVE_B		2905
+unisense_mmm		MACH_UNISENSE_MMM	UNISENSE_MMM		2906
+blueshark		MACH_BLUESHARK		BLUESHARK		2907
+e10			MACH_E10		E10			2908
+app3k_robin		MACH_APP3K_ROBIN	APP3K_ROBIN		2909
+pov15hd			MACH_POV15HD		POV15HD			2910
+stella			MACH_STELLA		STELLA			2911
+htc_iolite		MACH_MACH_HTC_IOLITE	MACH_HTC_IOLITE		2912
+linkstation_lschl	MACH_LINKSTATION_LSCHL	LINKSTATION_LSCHL	2913
+netwalker		MACH_NETWALKER		NETWALKER		2914
+acsx106			MACH_ACSX106		ACSX106			2915
+atlas5_c1		MACH_ATLAS5_C1		ATLAS5_C1		2916
+nsb3ast			MACH_NSB3AST		NSB3AST			2917
+gnet_slc		MACH_GNET_SLC		GNET_SLC		2918
+af4000			MACH_AF4000		AF4000			2919
+ark9431			MACH_ARK9431		ARK9431			2920
+fs_s5pc100		MACH_FS_S5PC100		FS_S5PC100		2921
+omap3505nova8		MACH_OMAP3505NOVA8	OMAP3505NOVA8		2922
+omap3621_edp1		MACH_OMAP3621_EDP1	OMAP3621_EDP1		2923
+oratisaes		MACH_ORATISAES		ORATISAES		2924
+smdkv310		MACH_SMDKV310		SMDKV310		2925
+siemens_l0		MACH_SIEMENS_L0		SIEMENS_L0		2926
+ventana			MACH_VENTANA		VENTANA			2927
+wm8505_7in_netbook	MACH_WM8505_7IN_NETBOOK	WM8505_7IN_NETBOOK	2928
+ec4350sdb		MACH_EC4350SDB		EC4350SDB		2929
+mimas			MACH_MIMAS		MIMAS			2930
+titan			MACH_TITAN		TITAN			2931
+craneboard		MACH_CRANEBOARD		CRANEBOARD		2932
+es2440			MACH_ES2440		ES2440			2933
+najay_a9263		MACH_NAJAY_A9263	NAJAY_A9263		2934
+htctornado		MACH_HTCTORNADO		HTCTORNADO		2935
+dimm_mx257		MACH_DIMM_MX257		DIMM_MX257		2936
+jigen301		MACH_JIGEN		JIGEN			2937
+smdk6450		MACH_SMDK6450		SMDK6450		2938
+meno_qng		MACH_MENO_QNG		MENO_QNG		2939
+ns2416			MACH_NS2416		NS2416			2940
+rpc353			MACH_RPC353		RPC353			2941
+tq6410			MACH_TQ6410		TQ6410			2942
+sky6410			MACH_SKY6410		SKY6410			2943
+dynasty			MACH_DYNASTY		DYNASTY			2944
+vivo			MACH_VIVO		VIVO			2945
+bury_bl7582		MACH_BURY_BL7582	BURY_BL7582		2946
+bury_bps5270		MACH_BURY_BPS5270	BURY_BPS5270		2947
+basi			MACH_BASI		BASI			2948
+tn200			MACH_TN200		TN200			2949
+c2mmi			MACH_C2MMI		C2MMI			2950
+meson_6236m		MACH_MESON_6236M	MESON_6236M		2951
+meson_8626m		MACH_MESON_8626M	MESON_8626M		2952
+tube			MACH_TUBE		TUBE			2953
+messina			MACH_MESSINA		MESSINA			2954
+mx50_arm2		MACH_MX50_ARM2		MX50_ARM2		2955
+cetus9263		MACH_CETUS9263		CETUS9263		2956
+brownstone		MACH_BROWNSTONE		BROWNSTONE		2957
+vmx25			MACH_VMX25		VMX25			2958
+vmx51			MACH_VMX51		VMX51			2959
+abacus			MACH_ABACUS		ABACUS			2960
+cm4745			MACH_CM4745		CM4745			2961
+oratislink		MACH_ORATISLINK		ORATISLINK		2962
+davinci_dm365_dvr	MACH_DAVINCI_DM365_DVR	DAVINCI_DM365_DVR	2963
+netviz			MACH_NETVIZ		NETVIZ			2964
+flexibity		MACH_FLEXIBITY		FLEXIBITY		2965
+wlan_computer		MACH_WLAN_COMPUTER	WLAN_COMPUTER		2966
+lpc24xx			MACH_LPC24XX		LPC24XX			2967
+spica			MACH_SPICA		SPICA			2968
+gpsdisplay		MACH_GPSDISPLAY		GPSDISPLAY		2969
+bipnet			MACH_BIPNET		BIPNET			2970
+overo_ctu_inertial	MACH_OVERO_CTU_INERTIAL	OVERO_CTU_INERTIAL	2971
+davinci_dm355_mmm	MACH_DAVINCI_DM355_MMM	DAVINCI_DM355_MMM	2972
+pc9260_v2		MACH_PC9260_V2		PC9260_V2		2973
+ptx7545			MACH_PTX7545		PTX7545			2974
+tm_efdc			MACH_TM_EFDC		TM_EFDC			2975
+remove_me		MACH_WALDO1		WALDO1			2976
+omap3_waldo1		MACH_OMAP3_WALDO1	OMAP3_WALDO1		2977
+flyer			MACH_FLYER		FLYER			2978
+tornado3240		MACH_TORNADO3240	TORNADO3240		2979
+soli_01			MACH_SOLI_01		SOLI_01			2980
+omapl138_europalc	MACH_OMAPL138_EUROPALC	OMAPL138_EUROPALC	2981
+helios_v1		MACH_HELIOS_V1		HELIOS_V1		2982
+netspace_lite_v2	MACH_NETSPACE_LITE_V2	NETSPACE_LITE_V2	2983
+ssc			MACH_SSC		SSC			2984
+premierwave_en		MACH_PREMIERWAVE_EN	PREMIERWAVE_EN		2985
+wasabi			MACH_WASABI		WASABI			2986
+vivo_w			MACH_VIVOW		VIVOW			2987
+mx50_rdp		MACH_MX50_RDP		MX50_RDP		2988
+universal_c210		MACH_UNIVERSAL_C210	UNIVERSAL_C210		2989
+real6410		MACH_REAL6410		REAL6410		2990
+spx_sakura		MACH_SPX_SAKURA		SPX_SAKURA		2991
+ij3k_2440		MACH_IJ3K_2440		IJ3K_2440		2992
+omap3_bc10		MACH_OMAP3_BC10		OMAP3_BC10		2993
+thebe			MACH_THEBE		THEBE			2994
+rv082			MACH_RV082		RV082			2995
+armlguest		MACH_ARMLGUEST		ARMLGUEST		2996
+tjinc1000		MACH_TJINC1000		TJINC1000		2997
+dockstar		MACH_DOCKSTAR		DOCKSTAR		2998
+ax8008			MACH_AX8008		AX8008			2999
+gnet_sgce		MACH_GNET_SGCE		GNET_SGCE		3000
+pxwnas_500_1000		MACH_PXWNAS_500_1000	PXWNAS_500_1000		3001
+ea20			MACH_EA20		EA20			3002
+awm2			MACH_AWM2		AWM2			3003
+ti8148evm		MACH_TI8148EVM		TI8148EVM		3004
+tegra_seaboard		MACH_TEGRA_SEABOARD	TEGRA_SEABOARD		3005
+linkstation_chlv2	MACH_LINKSTATION_CHLV2	LINKSTATION_CHLV2	3006
+tera_pro2_rack		MACH_TERA_PRO2_RACK	TERA_PRO2_RACK		3007
+rubys			MACH_RUBYS		RUBYS			3008
+aquarius		MACH_AQUARIUS		AQUARIUS		3009
+mx53_ard		MACH_MX53_ARD		MX53_ARD		3010
+mx53_smd		MACH_MX53_SMD		MX53_SMD		3011
+lswxl			MACH_LSWXL		LSWXL			3012
+dove_avng_v3		MACH_DOVE_AVNG_V3	DOVE_AVNG_V3		3013
+sdi_ess_9263		MACH_SDI_ESS_9263	SDI_ESS_9263		3014
+jocpu550		MACH_JOCPU550		JOCPU550		3015
+msm8x60_rumi3		MACH_MSM8X60_RUMI3	MSM8X60_RUMI3		3016
+msm8x60_ffa		MACH_MSM8X60_FFA	MSM8X60_FFA		3017
+yanomami		MACH_YANOMAMI		YANOMAMI		3018
+gta04			MACH_GTA04		GTA04			3019
+cm_a510			MACH_CM_A510		CM_A510			3020
+omap3_rfs200		MACH_OMAP3_RFS200	OMAP3_RFS200		3021
+kx33xx			MACH_KX33XX		KX33XX			3022
+ptx7510			MACH_PTX7510		PTX7510			3023
+top9000			MACH_TOP9000		TOP9000			3024
+teenote			MACH_TEENOTE		TEENOTE			3025
+ts3			MACH_TS3		TS3			3026
+a0			MACH_A0			A0			3027
+fsm9xxx_surf		MACH_FSM9XXX_SURF	FSM9XXX_SURF		3028
+fsm9xxx_ffa		MACH_FSM9XXX_FFA	FSM9XXX_FFA		3029
+frrhwcdma60w		MACH_FRRHWCDMA60W	FRRHWCDMA60W		3030
+remus			MACH_REMUS		REMUS			3031
+at91cap7xdk		MACH_AT91CAP7XDK	AT91CAP7XDK		3032
+at91cap7stk		MACH_AT91CAP7STK	AT91CAP7STK		3033
+kt_sbc_sam9_1		MACH_KT_SBC_SAM9_1	KT_SBC_SAM9_1		3034
+at91sam9263router	MACH_ORATISROUTER	ORATISROUTER		3035
+armada_xp_db		MACH_ARMADA_XP_DB	ARMADA_XP_DB		3036
+spdm			MACH_SPDM		SPDM			3037
+gtib			MACH_GTIB		GTIB			3038
+dgm3240			MACH_DGM3240		DGM3240			3039
+iv_atlas_i_lpe		MACH_ATLAS_I_LPE	ATLAS_I_LPE		3040
+htcmega			MACH_HTCMEGA		HTCMEGA			3041
+tricorder		MACH_TRICORDER		TRICORDER		3042
+tx28			MACH_TX28		TX28			3043
+bstbrd			MACH_BSTBRD		BSTBRD			3044
+pwb3090			MACH_PWB3090		PWB3090			3045
+idea6410		MACH_IDEA6410		IDEA6410		3046
+qbc9263			MACH_QBC9263		QBC9263			3047
+borabora		MACH_BORABORA		BORABORA		3048
+valdez			MACH_VALDEZ		VALDEZ			3049
+ls9g20			MACH_LS9G20		LS9G20			3050
+mios_v1			MACH_MIOS_V1		MIOS_V1			3051
+s5pc110_crespo		MACH_S5PC110_CRESPO	S5PC110_CRESPO		3052
+controltek9g20		MACH_CONTROLTEK9G20	CONTROLTEK9G20		3053
+tin307			MACH_TIN307		TIN307			3054
+tin510			MACH_TIN510		TIN510			3055
+ep3505			MACH_EP3517		EP3517			3056
+bluecheese		MACH_BLUECHEESE		BLUECHEESE		3057
+tem3x30			MACH_TEM3X30		TEM3X30			3058
+harvest_desoto		MACH_HARVEST_DESOTO	HARVEST_DESOTO		3059
+msm8x60_qrdc		MACH_MSM8X60_QRDC	MSM8X60_QRDC		3060
+spear900		MACH_SPEAR900		SPEAR900		3061
+pcontrol_g20		MACH_PCONTROL_G20	PCONTROL_G20		3062
+rdstor			MACH_RDSTOR		RDSTOR			3063
+usdloader		MACH_USDLOADER		USDLOADER		3064
+tsoploader		MACH_TSOPLOADER		TSOPLOADER		3065
+kronos			MACH_KRONOS		KRONOS			3066
+ffcore			MACH_FFCORE		FFCORE			3067
+mone			MACH_MONE		MONE			3068
+unit2s			MACH_UNIT2S		UNIT2S			3069
+acer_a5			MACH_ACER_A5		ACER_A5			3070
+etherpro_isp		MACH_ETHERPRO_ISP	ETHERPRO_ISP		3071
+stretchs7000		MACH_STRETCHS7000	STRETCHS7000		3072
+p87_smartsim		MACH_P87_SMARTSIM	P87_SMARTSIM		3073
+tulip			MACH_TULIP		TULIP			3074
+sunflower		MACH_SUNFLOWER		SUNFLOWER		3075
+rib			MACH_RIB		RIB			3076
+clod			MACH_CLOD		CLOD			3077
+rump			MACH_RUMP		RUMP			3078
+tenderloin		MACH_TENDERLOIN		TENDERLOIN		3079
+shortloin		MACH_SHORTLOIN		SHORTLOIN		3080
+roml1			MACH_CRESPO		CRESPO			3081
+antares			MACH_ANTARES		ANTARES			3082
+wb40n			MACH_WB40N		WB40N			3083
+herring			MACH_HERRING		HERRING			3084
+naxy400			MACH_NAXY400		NAXY400			3085
+naxy1200		MACH_NAXY1200		NAXY1200		3086
+vpr200			MACH_VPR200		VPR200			3087
+bug20			MACH_BUG20		BUG20			3088
+goflexnet		MACH_GOFLEXNET		GOFLEXNET		3089
+torbreck		MACH_TORBRECK		TORBRECK		3090
+saarb_mg1		MACH_SAARB_MG1		SAARB_MG1		3091
+callisto		MACH_CALLISTO		CALLISTO		3092
+multhsu			MACH_MULTHSU		MULTHSU			3093
+saluda			MACH_SALUDA		SALUDA			3094
+pemp_omap3_apollo	MACH_PEMP_OMAP3_APOLLO	PEMP_OMAP3_APOLLO	3095
+vc0718			MACH_VC0718		VC0718			3096
+mvblx			MACH_MVBLX		MVBLX			3097
+inhand_apeiron		MACH_INHAND_APEIRON	INHAND_APEIRON		3098
+inhand_fury		MACH_INHAND_FURY	INHAND_FURY		3099
+inhand_siren		MACH_INHAND_SIREN	INHAND_SIREN		3100
+hdnvp			MACH_HDNVP		HDNVP			3101
+softwinner		MACH_SOFTWINNER		SOFTWINNER		3102
+prima2_evb		MACH_PRIMA2_EVB		PRIMA2_EVB		3103
+nas6210			MACH_NAS6210		NAS6210			3104
+unisdev			MACH_UNISDEV		UNISDEV			3105
+sbca11			MACH_SBCA11		SBCA11			3106
+saga			MACH_SAGA		SAGA			3107
+ns_k330			MACH_NS_K330		NS_K330			3108
+tanna			MACH_TANNA		TANNA			3109
+imate8502		MACH_IMATE8502		IMATE8502		3110
+aspen			MACH_ASPEN		ASPEN			3111
+daintree_cwac		MACH_DAINTREE_CWAC	DAINTREE_CWAC		3112
+zmx25			MACH_ZMX25		ZMX25			3113
+maple1			MACH_MAPLE1		MAPLE1			3114
+qsd8x72_surf		MACH_QSD8X72_SURF	QSD8X72_SURF		3115
+qsd8x72_ffa		MACH_QSD8X72_FFA	QSD8X72_FFA		3116
+abilene			MACH_ABILENE		ABILENE			3117
+eigen_ttr		MACH_EIGEN_TTR		EIGEN_TTR		3118
+iomega_ix2_200		MACH_IOMEGA_IX2_200	IOMEGA_IX2_200		3119
+coretec_vcx7400		MACH_CORETEC_VCX7400	CORETEC_VCX7400		3120
+santiago		MACH_SANTIAGO		SANTIAGO		3121
+mx257sol		MACH_MX257SOL		MX257SOL		3122
+strasbourg		MACH_STRASBOURG		STRASBOURG		3123
+msm8x60_fluid		MACH_MSM8X60_FLUID	MSM8X60_FLUID		3124
+smartqv5		MACH_SMARTQV5		SMARTQV5		3125
+smartqv3		MACH_SMARTQV3		SMARTQV3		3126
+smartqv7		MACH_SMARTQV7		SMARTQV7		3127
+tegra_paz00		MACH_PAZ00		PAZ00			3128
+acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129
+htc_willow		MACH_HTCWILLOW		HTCWILLOW		3130
+fwbd_0404		MACH_FWBD_0404		FWBD_0404		3131
+hdgu			MACH_HDGU		HDGU			3132
+pyramid			MACH_PYRAMID		PYRAMID			3133
+epiphan			MACH_EPIPHAN		EPIPHAN			3134
+omap_bender		MACH_OMAP_BENDER	OMAP_BENDER		3135
+gurnard			MACH_GURNARD		GURNARD			3136
+gtl_it5100		MACH_GTL_IT5100		GTL_IT5100		3137
+bcm2708			MACH_BCM2708		BCM2708			3138
+mx51_ggc		MACH_MX51_GGC		MX51_GGC		3139
+sharespace		MACH_SHARESPACE		SHARESPACE		3140
+haba_knx_explorer	MACH_HABA_KNX_EXPLORER	HABA_KNX_EXPLORER	3141
+simtec_kirkmod		MACH_SIMTEC_KIRKMOD	SIMTEC_KIRKMOD		3142
+crux			MACH_CRUX		CRUX			3143
+mx51_bravo		MACH_MX51_BRAVO		MX51_BRAVO		3144
+charon			MACH_CHARON		CHARON			3145
+picocom3		MACH_PICOCOM3		PICOCOM3		3146
+picocom4		MACH_PICOCOM4		PICOCOM4		3147
+serrano			MACH_SERRANO		SERRANO			3148
+doubleshot		MACH_DOUBLESHOT		DOUBLESHOT		3149
+evsy			MACH_EVSY		EVSY			3150
+huashan			MACH_HUASHAN		HUASHAN			3151
+lausanne		MACH_LAUSANNE		LAUSANNE		3152
+emerald			MACH_EMERALD		EMERALD			3153
+tqma35			MACH_TQMA35		TQMA35			3154
+marvel			MACH_MARVEL		MARVEL			3155
+manuae			MACH_MANUAE		MANUAE			3156
+chacha			MACH_CHACHA		CHACHA			3157
+lemon			MACH_LEMON		LEMON			3158
+csc			MACH_CSC		CSC			3159
+gira_knxip_router	MACH_GIRA_KNXIP_ROUTER	GIRA_KNXIP_ROUTER	3160
+t20			MACH_T20		T20			3161
+hdmini			MACH_HDMINI		HDMINI			3162
+sciphone_g2		MACH_SCIPHONE_G2	SCIPHONE_G2		3163
+express			MACH_EXPRESS		EXPRESS			3164
+express_kt		MACH_EXPRESS_KT		EXPRESS_KT		3165
+maximasp		MACH_MAXIMASP		MAXIMASP		3166
+nitrogen_imx51		MACH_NITROGEN_IMX51	NITROGEN_IMX51		3167
+nitrogen_imx53		MACH_NITROGEN_IMX53	NITROGEN_IMX53		3168
+sunfire			MACH_SUNFIRE		SUNFIRE			3169
+arowana			MACH_AROWANA		AROWANA			3170
+tegra_daytona		MACH_TEGRA_DAYTONA	TEGRA_DAYTONA		3171
+tegra_swordfish		MACH_TEGRA_SWORDFISH	TEGRA_SWORDFISH		3172
+edison			MACH_EDISON		EDISON			3173
+svp8500v1		MACH_SVP8500V1		SVP8500V1		3174
+svp8500v2		MACH_SVP8500V2		SVP8500V2		3175
+svp5500			MACH_SVP5500		SVP5500			3176
+b5500			MACH_B5500		B5500			3177
+s5500			MACH_S5500		S5500			3178
+icon			MACH_ICON		ICON			3179
+elephant		MACH_ELEPHANT		ELEPHANT		3180
+msm8x60_charm_surf	MACH_MSM8X60_FUSION	MSM8X60_FUSION		3181
+shooter			MACH_SHOOTER		SHOOTER			3182
+spade_lte		MACH_SPADE_LTE		SPADE_LTE		3183
+philhwani		MACH_PHILHWANI		PHILHWANI		3184
+gsncomm			MACH_GSNCOMM		GSNCOMM			3185
+strasbourg_a2		MACH_STRASBOURG_A2	STRASBOURG_A2		3186
+mmm			MACH_MMM		MMM			3187
+davinci_dm365_bv	MACH_DAVINCI_DM365_BV	DAVINCI_DM365_BV	3188
+ag5evm			MACH_AG5EVM		AG5EVM			3189
+sc575plc		MACH_SC575PLC		SC575PLC		3190
+sc575hmi		MACH_SC575IPC		SC575IPC		3191
+omap3_tdm3730		MACH_OMAP3_TDM3730	OMAP3_TDM3730		3192
+rover_g7		MACH_G7			G7			3193
+top9000_eval		MACH_TOP9000_EVAL	TOP9000_EVAL		3194
+top9000_su		MACH_TOP9000_SU		TOP9000_SU		3195
+utm300			MACH_UTM300		UTM300			3196
+tsunagi			MACH_TSUNAGI		TSUNAGI			3197
+ts75xx			MACH_TS75XX		TS75XX			3198
+msm8x60_charm_ffa	MACH_MSM8X60_FUSN_FFA	MSM8X60_FUSN_FFA	3199
+ts47xx			MACH_TS47XX		TS47XX			3200
+da850_k5		MACH_DA850_K5		DA850_K5		3201
+ax502			MACH_AX502		AX502			3202
+igep0032		MACH_IGEP0032		IGEP0032		3203
+antero			MACH_ANTERO		ANTERO			3204
+synergy			MACH_SYNERGY		SYNERGY			3205
+ics_if_voip		MACH_ICS_IF_VOIP	ICS_IF_VOIP		3206
+wlf_cragg_6410		MACH_WLF_CRAGG_6410	WLF_CRAGG_6410		3207
+punica			MACH_PUNICA		PUNICA			3208
+sbc_nt250		MACH_SBC_NT250		SBC_NT250		3209
+mx27_wmultra		MACH_MX27_WMULTRA	MX27_WMULTRA		3210
+mackerel		MACH_MACKEREL		MACKEREL		3211
+pvd_imx27		MACH_MACH_PVD_IMX27	MACH_PVD_IMX27		3212
+fa9x27			MACH_FA9X27		FA9X27			3213
+ns2816tb		MACH_NS2816TB		NS2816TB		3214
+ns2816_ntpad		MACH_NS2816_NTPAD	NS2816_NTPAD		3215
+ns2816_ntnb		MACH_NS2816_NTNB	NS2816_NTNB		3216
+kaen			MACH_KAEN		KAEN			3217
+nv1000			MACH_NV1000		NV1000			3218
+nuc950ts		MACH_NUC950TS		NUC950TS		3219
+nokia_rm680		MACH_NOKIA_RM680	NOKIA_RM680		3220
+ast2200			MACH_AST2200		AST2200			3221
+lead			MACH_LEAD		LEAD			3222
+unino1			MACH_UNINO1		UNINO1			3223
+greeco			MACH_GREECO		GREECO			3224
+verdi			MACH_VERDI		VERDI			3225
+dm6446_adbox		MACH_DM6446_ADBOX	DM6446_ADBOX		3226
+quad_salsa		MACH_QUAD_SALSA		QUAD_SALSA		3227
+abb_gma_1_1		MACH_ABB_GMA_1_1	ABB_GMA_1_1		3228
+svcid			MACH_SVCID		SVCID			3229
+msm8960_sim		MACH_MSM8960_SIM	MSM8960_SIM		3230
+msm8960_rumi3		MACH_MSM8960_RUMI3	MSM8960_RUMI3		3231
+icon_g			MACH_ICON_G		ICON_G			3232
+mb3			MACH_MB3		MB3			3233
-- 
1.7.1



From marc at cpdesign.com.au  Fri Dec 10 00:42:42 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 10 Dec 2010 16:42:42 +1100
Subject: [PATCH] arm: Introduce VPR200 board
Message-ID: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>

Starting point for the vpr200 board.
Very similar core hardware to mx35 3stack.

Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
---
 arch/arm/Makefile                            |    1 +
 arch/arm/boards/vpr200/Makefile              |    4 +
 arch/arm/boards/vpr200/config.h              |   28 +
 arch/arm/boards/vpr200/env/bin/_update       |   39 ++
 arch/arm/boards/vpr200/env/bin/boot          |   67 ++
 arch/arm/boards/vpr200/env/bin/hush_hack     |    1 +
 arch/arm/boards/vpr200/env/bin/init          |   38 +
 arch/arm/boards/vpr200/env/bin/update_kernel |   15 +
 arch/arm/boards/vpr200/env/bin/update_rootfs |   20 +
 arch/arm/boards/vpr200/env/config            |   46 ++
 arch/arm/boards/vpr200/flash_header.c        |   46 ++
 arch/arm/boards/vpr200/lowlevel.c            |  255 +++++++
 arch/arm/boards/vpr200/vpr200.c              |  929 ++++++++++++++++++++++++++
 arch/arm/boards/vpr200/vpr200.dox            |   10 +
 arch/arm/configs/vpr200_defconfig            |   60 ++
 arch/arm/mach-imx/Kconfig                    |   13 +
 16 files changed, 1572 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/vpr200/Makefile
 create mode 100644 arch/arm/boards/vpr200/config.h
 create mode 100644 arch/arm/boards/vpr200/env/bin/_update
 create mode 100644 arch/arm/boards/vpr200/env/bin/boot
 create mode 100644 arch/arm/boards/vpr200/env/bin/hush_hack
 create mode 100644 arch/arm/boards/vpr200/env/bin/init
 create mode 100644 arch/arm/boards/vpr200/env/bin/update_kernel
 create mode 100644 arch/arm/boards/vpr200/env/bin/update_rootfs
 create mode 100644 arch/arm/boards/vpr200/env/config
 create mode 100644 arch/arm/boards/vpr200/flash_header.c
 create mode 100644 arch/arm/boards/vpr200/lowlevel.c
 create mode 100644 arch/arm/boards/vpr200/vpr200.c
 create mode 100644 arch/arm/boards/vpr200/vpr200.dox
 create mode 100644 arch/arm/configs/vpr200_defconfig

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9729c23..6e6be98 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -91,6 +91,7 @@ board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
 board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
 board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
 board-$(CONFIG_MACH_MINI2440)			:= mini2440
+board-$(CONFIG_MACH_VPR200)			:= vpr200
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/vpr200/Makefile b/arch/arm/boards/vpr200/Makefile
new file mode 100644
index 0000000..08bef79
--- /dev/null
+++ b/arch/arm/boards/vpr200/Makefile
@@ -0,0 +1,4 @@
+
+obj-y					+= lowlevel.o
+obj-y					+= vpr200.o
+obj-$(CONFIG_ARCH_IMX_INTERNAL_BOOT)	+= flash_header.o
diff --git a/arch/arm/boards/vpr200/config.h b/arch/arm/boards/vpr200/config.h
new file mode 100644
index 0000000..2f03006
--- /dev/null
+++ b/arch/arm/boards/vpr200/config.h
@@ -0,0 +1,28 @@
+/*
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * @file
+ * @brief Global defintions for the VPR-R CPU board.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MX35_HCLK_FREQ        24000000
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/vpr200/env/bin/_update b/arch/arm/boards/vpr200/env/bin/_update
new file mode 100644
index 0000000..ddd6b84
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/bin/_update
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+if [ -z "$part" -o -z "$image" ]; then
+	echo "define \$part and \$image"
+	exit 1
+fi
+
+if [ ! -e "$part" ]; then
+	echo "Partition $part does not exist"
+	exit 1
+fi
+
+if [ $# = 1 ]; then
+	image=$1
+fi
+
+if [ x$ip = xdhcp ]; then
+	dhcp
+fi
+
+ping $eth0.serverip
+if [ $? -ne 0 ] ; then
+	echo "Server did not reply! Update aborted."
+	exit 1
+fi
+
+unprotect $part
+
+echo
+echo "erasing partition $part"
+echo
+erase $part
+
+echo
+echo "flashing $image to $part"
+echo
+tftp $image $part
+
+protect $part
diff --git a/arch/arm/boards/vpr200/env/bin/boot b/arch/arm/boards/vpr200/env/bin/boot
new file mode 100644
index 0000000..80135db
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/bin/boot
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+. /env/config
+
+if [ x$1 = xnand ]; then
+	rootfs_loc=nand
+	kernel_loc=nand
+elif [ x$1 = xnor ]; then
+	rootfs_loc=nand
+	kernel_loc=nor
+elif [ x$1 = xnet ]; then
+	rootfs_loc=net
+	kernel_loc=net
+elif [ x$1 = xmmc ]; then
+	rootfs_loc=mmc
+	kernel_loc=mmc
+fi
+
+
+if [ x$ip = xdhcp ]; then
+	bootargs="$bootargs ip=dhcp"
+elif [ x$ip != xno ]; then
+	bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::"
+fi
+
+
+if [ $rootfs_loc != net ]; then
+	if [ x$rootfs_loc = xnand ]; then
+		rootfs_mtdblock=$rootfs_mtdblock_nand
+	elif [ x$rootfs_loc = xnor ]; then
+		rootfs_mtdblock=$rootfs_mtdblock_nor
+	else
+		rootfs_mtdblock=$rootfs_mmc_part
+	fi
+
+
+	if [ $rootfs_type = ubifs ]; then
+		bootargs="$bootargs ubi.mtd=$rootfs_mtdblock root=ubi0:$rootfs"
+	elif [ $rootfs_loc = mmc ]; then
+		bootargs="$bootargs root=/dev/mmcblk0p$rootfs_mmc_part"
+	else
+		bootargs="$bootargs root=/dev/mtdblock$rootfs_mtdblock"
+	fi
+
+	bootargs="$bootargs rootfstype=$rootfs_type"
+
+else
+	bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp"
+fi
+
+
+bootargs="$bootargs mtdparts=physmap-flash.0:$nor_parts;mxc_nand:$nand_parts"
+
+if [ $kernel_loc = net ]; then
+	if [ x$ip = xdhcp ]; then
+		dhcp
+	fi
+	tftp $kernel uImage || exit 1
+	bootm uImage
+elif [ $kernel_loc = nor ]; then
+	bootm /dev/nor0.kernel
+elif [ $kernel_loc = mmc ]; then
+	bootm /dev/disk0.kernel
+else
+	bootm /dev/nand0.kernel.bb
+fi
+
diff --git a/arch/arm/boards/vpr200/env/bin/hush_hack b/arch/arm/boards/vpr200/env/bin/hush_hack
new file mode 100644
index 0000000..5fffa92
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/bin/hush_hack
@@ -0,0 +1 @@
+nand -a /dev/nand0.*
diff --git a/arch/arm/boards/vpr200/env/bin/init b/arch/arm/boards/vpr200/env/bin/init
new file mode 100644
index 0000000..5e6f837
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/bin/init
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+PATH=/env/bin
+export PATH
+
+. /env/config
+if [ -e /dev/nor0 ]; then
+	addpart /dev/nor0 $nor_parts
+fi
+
+if [ -e /dev/nand0 ]; then
+	addpart /dev/nand0 $nand_parts
+
+	# Uh, oh, hush first expands wildcards and then starts executing
+	# commands. What a bug!
+	source /env/bin/hush_hack 
+fi
+
+if [ -e /dev/disk0 ]; then
+	addpart /dev/disk0 $mmc_boot_parts
+fi
+
+if [ -z $eth0.ethaddr ]; then
+	echo "WARN: no MAC address set for eth0."
+fi
+
+echo
+echo -n "Hit any key to stop autoboot: "
+timeout -a $autoboot_timeout
+if [ $? != 0 ]; then
+	echo
+	echo "type update_kernel nand|nor [<imagename>] to update kernel into flash"
+	echo "type update_rootfs nand|nor [<imagename>] to update rootfs into flash"
+	echo
+	exit
+fi
+
+boot
diff --git a/arch/arm/boards/vpr200/env/bin/update_kernel b/arch/arm/boards/vpr200/env/bin/update_kernel
new file mode 100644
index 0000000..63ad11a
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/bin/update_kernel
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+. /env/config
+image=$kernel
+
+if [ x$1 = xnand ]; then
+	part=/dev/nand0.kernel.bb
+elif [ x$1 = xnor ]; then
+	part=/dev/nor0.kernel
+else
+	echo "usage: $0 nor|nand [imagename]"
+	exit 1
+fi
+
+. /env/bin/_update $2
diff --git a/arch/arm/boards/vpr200/env/bin/update_rootfs b/arch/arm/boards/vpr200/env/bin/update_rootfs
new file mode 100644
index 0000000..53dd2ca
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/bin/update_rootfs
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+. /env/config
+
+if [ $rootfs_type = ubifs ]; then
+	image=${rootfs}.ubi
+else
+	image=${rootfs}.$rootfs_type
+fi
+
+if [ x$1 = xnand ]; then
+	part=/dev/nand0.root.bb
+elif [ x$1 = xnor ]; then
+	part=/dev/nor0.root
+else
+	echo "usage: $0 nor|nand [imagename]"
+	exit 1
+fi
+
+. /env/bin/_update $2
diff --git a/arch/arm/boards/vpr200/env/config b/arch/arm/boards/vpr200/env/config
new file mode 100644
index 0000000..300de2d
--- /dev/null
+++ b/arch/arm/boards/vpr200/env/config
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'no' if you don't want to pass the ip from barebox to the kernel
+ip=no
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'net', 'nor' or 'nand''
+kernel_loc=nor
+rootfs_loc=nand
+
+# can be either 'jffs2', or 'ubifs' for flash, 'ext3' for mmc
+rootfs_type=ubifs
+
+if [ x$boot_loc = $xmmc ]; then
+	kernel_loc=mmc
+	rootfs_loc=mmc
+	rootfs_type=ext3
+fi
+
+kernel=uImage
+rootfs=vpr200v1-rootfs
+envimage=vpr200-env
+
+autoboot_timeout=1
+
+nfsroot="/srv/tftpboot"
+debugargs="jtag=on nohlt debug"
+bootargs="earlyprintk=ttymxc0,115200 console=ttymxc0,115200"
+
+nor_parts="256k(barebox)ro,512k(bareboxenv),4M(kernel),-(scratch)"
+rootfs_mtdblock_nor=3
+
+nand_parts="120M(rootfs),-(root)"
+rootfs_mtdblock_nand=4
+
+#note: these are fake partitions within the first real partition on 
+#on the card. They are purely for the bootloader.
+mmc_boot_parts="256k(barebox)ro,512k(bareboxenv),4M(kernel)"
+#the second real partition is our boot partition.
+rootfs_mmc_part=2
diff --git a/arch/arm/boards/vpr200/flash_header.c b/arch/arm/boards/vpr200/flash_header.c
new file mode 100644
index 0000000..ef29bc2
--- /dev/null
+++ b/arch/arm/boards/vpr200/flash_header.c
@@ -0,0 +1,46 @@
+#include <common.h>
+#include <mach/imx-flash-header.h>
+#include <mach/imx-regs.h>
+
+extern void exception_vectors(void);
+
+void __naked __flash_header_start go(void)
+{
+	__asm__ __volatile__("b exception_vectors\n");
+}
+
+struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
+	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000304, },
+	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x0000030C, },
+	{ .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc3f, },
+	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0x92220000, },
+	{ .ptr_type = 4, .addr = 0x80000400, .val = 0x12345678, },
+	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0xA2220000, },
+	{ .ptr_type = 4, .addr = 0x80000000, .val = 0x87654321, },
+	{ .ptr_type = 4, .addr = 0x80000000, .val = 0x87654321, },
+	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0xB2220000, },
+	{ .ptr_type = 1, .addr = 0x80000233, .val = 0xda, },
+	{ .ptr_type = 1, .addr = 0x82000780, .val = 0xda, },
+	{ .ptr_type = 1, .addr = 0x82000400, .val = 0xda, },
+	{ .ptr_type = 4, .addr = 0xB8001000, .val = 0x82226080, },
+	{ .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc3f, },
+	{ .ptr_type = 4, .addr = 0xB800100C, .val = 0x007ffc3f, },
+	{ .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000304, },
+	{ .ptr_type = 4, .addr = 0xB8001008, .val = 0x00002000, },
+};
+
+
+struct imx_flash_header __flash_header_section flash_header = {
+	.app_code_jump_vector	= DEST_BASE + ((unsigned int)&exception_vectors - TEXT_BASE),
+	.app_code_barker	= APP_CODE_BARKER,
+	.app_code_csf		= 0,
+	.dcd_ptr_ptr		= FLASH_HEADER_BASE + offsetof(struct imx_flash_header, dcd),
+	.super_root_key		= 0,
+	.dcd			= FLASH_HEADER_BASE + offsetof(struct imx_flash_header, dcd_barker),
+	.app_dest		= DEST_BASE,
+	.dcd_barker		= DCD_BARKER,
+	.dcd_block_len		= sizeof(dcd_entry),
+};
+
+unsigned long __image_len_section barebox_len = 0x40000;
+
diff --git a/arch/arm/boards/vpr200/lowlevel.c b/arch/arm/boards/vpr200/lowlevel.c
new file mode 100644
index 0000000..7e777aa
--- /dev/null
+++ b/arch/arm/boards/vpr200/lowlevel.c
@@ -0,0 +1,255 @@
+/*
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer at pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <init.h>
+#include <mach/imx-regs.h>
+#include <mach/imx-pll.h>
+#include <mach/esdctl.h>
+#include <asm/cache-l2x0.h>
+#include <asm/io.h>
+#include <mach/imx-nand.h>
+#include <asm/barebox-arm.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/system.h>
+
+/* Assuming 24MHz input clock */
+#define MPCTL_PARAM_399     (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5))
+#define MPCTL_PARAM_532     ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1))
+#define PPCTL_PARAM_300     (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1))
+
+
+#ifdef CONFIG_NAND_IMX_BOOT
+static void __bare_init __naked insdram(void)
+{
+	uint32_t r;
+
+	/* Speed up NAND controller by adjusting the NFC divider */
+	r = readl(IMX_CCM_BASE + CCM_PDR4);
+	r &= ~(0xf << 28);
+	r |= 0x1 << 28;
+	writel(r, IMX_CCM_BASE + CCM_PDR4);
+
+	/* setup a stack to be able to call imx_nand_load_image() */
+	r = STACK_BASE + STACK_SIZE - 12;
+	__asm__ __volatile__("mov sp, %0" : : "r"(r));
+
+	imx_nand_load_image((void *)TEXT_BASE, 256 * 1024);
+
+	board_init_lowlevel_return();
+}
+#endif
+
+void __bare_init __naked board_init_lowlevel(void)
+{
+	uint32_t r, s;
+	unsigned long ccm_base = IMX_CCM_BASE;
+#ifdef CONFIG_NAND_IMX_BOOT
+	unsigned int *trg, *src;
+	int i;
+#endif
+
+	r = get_cr();
+	r |= CR_Z; /* Flow prediction (Z) */
+	r |= CR_U; /* unaligned accesses  */
+	r |= CR_FI; /* Low Int Latency     */
+
+	__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(s));
+	s |= 0x7;
+	__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1" : : "r"(s));
+
+	set_cr(r);
+
+	r = 0;
+	__asm__ __volatile__("mcr p15, 0, %0, c15, c2, 4" : : "r"(r));
+
+	/*
+	 * Branch predicition is now enabled.  Flush the BTAC to ensure a valid
+	 * starting point.  Don't flush BTAC while it is disabled to avoid
+	 * ARM1136 erratum 408023.
+	 */
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 6" : : "r"(r));
+
+	/* invalidate I cache and D cache */
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c7, 0" : : "r"(r));
+
+	/* invalidate TLBs */
+	__asm__ __volatile__("mcr p15, 0, %0, c8, c7, 0" : : "r"(r));
+
+	/* Drain the write buffer */
+	__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(r));
+
+	/* Also setup the Peripheral Port Remap register inside the core */
+	r = 0x40000015; /* start from AIPS 2GB region */
+	__asm__ __volatile__("mcr p15, 0, %0, c15, c2, 4" : : "r"(r));
+
+	/*
+	 * End of ARM1136 init
+	 */
+
+	writel(0x003F4208, ccm_base + CCM_CCMR);
+
+	/* Set MPLL , arm clock and ahb clock*/
+	writel(MPCTL_PARAM_532, ccm_base + CCM_MPCTL);
+
+	writel(PPCTL_PARAM_300, ccm_base + CCM_PPCTL);
+	writel(0x00001000, ccm_base + CCM_PDR0);
+
+	r = readl(ccm_base + CCM_CGR0);
+	r |= 0x00300000;
+	writel(r, ccm_base + CCM_CGR0);
+
+	r = readl(ccm_base + CCM_CGR1);
+	r |= 0x00000C00;
+	r |= 0x00000003;
+	writel(r, ccm_base + CCM_CGR1);
+
+	r = readl(IMX_L2CC_BASE + L2X0_AUX_CTRL);
+	r |= 0x1000;
+	writel(r, IMX_L2CC_BASE + L2X0_AUX_CTRL);
+
+	/* Skip SDRAM initialization if we run from RAM */
+	r = get_pc();
+	if (r > 0x80000000 && r < 0x90000000)
+		board_init_lowlevel_return();
+
+	/**
+	 * RAM init
+	 */
+	/* VPR200v1 has DDR2, DDR2_EN 0x200, DDR_EN 0x100, MDDR_EN 0x004 */
+	writel(0x00000304, ESDMISC); /*  */
+
+	/* set timing paramters (basically max delays for all)*/
+	writel(0x007ffc2f, ESDCFG0);
+	/* select Precharge-All mode */
+	writel(0x92220000, ESDCTL0);
+	/* Precharge-All */
+	writel(0x12345678, IMX_SDRAM_CS0 + 0x400);
+
+	/* select Load-Mode-Register mode */
+	writel(0xB8001000, ESDCTL0);
+	/* Load reg EMR2 */
+	writeb(0xda, 0x84000000);
+	/* Load reg EMR3 */
+	writeb(0xda, 0x86000000);
+	/* Load reg EMR1 -- enable DLL */
+	writeb(0xda, 0x82000400);
+	/* Load reg MR -- reset DLL */
+	writeb(0xda, 0x80000333);
+
+	/* select Precharge-All mode */
+	writel(0x92220000, ESDCTL0);
+	/* Precharge-All */
+	writel(0x12345678, IMX_SDRAM_CS0 + 0x400);
+
+	/* select Manual-Refresh mode */
+	writel(0xA2220000, ESDCTL0);
+	/* Manual-Refresh 2 times */
+	writel(0x87654321, IMX_SDRAM_CS0);
+	writel(0x87654321, IMX_SDRAM_CS0);
+
+	/* select Load-Mode-Register mode */
+	writel(0xB2220000, ESDCTL0);
+	/* Load reg MR -- CL3, BL8, end DLL reset */
+	writeb(0xda, 0x80000233);
+	/* Load reg EMR1 -- OCD default */
+	writeb(0xda, 0x82000780);
+	/* Load reg EMR1 -- OCD exit */
+	writeb(0xda, 0x82000400);
+
+	/* select normal-operation mode
+	 * DSIZ32-bit, BL8, COL10-bit, ROW13-bit
+	 * disable PWT & PRCT
+	 * disable Auto-Refresh */
+	writel(0x82220080, ESDCTL0);
+	/* enable Auto-Refresh */
+	writel(0x82228080, ESDCTL0);
+
+	/* BANK 2 */
+
+	/* set timing paramters (basically max delays for all)*/
+	writel(0x007ffc2f, ESDCFG1);
+	/* select Precharge-All mode */
+	writel(0x92220000, ESDCTL1);
+	/* Precharge-All */
+	writel(0x12345678, IMX_SDRAM_CS1 + 0x400);
+
+	/* select Load-Mode-Register mode */
+	writel(0xB8001000, ESDCTL1);
+	/* Load reg EMR2 */
+	writeb(0xda, 0x94000000);
+	/* Load reg EMR3 */
+	writeb(0xda, 0x96000000);
+	/* Load reg EMR1 -- enable DLL */
+	writeb(0xda, 0x92000400);
+	/* Load reg MR -- reset DLL */
+	writeb(0xda, 0x90000333);
+
+	/* select Precharge-All mode */
+	writel(0x92220000, ESDCTL1);
+	/* Precharge-All */
+	writel(0x12345678, IMX_SDRAM_CS1 + 0x400);
+
+	/* select Manual-Refresh mode */
+	writel(0xA2220000, ESDCTL1);
+	/* Manual-Refresh 2 times */
+	writel(0x87654321, IMX_SDRAM_CS1);
+	writel(0x87654321, IMX_SDRAM_CS1);
+
+	/* select Load-Mode-Register mode */
+	writel(0xB2220000, ESDCTL1);
+	/* Load reg MR -- CL3, BL8, end DLL reset */
+	writeb(0xda, 0x90000233);
+	/* Load reg EMR1 -- OCD default */
+	writeb(0xda, 0x92000780);
+	/* Load reg EMR1 -- OCD exit */
+	writeb(0xda, 0x92000400);
+
+	/* select normal-operation mode
+	 * DSIZ32-bit, BL8, COL10-bit, ROW13-bit
+	 * disable PWT & PRCT
+	 * disable Auto-Refresh */
+	writel(0x82220080, ESDCTL1);
+	/* enable Auto-Refresh */
+	writel(0x82228080, ESDCTL1);
+
+#ifdef CONFIG_NAND_IMX_BOOT
+	/* skip NAND boot if not running from NFC space */
+	r = get_pc();
+	if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x800)
+		board_init_lowlevel_return();
+
+	src = (unsigned int *)IMX_NFC_BASE;
+	trg = (unsigned int *)TEXT_BASE;
+
+	/* Move ourselves out of NFC SRAM */
+	for (i = 0; i < 0x800 / sizeof(int); i++)
+		*trg++ = *src++;
+
+	/* Jump to SDRAM */
+	r = (unsigned int)&insdram;
+	__asm__ __volatile__("mov pc, %0" : : "r"(r));
+#else
+	board_init_lowlevel_return();
+#endif
+}
+
diff --git a/arch/arm/boards/vpr200/vpr200.c b/arch/arm/boards/vpr200/vpr200.c
new file mode 100644
index 0000000..298195d
--- /dev/null
+++ b/arch/arm/boards/vpr200/vpr200.c
@@ -0,0 +1,929 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer, Pengutronix
+ *               2009 Marc Kleine-Budde, Pengutronix
+ *               2010 Marc Reilly, Creative Product Design
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Derived from:
+ *
+ * * mx35_3stack.c - board file for uboot-v1
+ *   Copyright (C) 2007, Guennadi Liakhovetski <lg at denx.de>
+ *   (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
+ *
+ */
+
+#include <common.h>
+#include <environment.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fec.h>
+#include <fs.h>
+#include <init.h>
+#include <nand.h>
+#include <net.h>
+#include <partition.h>
+#include <command.h>
+#include <getopt.h>
+
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+
+#include <mach/gpio.h>
+#include <mach/imx-nand.h>
+#include <mach/imx-regs.h>
+#include <mach/iomux-mx35.h>
+#include <mach/iomux-v3.h>
+#include <mach/pmic.h>
+#include <mach/imx-ipu-fb.h>
+#include <mach/generic.h>
+#include <mach/devices-imx35.h>
+
+#include <i2c/i2c.h>
+#include <mfd/mc13892.h>
+
+/* ------------------------------------------------------------------------- */
+/* Board revs for the VPR CPU */
+#define VPR_CPU_V1  0x19
+
+/*
+ * IO Defines for the VPR
+ *
+ * The current GPIO API considers the gpios as a contiguous bits across
+ * ports. These defines and macros convert the GPIO1_3 nomenclature to
+ * a numbered GPIO line.
+ */
+
+/* Port numbers start from 1 to be consistent with iMX docs */
+#define GPIO_FROM_PORT(x, y) (((x-1)*32) + y)
+
+#define LCD_PWR_PORT		1
+#define LCD_PWR_BIT		2
+#define LCD_PWR_GPIO		GPIO_FROM_PORT(LCD_PWR_PORT, LCD_PWR_BIT)
+
+#define FEC_ENABLE_PORT		1
+#define FEC_ENABLE_BIT		3
+#define FEC_ENABLE_GPIO		GPIO_FROM_PORT(FEC_ENABLE_PORT, FEC_ENABLE_BIT)
+
+#define FEC_RESET_PORT		3
+#define FEC_RESET_BIT		0
+#define FEC_RESET_GPIO		GPIO_FROM_PORT(FEC_RESET_PORT, FEC_RESET_BIT)
+
+#define DIAG_PORT		3
+#define DIAG_RED_BIT		14
+#define DIAG_GREEN_BIT		15
+#define DIAG_BLUE_BIT		30
+#define DIAG_RED_GPIO		GPIO_FROM_PORT(DIAG_PORT, DIAG_RED_BIT)
+#define DIAG_GREEN_GPIO		GPIO_FROM_PORT(DIAG_PORT, DIAG_GREEN_BIT)
+#define DIAG_BLUE_GPIO		GPIO_FROM_PORT(DIAG_PORT, DIAG_BLUE_BIT)
+
+#define SYS_CFG_PORT		2
+#define SYS_CFG_1_BIT		27
+#define SYS_CFG_2_BIT		28
+#define SYS_CFG_3_BIT		29
+#define SYS_CFG_4_BIT		30
+#define SYS_CFG_5_BIT		31
+#define SYS_CFG_1_GPIO		GPIO_FROM_PORT(SYS_CFG_PORT, SYS_CFG_1_BIT)
+#define SYS_CFG_2_GPIO		GPIO_FROM_PORT(SYS_CFG_PORT, SYS_CFG_2_BIT)
+#define SYS_CFG_3_GPIO		GPIO_FROM_PORT(SYS_CFG_PORT, SYS_CFG_3_BIT)
+#define SYS_CFG_4_GPIO		GPIO_FROM_PORT(SYS_CFG_PORT, SYS_CFG_4_BIT)
+#define SYS_CFG_5_GPIO		GPIO_FROM_PORT(SYS_CFG_PORT, SYS_CFG_5_BIT)
+
+#define BUTTON_PORT		1
+#define BUTTON1_BIT		4
+#define BUTTON2_BIT		5
+#define BUTTON3_BIT		7
+#define BUTTON4_BIT		8
+#define BUTTON5_BIT		9
+#define BUTTON6_BIT		10
+#define BUTTON7_BIT		11
+#define BUTTON8_BIT		12
+#define BUTTON1_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON1_BIT)
+#define BUTTON2_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON2_BIT)
+#define BUTTON3_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON3_BIT)
+#define BUTTON4_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON4_BIT)
+#define BUTTON5_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON5_BIT)
+#define BUTTON6_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON6_BIT)
+#define BUTTON7_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON7_BIT)
+#define BUTTON8_GPIO		GPIO_FROM_PORT(BUTTON_PORT, BUTTON8_BIT)
+
+#define BUZZER_PORT		1
+#define BUZZER_BIT		13
+#define BUZZER_GPIO		GPIO_FROM_PORT(BUZZER_PORT, BUZZER_BIT)
+
+#define BP_PORT			2
+#define BP_RESET_BIT		18
+#define BP_EOC_BIT		17
+#define BP_RESET_GPIO		GPIO_FROM_PORT(BP_PORT, BP_RESET_BIT)
+#define BP_EOC_GPIO		GPIO_FROM_PORT(BP_PORT, BP_EOC_BIT)
+
+#define RF_PORT			2
+#define RF_RESET_BIT		12
+#define RF_TDI_BIT		13
+#define RF_TDO_BIT		14
+#define RF_TCK_BIT		15
+#define RF_TMS_BIT		16
+#define RF_RESET_GPIO		GPIO_FROM_PORT(RF_PORT, RF_RESET_BIT)
+#define RF_TDI_GPIO		GPIO_FROM_PORT(RF_PORT, RF_TDI_BIT)
+#define RF_TDO_GPIO		GPIO_FROM_PORT(RF_PORT, RF_TDO_BIT)
+#define RF_TCK_GPIO		GPIO_FROM_PORT(RF_PORT, RF_TCK_BIT)
+#define RF_TMS_GPIO		GPIO_FROM_PORT(RF_PORT, RF_TMS_BIT)
+
+/* ------------------------------------------------------------------------- */
+static struct device_d cfi_dev = {
+	.id		= -1,
+	.name		= "cfi_flash",
+	.map_base	= IMX_CS0_BASE,
+	.size		= 64 * 1024 * 1024,
+};
+
+static struct fec_platform_data fec_info = {
+	.xcv_type	= MII100,
+	.phy_addr	= 0x0,
+};
+
+static struct memory_platform_data sdram_pdata = {
+	.name		= "ram0",
+	.flags		= DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id		= -1,
+	.name		= "mem",
+	.map_base	= IMX_SDRAM_CS0,
+	.size		= 128 * 1024 * 1024,
+	.platform_data	= &sdram_pdata,
+};
+
+static struct memory_platform_data sdram_pdata1 = {
+	.name		= "ram1",
+	.flags		= DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev1 = {
+	.id		= -1,
+	.name		= "mem",
+	.map_base	= IMX_SDRAM_CS1,
+	.size		= 128 * 1024 * 1024,
+	.platform_data	= &sdram_pdata1,
+};
+
+struct imx_nand_platform_data nand_info = {
+	.hw_ecc		= 1,
+	.flash_bbt	= 1,
+};
+
+static struct i2c_board_info i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("mc13892-i2c", 0x08),
+	}, {
+		I2C_BOARD_INFO("at24", 0x50),
+	},
+};
+
+static void vpr_display_enable(int enable)
+{
+	gpio_direction_output(LCD_PWR_GPIO, enable ? 0 : 1);
+}
+
+/*
+ * Same as imx35 pdk
+ */
+static struct fb_videomode CTP_CLAA070LC0ACW = {
+	/* 800x480 @ 60 Hz */
+	.name		= "CTP-CLAA070LC0ACW",
+	.refresh	= 60,
+	.xres		= 800,
+	.yres		= 480,
+	.pixclock	= KHZ2PICOS(27000),
+	.left_margin	= 50,
+	.right_margin	= 50,	/* whole line should have 900 clocks */
+	.upper_margin	= 10,
+	.lower_margin	= 10,	/* whole frame should have 500 lines */
+	.hsync_len	= 1,	/* note: DE only display */
+	.vsync_len	= 1,	/* note: DE only display */
+	.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+	.vmode		= FB_VMODE_NONINTERLACED,
+	.flag		= 0,
+};
+
+static struct imx_ipu_fb_platform_data ipu_fb_data = {
+	.mode		= &CTP_CLAA070LC0ACW,
+	.bpp		= 16,
+	.enable		= vpr_display_enable,
+};
+
+/* ------------------------------------------------------------------------- */
+/**
+ * Board has 5 lines that are tied high or low to give a system configuration
+ * ID. (ie board revision).
+ */
+static uint32_t vpr_read_sys_cfg(void)
+{
+	uint32_t ret = 0;
+
+	ret |= gpio_get_value(SYS_CFG_1_GPIO);
+	ret |= gpio_get_value(SYS_CFG_2_GPIO) << 1;
+	ret |= gpio_get_value(SYS_CFG_3_GPIO) << 2;
+	ret |= gpio_get_value(SYS_CFG_4_GPIO) << 3;
+	ret |= gpio_get_value(SYS_CFG_5_GPIO) << 4;
+
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * Init gpio lines for tri-color LED used for diagnostics.
+ *
+ * Note does not set the IOMUX directions, so this needs to be
+ * done elsewhere.
+ */
+void vpr_diag_init(void)
+{
+	/* active low outputs, all start off */
+	gpio_direction_output(DIAG_RED_GPIO, 1);
+	gpio_direction_output(DIAG_GREEN_GPIO, 1);
+	gpio_direction_output(DIAG_BLUE_GPIO, 1);
+}
+
+/**
+ *  Sets each color component of the tri color led
+ *
+ *  \param red      Zero for Off. All other values On.
+ *  \param green    Zero for Off. All other values On.
+ *  \param blue     Zero for Off. All other values On.
+ */
+void vpr_diag_set(int red, int green, int blue)
+{
+	/* active low outputs */
+	gpio_set_value(DIAG_RED_GPIO, !red);
+	gpio_set_value(DIAG_GREEN_GPIO, !green);
+	gpio_set_value(DIAG_BLUE_GPIO, !blue);
+}
+
+/**
+ * Enum matching all color component triplets to
+ * named identifiers.
+ */
+enum diag_led_color {
+	DIAG_LED_OFF        = 0x0,
+	DIAG_LED_BLUE       = 0x1,
+	DIAG_LED_GREEN      = 0x2,
+	DIAG_LED_AQUA       = 0x3,
+	DIAG_LED_RED        = 0x4,
+	DIAG_LED_MAGENTA    = 0x5,
+	DIAG_LED_YELLOW     = 0x6,
+	DIAG_LED_WHITE      = 0x7,
+};
+
+/**
+ * Set Diagnostic LED to specified color
+ */
+void vpr_diag_set_color(enum diag_led_color color)
+{
+	vpr_diag_set(color & 0x4, color & 0x02, color & 0x01);
+}
+
+/* ------------------------------------------------------------------------- */
+enum vpr_button {
+	BUTTONNONE = 0,
+	BUTTON1 = 0x01,
+	BUTTON2 = 0x02,
+	BUTTON3 = 0x04,
+	BUTTON4 = 0x08,
+	BUTTON5 = 0x10,
+	BUTTON6 = 0x20,
+	BUTTON7 = 0x40,
+	BUTTON8 = 0x80
+};
+
+static void vpr_button_init(void)
+{
+	gpio_direction_input(BUTTON1_GPIO);
+	gpio_direction_input(BUTTON2_GPIO);
+	gpio_direction_input(BUTTON3_GPIO);
+	gpio_direction_input(BUTTON4_GPIO);
+	gpio_direction_input(BUTTON5_GPIO);
+	gpio_direction_input(BUTTON6_GPIO);
+	gpio_direction_input(BUTTON7_GPIO);
+	gpio_direction_input(BUTTON8_GPIO);
+}
+
+static int vpr_button_state(void)
+{
+	uint32_t ret = 0;
+
+	ret |= (!gpio_get_value(BUTTON1_GPIO));
+	ret |= (!gpio_get_value(BUTTON2_GPIO)) << 1;
+	ret |= (!gpio_get_value(BUTTON3_GPIO)) << 2;
+	ret |= (!gpio_get_value(BUTTON4_GPIO)) << 3;
+	ret |= (!gpio_get_value(BUTTON5_GPIO)) << 4;
+	ret |= (!gpio_get_value(BUTTON6_GPIO)) << 5;
+	ret |= (!gpio_get_value(BUTTON7_GPIO)) << 6;
+	ret |= (!gpio_get_value(BUTTON8_GPIO)) << 7;
+
+	return ret;
+}
+
+static int vpr_button_state_to_number(int bstate)
+{
+	int ret = 1;
+	if (!bstate)
+		return 0;
+
+	while (!(bstate & 0x01)) {
+		bstate >>= 1;
+		++ret;
+	}
+	return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+static void vpr_buzzer_init(void)
+{
+	gpio_direction_output(BUZZER_GPIO, 0);
+}
+
+static void vpr_buzzer_off(void)
+{
+	gpio_set_value(BUZZER_GPIO, 0);
+}
+
+static void vpr_buzzer_on(void)
+{
+	gpio_set_value(BUZZER_GPIO, 1);
+}
+
+/* ------------------------------------------------------------------------- */
+static void vpr_bp_init(void)
+{
+	struct pad_desc bp_pads[] = {
+		MX35_PAD_ATA_DATA4__GPIO2_17,
+		MX35_PAD_ATA_DATA5__GPIO2_18,
+	};
+
+	mxc_iomux_v3_setup_multiple_pads(bp_pads, ARRAY_SIZE(bp_pads));
+
+	gpio_direction_output(BP_RESET_GPIO, 1);
+	gpio_direction_input(BP_EOC_GPIO);
+}
+
+static void vpr_rf_init(void)
+{
+	struct pad_desc rf_pads[] = {
+		MX35_PAD_ATA_IORDY__GPIO2_12,
+		MX35_PAD_ATA_DATA0__GPIO2_13,
+		MX35_PAD_ATA_DATA1__GPIO2_14,
+		MX35_PAD_ATA_DATA2__GPIO2_15,
+		MX35_PAD_ATA_DATA3__GPIO2_16,
+	};
+
+	mxc_iomux_v3_setup_multiple_pads(rf_pads, ARRAY_SIZE(rf_pads));
+
+	gpio_direction_output(RF_RESET_GPIO, 0);
+	gpio_direction_output(RF_TDI_GPIO, 1);
+	gpio_direction_output(RF_TCK_GPIO, 1);
+	gpio_direction_output(RF_TMS_GPIO, 1);
+	gpio_direction_input(RF_TDO_GPIO);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/*
+ * Board initialization order:
+ *  core_initcall
+ *  postcore_initcall
+ *  console_initcall
+ *  postconsole_initcall
+ *  coredevice_initcall
+ *  fs_initcall
+ *  device_initcall
+ *  late_initcall
+ */
+
+static int vpr_devices_init(void)
+{
+#define MAX_BOOTSRC_MSG 80
+	uint32_t reg;
+	char bootsrc_msg[MAX_BOOTSRC_MSG+1] = {0,};
+
+	/* take care of WDT */
+	writew(0xFFB3, IMX_WDT_BASE + 0);
+	writew(0x0000, IMX_WDT_BASE + 8);
+
+	/* CS0: Nor Flash */
+	writel(0x0000cf03, CSCR_U(0));
+	writel(0x10000d03, CSCR_L(0));
+	writel(0x00720900, CSCR_A(0));
+
+	reg = readl(IMX_CCM_BASE + CCM_RCSR);
+	/* some fuses provide us vital information about connected hardware */
+	if (reg & 0x20000000)
+		nand_info.width = 2;	/* 16 bit */
+	else
+		nand_info.width = 1;	/* 8 bit */
+
+	/* This platform supports NOR, NAND and SD */
+	imx35_add_nand(&nand_info);
+	register_device(&cfi_dev);
+	imx35_add_mmc0(NULL);
+
+	switch ((reg >> 25) & 0x3) {
+	case 0x03:		/* SD/MMC is the source */
+		vpr_diag_set_color(DIAG_LED_MAGENTA);
+		snprintf(bootsrc_msg, MAX_BOOTSRC_MSG, "SD boot: ");
+		devfs_add_partition("disk0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
+		devfs_add_partition("disk0", 0x40000, 0x80000, PARTITION_FIXED, "env0");
+		protect_file("/dev/self0", 1);
+		protect_file("/dev/env0", 1);
+		break;
+
+	case 0x01:		/* NAND is the source */
+		devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
+		dev_add_bb_dev("self_raw", "self0");
+		devfs_add_partition("nand0", 0x40000, 0x80000, PARTITION_FIXED, "env_raw");
+		dev_add_bb_dev("env_raw", "env0");
+		break;
+
+	case 0x00:		/* NOR is the source */
+		vpr_diag_set_color(DIAG_LED_AQUA);
+		snprintf(bootsrc_msg, MAX_BOOTSRC_MSG, "NOR boot: ");
+		devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
+		devfs_add_partition("nor0", 0x40000, 0x80000, PARTITION_FIXED, "env0");
+		protect_file("/dev/self0", 1);
+		protect_file("/dev/env0", 1);
+		break;
+	default:
+		printf("WARN: Unrecognized boot source.\n");
+		break;
+	}
+
+	/* delay printing message so protect file doesn't get in the middle */
+	printf(bootsrc_msg);
+
+	switch ((reg >> 10) & 0x3) {
+	case 0x03:
+		printf("Bootstrap mode\n");
+		break;
+	case 0x02:
+		printf("External\n");
+		break;
+	case 0x00:
+		printf("Internal\n");
+		break;
+	default:
+		break;
+	}
+
+	i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));
+
+	imx35_add_i2c0(NULL);
+	imx35_add_i2c1(NULL);
+	imx35_add_fec(&fec_info);
+
+	register_device(&sdram_dev);
+	register_device(&sdram_dev1);
+
+	imx35_add_fb(&ipu_fb_data);
+
+	vpr_button_init();
+	vpr_buzzer_init();
+	vpr_bp_init();
+	vpr_rf_init();
+
+	armlinux_add_dram(&sdram_dev);
+	/* TODO adding BANK1 causes early kernel crash when booting
+	 * off SD card */
+
+	armlinux_set_bootparams((void *)0x80000100);
+
+	armlinux_set_architecture(MACH_TYPE_VPR200);
+
+	/* For compat with the freescale kernel, relies on setting revision*/
+	armlinux_set_revision(0x00035100 | imx_silicon_revision());
+
+	return 0;
+}
+
+device_initcall(vpr_devices_init);
+
+static struct pad_desc vpr_pads[] = {
+	/* FEC */
+	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+	MX35_PAD_FEC_COL__FEC_COL,
+	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+	MX35_PAD_FEC_MDC__FEC_MDC,
+	MX35_PAD_FEC_MDIO__FEC_MDIO,
+	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+	MX35_PAD_FEC_CRS__FEC_CRS,
+	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+	/* FEC enable */
+	MX35_PAD_D3_REV__GPIO1_3,
+	/* UART 1*/
+	MX35_PAD_RXD1__UART1_RXD_MUX,
+	MX35_PAD_TXD1__UART1_TXD_MUX,
+	MX35_PAD_RTS1__UART1_RTS,
+	MX35_PAD_CTS1__UART1_CTS,
+	/* I2C1 */
+	MX35_PAD_I2C1_CLK__I2C1_SCL,
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+	/* I2C2 */
+	MX35_PAD_I2C2_CLK__I2C2_SCL,
+	MX35_PAD_I2C2_DAT__I2C2_SDA,
+	/* Sys config */
+	MX35_PAD_ATA_DATA14__GPIO2_27,
+	MX35_PAD_ATA_DATA15__GPIO2_28,
+	MX35_PAD_ATA_INTRQ__GPIO2_29,
+	MX35_PAD_ATA_BUFF_EN__GPIO2_30,
+	MX35_PAD_ATA_DMARQ__GPIO2_31,
+	/* LCD enable */
+	MX35_PAD_D3_VSYNC__GPIO1_2,
+	/* Display */
+	MX35_PAD_LD0__IPU_DISPB_DAT_0,
+	MX35_PAD_LD1__IPU_DISPB_DAT_1,
+	MX35_PAD_LD2__IPU_DISPB_DAT_2,
+	MX35_PAD_LD3__IPU_DISPB_DAT_3,
+	MX35_PAD_LD4__IPU_DISPB_DAT_4,
+	MX35_PAD_LD5__IPU_DISPB_DAT_5,
+	MX35_PAD_LD6__IPU_DISPB_DAT_6,
+	MX35_PAD_LD7__IPU_DISPB_DAT_7,
+	MX35_PAD_LD8__IPU_DISPB_DAT_8,
+	MX35_PAD_LD9__IPU_DISPB_DAT_9,
+	MX35_PAD_LD10__IPU_DISPB_DAT_10,
+	MX35_PAD_LD11__IPU_DISPB_DAT_11,
+	MX35_PAD_LD12__IPU_DISPB_DAT_12,
+	MX35_PAD_LD13__IPU_DISPB_DAT_13,
+	MX35_PAD_LD14__IPU_DISPB_DAT_14,
+	MX35_PAD_LD15__IPU_DISPB_DAT_15,
+	MX35_PAD_LD16__IPU_DISPB_DAT_16,
+	MX35_PAD_LD17__IPU_DISPB_DAT_17,
+	MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+	/* Buttons */
+	MX35_PAD_SCKR__GPIO1_4,
+	MX35_PAD_COMPARE__GPIO1_5,
+	MX35_PAD_SCKT__GPIO1_7,
+	MX35_PAD_FST__GPIO1_8,
+	MX35_PAD_HCKT__GPIO1_9,
+	MX35_PAD_TX5_RX0__GPIO1_10,
+	MX35_PAD_TX4_RX1__GPIO1_11,
+	MX35_PAD_TX3_RX2__GPIO1_12,
+	/* Buzzer */
+	MX35_PAD_TX2_RX3__GPIO1_13,
+	/* Diag LED */
+	MX35_PAD_USBOTG_PWR__GPIO3_14,
+	MX35_PAD_USBOTG_OC__GPIO3_15,
+	MX35_PAD_D3_HSYNC__GPIO3_30,
+};
+
+
+static int vpr_console_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(vpr_pads, ARRAY_SIZE(vpr_pads));
+
+	imx35_add_uart0();
+	return 0;
+}
+
+console_initcall(vpr_console_init);
+
+static int vpr_post_console_init(void)
+{
+	vpr_diag_init();
+	vpr_diag_set_color(DIAG_LED_YELLOW);
+	return 0;
+}
+
+postcore_initcall(vpr_post_console_init);
+
+static int vpr_core_init(void)
+{
+	u32 reg;
+
+	/* enable clock for SDHC1, I2C[1] and FEC */
+	reg = readl(IMX_CCM_BASE + CCM_CGR1);
+	reg |= 0x3 << CCM_CGR1_FEC_SHIFT;
+	reg |= 0x3 << CCM_CGR1_I2C1_SHIFT;
+	reg |= 0x3 << CCM_CGR1_SDHC1_SHIFT;
+	reg = writel(reg, IMX_CCM_BASE + CCM_CGR1);
+
+	/* AIPS setup - Only setup MPROTx regs. The PACR defaults are good.*/
+	/*
+	 * Set all MPROTx to be non-bufferable, trusted for R/W,
+	 * not forced to user-mode.
+	 */
+	writel(0x77777777, IMX_AIPS1_BASE);
+	writel(0x77777777, IMX_AIPS1_BASE + 0x4);
+	writel(0x77777777, IMX_AIPS2_BASE);
+	writel(0x77777777, IMX_AIPS2_BASE + 0x4);
+
+	/*
+	 * Clear the on and off peripheral modules Supervisor Protect bit
+	 * for SDMA to access them. Did not change the AIPS control registers
+	 * (offset 0x20) access type
+	 */
+	writel(0x0, IMX_AIPS1_BASE + 0x40);
+	writel(0x0, IMX_AIPS1_BASE + 0x44);
+	writel(0x0, IMX_AIPS1_BASE + 0x48);
+	writel(0x0, IMX_AIPS1_BASE + 0x4C);
+	reg = readl(IMX_AIPS1_BASE + 0x50);
+	reg &= 0x00FFFFFF;
+	writel(reg, IMX_AIPS1_BASE + 0x50);
+
+	writel(0x0, IMX_AIPS2_BASE + 0x40);
+	writel(0x0, IMX_AIPS2_BASE + 0x44);
+	writel(0x0, IMX_AIPS2_BASE + 0x48);
+	writel(0x0, IMX_AIPS2_BASE + 0x4C);
+	reg = readl(IMX_AIPS2_BASE + 0x50);
+	reg &= 0x00FFFFFF;
+	writel(reg, IMX_AIPS2_BASE + 0x50);
+
+	/* MAX (Multi-Layer AHB Crossbar Switch) setup */
+
+	/* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
+#define MAX_PARAM1 0x00302154
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x000); /* for S0 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x100); /* for S1 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x200); /* for S2 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x300); /* for S3 */
+	writel(MAX_PARAM1, IMX_MAX_BASE + 0x400); /* for S4 */
+
+	/* SGPCR - always park on last master */
+	writel(0x10, IMX_MAX_BASE + 0x10);	/* for S0 */
+	writel(0x10, IMX_MAX_BASE + 0x110);	/* for S1 */
+	writel(0x10, IMX_MAX_BASE + 0x210);	/* for S2 */
+	writel(0x10, IMX_MAX_BASE + 0x310);	/* for S3 */
+	writel(0x10, IMX_MAX_BASE + 0x410);	/* for S4 */
+
+	/* MGPCR - restore default values */
+	writel(0x0, IMX_MAX_BASE + 0x800);	/* for M0 */
+	writel(0x0, IMX_MAX_BASE + 0x900);	/* for M1 */
+	writel(0x0, IMX_MAX_BASE + 0xa00);	/* for M2 */
+	writel(0x0, IMX_MAX_BASE + 0xb00);	/* for M3 */
+	writel(0x0, IMX_MAX_BASE + 0xc00);	/* for M4 */
+	writel(0x0, IMX_MAX_BASE + 0xd00);	/* for M5 */
+
+	return 0;
+}
+
+core_initcall(vpr_core_init);
+
+/* -------------------------------------------------------------------------*/
+
+static int vpr_pmic_init_v1(struct mc13892 *mc13892)
+{
+	int err = 0;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	/* VGEN2[2:0] = b111 --> output to 3.15V */
+	mc13892_set_bits(mc13892, MC13892_REG_SETTING_0, 0x7 << 6, 0x7 << 6);
+
+	/* VCHRG[2:0] = 0b011, Charge reg output voltage 4.200 */
+	val |= 0x3;
+	mask |= 0x7;
+	/* ICHRG[3:0] = 0b1011, Current limit 960mA*/
+	val |= 0xb << 3;
+	mask |= 0xf << 3;
+	/* PLIM[1:0] = 0b11, Power limit 1000mW */
+	val |= 3 << 15;
+	mask |= 0x3 << 15;
+	/* Enable setting of V I */
+	val |= 1 << 23;
+	mask |= 0x1 << 23;
+	err |= mc13892_set_bits(mc13892, MC13892_REG_CHARGE, mask, val);
+
+	gpio_direction_output(FEC_RESET_GPIO, 0);
+
+	/*turn on the FEC power supply */
+	/* VGEN1[1:0] = 0b11*/
+	err |= mc13892_set_bits(mc13892, MC13892_REG_SETTING_0, 0x03, 0x03);
+	/* VGEN1EN = 1 */
+	err |= mc13892_set_bits(mc13892, MC13892_REG_MODE_0, 0x01, 0x01);
+	if (err) {
+		dev_err(&mc13892->client->dev,
+			"Init sequence failed, the system might not be working!\n");
+	}
+
+	gpio_direction_output(FEC_ENABLE_GPIO, 1);
+	mdelay(10);
+	gpio_set_value(FEC_RESET_GPIO, 1);
+
+	return err;
+}
+
+/*
+ * Maybe this is a bit dodgy because the env is only set up in
+ * a late_initcall?
+ */
+static void vpr_save_boot_loc(void)
+{
+	uint32_t reg;
+	reg = readl(IMX_CCM_BASE + CCM_RCSR);
+
+	switch ((reg >> 25) & 0x3) {
+	case 0x03:		/* SD/MMC is the source */
+		setenv("boot_loc", "mmc");
+		export("boot_loc");
+		break;
+	case 0x01:		/* NAND is the source */
+		setenv("boot_loc", "nane");
+		export("boot_loc");
+		break;
+
+	case 0x00:		/* NOR is the source */
+		setenv("boot_loc", "nor");
+		export("boot_loc");
+		break;
+	default:
+		break;
+	}
+}
+
+static int vpr_final_init(void)
+{
+	struct mc13892 *mc13892;
+	uint32_t system_rev;
+
+	mc13892 = mc13892_get();
+	if (!mc13892) {
+		printf("FAILED to get mc13892 handle!\n");
+		return 0;
+	}
+
+	system_rev = vpr_read_sys_cfg();
+	printf("VPR CPU board version 0x%02x.\n", system_rev);
+	switch (system_rev) {
+	case VPR_CPU_V1:
+		vpr_pmic_init_v1(mc13892);
+		break;
+	default:
+		printf("Unknown revision 0x%02x.\n", system_rev);
+		return 0;
+	}
+
+	vpr_save_boot_loc();
+
+	return 0;
+}
+
+late_initcall(vpr_final_init);
+
+#ifdef CONFIG_NAND_IMX_BOOT
+void __bare_init nand_boot(void)
+{
+	/*
+	 * The driver is able to detect NAND's pagesize by CPU internal
+	 * fuses or external pull ups. But not the blocksize...
+	 */
+	imx_nand_load_image((void *)TEXT_BASE, 256 * 1024);
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int do_diagled(struct command *cmdtp, int argc, char *argv[])
+{
+	int color;
+
+	if (argc != 2)
+		return COMMAND_ERROR_USAGE;
+
+	color = simple_strtoul(argv[1], NULL, 0);
+	vpr_diag_set_color(color);
+
+	return 0;
+}
+
+BAREBOX_CMD_HELP_START(diagled)
+BAREBOX_CMD_HELP_USAGE("diagled [color]\n")
+BAREBOX_CMD_HELP_SHORT("Sets the color of the diagnostic LED.\n")
+BAREBOX_CMD_HELP_TEXT("\toff\t 0\n")
+BAREBOX_CMD_HELP_TEXT("\tblue\t 1\n")
+BAREBOX_CMD_HELP_TEXT("\tgreen\t 2\n")
+BAREBOX_CMD_HELP_TEXT("\taqua\t 3\n")
+BAREBOX_CMD_HELP_TEXT("\tred\t 4\n")
+BAREBOX_CMD_HELP_TEXT("\tmagenta\t 5\n")
+BAREBOX_CMD_HELP_TEXT("\tyellow\t 6\n")
+BAREBOX_CMD_HELP_TEXT("\twhite\t 7\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(diagled)
+	.cmd            = do_diagled,
+	.usage          = "Set color of diagnositc tri-color LED",
+	BAREBOX_CMD_HELP(cmd_diagled_help)
+BAREBOX_CMD_END
+
+/* ------------------------------------------------------------------------ */
+
+static int do_waitbutton(struct command *cmdtp, int argc, char *argv[])
+{
+	int opt;
+	uint64_t start;
+	ulong timeout = 0;
+	uint32_t bstate;
+
+	while ((opt = getopt(argc, argv, "t:")) > 0) {
+		switch (opt) {
+		case 't':
+			timeout = simple_strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	start = get_time_ns();
+	while (!timeout || !is_timeout(start, timeout * SECOND)) {
+		bstate = vpr_button_state();
+		if (bstate) {
+			printf("%d\n", vpr_button_state_to_number(bstate));
+			return 0;
+		}
+		if (ctrlc())
+			return -EINTR;
+	}
+
+	return -ETIMEDOUT;
+}
+
+BAREBOX_CMD_HELP_START(waitbutton)
+BAREBOX_CMD_HELP_USAGE("waitbutton [-t]\n")
+BAREBOX_CMD_HELP_SHORT("Prints the button number of the next pressed button.\n")
+BAREBOX_CMD_HELP_OPT("-t <seconds>", "time in seconds to wait. 0 (default) is forever.")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(button)
+	.cmd            = do_waitbutton,
+	.usage          = "Wait for button press",
+	BAREBOX_CMD_HELP(cmd_waitbutton_help)
+BAREBOX_CMD_END
+
+/* ------------------------------------------------------------------------ */
+
+static int do_buzzer(struct command *cmdtp, int argc, char *argv[])
+{
+	int opt;
+	uint64_t start;
+	ulong durationms = 200;
+
+	while ((opt = getopt(argc, argv, "d:")) > 0) {
+		switch (opt) {
+		case 'd':
+			durationms = simple_strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	vpr_buzzer_on();
+
+	start = get_time_ns();
+	while (!is_timeout(start, durationms * MSECOND)) {
+
+		vpr_buzzer_on();
+		udelay(120);
+		vpr_buzzer_off();
+		udelay(120);
+
+		if (ctrlc())
+			break;
+	}
+
+	vpr_buzzer_off();
+	return 0;
+}
+
+BAREBOX_CMD_HELP_START(buzzer)
+BAREBOX_CMD_HELP_USAGE("buzzer [-d]\n")
+BAREBOX_CMD_HELP_SHORT("Buzzer beep.\n")
+BAREBOX_CMD_HELP_OPT  ("-d <ms>", "time in milli-seconds to stay on. (default 200ms)\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(buzzer)
+	.cmd            = do_buzzer,
+	.usage          = "Buzzer beep",
+	BAREBOX_CMD_HELP(cmd_buzzer_help)
+BAREBOX_CMD_END
+
diff --git a/arch/arm/boards/vpr200/vpr200.dox b/arch/arm/boards/vpr200/vpr200.dox
new file mode 100644
index 0000000..304e00f
--- /dev/null
+++ b/arch/arm/boards/vpr200/vpr200.dox
@@ -0,0 +1,10 @@
+/** @page vpr200 VPR200
+
+The vpr200 board uses a iMX35 CPU.
+
+- 64 MiB NOR Memory
+- 2x 128 Mib RAM
+- 512 MiB NAND
+- 256 byte EEPROM
+
+*/
diff --git a/arch/arm/configs/vpr200_defconfig b/arch/arm/configs/vpr200_defconfig
new file mode 100644
index 0000000..6b1c64e
--- /dev/null
+++ b/arch/arm/configs/vpr200_defconfig
@@ -0,0 +1,60 @@
+CONFIG_ARCH_IMX=y
+CONFIG_ARCH_IMX_INTERNAL_BOOT=y
+CONFIG_ARCH_IMX_INTERNAL_BOOT_NOR=y
+CONFIG_ARCH_IMX35=y
+CONFIG_MACH_VPR200=y
+CONFIG_IMX_CLKO=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_TEXT_BASE=0x87F00000
+CONFIG_MALLOC_SIZE=0x4000000
+CONFIG_EXPERIMENTAL=y
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/vpr200/env/"
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEVICE_NOISE=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+# CONFIG_SPI is not set
+CONFIG_I2C=y
+CONFIG_I2C_IMX=y
+CONFIG_DRIVER_I2C_AT24=y
+CONFIG_DRIVER_CFI=y
+CONFIG_CFI_BUFFER_WRITE=y
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_IMX=y
+CONFIG_NAND_IMX_BOOT=y
+CONFIG_UBI=y
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_IMX_IPU=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_I2C_MC13892=y
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f3506af..1947ace 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -19,6 +19,7 @@ config ARCH_TEXT_BASE
 	default 0xa7e00000 if MACH_NESO
 	default 0x97f00000 if MACH_MX51_PDK
 	default 0x87f00000 if MACH_GUF_CUPID
+	default 0x87f00000 if MACH_VPR200
 
 config BOARDINFO
 	default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25
@@ -36,6 +37,7 @@ config BOARDINFO
 	default "Garz+Fricke Neso" if MACH_NESO
 	default "Freescale i.MX51 PDK" if MACH_FREESCALE_MX51_PDK
 	default "Garz+Fricke Cupid" if MACH_GUF_CUPID
+	default "VPR200" if MACH_VPR200
 
 config ARCH_HAS_FEC_IMX
 	bool
@@ -310,6 +312,17 @@ config MACH_GUF_CUPID
 	  Say Y here if you are using the Garz+Fricke Neso board equipped
 	  with a Freescale i.MX35 Processor
 
+config MACH_VPR200
+	bool "VPR200"
+	select HAS_CFI
+	select MACH_HAS_LOWLEVEL_INIT
+	select I2C
+	select I2C_IMX
+	select I2C_MC13892
+	help
+	  Say Y here if you are using the VPR200 (i.MX35 Processor)
+
+
 endchoice
 
 endif
-- 
1.7.1



From plagnioj at jcrosoft.com  Fri Dec 10 01:43:59 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 10 Dec 2010 07:43:59 +0100
Subject: [PATCH] arm: update mach-types
In-Reply-To: <1291952264-3363-1-git-send-email-marc@cpdesign.com.au>
References: <1291952264-3363-1-git-send-email-marc@cpdesign.com.au>
Message-ID: <20101210064359.GD19897@game.jcrosoft.org>

PLwase specify against which kernel

Best Regards,
J.


From plagnioj at jcrosoft.com  Fri Dec 10 01:48:41 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 10 Dec 2010 07:48:41 +0100
Subject: [PATCH] arm: Introduce VPR200 board
In-Reply-To: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>
References: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>
Message-ID: <20101210064841.GE19897@game.jcrosoft.org>

On 16:42 Fri 10 Dec     , Marc Reilly wrote:
> Starting point for the vpr200 board.
> Very similar core hardware to mx35 3stack.
> 
> Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
> ---
>  arch/arm/Makefile                            |    1 +
>  arch/arm/boards/vpr200/Makefile              |    4 +
>  arch/arm/boards/vpr200/config.h              |   28 +
>  arch/arm/boards/vpr200/env/bin/_update       |   39 ++
>  arch/arm/boards/vpr200/env/bin/boot          |   67 ++
>  arch/arm/boards/vpr200/env/bin/hush_hack     |    1 +
>  arch/arm/boards/vpr200/env/bin/init          |   38 +
>  arch/arm/boards/vpr200/env/bin/update_kernel |   15 +
>  arch/arm/boards/vpr200/env/bin/update_rootfs |   20 +
con u use the defaultenv?
>  arch/arm/boards/vpr200/env/config            |   46 ++
>  arch/arm/boards/vpr200/flash_header.c        |   46 ++
>  arch/arm/boards/vpr200/lowlevel.c            |  255 +++++++
>  arch/arm/boards/vpr200/vpr200.c              |  929 ++++++++++++++++++++++++++
>  arch/arm/boards/vpr200/vpr200.dox            |   10 +
>  arch/arm/configs/vpr200_defconfig            |   60 ++
>  arch/arm/mach-imx/Kconfig                    |   13 +
>  16 files changed, 1572 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/boards/vpr200/Makefile
>  create mode 100644 arch/arm/boards/vpr200/config.h
>  create mode 100644 arch/arm/boards/vpr200/env/bin/_update
>  create mode 100644 arch/arm/boards/vpr200/env/bin/boot
>  create mode 100644 arch/arm/boards/vpr200/env/bin/hush_hack
>  create mode 100644 arch/arm/boards/vpr200/env/bin/init
>  create mode 100644 arch/arm/boards/vpr200/env/bin/update_kernel
>  create mode 100644 arch/arm/boards/vpr200/env/bin/update_rootfs
>  create mode 100644 arch/arm/boards/vpr200/env/config
>  create mode 100644 arch/arm/boards/vpr200/flash_header.c
>  create mode 100644 arch/arm/boards/vpr200/lowlevel.c
>  create mode 100644 arch/arm/boards/vpr200/vpr200.c
>  create mode 100644 arch/arm/boards/vpr200/vpr200.dox
>  create mode 100644 arch/arm/configs/vpr200_defconfig
> 
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 9729c23..6e6be98 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -91,6 +91,7 @@ board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
>  board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
>  board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
>  board-$(CONFIG_MACH_MINI2440)			:= mini2440
> +board-$(CONFIG_MACH_VPR200)			:= vpr200
>  
>  machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
>  
> +static int do_diagled(struct command *cmdtp, int argc, char *argv[])
> +{
> +	int color;
> +
> +	if (argc != 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	color = simple_strtoul(argv[1], NULL, 0);
> +	vpr_diag_set_color(color);
> +
> +	return 0;
> +}
it will be better to have a common API for led management
> +
> +BAREBOX_CMD_HELP_START(diagled)
> +BAREBOX_CMD_HELP_USAGE("diagled [color]\n")
> +BAREBOX_CMD_HELP_SHORT("Sets the color of the diagnostic LED.\n")
> +BAREBOX_CMD_HELP_TEXT("\toff\t 0\n")
> +BAREBOX_CMD_HELP_TEXT("\tblue\t 1\n")
> +BAREBOX_CMD_HELP_TEXT("\tgreen\t 2\n")
> +BAREBOX_CMD_HELP_TEXT("\taqua\t 3\n")
> +BAREBOX_CMD_HELP_TEXT("\tred\t 4\n")
> +BAREBOX_CMD_HELP_TEXT("\tmagenta\t 5\n")
> +BAREBOX_CMD_HELP_TEXT("\tyellow\t 6\n")
> +BAREBOX_CMD_HELP_TEXT("\twhite\t 7\n")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(diagled)
> +	.cmd            = do_diagled,
> +	.usage          = "Set color of diagnositc tri-color LED",
> +	BAREBOX_CMD_HELP(cmd_diagled_help)
> +BAREBOX_CMD_END
> +
> +/* ------------------------------------------------------------------------ */
> +
> +static int do_waitbutton(struct command *cmdtp, int argc, char *argv[])
> +{
> +	int opt;
> +	uint64_t start;
> +	ulong timeout = 0;
> +	uint32_t bstate;
> +
> +	while ((opt = getopt(argc, argv, "t:")) > 0) {
> +		switch (opt) {
> +		case 't':
> +			timeout = simple_strtol(optarg, NULL, 0);
> +			break;
> +		}
> +	}
> +
> +	start = get_time_ns();
> +	while (!timeout || !is_timeout(start, timeout * SECOND)) {
> +		bstate = vpr_button_state();
> +		if (bstate) {
> +			printf("%d\n", vpr_button_state_to_number(bstate));
> +			return 0;
> +		}
> +		if (ctrlc())
> +			return -EINTR;
> +	}
> +
> +	return -ETIMEDOUT;
> +}
ditto here
> +
> +BAREBOX_CMD_HELP_START(waitbutton)
> +BAREBOX_CMD_HELP_USAGE("waitbutton [-t]\n")
> +BAREBOX_CMD_HELP_SHORT("Prints the button number of the next pressed button.\n")
> +BAREBOX_CMD_HELP_OPT("-t <seconds>", "time in seconds to wait. 0 (default) is forever.")
> +BAREBOX_CMD_HELP_END

please also check your patch you have some whitespace and other too long line
issue

Best Regards,
J.


From marek.belisko at gmail.com  Fri Dec 10 02:21:54 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 10 Dec 2010 08:21:54 +0100
Subject: [PATCH] arm: Introduce VPR200 board
In-Reply-To: <20101210064841.GE19897@game.jcrosoft.org>
References: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>
	<20101210064841.GE19897@game.jcrosoft.org>
Message-ID: <AANLkTi=H_a_S1iDZttpphv906DxB9xUdDXusYRAPyL7r@mail.gmail.com>

On Fri, Dec 10, 2010 at 7:48 AM, Jean-Christophe PLAGNIOL-VILLARD
<plagnioj at jcrosoft.com> wrote:
> On 16:42 Fri 10 Dec ? ? , Marc Reilly wrote:
>> Starting point for the vpr200 board.
>> Very similar core hardware to mx35 3stack.
>>
>> Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
>> ---
>> ?arch/arm/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
>> ?arch/arm/boards/vpr200/Makefile ? ? ? ? ? ? ?| ? ?4 +
>> ?arch/arm/boards/vpr200/config.h ? ? ? ? ? ? ?| ? 28 +
>> ?arch/arm/boards/vpr200/env/bin/_update ? ? ? | ? 39 ++
>> ?arch/arm/boards/vpr200/env/bin/boot ? ? ? ? ?| ? 67 ++
>> ?arch/arm/boards/vpr200/env/bin/hush_hack ? ? | ? ?1 +
>> ?arch/arm/boards/vpr200/env/bin/init ? ? ? ? ?| ? 38 +
>> ?arch/arm/boards/vpr200/env/bin/update_kernel | ? 15 +
>> ?arch/arm/boards/vpr200/env/bin/update_rootfs | ? 20 +
> con u use the defaultenv?
>> ?arch/arm/boards/vpr200/env/config ? ? ? ? ? ?| ? 46 ++
>> ?arch/arm/boards/vpr200/flash_header.c ? ? ? ?| ? 46 ++
>> ?arch/arm/boards/vpr200/lowlevel.c ? ? ? ? ? ?| ?255 +++++++
>> ?arch/arm/boards/vpr200/vpr200.c ? ? ? ? ? ? ?| ?929 ++++++++++++++++++++++++++
>> ?arch/arm/boards/vpr200/vpr200.dox ? ? ? ? ? ?| ? 10 +
>> ?arch/arm/configs/vpr200_defconfig ? ? ? ? ? ?| ? 60 ++
>> ?arch/arm/mach-imx/Kconfig ? ? ? ? ? ? ? ? ? ?| ? 13 +
>> ?16 files changed, 1572 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/boards/vpr200/Makefile
>> ?create mode 100644 arch/arm/boards/vpr200/config.h
>> ?create mode 100644 arch/arm/boards/vpr200/env/bin/_update
>> ?create mode 100644 arch/arm/boards/vpr200/env/bin/boot
>> ?create mode 100644 arch/arm/boards/vpr200/env/bin/hush_hack
>> ?create mode 100644 arch/arm/boards/vpr200/env/bin/init
>> ?create mode 100644 arch/arm/boards/vpr200/env/bin/update_kernel
>> ?create mode 100644 arch/arm/boards/vpr200/env/bin/update_rootfs
>> ?create mode 100644 arch/arm/boards/vpr200/env/config
>> ?create mode 100644 arch/arm/boards/vpr200/flash_header.c
>> ?create mode 100644 arch/arm/boards/vpr200/lowlevel.c
>> ?create mode 100644 arch/arm/boards/vpr200/vpr200.c
>> ?create mode 100644 arch/arm/boards/vpr200/vpr200.dox
>> ?create mode 100644 arch/arm/configs/vpr200_defconfig
>>
>> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
>> index 9729c23..6e6be98 100644
>> --- a/arch/arm/Makefile
>> +++ b/arch/arm/Makefile
>> @@ -91,6 +91,7 @@ board-$(CONFIG_MACH_CHUMBY) ? ? ? ? ? ? ? ? := chumby_falconwing
>> ?board-$(CONFIG_MACH_FREESCALE_MX51_PDK) ? ? ? ? ? ? ?:= freescale-mx51-pdk
>> ?board-$(CONFIG_MACH_GUF_CUPID) ? ? ? ? ? ? ? ? ? ? ? := guf-cupid
>> ?board-$(CONFIG_MACH_MINI2440) ? ? ? ? ? ? ? ? ? ? ? ?:= mini2440
>> +board-$(CONFIG_MACH_VPR200) ? ? ? ? ? ? ? ? ?:= vpr200
>>
>> ?machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
>>
>> +static int do_diagled(struct command *cmdtp, int argc, char *argv[])
>> +{
>> + ? ? int color;
>> +
>> + ? ? if (argc != 2)
>> + ? ? ? ? ? ? return COMMAND_ERROR_USAGE;
>> +
>> + ? ? color = simple_strtoul(argv[1], NULL, 0);
>> + ? ? vpr_diag_set_color(color);
>> +
>> + ? ? return 0;
>> +}
> it will be better to have a common API for led management
>> +
>> +BAREBOX_CMD_HELP_START(diagled)
>> +BAREBOX_CMD_HELP_USAGE("diagled [color]\n")
>> +BAREBOX_CMD_HELP_SHORT("Sets the color of the diagnostic LED.\n")
>> +BAREBOX_CMD_HELP_TEXT("\toff\t 0\n")
>> +BAREBOX_CMD_HELP_TEXT("\tblue\t 1\n")
>> +BAREBOX_CMD_HELP_TEXT("\tgreen\t 2\n")
>> +BAREBOX_CMD_HELP_TEXT("\taqua\t 3\n")
>> +BAREBOX_CMD_HELP_TEXT("\tred\t 4\n")
>> +BAREBOX_CMD_HELP_TEXT("\tmagenta\t 5\n")
>> +BAREBOX_CMD_HELP_TEXT("\tyellow\t 6\n")
>> +BAREBOX_CMD_HELP_TEXT("\twhite\t 7\n")
>> +BAREBOX_CMD_HELP_END
>> +
>> +BAREBOX_CMD_START(diagled)
>> + ? ? .cmd ? ? ? ? ? ?= do_diagled,
>> + ? ? .usage ? ? ? ? ?= "Set color of diagnositc tri-color LED",
>> + ? ? BAREBOX_CMD_HELP(cmd_diagled_help)
>> +BAREBOX_CMD_END
>> +
>> +/* ------------------------------------------------------------------------ */
>> +
>> +static int do_waitbutton(struct command *cmdtp, int argc, char *argv[])
>> +{
>> + ? ? int opt;
>> + ? ? uint64_t start;
>> + ? ? ulong timeout = 0;
>> + ? ? uint32_t bstate;
>> +
>> + ? ? while ((opt = getopt(argc, argv, "t:")) > 0) {
>> + ? ? ? ? ? ? switch (opt) {
>> + ? ? ? ? ? ? case 't':
>> + ? ? ? ? ? ? ? ? ? ? timeout = simple_strtol(optarg, NULL, 0);
>> + ? ? ? ? ? ? ? ? ? ? break;
>> + ? ? ? ? ? ? }
>> + ? ? }
>> +
>> + ? ? start = get_time_ns();
>> + ? ? while (!timeout || !is_timeout(start, timeout * SECOND)) {
>> + ? ? ? ? ? ? bstate = vpr_button_state();
>> + ? ? ? ? ? ? if (bstate) {
>> + ? ? ? ? ? ? ? ? ? ? printf("%d\n", vpr_button_state_to_number(bstate));
>> + ? ? ? ? ? ? ? ? ? ? return 0;
>> + ? ? ? ? ? ? }
>> + ? ? ? ? ? ? if (ctrlc())
>> + ? ? ? ? ? ? ? ? ? ? return -EINTR;
>> + ? ? }
>> +
>> + ? ? return -ETIMEDOUT;
>> +}
> ditto here
>> +
>> +BAREBOX_CMD_HELP_START(waitbutton)
>> +BAREBOX_CMD_HELP_USAGE("waitbutton [-t]\n")
>> +BAREBOX_CMD_HELP_SHORT("Prints the button number of the next pressed button.\n")
>> +BAREBOX_CMD_HELP_OPT("-t <seconds>", "time in seconds to wait. 0 (default) is forever.")
>> +BAREBOX_CMD_HELP_END
>
> please also check your patch you have some whitespace and other too long line
> issue
FYI can be used checkpatch.pl in scripts directory ;)
>
> Best Regards,
> J.
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From marc at cpdesign.com.au  Fri Dec 10 02:53:20 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 10 Dec 2010 18:53:20 +1100
Subject: [PATCH] arm: update mach-types
In-Reply-To: <20101210064359.GD19897@game.jcrosoft.org>
References: <1291952264-3363-1-git-send-email-marc@cpdesign.com.au>
	<20101210064359.GD19897@game.jcrosoft.org>
Message-ID: <201012101853.20192.marc@cpdesign.com.au>

Hi,

> PLwase specify against which kernel
It's directly from http://www.arm.linux.org.uk/developer/machines/

To be honest, I didn't even think about needing to match up against a specific 
version of the kernel, but I guess it does deserve consideration. 
From my understanding, the machine numbers are reserved forever and there is a 
1:1 correspondence between the mach number and the device itself. It's only 
the label that may change. So this patch would be bad if someone has changed 
their machine name, but hasn't changed their code within barebox.

I'll leave my thinking there because it's late friday arvo, and smarter minds 
have probably thought this one out before. :)

Otherwise, would it be better if I just submitted a "one liner" patch which 
just adds my new machine?

Cheers,
Marc
 


From marc at cpdesign.com.au  Fri Dec 10 03:13:02 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Fri, 10 Dec 2010 19:13:02 +1100
Subject: [PATCH] arm: Introduce VPR200 board
In-Reply-To: <AANLkTi=H_a_S1iDZttpphv906DxB9xUdDXusYRAPyL7r@mail.gmail.com>
References: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>
	<20101210064841.GE19897@game.jcrosoft.org>
	<AANLkTi=H_a_S1iDZttpphv906DxB9xUdDXusYRAPyL7r@mail.gmail.com>
Message-ID: <201012101913.02927.marc@cpdesign.com.au>

Hi,

Thanks for your responses.

> >> Starting point for the vpr200 board.
> >> Very similar core hardware to mx35 3stack.
> >> 
> >> Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
> >> ---
> >>  arch/arm/Makefile                            |    1 +
> >>  arch/arm/boards/vpr200/Makefile              |    4 +
> >>  arch/arm/boards/vpr200/config.h              |   28 +
> >>  arch/arm/boards/vpr200/env/bin/_update       |   39 ++
> >>  arch/arm/boards/vpr200/env/bin/boot          |   67 ++
> >>  arch/arm/boards/vpr200/env/bin/hush_hack     |    1 +
> >>  arch/arm/boards/vpr200/env/bin/init          |   38 +
> >>  arch/arm/boards/vpr200/env/bin/update_kernel |   15 +
> >>  arch/arm/boards/vpr200/env/bin/update_rootfs |   20 +
> > 
> > con u use the defaultenv?
Yes, I will.

> >> +static int do_diagled(struct command *cmdtp, int argc, char *argv[])
> >> +{
> >> +     int color;
> >> +
> >> +     if (argc != 2)
> >> +             return COMMAND_ERROR_USAGE;
> >> +
> >> +     color = simple_strtoul(argv[1], NULL, 0);
> >> +     vpr_diag_set_color(color);
> >> +
> >> +     return 0;
> >> +}
> > 
> > it will be better to have a common API for led management

I agree, but I have to start somewhere :) 

> > 
> >> +
> >> +BAREBOX_CMD_HELP_START(diagled)
> >> +BAREBOX_CMD_HELP_USAGE("diagled [color]\n")
> >> +BAREBOX_CMD_HELP_SHORT("Sets the color of the diagnostic LED.\n")
> >> +BAREBOX_CMD_HELP_TEXT("\toff\t 0\n")
> >> +BAREBOX_CMD_HELP_TEXT("\tblue\t 1\n")
> >> +BAREBOX_CMD_HELP_TEXT("\tgreen\t 2\n")
> >> +BAREBOX_CMD_HELP_TEXT("\taqua\t 3\n")
> >> +BAREBOX_CMD_HELP_TEXT("\tred\t 4\n")
> >> +BAREBOX_CMD_HELP_TEXT("\tmagenta\t 5\n")
> >> +BAREBOX_CMD_HELP_TEXT("\tyellow\t 6\n")
> >> +BAREBOX_CMD_HELP_TEXT("\twhite\t 7\n")
> >> +BAREBOX_CMD_HELP_END
> >> +
> >> +BAREBOX_CMD_START(diagled)
> >> +     .cmd            = do_diagled,
> >> +     .usage          = "Set color of diagnositc tri-color LED",
> >> +     BAREBOX_CMD_HELP(cmd_diagled_help)
> >> +BAREBOX_CMD_END
> >> +
> >> +/*
> >> -----------------------------------------------------------------------
> >> - */ +
> >> +static int do_waitbutton(struct command *cmdtp, int argc, char *argv[])
> >> +{
> >> +     int opt;
> >> +     uint64_t start;
> >> +     ulong timeout = 0;
> >> +     uint32_t bstate;
> >> +
> >> +     while ((opt = getopt(argc, argv, "t:")) > 0) {
> >> +             switch (opt) {
> >> +             case 't':
> >> +                     timeout = simple_strtol(optarg, NULL, 0);
> >> +                     break;
> >> +             }
> >> +     }
> >> +
> >> +     start = get_time_ns();
> >> +     while (!timeout || !is_timeout(start, timeout * SECOND)) {
> >> +             bstate = vpr_button_state();
> >> +             if (bstate) {
> >> +                     printf("%d\n",
> >> vpr_button_state_to_number(bstate)); +                     return 0;
> >> +             }
> >> +             if (ctrlc())
> >> +                     return -EINTR;
> >> +     }
> >> +
> >> +     return -ETIMEDOUT;
> >> +}
> > 
> > ditto here

Again, I agree, and I'm happy to work towards that, but would rather start 
from here, and move towards something more generic.

These extra commands were mainly for quick HW testing, and I didn't see any 
reason to drop them.

> > 
> >> +
> >> +BAREBOX_CMD_HELP_START(waitbutton)
> >> +BAREBOX_CMD_HELP_USAGE("waitbutton [-t]\n")
> >> +BAREBOX_CMD_HELP_SHORT("Prints the button number of the next pressed
> >> button.\n") +BAREBOX_CMD_HELP_OPT("-t <seconds>", "time in seconds to
> >> wait. 0 (default) is forever.") +BAREBOX_CMD_HELP_END
> > 
> > please also check your patch you have some whitespace and other too long
> > line issue
> 
> FYI can be used checkpatch.pl in scripts directory ;)

Thanks, I had found them but made the "executive" (ie. cheeky:) decision to 
"stretch the rules" (ie. ignore them.)
I did play with most of the long lines - and IMHO it made more sense as is. 
Other issues were inherited from copied code, so I didn't feel to guilty 
ignoring them.


I'll be resubmitting, omitting some of the redundant env/ files, but I'll wait 
a couple of days and see it there are any other comments.

Cheers
Marc 



From plagnioj at jcrosoft.com  Fri Dec 10 03:20:20 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 10 Dec 2010 09:20:20 +0100
Subject: [PATCH] arm: update mach-types
In-Reply-To: <201012101853.20192.marc@cpdesign.com.au>
References: <1291952264-3363-1-git-send-email-marc@cpdesign.com.au>
	<20101210064359.GD19897@game.jcrosoft.org>
	<201012101853.20192.marc@cpdesign.com.au>
Message-ID: <20101210082020.GF19897@game.jcrosoft.org>

On 18:53 Fri 10 Dec     , Marc Reilly wrote:
> Hi,
> 
> > PLwase specify against which kernel
> It's directly from http://www.arm.linux.org.uk/developer/machines/
> 
> To be honest, I didn't even think about needing to match up against a specific 
> version of the kernel, but I guess it does deserve consideration. 
> From my understanding, the machine numbers are reserved forever and there is a 
> 1:1 correspondence between the mach number and the device itself. It's only 
> the label that may change. So this patch would be bad if someone has changed 
> their machine name, but hasn't changed their code within barebox.
not really sometimes they change so to trac it it's better to have a reference
> 
> I'll leave my thinking there because it's late friday arvo, and smarter minds 
> have probably thought this one out before. :)
> 
> Otherwise, would it be better if I just submitted a "one liner" patch which 
> just adds my new machine?
no we update the whole file we need to be sync with the kernel

Best Regards,
J.


From s.hauer at pengutronix.de  Fri Dec 10 04:51:46 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 10 Dec 2010 10:51:46 +0100
Subject: [PATCH] arm: Introduce VPR200 board
In-Reply-To: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>
References: <1291959762-14350-1-git-send-email-marc@cpdesign.com.au>
Message-ID: <20101210095146.GW6017@pengutronix.de>

Hi Marc,

On Fri, Dec 10, 2010 at 04:42:42PM +1100, Marc Reilly wrote:
> Starting point for the vpr200 board.
> Very similar core hardware to mx35 3stack.
> 
> Signed-off-by: Marc Reilly <marc at cpdesign.com.au>
> ---
>  arch/arm/Makefile                            |    1 +
>  arch/arm/boards/vpr200/Makefile              |    4 +
>  arch/arm/boards/vpr200/config.h              |   28 +
>  arch/arm/boards/vpr200/env/bin/_update       |   39 ++
>  arch/arm/boards/vpr200/env/bin/boot          |   67 ++
>  arch/arm/boards/vpr200/env/bin/hush_hack     |    1 +
>  arch/arm/boards/vpr200/env/bin/init          |   38 +
>  arch/arm/boards/vpr200/env/bin/update_kernel |   15 +
>  arch/arm/boards/vpr200/env/bin/update_rootfs |   20 +
>  arch/arm/boards/vpr200/env/config            |   46 ++

Jean-Christophe already noted it. It would be good if you used the
default environment or say what's missing so that we can fix it.

>  arch/arm/boards/vpr200/flash_header.c        |   46 ++
>  arch/arm/boards/vpr200/lowlevel.c            |  255 +++++++
>  arch/arm/boards/vpr200/vpr200.c              |  929 ++++++++++++++++++++++++++
>  arch/arm/boards/vpr200/vpr200.dox            |   10 +
>  arch/arm/configs/vpr200_defconfig            |   60 ++
>  arch/arm/mach-imx/Kconfig                    |   13 +
>  16 files changed, 1572 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/boards/vpr200/Makefile
>  create mode 100644 arch/arm/boards/vpr200/config.h
>  create mode 100644 arch/arm/boards/vpr200/env/bin/_update
>  create mode 100644 arch/arm/boards/vpr200/env/bin/boot
>  create mode 100644 arch/arm/boards/vpr200/env/bin/hush_hack
>  create mode 100644 arch/arm/boards/vpr200/env/bin/init
>  create mode 100644 arch/arm/boards/vpr200/env/bin/update_kernel
>  create mode 100644 arch/arm/boards/vpr200/env/bin/update_rootfs
>  create mode 100644 arch/arm/boards/vpr200/env/config
>  create mode 100644 arch/arm/boards/vpr200/flash_header.c
>  create mode 100644 arch/arm/boards/vpr200/lowlevel.c
>  create mode 100644 arch/arm/boards/vpr200/vpr200.c
>  create mode 100644 arch/arm/boards/vpr200/vpr200.dox
>  create mode 100644 arch/arm/configs/vpr200_defconfig
> 
> diff --git a/arch/arm/boards/vpr200/vpr200.c b/arch/arm/boards/vpr200/vpr200.c
> new file mode 100644
> index 0000000..298195d
> --- /dev/null
> +++ b/arch/arm/boards/vpr200/vpr200.c
> @@ -0,0 +1,929 @@
> +/*
> + * Copyright (C) 2007 Sascha Hauer, Pengutronix
> + *               2009 Marc Kleine-Budde, Pengutronix
> + *               2010 Marc Reilly, Creative Product Design
> + *
> + * 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, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + * Derived from:
> + *
> + * * mx35_3stack.c - board file for uboot-v1
> + *   Copyright (C) 2007, Guennadi Liakhovetski <lg at denx.de>
> + *   (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
> + *
> + */
> +
> +#include <common.h>
> +#include <environment.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <fec.h>
> +#include <fs.h>
> +#include <init.h>
> +#include <nand.h>
> +#include <net.h>
> +#include <partition.h>
> +#include <command.h>
> +#include <getopt.h>
> +
> +#include <asm/armlinux.h>
> +#include <asm/io.h>
> +#include <generated/mach-types.h>
> +
> +#include <mach/gpio.h>
> +#include <mach/imx-nand.h>
> +#include <mach/imx-regs.h>
> +#include <mach/iomux-mx35.h>
> +#include <mach/iomux-v3.h>
> +#include <mach/pmic.h>
> +#include <mach/imx-ipu-fb.h>
> +#include <mach/generic.h>
> +#include <mach/devices-imx35.h>
> +
> +#include <i2c/i2c.h>
> +#include <mfd/mc13892.h>
> +
> +/* ------------------------------------------------------------------------- */
> +/* Board revs for the VPR CPU */
> +#define VPR_CPU_V1  0x19
> +
> +/*
> + * IO Defines for the VPR
> + *
> + * The current GPIO API considers the gpios as a contiguous bits across
> + * ports. These defines and macros convert the GPIO1_3 nomenclature to
> + * a numbered GPIO line.
> + */
> +
> +/* Port numbers start from 1 to be consistent with iMX docs */
> +#define GPIO_FROM_PORT(x, y) (((x-1)*32) + y)

We have the following in the kernel now:

/* There's a off-by-one betweem the gpio bank number and the gpiochip */
/* range e.g. GPIO_1_5 is gpio 5 under linux */
#define IMX_GPIO_NR(bank, nr)          (((bank) - 1) * 32 + (nr))

Would be good to use the same in barebox, maybe in
arch/arm/mach-imx/include/mach/imx-regs.h

> +
> +#define LCD_PWR_PORT		1
> +#define LCD_PWR_BIT		2
> +#define LCD_PWR_GPIO		GPIO_FROM_PORT(LCD_PWR_PORT, LCD_PWR_BIT)

Do you need the *_PORT *_BIT defines? I think the following is shorter
and still reads better:

#define LCD_PWR_GPIO	IMX_GPIO_NR(1, 2)


> +
> +/* ------------------------------------------------------------------------- */
> +
> +/**
> + * Init gpio lines for tri-color LED used for diagnostics.
> + *
> + * Note does not set the IOMUX directions, so this needs to be
> + * done elsewhere.
> + */
> +void vpr_diag_init(void)
> +{
> +	/* active low outputs, all start off */
> +	gpio_direction_output(DIAG_RED_GPIO, 1);
> +	gpio_direction_output(DIAG_GREEN_GPIO, 1);
> +	gpio_direction_output(DIAG_BLUE_GPIO, 1);
> +}

static

> +
> +/**
> + *  Sets each color component of the tri color led
> + *
> + *  \param red      Zero for Off. All other values On.
> + *  \param green    Zero for Off. All other values On.
> + *  \param blue     Zero for Off. All other values On.
> + */
> +void vpr_diag_set(int red, int green, int blue)
> +{
> +	/* active low outputs */
> +	gpio_set_value(DIAG_RED_GPIO, !red);
> +	gpio_set_value(DIAG_GREEN_GPIO, !green);
> +	gpio_set_value(DIAG_BLUE_GPIO, !blue);
> +}

maybe static, but you probably want to be able to call this elsewhere
from the code for debugging purposes.

> +
> +/**
> + * Enum matching all color component triplets to
> + * named identifiers.
> + */
> +enum diag_led_color {
> +	DIAG_LED_OFF        = 0x0,
> +	DIAG_LED_BLUE       = 0x1,
> +	DIAG_LED_GREEN      = 0x2,
> +	DIAG_LED_AQUA       = 0x3,
> +	DIAG_LED_RED        = 0x4,
> +	DIAG_LED_MAGENTA    = 0x5,
> +	DIAG_LED_YELLOW     = 0x6,
> +	DIAG_LED_WHITE      = 0x7,
> +};
> +
> +/**
> + * Set Diagnostic LED to specified color
> + */
> +void vpr_diag_set_color(enum diag_led_color color)
> +{
> +	vpr_diag_set(color & 0x4, color & 0x02, color & 0x01);
> +}

This is one function too much for the LED. One of vpr_diag_set and
vpr_diag_set_color should be enough. Also, if you want this globally
available, the enum shouldn't be declared in this file.

> +
> +/* ------------------------------------------------------------------------- */
> +enum vpr_button {
> +	BUTTONNONE = 0,
> +	BUTTON1 = 0x01,
> +	BUTTON2 = 0x02,
> +	BUTTON3 = 0x04,
> +	BUTTON4 = 0x08,
> +	BUTTON5 = 0x10,
> +	BUTTON6 = 0x20,
> +	BUTTON7 = 0x40,
> +	BUTTON8 = 0x80
> +};
> +
> +static void vpr_button_init(void)
> +{
> +	gpio_direction_input(BUTTON1_GPIO);
> +	gpio_direction_input(BUTTON2_GPIO);
> +	gpio_direction_input(BUTTON3_GPIO);
> +	gpio_direction_input(BUTTON4_GPIO);
> +	gpio_direction_input(BUTTON5_GPIO);
> +	gpio_direction_input(BUTTON6_GPIO);
> +	gpio_direction_input(BUTTON7_GPIO);
> +	gpio_direction_input(BUTTON8_GPIO);
> +}
> +
> +static int vpr_button_state(void)
> +{
> +	uint32_t ret = 0;
> +
> +	ret |= (!gpio_get_value(BUTTON1_GPIO));
> +	ret |= (!gpio_get_value(BUTTON2_GPIO)) << 1;
> +	ret |= (!gpio_get_value(BUTTON3_GPIO)) << 2;
> +	ret |= (!gpio_get_value(BUTTON4_GPIO)) << 3;
> +	ret |= (!gpio_get_value(BUTTON5_GPIO)) << 4;
> +	ret |= (!gpio_get_value(BUTTON6_GPIO)) << 5;
> +	ret |= (!gpio_get_value(BUTTON7_GPIO)) << 6;
> +	ret |= (!gpio_get_value(BUTTON8_GPIO)) << 7;
> +
> +	return ret;
> +}
> +
> +static int vpr_button_state_to_number(int bstate)
> +{
> +	int ret = 1;
> +	if (!bstate)
> +		return 0;
> +
> +	while (!(bstate & 0x01)) {
> +		bstate >>= 1;
> +		++ret;
> +	}
> +	return ret;
> +}

This function does not seem to be very useful, see below

> +
> +/* ------------------------------------------------------------------------- */
> +static void vpr_buzzer_init(void)
> +{
> +	gpio_direction_output(BUZZER_GPIO, 0);
> +}
> +
> +static void vpr_buzzer_off(void)
> +{
> +	gpio_set_value(BUZZER_GPIO, 0);
> +}
> +
> +static void vpr_buzzer_on(void)
> +{
> +	gpio_set_value(BUZZER_GPIO, 1);
> +}
> +
> +/* ------------------------------------------------------------------------- */
> +static void vpr_bp_init(void)
> +{
> +	struct pad_desc bp_pads[] = {
> +		MX35_PAD_ATA_DATA4__GPIO2_17,
> +		MX35_PAD_ATA_DATA5__GPIO2_18,
> +	};
> +
> +	mxc_iomux_v3_setup_multiple_pads(bp_pads, ARRAY_SIZE(bp_pads));
> +
> +	gpio_direction_output(BP_RESET_GPIO, 1);
> +	gpio_direction_input(BP_EOC_GPIO);
> +}
> +
> +static void vpr_rf_init(void)
> +{
> +	struct pad_desc rf_pads[] = {
> +		MX35_PAD_ATA_IORDY__GPIO2_12,
> +		MX35_PAD_ATA_DATA0__GPIO2_13,
> +		MX35_PAD_ATA_DATA1__GPIO2_14,
> +		MX35_PAD_ATA_DATA2__GPIO2_15,
> +		MX35_PAD_ATA_DATA3__GPIO2_16,
> +	};
> +
> +	mxc_iomux_v3_setup_multiple_pads(rf_pads, ARRAY_SIZE(rf_pads));
> +
> +	gpio_direction_output(RF_RESET_GPIO, 0);
> +	gpio_direction_output(RF_TDI_GPIO, 1);
> +	gpio_direction_output(RF_TCK_GPIO, 1);
> +	gpio_direction_output(RF_TMS_GPIO, 1);
> +	gpio_direction_input(RF_TDO_GPIO);
> +}
> +
> +
> +/* ------------------------------------------------------------------------- */
> +/*
> + * Board initialization order:
> + *  core_initcall
> + *  postcore_initcall
> + *  console_initcall
> + *  postconsole_initcall
> + *  coredevice_initcall
> + *  fs_initcall
> + *  device_initcall
> + *  late_initcall
> + */
> +
> +static int vpr_devices_init(void)
> +{
> +#define MAX_BOOTSRC_MSG 80
> +	uint32_t reg;
> +	char bootsrc_msg[MAX_BOOTSRC_MSG+1] = {0,};
> +
> +	/* take care of WDT */
> +	writew(0xFFB3, IMX_WDT_BASE + 0);
> +	writew(0x0000, IMX_WDT_BASE + 8);
> +
> +	/* CS0: Nor Flash */
> +	writel(0x0000cf03, CSCR_U(0));
> +	writel(0x10000d03, CSCR_L(0));
> +	writel(0x00720900, CSCR_A(0));
> +
> +	reg = readl(IMX_CCM_BASE + CCM_RCSR);
> +	/* some fuses provide us vital information about connected hardware */
> +	if (reg & 0x20000000)
> +		nand_info.width = 2;	/* 16 bit */
> +	else
> +		nand_info.width = 1;	/* 8 bit */
> +
> +	/* This platform supports NOR, NAND and SD */
> +	imx35_add_nand(&nand_info);
> +	register_device(&cfi_dev);
> +	imx35_add_mmc0(NULL);
> +
> +	switch ((reg >> 25) & 0x3) {
> +	case 0x03:		/* SD/MMC is the source */
> +		vpr_diag_set_color(DIAG_LED_MAGENTA);
> +		snprintf(bootsrc_msg, MAX_BOOTSRC_MSG, "SD boot: ");
> +		devfs_add_partition("disk0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
> +		devfs_add_partition("disk0", 0x40000, 0x80000, PARTITION_FIXED, "env0");
> +		protect_file("/dev/self0", 1);
> +		protect_file("/dev/env0", 1);
> +		break;
> +
> +	case 0x01:		/* NAND is the source */
> +		devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
> +		dev_add_bb_dev("self_raw", "self0");
> +		devfs_add_partition("nand0", 0x40000, 0x80000, PARTITION_FIXED, "env_raw");
> +		dev_add_bb_dev("env_raw", "env0");
> +		break;
> +
> +	case 0x00:		/* NOR is the source */
> +		vpr_diag_set_color(DIAG_LED_AQUA);
> +		snprintf(bootsrc_msg, MAX_BOOTSRC_MSG, "NOR boot: ");
> +		devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
> +		devfs_add_partition("nor0", 0x40000, 0x80000, PARTITION_FIXED, "env0");
> +		protect_file("/dev/self0", 1);
> +		protect_file("/dev/env0", 1);
> +		break;
> +	default:
> +		printf("WARN: Unrecognized boot source.\n");
> +		break;
> +	}
> +
> +	/* delay printing message so protect file doesn't get in the middle */
> +	printf(bootsrc_msg);
> +
> +	switch ((reg >> 10) & 0x3) {
> +	case 0x03:
> +		printf("Bootstrap mode\n");
> +		break;
> +	case 0x02:
> +		printf("External\n");
> +		break;
> +	case 0x00:
> +		printf("Internal\n");
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));
> +
> +	imx35_add_i2c0(NULL);
> +	imx35_add_i2c1(NULL);
> +	imx35_add_fec(&fec_info);
> +
> +	register_device(&sdram_dev);
> +	register_device(&sdram_dev1);
> +
> +	imx35_add_fb(&ipu_fb_data);
> +
> +	vpr_button_init();
> +	vpr_buzzer_init();
> +	vpr_bp_init();
> +	vpr_rf_init();
> +
> +	armlinux_add_dram(&sdram_dev);
> +	/* TODO adding BANK1 causes early kernel crash when booting
> +	 * off SD card */
> +
> +	armlinux_set_bootparams((void *)0x80000100);
> +
> +	armlinux_set_architecture(MACH_TYPE_VPR200);
> +
> +	/* For compat with the freescale kernel, relies on setting revision*/
> +	armlinux_set_revision(0x00035100 | imx_silicon_revision());
> +
> +	return 0;
> +}
> +
> +device_initcall(vpr_devices_init);
> +
> +static struct pad_desc vpr_pads[] = {
> +	/* FEC */
> +	MX35_PAD_FEC_RX_DV__FEC_RX_DV,
> +	MX35_PAD_FEC_COL__FEC_COL,
> +	MX35_PAD_FEC_TX_EN__FEC_TX_EN,
> +	MX35_PAD_FEC_MDC__FEC_MDC,
> +	MX35_PAD_FEC_MDIO__FEC_MDIO,
> +	MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
> +	MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
> +	MX35_PAD_FEC_CRS__FEC_CRS,
> +	MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
> +	MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
> +	MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
> +	MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
> +	MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
> +	MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
> +	MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
> +	MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
> +	/* FEC enable */
> +	MX35_PAD_D3_REV__GPIO1_3,
> +	/* UART 1*/
> +	MX35_PAD_RXD1__UART1_RXD_MUX,
> +	MX35_PAD_TXD1__UART1_TXD_MUX,
> +	MX35_PAD_RTS1__UART1_RTS,
> +	MX35_PAD_CTS1__UART1_CTS,
> +	/* I2C1 */
> +	MX35_PAD_I2C1_CLK__I2C1_SCL,
> +	MX35_PAD_I2C1_DAT__I2C1_SDA,
> +	/* I2C2 */
> +	MX35_PAD_I2C2_CLK__I2C2_SCL,
> +	MX35_PAD_I2C2_DAT__I2C2_SDA,
> +	/* Sys config */
> +	MX35_PAD_ATA_DATA14__GPIO2_27,
> +	MX35_PAD_ATA_DATA15__GPIO2_28,
> +	MX35_PAD_ATA_INTRQ__GPIO2_29,
> +	MX35_PAD_ATA_BUFF_EN__GPIO2_30,
> +	MX35_PAD_ATA_DMARQ__GPIO2_31,
> +	/* LCD enable */
> +	MX35_PAD_D3_VSYNC__GPIO1_2,
> +	/* Display */
> +	MX35_PAD_LD0__IPU_DISPB_DAT_0,
> +	MX35_PAD_LD1__IPU_DISPB_DAT_1,
> +	MX35_PAD_LD2__IPU_DISPB_DAT_2,
> +	MX35_PAD_LD3__IPU_DISPB_DAT_3,
> +	MX35_PAD_LD4__IPU_DISPB_DAT_4,
> +	MX35_PAD_LD5__IPU_DISPB_DAT_5,
> +	MX35_PAD_LD6__IPU_DISPB_DAT_6,
> +	MX35_PAD_LD7__IPU_DISPB_DAT_7,
> +	MX35_PAD_LD8__IPU_DISPB_DAT_8,
> +	MX35_PAD_LD9__IPU_DISPB_DAT_9,
> +	MX35_PAD_LD10__IPU_DISPB_DAT_10,
> +	MX35_PAD_LD11__IPU_DISPB_DAT_11,
> +	MX35_PAD_LD12__IPU_DISPB_DAT_12,
> +	MX35_PAD_LD13__IPU_DISPB_DAT_13,
> +	MX35_PAD_LD14__IPU_DISPB_DAT_14,
> +	MX35_PAD_LD15__IPU_DISPB_DAT_15,
> +	MX35_PAD_LD16__IPU_DISPB_DAT_16,
> +	MX35_PAD_LD17__IPU_DISPB_DAT_17,
> +	MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
> +	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
> +	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
> +	/* Buttons */
> +	MX35_PAD_SCKR__GPIO1_4,
> +	MX35_PAD_COMPARE__GPIO1_5,
> +	MX35_PAD_SCKT__GPIO1_7,
> +	MX35_PAD_FST__GPIO1_8,
> +	MX35_PAD_HCKT__GPIO1_9,
> +	MX35_PAD_TX5_RX0__GPIO1_10,
> +	MX35_PAD_TX4_RX1__GPIO1_11,
> +	MX35_PAD_TX3_RX2__GPIO1_12,
> +	/* Buzzer */
> +	MX35_PAD_TX2_RX3__GPIO1_13,
> +	/* Diag LED */
> +	MX35_PAD_USBOTG_PWR__GPIO3_14,
> +	MX35_PAD_USBOTG_OC__GPIO3_15,
> +	MX35_PAD_D3_HSYNC__GPIO3_30,
> +};
> +
> +
> +static int vpr_console_init(void)
> +{
> +	mxc_iomux_v3_setup_multiple_pads(vpr_pads, ARRAY_SIZE(vpr_pads));
> +
> +	imx35_add_uart0();
> +	return 0;
> +}
> +
> +console_initcall(vpr_console_init);
> +
> +static int vpr_post_console_init(void)
> +{
> +	vpr_diag_init();
> +	vpr_diag_set_color(DIAG_LED_YELLOW);
> +	return 0;
> +}
> +
> +postcore_initcall(vpr_post_console_init);
> +
> +static int vpr_core_init(void)
> +{
> +	u32 reg;
> +
> +	/* enable clock for SDHC1, I2C[1] and FEC */
> +	reg = readl(IMX_CCM_BASE + CCM_CGR1);
> +	reg |= 0x3 << CCM_CGR1_FEC_SHIFT;
> +	reg |= 0x3 << CCM_CGR1_I2C1_SHIFT;
> +	reg |= 0x3 << CCM_CGR1_SDHC1_SHIFT;
> +	reg = writel(reg, IMX_CCM_BASE + CCM_CGR1);
> +
> +	/* AIPS setup - Only setup MPROTx regs. The PACR defaults are good.*/
> +	/*
> +	 * Set all MPROTx to be non-bufferable, trusted for R/W,
> +	 * not forced to user-mode.
> +	 */
> +	writel(0x77777777, IMX_AIPS1_BASE);
> +	writel(0x77777777, IMX_AIPS1_BASE + 0x4);
> +	writel(0x77777777, IMX_AIPS2_BASE);
> +	writel(0x77777777, IMX_AIPS2_BASE + 0x4);
> +
> +	/*
> +	 * Clear the on and off peripheral modules Supervisor Protect bit
> +	 * for SDMA to access them. Did not change the AIPS control registers
> +	 * (offset 0x20) access type
> +	 */
> +	writel(0x0, IMX_AIPS1_BASE + 0x40);
> +	writel(0x0, IMX_AIPS1_BASE + 0x44);
> +	writel(0x0, IMX_AIPS1_BASE + 0x48);
> +	writel(0x0, IMX_AIPS1_BASE + 0x4C);
> +	reg = readl(IMX_AIPS1_BASE + 0x50);
> +	reg &= 0x00FFFFFF;
> +	writel(reg, IMX_AIPS1_BASE + 0x50);
> +
> +	writel(0x0, IMX_AIPS2_BASE + 0x40);
> +	writel(0x0, IMX_AIPS2_BASE + 0x44);
> +	writel(0x0, IMX_AIPS2_BASE + 0x48);
> +	writel(0x0, IMX_AIPS2_BASE + 0x4C);
> +	reg = readl(IMX_AIPS2_BASE + 0x50);
> +	reg &= 0x00FFFFFF;
> +	writel(reg, IMX_AIPS2_BASE + 0x50);
> +
> +	/* MAX (Multi-Layer AHB Crossbar Switch) setup */
> +
> +	/* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
> +#define MAX_PARAM1 0x00302154
> +	writel(MAX_PARAM1, IMX_MAX_BASE + 0x000); /* for S0 */
> +	writel(MAX_PARAM1, IMX_MAX_BASE + 0x100); /* for S1 */
> +	writel(MAX_PARAM1, IMX_MAX_BASE + 0x200); /* for S2 */
> +	writel(MAX_PARAM1, IMX_MAX_BASE + 0x300); /* for S3 */
> +	writel(MAX_PARAM1, IMX_MAX_BASE + 0x400); /* for S4 */
> +
> +	/* SGPCR - always park on last master */
> +	writel(0x10, IMX_MAX_BASE + 0x10);	/* for S0 */
> +	writel(0x10, IMX_MAX_BASE + 0x110);	/* for S1 */
> +	writel(0x10, IMX_MAX_BASE + 0x210);	/* for S2 */
> +	writel(0x10, IMX_MAX_BASE + 0x310);	/* for S3 */
> +	writel(0x10, IMX_MAX_BASE + 0x410);	/* for S4 */
> +
> +	/* MGPCR - restore default values */
> +	writel(0x0, IMX_MAX_BASE + 0x800);	/* for M0 */
> +	writel(0x0, IMX_MAX_BASE + 0x900);	/* for M1 */
> +	writel(0x0, IMX_MAX_BASE + 0xa00);	/* for M2 */
> +	writel(0x0, IMX_MAX_BASE + 0xb00);	/* for M3 */
> +	writel(0x0, IMX_MAX_BASE + 0xc00);	/* for M4 */
> +	writel(0x0, IMX_MAX_BASE + 0xd00);	/* for M5 */
> +
> +	return 0;
> +}
> +
> +core_initcall(vpr_core_init);
> +
> +/* -------------------------------------------------------------------------*/
> +
> +static int vpr_pmic_init_v1(struct mc13892 *mc13892)
> +{
> +	int err = 0;
> +	unsigned int mask = 0;
> +	unsigned int val = 0;
> +
> +	/* VGEN2[2:0] = b111 --> output to 3.15V */
> +	mc13892_set_bits(mc13892, MC13892_REG_SETTING_0, 0x7 << 6, 0x7 << 6);
> +
> +	/* VCHRG[2:0] = 0b011, Charge reg output voltage 4.200 */
> +	val |= 0x3;
> +	mask |= 0x7;
> +	/* ICHRG[3:0] = 0b1011, Current limit 960mA*/
> +	val |= 0xb << 3;
> +	mask |= 0xf << 3;
> +	/* PLIM[1:0] = 0b11, Power limit 1000mW */
> +	val |= 3 << 15;
> +	mask |= 0x3 << 15;
> +	/* Enable setting of V I */
> +	val |= 1 << 23;
> +	mask |= 0x1 << 23;
> +	err |= mc13892_set_bits(mc13892, MC13892_REG_CHARGE, mask, val);
> +
> +	gpio_direction_output(FEC_RESET_GPIO, 0);
> +
> +	/*turn on the FEC power supply */
> +	/* VGEN1[1:0] = 0b11*/
> +	err |= mc13892_set_bits(mc13892, MC13892_REG_SETTING_0, 0x03, 0x03);
> +	/* VGEN1EN = 1 */
> +	err |= mc13892_set_bits(mc13892, MC13892_REG_MODE_0, 0x01, 0x01);
> +	if (err) {
> +		dev_err(&mc13892->client->dev,
> +			"Init sequence failed, the system might not be working!\n");
> +	}
> +
> +	gpio_direction_output(FEC_ENABLE_GPIO, 1);
> +	mdelay(10);
> +	gpio_set_value(FEC_RESET_GPIO, 1);
> +
> +	return err;
> +}
> +
> +/*
> + * Maybe this is a bit dodgy because the env is only set up in
> + * a late_initcall?
> + */
> +static void vpr_save_boot_loc(void)
> +{
> +	uint32_t reg;
> +	reg = readl(IMX_CCM_BASE + CCM_RCSR);
> +
> +	switch ((reg >> 25) & 0x3) {
> +	case 0x03:		/* SD/MMC is the source */
> +		setenv("boot_loc", "mmc");
> +		export("boot_loc");
> +		break;
> +	case 0x01:		/* NAND is the source */
> +		setenv("boot_loc", "nane");

s/nane/nand/

> +		export("boot_loc");
> +		break;
> +
> +	case 0x00:		/* NOR is the source */
> +		setenv("boot_loc", "nor");
> +		export("boot_loc");
> +		break;
> +	default:
> +		break;
> +	}
> +}

Nice function. This could be useful on other boards aswell to continue
booting from the medium barebox is on.

> +
> +static int vpr_final_init(void)
> +{
> +	struct mc13892 *mc13892;
> +	uint32_t system_rev;
> +
> +	mc13892 = mc13892_get();
> +	if (!mc13892) {
> +		printf("FAILED to get mc13892 handle!\n");
> +		return 0;
> +	}
> +
> +	system_rev = vpr_read_sys_cfg();
> +	printf("VPR CPU board version 0x%02x.\n", system_rev);
> +	switch (system_rev) {
> +	case VPR_CPU_V1:
> +		vpr_pmic_init_v1(mc13892);
> +		break;
> +	default:
> +		printf("Unknown revision 0x%02x.\n", system_rev);
> +		return 0;
> +	}
> +
> +	vpr_save_boot_loc();
> +
> +	return 0;
> +}
> +
> +late_initcall(vpr_final_init);
> +
> +#ifdef CONFIG_NAND_IMX_BOOT
> +void __bare_init nand_boot(void)
> +{
> +	/*
> +	 * The driver is able to detect NAND's pagesize by CPU internal
> +	 * fuses or external pull ups. But not the blocksize...
> +	 */
> +	imx_nand_load_image((void *)TEXT_BASE, 256 * 1024);
> +}
> +#endif
> +
> +/* ------------------------------------------------------------------------ */
> +
> +static int do_diagled(struct command *cmdtp, int argc, char *argv[])
> +{
> +	int color;
> +
> +	if (argc != 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	color = simple_strtoul(argv[1], NULL, 0);
> +	vpr_diag_set_color(color);
> +
> +	return 0;
> +}
> +
> +BAREBOX_CMD_HELP_START(diagled)
> +BAREBOX_CMD_HELP_USAGE("diagled [color]\n")
> +BAREBOX_CMD_HELP_SHORT("Sets the color of the diagnostic LED.\n")
> +BAREBOX_CMD_HELP_TEXT("\toff\t 0\n")
> +BAREBOX_CMD_HELP_TEXT("\tblue\t 1\n")
> +BAREBOX_CMD_HELP_TEXT("\tgreen\t 2\n")
> +BAREBOX_CMD_HELP_TEXT("\taqua\t 3\n")
> +BAREBOX_CMD_HELP_TEXT("\tred\t 4\n")
> +BAREBOX_CMD_HELP_TEXT("\tmagenta\t 5\n")
> +BAREBOX_CMD_HELP_TEXT("\tyellow\t 6\n")
> +BAREBOX_CMD_HELP_TEXT("\twhite\t 7\n")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(diagled)
> +	.cmd            = do_diagled,
> +	.usage          = "Set color of diagnositc tri-color LED",
> +	BAREBOX_CMD_HELP(cmd_diagled_help)
> +BAREBOX_CMD_END
> +
> +/* ------------------------------------------------------------------------ */
> +
> +static int do_waitbutton(struct command *cmdtp, int argc, char *argv[])
> +{
> +	int opt;
> +	uint64_t start;
> +	ulong timeout = 0;
> +	uint32_t bstate;
> +
> +	while ((opt = getopt(argc, argv, "t:")) > 0) {
> +		switch (opt) {
> +		case 't':
> +			timeout = simple_strtol(optarg, NULL, 0);
> +			break;
> +		}
> +	}
> +
> +	start = get_time_ns();
> +	while (!timeout || !is_timeout(start, timeout * SECOND)) {
> +		bstate = vpr_button_state();
> +		if (bstate) {
> +			printf("%d\n", vpr_button_state_to_number(bstate));
> +			return 0;
> +		}
> +		if (ctrlc())
> +			return -EINTR;
> +	}
> +
> +	return -ETIMEDOUT;
> +}

Given that this command is debugging only, wouldn't it be enough to just
print the result of vpr_button_state() in a loop until the user presses
ctrl-c?

> +
> +BAREBOX_CMD_HELP_START(waitbutton)
> +BAREBOX_CMD_HELP_USAGE("waitbutton [-t]\n")
> +BAREBOX_CMD_HELP_SHORT("Prints the button number of the next pressed button.\n")
> +BAREBOX_CMD_HELP_OPT("-t <seconds>", "time in seconds to wait. 0 (default) is forever.")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(button)
> +	.cmd            = do_waitbutton,
> +	.usage          = "Wait for button press",
> +	BAREBOX_CMD_HELP(cmd_waitbutton_help)
> +BAREBOX_CMD_END
> +
> +/* ------------------------------------------------------------------------ */
> +
> +static int do_buzzer(struct command *cmdtp, int argc, char *argv[])
> +{
> +	int opt;
> +	uint64_t start;
> +	ulong durationms = 200;
> +
> +	while ((opt = getopt(argc, argv, "d:")) > 0) {
> +		switch (opt) {
> +		case 'd':
> +			durationms = simple_strtol(optarg, NULL, 0);
> +			break;
> +		}
> +	}
> +
> +	vpr_buzzer_on();
> +
> +	start = get_time_ns();
> +	while (!is_timeout(start, durationms * MSECOND)) {
> +
> +		vpr_buzzer_on();
> +		udelay(120);
> +		vpr_buzzer_off();
> +		udelay(120);
> +
> +		if (ctrlc())
> +			break;
> +	}
> +
> +	vpr_buzzer_off();
> +	return 0;
> +}
> +
> +BAREBOX_CMD_HELP_START(buzzer)
> +BAREBOX_CMD_HELP_USAGE("buzzer [-d]\n")
> +BAREBOX_CMD_HELP_SHORT("Buzzer beep.\n")
> +BAREBOX_CMD_HELP_OPT  ("-d <ms>", "time in milli-seconds to stay on. (default 200ms)\n")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(buzzer)
> +	.cmd            = do_buzzer,
> +	.usage          = "Buzzer beep",
> +	BAREBOX_CMD_HELP(cmd_buzzer_help)
> +BAREBOX_CMD_END
> +
> diff --git a/arch/arm/boards/vpr200/vpr200.dox b/arch/arm/boards/vpr200/vpr200.dox
> new file mode 100644
> index 0000000..304e00f
> --- /dev/null
> +++ b/arch/arm/boards/vpr200/vpr200.dox
> @@ -0,0 +1,10 @@
> +/** @page vpr200 VPR200
> +
> +The vpr200 board uses a iMX35 CPU.
> +
> +- 64 MiB NOR Memory
> +- 2x 128 Mib RAM
> +- 512 MiB NAND
> +- 256 byte EEPROM
> +
> +*/
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From Fabio.Porcedda at telit.com  Fri Dec 10 05:47:47 2010
From: Fabio.Porcedda at telit.com (Fabio Porcedda)
Date: Fri, 10 Dec 2010 11:47:47 +0100
Subject: [PATCH] common: fix 'dummy' is used uninitialized in this function
	warning
Message-ID: <24A9345B397CD24AA76A4E82E237956545F839FBC2@XCHTS.tmt.telital.com>

fix this gcc 4.4 warning:

xyzModem.c: In function 'xyzModem_stream_open':
xyzModem.c:564: warning: 'dummy' is used uninitialized in this function

Copied from U-Boot

Signed-off-by: Fabio Porcedda <fabio.porcedda at telit.com>
---
 commands/xyzModem.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/xyzModem.c b/commands/xyzModem.c
index 1dd255d..71d7d68 100644
--- a/commands/xyzModem.c
+++ b/commands/xyzModem.c
@@ -492,7 +492,7 @@ int xyzModem_stream_open(connection_info_t *info, int *err)
 			       xyzModem_CHAR_TIMEOUT);
 #else
 /* TODO: CHECK ! */
-	int dummy;
+	int dummy = 0;
 	xyz.__chan = &dummy;
 #endif
 	xyz.len = 0;
-- 
1.7.3.3


From jacmet at sunsite.dk  Fri Dec 10 07:50:12 2010
From: jacmet at sunsite.dk (Peter Korsgaard)
Date: Fri, 10 Dec 2010 13:50:12 +0100
Subject: [PATCH] console_simple: add fprintf / console_list for
	commands/loadb.c
Message-ID: <1291985412-7645-1-git-send-email-jacmet@sunsite.dk>

commands/loadb.c doesn't build with CONFIG_CONSOLE_SIMPLE, because it uses
fprintf / for_each_console (which uses console_list).

Fix it by adding trivial implementations of both in console_simple.

Signed-off-by: Peter Korsgaard <jacmet at sunsite.dk>
---
 common/console_simple.c |   26 +++++++++++++++++++++++++-
 1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/common/console_simple.c b/common/console_simple.c
index 7695e05..1b58dea 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -3,6 +3,8 @@
 #include <fs.h>
 #include <errno.h>
 
+LIST_HEAD(console_list);
+EXPORT_SYMBOL(console_list);
 static struct console_device *console;
 
 int printf (const char *fmt, ...)
@@ -43,6 +45,25 @@ int vprintf (const char *fmt, va_list args)
 }
 EXPORT_SYMBOL(vprintf);
 
+void fprintf (int file, const char *fmt, ...)
+{
+	va_list args;
+	uint i;
+	char printbuffer[CFG_PBSIZE];
+
+	va_start (args, fmt);
+
+	/* For this to work, printbuffer must be larger than
+	 * anything we ever want to print.
+	 */
+	i = vsprintf (printbuffer, fmt, args);
+	va_end (args);
+
+	/* Print the string */
+	fputs(file, printbuffer);
+}
+EXPORT_SYMBOL(fprintf);
+
 void console_puts(unsigned int ch, const char *str)
 {
 	const char *s = str;
@@ -127,7 +148,10 @@ EXPORT_SYMBOL(ctrlc);
 
 int console_register(struct console_device *newcdev)
 {
-	if (!console)
+	if (!console) {
 		console = newcdev;
+		console_list.prev = console_list.next = &newcdev->list;
+		newcdev->list.prev = newcdev->list.next = &console_list;
+	}
 	return 0;
 }
-- 
1.7.1



From plagnioj at jcrosoft.com  Sat Dec 11 02:18:49 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 11 Dec 2010 08:18:49 +0100
Subject: [PATCH] Add basic support from ARM Versatile/PB
Message-ID: <1292051929-3545-1-git-send-email-plagnioj@jcrosoft.com>

From: Alexey Zaytsev <alexey.zaytsev at gmail.com>

tested with qemu only

qemu-system-arm -M versatilepb -monitor null -kernel barebox -net nic -net user -tftp "<uImage-path>/" -serial stdio

add -nographic if you do not want the lcd via sdl

Signed-off-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>

update:
 - use default env
 - move arm_timer.h as in the kernel
 - add nor flash support
 - udpate defconfig
 - fix copyright copy from linux
 - fix ARCH_TEXT_BASE

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
Hi,

	HOw about setup a ftp or http with some testing kernel and rootfs that
	we can use with qemu to do automatic tests

	so people can easy test their modification on other boards or arch
	with spend too much time

Best Regards,
J.
 arch/arm/Kconfig                                |    5 +
 arch/arm/Makefile                               |    2 +
 arch/arm/boards/versatile/Kconfig               |   10 +
 arch/arm/boards/versatile/Makefile              |    2 +
 arch/arm/boards/versatile/config.h              |    5 +
 arch/arm/boards/versatile/versatilepb.c         |   72 ++++
 arch/arm/configs/versatilepb_defconfig          |   48 +++
 arch/arm/include/asm/hardware/arm_timer.h       |   33 ++
 arch/arm/mach-versatile/Kconfig                 |   16 +
 arch/arm/mach-versatile/Makefile                |    2 +
 arch/arm/mach-versatile/core.c                  |  224 ++++++++++++
 arch/arm/mach-versatile/include/mach/clkdev.h   |    7 +
 arch/arm/mach-versatile/include/mach/debug_ll.h |   37 ++
 arch/arm/mach-versatile/include/mach/init.h     |    8 +
 arch/arm/mach-versatile/include/mach/platform.h |  417 +++++++++++++++++++++++
 15 files changed, 888 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/versatile/Kconfig
 create mode 100644 arch/arm/boards/versatile/Makefile
 create mode 100644 arch/arm/boards/versatile/config.h
 create mode 100644 arch/arm/boards/versatile/versatilepb.c
 create mode 100644 arch/arm/configs/versatilepb_defconfig
 create mode 100644 arch/arm/include/asm/hardware/arm_timer.h
 create mode 100644 arch/arm/mach-versatile/Kconfig
 create mode 100644 arch/arm/mach-versatile/Makefile
 create mode 100644 arch/arm/mach-versatile/core.c
 create mode 100644 arch/arm/mach-versatile/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-versatile/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-versatile/include/mach/init.h
 create mode 100644 arch/arm/mach-versatile/include/mach/platform.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8cb86cb..f1536a5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -61,6 +61,10 @@ config ARCH_S3C24xx
 	select CPU_ARM920T
 	select GENERIC_GPIO
 
+config ARCH_VERSATILE
+	bool "ARM Versatile boards (ARM926EJ-S)"
+	select CPU_ARM926T
+
 endchoice
 
 source arch/arm/cpu/Kconfig
@@ -72,6 +76,7 @@ source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
 source arch/arm/mach-omap/Kconfig
 source arch/arm/mach-s3c24xx/Kconfig
+source arch/arm/mach-versatile/Kconfig
 
 config AEABI
 	bool "Use the ARM EABI to compile barebox"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9729c23..7b68f98 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -46,6 +46,7 @@ machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_OMAP)		:= omap
 machine-$(CONFIG_ARCH_S3C24xx)		:= s3c24xx
+machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 
 # Board directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -91,6 +92,7 @@ board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
 board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
 board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
 board-$(CONFIG_MACH_MINI2440)			:= mini2440
+board-$(CONFIG_MACH_VERSATILEPB)		:= versatile
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
new file mode 100644
index 0000000..2428901
--- /dev/null
+++ b/arch/arm/boards/versatile/Kconfig
@@ -0,0 +1,10 @@
+
+if MACH_VERSATILEPB
+
+config ARCH_TEXT_BASE
+	hex
+	default 0x01000000
+
+config BOARDINFO
+	default "ARM Versatile/PB (ARM926EJ-S)"
+endif
diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
new file mode 100644
index 0000000..a17aed3
--- /dev/null
+++ b/arch/arm/boards/versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
new file mode 100644
index 0000000..25bb18f
--- /dev/null
+++ b/arch/arm/boards/versatile/config.h
@@ -0,0 +1,5 @@
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif	/* __CONFIG_H */
diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c
new file mode 100644
index 0000000..5568f21
--- /dev/null
+++ b/arch/arm/boards/versatile/versatilepb.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009-2010 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * 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; version 2 of
+ * the License.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/init.h>
+#include <mach/platform.h>
+#include <environment.h>
+#include <partition.h>
+#include <sizes.h>
+
+static struct device_d cfi_dev = {
+	.id		= -1,
+	.name		= "cfi_flash",
+	.map_base	= VERSATILE_FLASH_BASE,
+	.size		= VERSATILE_FLASH_SIZE,
+};
+
+static int vpb_console_init(void)
+{
+	versatile_register_uart(0);
+	return 0;
+}
+console_initcall(vpb_console_init);
+
+static struct device_d smc911x_dev = {
+	.id		= -1,
+	.name		= "smc91c111",
+	.map_base	= VERSATILE_ETH_BASE,
+	.size		= 64 * 1024,
+};
+
+static int vpb_devices_init(void)
+{
+	versatile_add_sdram(64 * 1024 *1024);
+
+	register_device(&cfi_dev);
+	devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self");
+	devfs_add_partition("nor0", 0x40000, 0x20000, PARTITION_FIXED, "env0");
+
+	register_device(&smc911x_dev);
+
+	armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
+	armlinux_set_bootparams((void *)(0x00000100));
+
+	return 0;
+}
+device_initcall(vpb_devices_init);
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
new file mode 100644
index 0000000..6ffdf28
--- /dev/null
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -0,0 +1,48 @@
+CONFIG_ARCH_VERSATILE=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_PROMPT="versatilepb> "
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/versatile/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_UNLZO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_DRIVER_NET_SMC91111=y
+CONFIG_FS_CRAMFS=y
+CONFIG_SHA1=y
+CONFIG_SHA256=y
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h
new file mode 100644
index 0000000..0433279
--- /dev/null
+++ b/arch/arm/include/asm/hardware/arm_timer.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+/*
+ * From Linux v2.6.35
+ * arch/arm/include/asm/hardware/arm_timer.h
+ *
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms.  Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD	0x00			/* ACVR rw */
+#define TIMER_VALUE	0x04			/* ACVR ro */
+#define TIMER_CTRL	0x08			/* ACVR rw */
+#define TIMER_CTRL_ONESHOT	(1 << 0)	/*  CVR */
+#define TIMER_CTRL_32BIT	(1 << 1)	/*  CVR */
+#define TIMER_CTRL_DIV1		(0 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV16	(1 << 2)	/* ACVR */
+#define TIMER_CTRL_DIV256	(2 << 2)	/* ACVR */
+#define TIMER_CTRL_IE		(1 << 5)	/*   VR */
+#define TIMER_CTRL_PERIODIC	(1 << 6)	/* ACVR */
+#define TIMER_CTRL_ENABLE	(1 << 7)	/* ACVR */
+
+#define TIMER_INTCLR	0x0c			/* ACVR wo */
+#define TIMER_RIS	0x10			/*  CVR ro */
+#define TIMER_MIS	0x14			/*  CVR ro */
+#define TIMER_BGLOAD	0x18			/*  CVR rw */
+
+#endif
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 0000000..9a1bf95
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,16 @@
+
+if ARCH_VERSATILE
+
+choice
+	prompt "ARM Board type"
+
+config MACH_VERSATILEPB
+	bool "ARM Versatile/PB (ARM926EJ-S)"
+	select ARM_AMBA
+	select CLKDEV_LOOKUP
+
+endchoice
+
+source arch/arm/boards/versatile/Kconfig
+
+endif
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 0000000..a8da54c
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += core.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
new file mode 100644
index 0000000..ee14f5f
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio at jcrosoft.com>
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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; version 2 of
+ * the License.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <debug_ll.h>
+
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/armlinux.h>
+
+#include <mach/platform.h>
+#include <mach/init.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id = -1,
+	.name = "mem",
+	.map_base = 0x00000000,
+	.platform_data	= &ram_pdata,
+};
+
+void versatile_add_sdram(u32 size)
+{
+	sdram_dev.size = size;
+	register_device(&sdram_dev);
+	armlinux_add_dram(&sdram_dev);
+}
+
+static struct device_d uart0_serial_device = {
+	.id = 0,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART0_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart1_serial_device = {
+	.id = 1,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART1_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart2_serial_device = {
+	.id = 2,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART2_BASE,
+	.size = 4096,
+};
+
+static struct device_d uart3_serial_device = {
+	.id = 3,
+	.name = "uart-pl011",
+	.map_base = VERSATILE_UART3_BASE,
+	.size = 4096,
+};
+
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk ref_clk_24 = {
+	.rate = 24000000,
+};
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Create a clock structure with the given name */
+int vpb_clk_create(struct clk *clk, const char *dev_id)
+{
+	struct clk_lookup *clkdev;
+
+	clkdev = clkdev_alloc(clk, NULL, dev_id);
+	if (!clkdev)
+		return -ENOMEM;
+
+	clkdev_add(clkdev);
+	return 0;
+}
+
+/* 1Mhz / 256 */
+#define TIMER_FREQ (1000000/256)
+
+#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
+#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
+#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
+
+static uint64_t vpb_clocksource_read(void)
+{
+	return ~readl(TIMER0_BASE + TIMER_VALUE);
+}
+
+static struct clocksource vpb_cs = {
+	.read = vpb_clocksource_read,
+	.mask = CLOCKSOURCE_MASK(32),
+	.shift = 10,
+};
+
+/* From Linux v2.6.35
+ * arch/arm/mach-versatile/core.c */
+static void versatile_timer_init (void)
+{
+	u32 val;
+
+	/*
+	 * set clock frequency:
+	 *      VERSATILE_REFCLK is 32KHz
+	 *      VERSATILE_TIMCLK is 1MHz
+	 */
+
+	val = readl(VERSATILE_SCTL_BASE);
+	val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
+	writel(val, VERSATILE_SCTL_BASE);
+
+	/*
+	 * Disable all timers, just to be sure.
+	 */
+
+	writel(0, TIMER0_BASE + TIMER_CTRL);
+	writel(0, TIMER1_BASE + TIMER_CTRL);
+	writel(0, TIMER2_BASE + TIMER_CTRL);
+	writel(0, TIMER3_BASE + TIMER_CTRL);
+
+	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
+					TIMER0_BASE + TIMER_CTRL);
+}
+
+static int vpb_clocksource_init(void)
+{
+	versatile_timer_init();
+	vpb_cs.mult = clocksource_hz2mult(TIMER_FREQ, vpb_cs.shift);
+
+	return init_clock(&vpb_cs);
+}
+
+core_initcall(vpb_clocksource_init);
+
+void versatile_register_uart(unsigned id)
+{
+	switch (id) {
+	case 0:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart0_serial_device));
+		register_device(&uart0_serial_device);
+		break;
+	case 1:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart1_serial_device));
+		register_device(&uart1_serial_device);
+		break;
+	case 2:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart2_serial_device));
+		register_device(&uart2_serial_device);
+		break;
+	case 3:
+		vpb_clk_create(&ref_clk_24, dev_name(&uart3_serial_device));
+		register_device(&uart3_serial_device);
+		break;
+	}
+}
+
+void __noreturn reset_cpu (unsigned long ignored)
+{
+	u32 val;
+
+	val = __raw_readl(VERSATILE_SYS_RESETCTL) & ~0x7;
+	val |= 0x105;
+
+	__raw_writel(0xa05f, VERSATILE_SYS_LOCK);
+	__raw_writel(val, VERSATILE_SYS_RESETCTL);
+	__raw_writel(0, VERSATILE_SYS_LOCK);
+
+	while(1);
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
new file mode 100644
index 0000000..514fcfb
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd
+ * Author: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+ *
+ * barebox 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * barebox 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 barebox.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define   __MACH_DEBUG_LL_H__
+
+#include <linux/amba/serial.h>
+#include <asm/io.h>
+
+static inline void putc(char c)
+{
+	/* Wait until there is space in the FIFO */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+
+	/* Send the character */
+	writel(c, 0x101F1000 + UART01x_DR);
+
+	/* Wait to make sure it hits the line, in case we die too soon. */
+	while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h
new file mode 100644
index 0000000..878cde0
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/init.h
@@ -0,0 +1,8 @@
+
+#ifndef __VERSATILE_INIT_H__
+#define __VERSATILE_INIT_H__
+
+void versatile_add_sdram(u32 size);
+void versatile_register_uart(unsigned id);
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 0000000..779b2fb
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,417 @@
+/*
+ * ach-arm926ejs/include/mach/platform.h
+ *
+ * Borrowed from Linux v2.6.35
+ * arch/arm/mach-versatile/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003.  All rights reserved.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __address_h
+#define __address_h                     1
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_BOOT_ROM_LO          0x30000000		/* DoC Base (64Mb)...*/
+#define VERSATILE_BOOT_ROM_HI          0x30000000
+#define VERSATILE_BOOT_ROM_BASE        VERSATILE_BOOT_ROM_HI	 /*  Normal position */
+#define VERSATILE_BOOT_ROM_SIZE        SZ_64M
+
+#define VERSATILE_SSRAM_BASE           /* VERSATILE_SSMC_BASE ? */
+#define VERSATILE_SSRAM_SIZE           SZ_2M
+
+#define VERSATILE_FLASH_BASE           0x34000000
+#define VERSATILE_FLASH_SIZE           SZ_64M
+
+/*
+ *  SDRAM
+ */
+#define VERSATILE_SDRAM_BASE           0x00000000
+
+/*
+ *  Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define VERSATILE_SYS_ID_OFFSET               0x00
+#define VERSATILE_SYS_SW_OFFSET               0x04
+#define VERSATILE_SYS_LED_OFFSET              0x08
+#define VERSATILE_SYS_OSC0_OFFSET             0x0C
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x10
+#define VERSATILE_SYS_OSC2_OFFSET             0x14
+#define VERSATILE_SYS_OSC3_OFFSET             0x18
+#define VERSATILE_SYS_OSC4_OFFSET             0x1C
+#elif defined(CONFIG_MACH_VERSATILE_AB)
+#define VERSATILE_SYS_OSC1_OFFSET             0x1C
+#endif
+
+#define VERSATILE_SYS_OSCCLCD_OFFSET          0x1c
+
+#define VERSATILE_SYS_LOCK_OFFSET             0x20
+#define VERSATILE_SYS_100HZ_OFFSET            0x24
+#define VERSATILE_SYS_CFGDATA1_OFFSET         0x28
+#define VERSATILE_SYS_CFGDATA2_OFFSET         0x2C
+#define VERSATILE_SYS_FLAGS_OFFSET            0x30
+#define VERSATILE_SYS_FLAGSSET_OFFSET         0x30
+#define VERSATILE_SYS_FLAGSCLR_OFFSET         0x34
+#define VERSATILE_SYS_NVFLAGS_OFFSET          0x38
+#define VERSATILE_SYS_NVFLAGSSET_OFFSET       0x38
+#define VERSATILE_SYS_NVFLAGSCLR_OFFSET       0x3C
+#define VERSATILE_SYS_RESETCTL_OFFSET         0x40
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
+#define VERSATILE_SYS_MCI_OFFSET              0x48
+#define VERSATILE_SYS_FLASH_OFFSET            0x4C
+#define VERSATILE_SYS_CLCD_OFFSET             0x50
+#define VERSATILE_SYS_CLCDSER_OFFSET          0x54
+#define VERSATILE_SYS_BOOTCS_OFFSET           0x58
+#define VERSATILE_SYS_24MHz_OFFSET            0x5C
+#define VERSATILE_SYS_MISC_OFFSET             0x60
+#define VERSATILE_SYS_TEST_OSC0_OFFSET        0x80
+#define VERSATILE_SYS_TEST_OSC1_OFFSET        0x84
+#define VERSATILE_SYS_TEST_OSC2_OFFSET        0x88
+#define VERSATILE_SYS_TEST_OSC3_OFFSET        0x8C
+#define VERSATILE_SYS_TEST_OSC4_OFFSET        0x90
+
+#define VERSATILE_SYS_BASE                    0x10000000
+#define VERSATILE_SYS_ID                      (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
+#define VERSATILE_SYS_SW                      (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
+#define VERSATILE_SYS_LED                     (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
+#define VERSATILE_SYS_OSC0                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
+#define VERSATILE_SYS_OSC1                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC2                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
+#define VERSATILE_SYS_OSC3                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
+#define VERSATILE_SYS_OSC4                    (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
+#endif
+
+#define VERSATILE_SYS_LOCK                    (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
+#define VERSATILE_SYS_100HZ                   (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
+#define VERSATILE_SYS_CFGDATA1                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
+#define VERSATILE_SYS_CFGDATA2                (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
+#define VERSATILE_SYS_FLAGS                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
+#define VERSATILE_SYS_FLAGSSET                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
+#define VERSATILE_SYS_FLAGSCLR                (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
+#define VERSATILE_SYS_NVFLAGS                 (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
+#define VERSATILE_SYS_NVFLAGSSET              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
+#define VERSATILE_SYS_NVFLAGSCLR              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
+#define VERSATILE_SYS_RESETCTL                (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
+#define VERSATILE_SYS_MCI                     (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYS_FLASH                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_SYS_CLCD                    (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
+#define VERSATILE_SYS_CLCDSER                 (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
+#define VERSATILE_SYS_BOOTCS                  (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
+#define VERSATILE_SYS_24MHz                   (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_SYS_MISC                    (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
+#define VERSATILE_SYS_TEST_OSC0               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
+#define VERSATILE_SYS_TEST_OSC1               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
+#define VERSATILE_SYS_TEST_OSC2               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
+#define VERSATILE_SYS_TEST_OSC3               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
+#define VERSATILE_SYS_TEST_OSC4               (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
+
+/*
+ * Values for VERSATILE_SYS_RESET_CTRL
+ */
+#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR    0x01
+#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT   0x02
+#define VERSATILE_SYS_CTRL_RESET_DLLRESET     0x03
+#define VERSATILE_SYS_CTRL_RESET_PLLRESET     0x04
+#define VERSATILE_SYS_CTRL_RESET_POR          0x05
+#define VERSATILE_SYS_CTRL_RESET_DoC          0x06
+
+#define VERSATILE_SYS_CTRL_LED         (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile control registers
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * VERSATILE_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4  = build value
+ * 3:0   = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * VERSATILE_SYS_LOCK
+ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
+ *     SYS_CLD, SYS_BOOTCS
+ */
+#define VERSATILE_SYS_LOCK_LOCKED    (1 << 16)
+#define VERSATILE_SYS_LOCKVAL_MASK	0xFFFF		/* write 0xA05F to enable write access */
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN	(1 << 0)	/* Enable writing to flash */
+
+/*
+ * VERSATILE_INTREG
+ *     - used to acknowledge and control MMCI and UART interrupts
+ */
+#define VERSATILE_INTREG_WPROT        0x00    /* MMC protection status (no interrupt generated) */
+#define VERSATILE_INTREG_RI0          0x01    /* Ring indicator UART0 is asserted,              */
+#define VERSATILE_INTREG_CARDIN       0x08    /* MMCI card in detect                            */
+                                                /* write 1 to acknowledge and clear               */
+#define VERSATILE_INTREG_RI1          0x02    /* Ring indicator UART1 is asserted,              */
+#define VERSATILE_INTREG_CARDINSERT   0x03    /* Signal insertion of MMC card                   */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_PCI_CORE_BASE        0x10001000	/* PCI core control */
+#define VERSATILE_I2C_BASE             0x10002000	/* I2C control */
+#define VERSATILE_SIC_BASE             0x10003000	/* Secondary interrupt controller */
+#define VERSATILE_AACI_BASE            0x10004000	/* Audio */
+#define VERSATILE_MMCI0_BASE           0x10005000	/* MMC interface */
+#define VERSATILE_KMI0_BASE            0x10006000	/* KMI interface */
+#define VERSATILE_KMI1_BASE            0x10007000	/* KMI 2nd interface */
+#define VERSATILE_CHAR_LCD_BASE        0x10008000	/* Character LCD */
+#define VERSATILE_UART3_BASE           0x10009000	/* UART 3 */
+#define VERSATILE_SCI1_BASE            0x1000A000
+#define VERSATILE_MMCI1_BASE           0x1000B000    /* MMC Interface */
+	/* 0x1000C000 - 0x1000CFFF = reserved */
+#define VERSATILE_ETH_BASE             0x10010000	/* Ethernet */
+#define VERSATILE_USB_BASE             0x10020000	/* USB */
+	/* 0x10030000 - 0x100FFFFF = reserved */
+#define VERSATILE_SMC_BASE             0x10100000	/* SMC */
+#define VERSATILE_MPMC_BASE            0x10110000	/* MPMC */
+#define VERSATILE_CLCD_BASE            0x10120000	/* CLCD */
+#define VERSATILE_DMAC_BASE            0x10130000	/* DMA controller */
+#define VERSATILE_VIC_BASE             0x10140000	/* Vectored interrupt controller */
+#define VERSATILE_PERIPH_BASE          0x10150000	/* off-chip peripherals alias from */
+                                                /* 0x10000000 - 0x100FFFFF */
+#define VERSATILE_AHBM_BASE            0x101D0000	/* AHB monitor */
+#define VERSATILE_SCTL_BASE            0x101E0000	/* System controller */
+#define VERSATILE_WATCHDOG_BASE        0x101E1000	/* Watchdog */
+#define VERSATILE_TIMER0_1_BASE        0x101E2000	/* Timer 0 and 1 */
+#define VERSATILE_TIMER2_3_BASE        0x101E3000	/* Timer 2 and 3 */
+#define VERSATILE_GPIO0_BASE           0x101E4000	/* GPIO port 0 */
+#define VERSATILE_GPIO1_BASE           0x101E5000	/* GPIO port 1 */
+#define VERSATILE_GPIO2_BASE           0x101E6000	/* GPIO port 2 */
+#define VERSATILE_GPIO3_BASE           0x101E7000	/* GPIO port 3 */
+#define VERSATILE_RTC_BASE             0x101E8000	/* Real Time Clock */
+	/* 0x101E9000 - reserved */
+#define VERSATILE_SCI_BASE             0x101F0000	/* Smart card controller */
+#define VERSATILE_UART0_BASE           0x101F1000	/* Uart 0 */
+#define VERSATILE_UART1_BASE           0x101F2000	/* Uart 1 */
+#define VERSATILE_UART2_BASE           0x101F3000	/* Uart 2 */
+#define VERSATILE_SSP_BASE             0x101F4000	/* Synchronous Serial Port */
+
+#define VERSATILE_SSMC_BASE            0x20000000	/* SSMC */
+#define VERSATILE_IB2_BASE             0x24000000	/* IB2 module */
+#define VERSATILE_MBX_BASE             0x40000000	/* MBX */
+
+/* PCI space */
+#define VERSATILE_PCI_BASE             0x41000000	/* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE	       0x42000000
+#define VERSATILE_PCI_MEM_BASE0        0x44000000
+#define VERSATILE_PCI_MEM_BASE1        0x50000000
+#define VERSATILE_PCI_MEM_BASE2        0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE	       0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */
+
+#define VERSATILE_SDRAM67_BASE         0x70000000	/* SDRAM banks 6 and 7 */
+#define VERSATILE_LT_BASE              0x80000000	/* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define VERSATILE_DOC_BASE             0x2C000000
+#define VERSATILE_DOC_SIZE             (16 << 20)
+#define VERSATILE_DOC_PAGE_SIZE        512
+#define VERSATILE_DOC_TOTAL_PAGES     (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES    32
+#define START_PAGE          0x80
+
+/*
+ *  LED settings, bits [7:0]
+ */
+#define VERSATILE_SYS_LED0             (1 << 0)
+#define VERSATILE_SYS_LED1             (1 << 1)
+#define VERSATILE_SYS_LED2             (1 << 2)
+#define VERSATILE_SYS_LED3             (1 << 3)
+#define VERSATILE_SYS_LED4             (1 << 4)
+#define VERSATILE_SYS_LED5             (1 << 5)
+#define VERSATILE_SYS_LED6             (1 << 6)
+#define VERSATILE_SYS_LED7             (1 << 7)
+
+#define ALL_LEDS                  0xFF
+
+#define LED_BANK                  VERSATILE_SYS_LED
+
+/*
+ * Control registers
+ */
+#define VERSATILE_IDFIELD_OFFSET	0x0	/* Versatile build information */
+#define VERSATILE_FLASHPROG_OFFSET	0x4	/* Flash devices */
+#define VERSATILE_INTREG_OFFSET		0x8	/* Interrupt control */
+#define VERSATILE_DECODE_OFFSET		0xC	/* Fitted logic modules */
+
+
+/* ------------------------------------------------------------------------
+ *  Versatile Interrupt Controller - control registers
+ * ------------------------------------------------------------------------
+ *
+ *  Offsets from interrupt controller base
+ *
+ *  System Controller interrupt controller base is
+ *
+ * 	VERSATILE_IC_BASE
+ *
+ *  Core Module interrupt controller base is
+ *
+ * 	VERSATILE_SYS_IC
+ *
+ */
+/* VIC definitions in include/asm-arm/hardware/vic.h */
+
+#define SIC_IRQ_STATUS                  0
+#define SIC_IRQ_RAW_STATUS              0x04
+#define SIC_IRQ_ENABLE                  0x08
+#define SIC_IRQ_ENABLE_SET              0x08
+#define SIC_IRQ_ENABLE_CLEAR            0x0C
+#define SIC_INT_SOFT_SET                0x10
+#define SIC_INT_SOFT_CLEAR              0x14
+#define SIC_INT_PIC_ENABLE              0x20	/* read status of pass through mask */
+#define SIC_INT_PIC_ENABLES             0x20	/* set interrupt pass through bits */
+#define SIC_INT_PIC_ENABLEC             0x24	/* Clear interrupt pass through bits */
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+
+#define INT_WDOGINT                     0	/* Watchdog timer */
+#define INT_SOFTINT                     1	/* Software interrupt */
+#define INT_COMMRx                      2	/* Debug Comm Rx interrupt */
+#define INT_COMMTx                      3	/* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1                 4	/* Timer 0 and 1 */
+#define INT_TIMERINT2_3                 5	/* Timer 2 and 3 */
+#define INT_GPIOINT0                    6	/* GPIO 0 */
+#define INT_GPIOINT1                    7	/* GPIO 1 */
+#define INT_GPIOINT2                    8	/* GPIO 2 */
+#define INT_GPIOINT3                    9	/* GPIO 3 */
+#define INT_RTCINT                      10	/* Real Time Clock */
+#define INT_SSPINT                      11	/* Synchronous Serial Port */
+#define INT_UARTINT0                    12	/* UART 0 on development chip */
+#define INT_UARTINT1                    13	/* UART 1 on development chip */
+#define INT_UARTINT2                    14	/* UART 2 on development chip */
+#define INT_SCIINT                      15	/* Smart Card Interface */
+#define INT_CLCDINT                     16	/* CLCD controller */
+#define INT_DMAINT                      17	/* DMA controller */
+#define INT_PWRFAILINT                  18	/* Power failure */
+#define INT_MBXINT                      19	/* Graphics processor */
+#define INT_GNDINT                      20	/* Reserved */
+	/* External interrupt signals from logic tiles or secondary controller */
+#define INT_VICSOURCE21                 21	/* Disk on Chip */
+#define INT_VICSOURCE22                 22	/* MCI0A */
+#define INT_VICSOURCE23                 23	/* MCI1A */
+#define INT_VICSOURCE24                 24	/* AACI */
+#define INT_VICSOURCE25                 25	/* Ethernet */
+#define INT_VICSOURCE26                 26	/* USB */
+#define INT_VICSOURCE27                 27	/* PCI 0 */
+#define INT_VICSOURCE28                 28	/* PCI 1 */
+#define INT_VICSOURCE29                 29	/* PCI 2 */
+#define INT_VICSOURCE30                 30	/* PCI 3 */
+#define INT_VICSOURCE31                 31	/* SIC source */
+
+#define VERSATILE_SC_VALID_INT               0x003FFFFF
+
+#define MAXIRQNUM                       31
+#define MAXFIQNUM                       31
+#define MAXSWINUM                       31
+
+/* ------------------------------------------------------------------------
+ *  Interrupts - bit assignment (secondary)
+ * ------------------------------------------------------------------------
+ */
+#define SIC_INT_MMCI0B                  1	/* Multimedia Card 0B */
+#define SIC_INT_MMCI1B                  2	/* Multimedia Card 1B */
+#define SIC_INT_KMI0                    3	/* Keyboard/Mouse port 0 */
+#define SIC_INT_KMI1                    4	/* Keyboard/Mouse port 1 */
+#define SIC_INT_SCI3                    5	/* Smart Card interface */
+#define SIC_INT_UART3                   6	/* UART 3 empty or data available */
+#define SIC_INT_CLCD                    7	/* Character LCD */
+#define SIC_INT_TOUCH                   8	/* Touchscreen */
+#define SIC_INT_KEYPAD                  9	/* Key pressed on display keypad */
+	/* 10:20 - reserved */
+#define SIC_INT_DoC                     21	/* Disk on Chip memory controller */
+#define SIC_INT_MMCI0A                  22	/* MMC 0A */
+#define SIC_INT_MMCI1A                  23	/* MMC 1A */
+#define SIC_INT_AACI                    24	/* Audio Codec */
+#define SIC_INT_ETH                     25	/* Ethernet controller */
+#define SIC_INT_USB                     26	/* USB controller */
+#define SIC_INT_PCI0                    27
+#define SIC_INT_PCI1                    28
+#define SIC_INT_PCI2                    29
+#define SIC_INT_PCI3                    30
+
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK	0
+#define VERSATILE_TIMCLK	1
+
+#define VERSATILE_TIMER1_EnSel	15
+#define VERSATILE_TIMER2_EnSel	17
+#define VERSATILE_TIMER3_EnSel	19
+#define VERSATILE_TIMER4_EnSel	21
+
+
+#define VERSATILE_CSR_BASE             0x10000000
+#define VERSATILE_CSR_SIZE             0x10000000
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+/*
+ * IB2 Versatile/AB expansion board definitions
+ */
+#define VERSATILE_IB2_CAMERA_BANK	VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG	(VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE		(VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER		(VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR		(VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE		(VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL		(VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT		(VERSATILE_IB2_CTL_BASE + 4)
+#endif
+
+#endif
-- 
1.7.2.3



From marc at cpdesign.com.au  Sat Dec 11 02:39:43 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Sat, 11 Dec 2010 18:39:43 +1100
Subject: [PATCH] imx: add IMX_GPIO_NR macro.
Message-ID: <1292053183-26915-1-git-send-email-marc@cpdesign.com.au>

Simplifies specifying gpio numbers from bank/number info.

From baruch at tkos.co.il  Mon Dec 13 01:00:10 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 13 Dec 2010 08:00:10 +0200
Subject: [PATCH] remove redundant .gitignore entries
Message-ID: <13507e3e1f3a5dfa2e79be2ffcfbe6d7b9e84bb3.1292219932.git.baruch@tkos.co.il>

The ARCH and CROSS_COMPILE entries were introduced in commit cdfd8bdd, probably
by mistake.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 .gitignore |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6f04601..cdc4df0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,8 +34,6 @@ barebox.netx
 barebox.map
 System.map
 Module.symvers
-ARCH
-CROSS_COMPILE
 barebox_default_env
 
 #
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:27 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:27 +0100
Subject: [PATCH 04/14] STM378x: Do not configure any pin usage in the driver
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-5-git-send-email-jbe@pengutronix.de>

Only the platform should configure pins to be used by the driver.
The driver must work independently from the settings.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/serial/stm-serial.c |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index 3edd484..a225e30 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -134,13 +134,6 @@ static int stm_clocksource_clock_change(struct notifier_block *nb, unsigned long
 static int stm_serial_init_port(struct console_device *cdev)
 {
 	struct device_d *dev = cdev->dev;
-	/*
-	 * If the board specific file registers this console we should force
-	 * the usage of the debug UART pins, to be able to let the user see
-	 * the output, even if the board file forgets to configure these pins.
-	 */
-	imx_gpio_mode(PWM1_DUART_TX);
-	imx_gpio_mode(PWM0_DUART_RX);
 
 	/* Disable UART */
 	writel(0, dev->map_base + UARTDBGCR);
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:25 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:25 +0100
Subject: [PATCH 02/14] Add macro for correct rounding in integer devisions
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-3-git-send-email-jbe@pengutronix.de>

Just stolen from Linux.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/stm378x.c |    2 +-
 include/common.h      |    7 +++++++
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index 039fbb9..a2802af 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -484,7 +484,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 	ssp = imx_get_sspclk(0) * 1000;
 
 	for (div = 2; div < 255; div += 2) {
-		rate = (((ssp + (nc >> 1) ) / nc) + (div >> 1)) / div;
+		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
 		if (rate <= 0x100)
 			break;
 	}
diff --git a/include/common.h b/include/common.h
index be83a31..1bea10c 100644
--- a/include/common.h
+++ b/include/common.h
@@ -224,4 +224,11 @@ extern const char version_string[];
 
 #define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
 
+#define DIV_ROUND_CLOSEST(x, divisor)(			\
+{							\
+	typeof(divisor) __divisor = divisor;		\
+	(((x) + ((__divisor) / 2)) / (__divisor));	\
+}							\
+)
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:32 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:32 +0100
Subject: [PATCH 09/14] STM378x: Adapt the serial driver to support i.MX23 and
	i.MX28
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-10-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/serial/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3a8882f..04d9b98 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -21,7 +21,7 @@ config DRIVER_SERIAL_IMX
 config DRIVER_SERIAL_STM378X
 	depends on ARCH_STM
 	default y
-	bool "i.MX23 serial driver"
+	bool "i.MX23/i.MX28 serial driver"
 
 config DRIVER_SERIAL_NETX
 	depends on ARCH_NETX
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:34 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:34 +0100
Subject: [PATCH 11/14] Fixup the FEC driver files
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-12-git-send-email-jbe@pengutronix.de>

Some register bits are not defined in the IMX CPUs using this FEC (at least
I did not find anything about them in the related datasheets) and they will
get (partially) a new meaning in the i.MX28 CPU. So, removing them from the
source seems the best way to avoid any accidental usage on i.MX28.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/net/fec_imx.c |    3 +--
 drivers/net/fec_imx.h |    4 ----
 2 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 9c8de77..91ef929 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -476,8 +476,7 @@ static int fec_recv(struct eth_device *dev)
 	ievent = readl(fec->regs + FEC_IEVENT);
 	writel(ievent, fec->regs + FEC_IEVENT);
 
-	if (ievent & (FEC_IEVENT_BABT | FEC_IEVENT_XFIFO_ERROR |
-				FEC_IEVENT_RFIFO_ERROR)) {
+	if (ievent & FEC_IEVENT_BABT) {
 		/* BABT, Rx/Tx FIFO errors */
 		fec_halt(dev);
 		fec_init(dev);
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index ce0fd89..f7fbdc9 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -73,8 +73,6 @@
 #define FEC_IEVENT_LATE_COL             0x00200000
 #define FEC_IEVENT_COL_RETRY_LIM        0x00100000
 #define FEC_IEVENT_XFIFO_UN             0x00080000
-#define FEC_IEVENT_XFIFO_ERROR          0x00040000
-#define FEC_IEVENT_RFIFO_ERROR          0x00020000
 
 #define FEC_IMASK_HBERR                 0x80000000
 #define FEC_IMASK_BABR                  0x40000000
@@ -84,8 +82,6 @@
 #define FEC_IMASK_LATE_COL              0x00200000
 #define FEC_IMASK_COL_RETRY_LIM         0x00100000
 #define FEC_IMASK_XFIFO_UN              0x00080000
-#define FEC_IMASK_XFIFO_ERROR           0x00040000
-#define FEC_IMASK_RFIFO_ERROR           0x00020000
 
 #define FEC_RCNTRL_MAX_FL_SHIFT         16
 #define FEC_RCNTRL_LOOP                 0x01
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:30 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:30 +0100
Subject: [PATCH 07/14] IMX: Ignore i.MX23/i.MX28 related code in shared devices
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-8-git-send-email-jbe@pengutronix.de>

At least the FEC and the CAN controller drivers can also be used by the i.MX28.
When still used by IMX, the i.MX28 (and maybe i.MX23) related code must be
ignored.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-imx/include/mach/generic.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 9ca838b..2926036 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -51,3 +51,5 @@ u64 imx_uid(void);
 #define cpu_is_mx51()	(0)
 #endif
 
+#define cpu_is_mx23()	(0)
+#define cpu_is_mx28()	(0)
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:24 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:24 +0100
Subject: [PATCH 01/14] Make DIV_ROUND_UP macro globally available
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-2-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/speed-imx23.c |    3 +--
 drivers/spi/imx_spi.c           |    3 ---
 include/common.h                |    2 ++
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
index 7418ad5..f32ae92 100644
--- a/arch/arm/mach-stm/speed-imx23.c
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -244,8 +244,7 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
 		printf("Cannot setup SSP unit clock to %u Hz, base clock is only %u Hz\n", nc, ssp_div);
 		ssp_div = 1U;
 	} else {
-		ssp_div += nc - 1U;
-		ssp_div /= nc;
+		ssp_div = DIV_ROUND_UP(ssp_div, nc);
 		if (ssp_div > CLKCTRL_SSP_DIV_MASK)
 			ssp_div = CLKCTRL_SSP_DIV_MASK;
 	}
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 2ad1bfa..1857d6c 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -224,9 +224,6 @@ static unsigned int cspi_2_3_xchg_single(struct imx_spi *imx, unsigned int data)
 	return readl(base + CSPI_2_3_RXDATA);
 }
 
-/* FIXME: include/linux/kernel.h */
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
 static unsigned int cspi_2_3_clkdiv(unsigned int fin, unsigned int fspi)
 {
 	/*
diff --git a/include/common.h b/include/common.h
index a14bfc1..be83a31 100644
--- a/include/common.h
+++ b/include/common.h
@@ -222,4 +222,6 @@ extern const char version_string[];
 
 #define IOMEM(addr)	((void __force __iomem *)(addr))
 
+#define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:36 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:36 +0100
Subject: [PATCH 13/14] STM378x: Add TX28 CPU module
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-14-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 Documentation/boards.dox           |    1 +
 arch/arm/Makefile                  |    1 +
 arch/arm/boards/karo-tx28/Makefile |    1 +
 arch/arm/boards/karo-tx28/config.h |   16 +++++
 arch/arm/boards/karo-tx28/tx28.c   |  119 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-stm/Kconfig          |   16 +++++
 6 files changed, 154 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/karo-tx28/Makefile
 create mode 100644 arch/arm/boards/karo-tx28/config.h
 create mode 100644 arch/arm/boards/karo-tx28/tx28.c

diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index c04e06b..8087f01 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -14,6 +14,7 @@ ARM type:
 @li @subpage pcm043
 @li @subpage imx21ads
 @li @subpage imx27ads
+ at li @subpage tx28
 @li @subpage the3stack
 @li @subpage mx23_evk
 @li @subpage board_babage
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9729c23..9d3350b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -88,6 +88,7 @@ board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
 board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
 board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
+board-$(CONFIG_MACH_TX28)			:= karo-tx28
 board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
 board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
 board-$(CONFIG_MACH_MINI2440)			:= mini2440
diff --git a/arch/arm/boards/karo-tx28/Makefile b/arch/arm/boards/karo-tx28/Makefile
new file mode 100644
index 0000000..6f7e865
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/Makefile
@@ -0,0 +1 @@
+obj-y += tx28.o
diff --git a/arch/arm/boards/karo-tx28/config.h b/arch/arm/boards/karo-tx28/config.h
new file mode 100644
index 0000000..8f18fda
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/config.h
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+#ifndef _CONFIG_H_
+# define _CONFIG_H_
+
+#endif /* _CONFIG_H_ */
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
new file mode 100644
index 0000000..d5edf5d
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <kernel at pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id = -1,
+	.name = "mem",
+	.map_base = IMX_MEMORY_BASE,
+	.size = 128 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+/* setup the CPU card internal signals */
+static const uint32_t tx28_pad_setup[] = {
+	/* NAND interface */
+	GPMI_D0 | VE_3_3V | PULLUP(1),
+	GPMI_D1 | VE_3_3V | PULLUP(1),
+	GPMI_D2 | VE_3_3V | PULLUP(1),
+	GPMI_D3 | VE_3_3V | PULLUP(1),
+	GPMI_D4 | VE_3_3V | PULLUP(1),
+	GPMI_D5 | VE_3_3V | PULLUP(1),
+	GPMI_D6 | VE_3_3V | PULLUP(1),
+	GPMI_D7 | VE_3_3V | PULLUP(1),
+	GPMI_READY0 | VE_3_3V | PULLUP(0),	/* external PU */
+	GPMI_RDN | VE_3_3V | PULLUP(1),
+	GPMI_WRN | VE_3_3V | BITKEEPER(1),
+	GPMI_ALE | VE_3_3V | PULLUP(1),
+	GPMI_CLE | VE_3_3V | PULLUP(1),
+	GPMI_RESETN_GPIO | VE_3_3V | GPIO_IN,	/* act as WP, external PU */
+
+	/* Network interface */
+
+	/*
+	 * Note: To setup the external phy in a manner the baseboard
+	 * supports, its configuration is divided into a small part here in
+	 * the CPU card setup and the remaining configuration in the baseboard
+	 * file.
+	 * Here: Switch on the power supply to the external phy, but keep its
+	 * reset line low.
+	 */
+
+	/* send a "good morning" to the ext. phy 0 = reset */
+	ENET0_RX_CLK_GPIO | VE_3_3V | PULLUP(0) | GPIO_OUT | GPIO_VALUE(0),
+
+	/* phy power control 1 = on */
+	PWM4_GPIO | VE_3_3V | GPIO_OUT | PULLUP(0) | GPIO_VALUE(1),
+
+	ENET_CLK | VE_3_3V | BITKEEPER(0),
+	ENET0_MDC | VE_3_3V | PULLUP(0),
+	ENET0_MDIO | VE_3_3V | PULLUP(0),
+	ENET0_TXD0 | VE_3_3V | PULLUP(0),
+	ENET0_TXD1 | VE_3_3V | PULLUP(0),
+	ENET0_TX_EN | VE_3_3V | PULLUP(0),
+	ENET0_TX_CLK | VE_3_3V | BITKEEPER(0),
+
+};
+
+extern void base_board_init(void);
+
+static int tx28_devices_init(void)
+{
+	int i;
+
+	/* initizalize gpios */
+	for (i = 0; i < ARRAY_SIZE(tx28_pad_setup); i++)
+		imx_gpio_mode(tx28_pad_setup[i]);
+
+	register_device(&sdram_dev);
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void *)(sdram_dev.map_base + 0x100));
+	armlinux_set_architecture(MACH_TYPE_TX28);
+
+	base_board_init();
+
+	return 0;
+}
+
+device_initcall(tx28_devices_init);
+
+/**
+ at page tx28 KARO's TX28 CPU module
+
+http://www.karo-electronics.de/
+
+This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
+
+- 128 MiB synchronous dynamic RAM (DDR2 type), 200 MHz support
+- 128 MiB NAND K9F1G08U0A (3.3V type)
+- PCA9554 GPIO expander
+- DS1339 RTC
+- LAN8710 Phy
+
+*/
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 9a46138..824b2cf 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -4,10 +4,12 @@ config ARCH_TEXT_BASE
 	hex
 	default 0x41000000 if MACH_MX23EVK
 	default 0x42000000 if MACH_CHUMBY
+	default 0x47000000 if MACH_TX28
 
 config BOARDINFO
 	default "Freescale i.MX23-EVK" if MACH_MX23EVK
 	default "Chumby Falconwing" if MACH_CHUMBY
+	default "Karo TX28" if MACH_TX28
 
 comment "SigmaTel/Freescale i.MX System-on-Chip"
 
@@ -46,6 +48,20 @@ endchoice
 
 endif
 
+if ARCH_IMX28
+
+choice
+	prompt "i.MX28 Board Type"
+
+config MACH_TX28
+	bool "KARO tx28"
+	help
+	  Say Y here if you are using the KARO TX28 CPU module.
+
+endchoice
+
+endif
+
 menu "Board specific settings       "
 
 endmenu
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:29 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:29 +0100
Subject: [PATCH 06/14] STM378x: Separate i.MX23 clock handling
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-7-git-send-email-jbe@pengutronix.de>

Separate i.MX23 clock handling to simplify the addition of the upcoming i.MX28.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/include/mach/clock-imx23.h |   26 ++++++++++++++++++++++++++
 arch/arm/mach-stm/include/mach/clock.h       |   19 ++++++-------------
 2 files changed, 32 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx23.h

diff --git a/arch/arm/mach-stm/include/mach/clock-imx23.h b/arch/arm/mach-stm/include/mach/clock-imx23.h
new file mode 100644
index 0000000..bb499f2
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx23.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef MACH_CLOCK_IMX23_H
+# define MACH_CLOCK_IMX23_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(void);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned);
+
+#endif /* MACH_CLOCK_IMX23_H */
diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h
index 0e1a6d6..5200e89 100644
--- a/arch/arm/mach-stm/include/mach/clock.h
+++ b/arch/arm/mach-stm/include/mach/clock.h
@@ -17,18 +17,11 @@
  * MA 02111-1307 USA
  */
 
-#ifndef ASM_ARCH_CLOCK_IMX23_H
-#define ASM_ARCH_CLOCK_IMX23_H
+#ifndef __MACH_CLOCK_H
+# define __MACH_CLOCK_H
 
-unsigned imx_get_mpllclk(void);
-unsigned imx_get_emiclk(void);
-unsigned imx_get_ioclk(void);
-unsigned imx_get_armclk(void);
-unsigned imx_get_hclk(void);
-unsigned imx_get_xclk(void);
-unsigned imx_get_sspclk(unsigned);
-unsigned imx_set_sspclk(unsigned, unsigned, int);
-unsigned imx_set_ioclk(unsigned);
-
-#endif /* ASM_ARCH_CLOCK_IMX23_H */
+#if defined CONFIG_ARCH_IMX23
+# include <mach/clock-imx23.h>
+#endif
 
+#endif /* __MACH_CLOCK_H */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:23 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:23 +0100
Subject: [PATCH] i.MX28 architecture inclusion into barebox
Message-ID: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>

This patch stack adds the new Freescale i.MX28 CPU as a basic implementation
to barebox. This new CPU shares most components with the existing i.MX23
(former STM378x), but also some components with the existing IMX. So, this
patch stack has to touch i.MX23 related files and also some IMX related ones.
As a user of this implementation the stack comes with support for the KARO
TX28 CPU card and its evaluation starterkit-5.

The following changes since commit 4f21f1ec978c5cb43a25d1b52a49ff5fe84d4206:

  arm: update mach-types (2010-12-10 10:06:18 +0100)

are available in the git repository at:
  http://git.pengutronix.de/git/jbe/for_barebox_next/ next_iMX28v4

Juergen Beisert (14):
      Make DIV_ROUND_UP macro globally available
      Add macro for correct rounding in integer devisions
      STM378x: Use Hz as the clock unit like in all other arch
      STM378x: Do not configure any pin usage in the driver
      STM378x: Parameterize the max. possible GPIO number
      STM378x: Separate i.MX23 clock handling
      IMX: Ignore i.MX23/i.MX28 related code in shared devices
      STM378x: Add i.MX28 architecture
      STM378x: Adapt the serial driver to support i.MX23 and i.MX28
      STM378x: Adapt the MCI driver to support i.MX23 and i.MX28
      Fixup the FEC driver files
      MX28: add FEC support
      STM378x: Add TX28 CPU module
      STM378x: Add the TX28 Starterkit-5 baseboard

 Documentation/boards.dox                         |    1 +
 arch/arm/Makefile                                |    1 +
 arch/arm/boards/karo-tx28/Makefile               |    2 +
 arch/arm/boards/karo-tx28/config.h               |   16 +
 arch/arm/boards/karo-tx28/env/config             |   47 ++
 arch/arm/boards/karo-tx28/tx28-stk5.c            |  229 +++++++++
 arch/arm/boards/karo-tx28/tx28.c                 |  156 ++++++
 arch/arm/configs/tx28stk5_defconfig              |   38 ++
 arch/arm/mach-imx/include/mach/generic.h         |    2 +
 arch/arm/mach-stm/Kconfig                        |   36 ++
 arch/arm/mach-stm/Makefile                       |    5 +-
 arch/arm/mach-stm/clocksource-imx28.c            |   73 +++
 arch/arm/mach-stm/{imx23.c => imx.c}             |    0
 arch/arm/mach-stm/include/mach/clock-imx23.h     |   26 +
 arch/arm/mach-stm/include/mach/clock-imx28.h     |   29 ++
 arch/arm/mach-stm/include/mach/clock.h           |   22 +-
 arch/arm/mach-stm/include/mach/generic.h         |    6 +
 arch/arm/mach-stm/include/mach/gpio.h            |    3 +
 arch/arm/mach-stm/include/mach/imx-regs.h        |    9 +
 arch/arm/mach-stm/include/mach/imx28-regs.h      |   47 ++
 arch/arm/mach-stm/include/mach/iomux-imx28.h     |  552 ++++++++++++++++++++++
 arch/arm/mach-stm/{iomux-imx23.c => iomux-imx.c} |   29 +-
 arch/arm/mach-stm/{reset-imx23.c => reset-imx.c} |    0
 arch/arm/mach-stm/speed-imx23.c                  |   52 +-
 arch/arm/mach-stm/speed-imx28.c                  |  392 +++++++++++++++
 drivers/mci/Kconfig                              |    4 +-
 drivers/mci/stm378x.c                            |  141 +++++-
 drivers/net/fec_imx.c                            |   95 +++-
 drivers/net/fec_imx.h                            |   21 +-
 drivers/serial/Kconfig                           |    2 +-
 drivers/serial/stm-serial.c                      |    9 +-
 drivers/spi/imx_spi.c                            |    3 -
 include/common.h                                 |    9 +
 33 files changed, 1955 insertions(+), 102 deletions(-)
 create mode 100644 arch/arm/boards/karo-tx28/Makefile
 create mode 100644 arch/arm/boards/karo-tx28/config.h
 create mode 100644 arch/arm/boards/karo-tx28/env/config
 create mode 100644 arch/arm/boards/karo-tx28/tx28-stk5.c
 create mode 100644 arch/arm/boards/karo-tx28/tx28.c
 create mode 100644 arch/arm/configs/tx28stk5_defconfig
 create mode 100644 arch/arm/mach-stm/clocksource-imx28.c
 rename arch/arm/mach-stm/{imx23.c => imx.c} (100%)
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx23.h
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx28.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx28-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx28.h
 rename arch/arm/mach-stm/{iomux-imx23.c => iomux-imx.c} (82%)
 rename arch/arm/mach-stm/{reset-imx23.c => reset-imx.c} (100%)
 create mode 100644 arch/arm/mach-stm/speed-imx28.c



From jbe at pengutronix.de  Mon Dec 13 05:53:26 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:26 +0100
Subject: [PATCH 03/14] STM378x: Use Hz as the clock unit like in all other arch
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-4-git-send-email-jbe@pengutronix.de>

i.MX23 currently uses kHz as the unit for its clock handling and calculation
to avoid overflows when calculation with the internal 480 MHz PLL and its
fractional divider. This patch changes all routines to accept Hz and deliver
Hz as the clock unit.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/speed-imx23.c |   49 +++++++++++++++++++--------------------
 drivers/mci/stm378x.c           |   10 ++++----
 drivers/serial/stm-serial.c     |    2 +-
 3 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
index f32ae92..a31139d 100644
--- a/arch/arm/mach-stm/speed-imx23.c
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -29,8 +29,6 @@
 #include <mach/generic.h>
 #include <mach/clock.h>
 
-/* Note: all clock frequencies are returned in kHz */
-
 #define HW_CLKCTRL_PLLCTRL0 0x000
 #define HW_CLKCTRL_PLLCTRL1 0x010
 #define HW_CLKCTRL_CPU 0x20
@@ -84,13 +82,13 @@
 unsigned imx_get_mpllclk(void)
 {
 	/* the main PLL runs at 480 MHz */
-	return 480U * 1000U;
+	return 480000000;
 }
 
 unsigned imx_get_xtalclk(void)
 {
 	/* the external reference runs at 24 MHz */
-	return 24U * 1000U;
+	return 24000000;
 }
 
 /* used for the SDRAM controller */
@@ -105,14 +103,15 @@ unsigned imx_get_emiclk(void)
 	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
 		return imx_get_xtalclk() / GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
 
-	rate = imx_get_mpllclk();
+	rate = imx_get_mpllclk() / 1000;
 	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
 	if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
 		rate *= 18U;
 		rate /= GET_EMIFRAC(reg);
 	}
 
-	return rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+	return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
+			* 1000;
 }
 
 /*
@@ -121,7 +120,7 @@ unsigned imx_get_emiclk(void)
 unsigned imx_get_ioclk(void)
 {
 	uint32_t reg;
-	unsigned rate = imx_get_mpllclk();
+	unsigned rate = imx_get_mpllclk() / 1000;
 
 	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
 	if (reg & CLKCTRL_FRAC_CLKGATEIO)
@@ -129,12 +128,12 @@ unsigned imx_get_ioclk(void)
 
 	rate *= 18U;
 	rate /= GET_IOFRAC(reg);
-	return rate;
+	return rate * 1000;
 }
 
 /**
  * Setup a new frequency to the IOCLK domain.
- * @param nc New frequency in [kHz]
+ * @param nc New frequency in [Hz]
  *
  * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
  */
@@ -143,10 +142,9 @@ unsigned imx_set_ioclk(unsigned nc)
 	uint32_t reg;
 	unsigned div;
 
-	div = imx_get_mpllclk();
-	div *= 18U;
-	div += nc >> 1;
-	div /= nc;
+	nc /= 1000;
+	div = (imx_get_mpllclk() / 1000) * 18;
+	div = DIV_ROUND_CLOSEST(div, nc);
 	if (div > 0x3f)
 		div = 0x3f;
 	/* mask the current settings */
@@ -171,24 +169,25 @@ unsigned imx_get_armclk(void)
 	if (reg & CLKCTRL_FRAC_CLKGATECPU)
 		return 0U;	/* should not possible, shouldn't it? */
 
-	rate = imx_get_mpllclk();
+	rate = imx_get_mpllclk() / 1000;
 	rate *= 18U;
 	rate /= GET_CPUFRAC(reg);
 
-	return rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+	return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
+			* 1000;
 }
 
 /* this is the AHB and APBH bus clock */
 unsigned imx_get_hclk(void)
 {
-	unsigned rate = imx_get_armclk();
+	unsigned rate = imx_get_armclk() / 1000;
 
 	if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
 		rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
 		rate >>= 5U; /* / 32 */
 	} else
 		rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
-	return rate;
+	return rate * 1000;
 }
 
 /*
@@ -219,7 +218,7 @@ unsigned imx_get_sspclk(unsigned index)
 
 /**
  * @param index Unit index (ignored on i.MX23)
- * @param nc New frequency in [kHz]
+ * @param nc New frequency in [Hz]
  * @param high != 0 if ioclk should be the source
  * @return The new possible frequency in [kHz]
  */
@@ -269,11 +268,11 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
 
 void imx_dump_clocks(void)
 {
-	printf("mpll:    %10u kHz\n", imx_get_mpllclk());
-	printf("arm:     %10u kHz\n", imx_get_armclk());
-	printf("ioclk:   %10u kHz\n", imx_get_ioclk());
-	printf("emiclk:  %10u kHz\n", imx_get_emiclk());
-	printf("hclk:    %10u kHz\n", imx_get_hclk());
-	printf("xclk:    %10u kHz\n", imx_get_xclk());
-	printf("ssp:     %10u kHz\n", imx_get_sspclk(0));
+	printf("mpll:    %10u kHz\n", imx_get_mpllclk() / 1000);
+	printf("arm:     %10u kHz\n", imx_get_armclk() / 1000);
+	printf("ioclk:   %10u kHz\n", imx_get_ioclk() / 1000);
+	printf("emiclk:  %10u kHz\n", imx_get_emiclk() / 1000);
+	printf("hclk:    %10u kHz\n", imx_get_hclk() / 1000);
+	printf("xclk:    %10u kHz\n", imx_get_xclk() / 1000);
+	printf("ssp:     %10u kHz\n", imx_get_sspclk(0) / 1000);
 }
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index a2802af..fb74822 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -481,7 +481,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 		return 0;
 	}
 
-	ssp = imx_get_sspclk(0) * 1000;
+	ssp = imx_get_sspclk(0);
 
 	for (div = 2; div < 255; div += 2) {
 		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
@@ -658,20 +658,20 @@ static int stm_mci_probe(struct device_d *hw_dev)
 	host->host_caps = pd->caps;
 
 	if (pd->f_min == 0) {
-		host->f_min = imx_get_sspclk(0) / 254U / 256U * 1000U;
+		host->f_min = imx_get_sspclk(0) / 254U / 256U;
 		pr_debug("Min. frequency is %u Hz\n", host->f_min);
 	} else {
 		host->f_min = pd->f_min;
 		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
-			host->f_min, imx_get_sspclk(0) / 254U / 256U * 1000U);
+			host->f_min, imx_get_sspclk(0) / 254U / 256U);
 	}
 	if (pd->f_max == 0) {
-		host->f_max = imx_get_sspclk(0) / 2U / 1U * 1000U;
+		host->f_max = imx_get_sspclk(0) / 2U / 1U;
 		pr_debug("Max. frequency is %u Hz\n", host->f_max);
 	} else {
 		host->f_max =  pd->f_max;
 		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
-			host->f_max, imx_get_sspclk(0) / 2U / 1U * 1000U);
+			host->f_max, imx_get_sspclk(0) / 2U / 1U);
 	}
 
 #ifdef CONFIG_MCI_INFO
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index 90563f5..3edd484 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -108,7 +108,7 @@ static int stm_serial_setbaudrate(struct console_device *cdev, int new_baudrate)
 	writel(0, dev->map_base + UARTDBGCR);
 
 	/* Calculate and set baudrate */
-	quot = (imx_get_xclk() * 4000) / new_baudrate;
+	quot = (imx_get_xclk() * 4) / new_baudrate;
 	writel(quot & 0x3f, dev->map_base + UARTDBGFBRD);
 	writel(quot >> 6, dev->map_base + UARTDBGIBRD);
 
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:35 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:35 +0100
Subject: [PATCH 12/14] MX28: add FEC support
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-13-git-send-email-jbe@pengutronix.de>

The i.MX28 comes with an extended ethernet controller (ENET/FEC) which
is backwards compatible to the FEC known from other i.MX CPUs. Add a few
adaptions to the existing driver to make it work with the MX28 FEC.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/Kconfig |    1 +
 drivers/net/fec_imx.c     |   92 +++++++++++++++++++++++++++++++++++++-------
 drivers/net/fec_imx.h     |   17 +++++++-
 3 files changed, 93 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 15765fd..9a46138 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -21,6 +21,7 @@ config ARCH_IMX23
 config ARCH_IMX28
 	bool "i.MX28"
 	select CPU_ARM926T
+	select ARCH_HAS_FEC_IMX
 
 endchoice
 
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 91ef929..e63e42e 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -29,10 +29,13 @@
 
 #include <asm/mmu.h>
 #include <asm/io.h>
+#include <mach/generic.h>
 #include <mach/imx-regs.h>
 #include <clock.h>
 #include <mach/clock.h>
-#include <mach/iim.h>
+#ifndef CONFIG_ARCH_STM
+# include <mach/iim.h>
+#endif
 #include <xfuncs.h>
 
 #include "fec_imx.h"
@@ -151,6 +154,39 @@ static int fec_tx_task_disable(struct fec_priv *fec)
 }
 
 /**
+ * Swap endianess to send data on an i.MX28 based platform
+ * @param buf Pointer to little endian data
+ * @param len Size in words (max. 1500 bytes)
+ * @return Pointer to the big endian data
+ */
+static void *imx28_fix_endianess_wr(uint32_t *buf, unsigned wlen)
+{
+	unsigned u;
+	static uint32_t data[376];	/* = 1500 bytes + 4 bytes */
+
+	for (u = 0; u < wlen; u++, buf++)
+		data[u] = __swab32(*buf);
+
+	return data;
+}
+
+/**
+ * Swap endianess to read data on an i.MX28 based platform
+ * @param buf Pointer to little endian data
+ * @param len Size in words (max. 1500 bytes)
+ *
+ * TODO: Check for the risk of destroying some other data behind the buffer
+ * if its size is not a multiple of 4.
+ */
+static void imx28_fix_endianess_rd(uint32_t *buf, unsigned wlen)
+{
+	unsigned u;
+
+	for (u = 0; u < wlen; u++, buf++)
+		*buf = __swab32(*buf);
+}
+
+/**
  * Initialize receive task's buffer descriptors
  * @param[in] fec all we know about the device yet
  * @param[in] count receive buffer count to be allocated
@@ -233,7 +269,11 @@ static void fec_rbd_clean(int last, struct buffer_descriptor __iomem *pRbd)
 
 static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac)
 {
+#ifdef CONFIG_ARCH_STM
+	return -1;
+#else
 	return imx_iim_get_mac(mac);
+#endif
 }
 
 static int fec_set_hwaddr(struct eth_device *dev, unsigned char *mac)
@@ -270,12 +310,13 @@ static int fec_init(struct eth_device *dev)
 		/*
 		 * Frame length=1518; 7-wire mode
 		 */
-		writel((1518 << 16), fec->regs + FEC_R_CNTRL);
+		writel(FEC_R_CNTRL_MAX_FL(1518), fec->regs + FEC_R_CNTRL);
 	} else {
 		/*
 		 * Frame length=1518; MII mode;
 		 */
-		writel((1518 << 16) | (1 << 2), fec->regs + FEC_R_CNTRL);
+		writel(FEC_R_CNTRL_MAX_FL(1518) | FEC_R_CNTRL_MII_MODE,
+			fec->regs + FEC_R_CNTRL);
 		/*
 		 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
 		 * and do not drop the Preamble.
@@ -285,16 +326,26 @@ static int fec_init(struct eth_device *dev)
 	}
 
 	if (fec->xcv_type == RMII) {
-		/* disable the gasket and wait */
-		writel(0, fec->regs + FEC_MIIGSK_ENR);
-		while (readl(fec->regs + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
-			udelay(1);
+		if (cpu_is_mx28()) {
+			/* just another way to enable RMII */
+			uint32_t reg = readl(fec->regs + FEC_R_CNTRL);
+			writel(reg | FEC_R_CNTRL_RMII_MODE
+				/* the linux driver add these bits, why not we? */
+				/* | FEC_R_CNTRL_FCE | */
+				/* FEC_R_CNTRL_NO_LGTH_CHECK */,
+				fec->regs + FEC_R_CNTRL);
+		} else {
+			/* disable the gasket and wait */
+			writel(0, fec->regs + FEC_MIIGSK_ENR);
+			while (readl(fec->regs + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
+				udelay(1);
 
-		/* configure the gasket for RMII, 50 MHz, no loopback, no echo */
-		writel(FEC_MIIGSK_CFGR_IF_MODE_RMII, fec->regs + FEC_MIIGSK_CFGR);
+			/* configure the gasket for RMII, 50 MHz, no loopback, no echo */
+			writel(FEC_MIIGSK_CFGR_IF_MODE_RMII, fec->regs + FEC_MIIGSK_CFGR);
 
-		/* re-enable the gasket */
-		writel(FEC_MIIGSK_ENR_EN, fec->regs + FEC_MIIGSK_ENR);
+			/* re-enable the gasket */
+			writel(FEC_MIIGSK_ENR_EN, fec->regs + FEC_MIIGSK_ENR);
+		}
 	}
 
 	/*
@@ -419,6 +470,9 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length)
 	 * Note: We are always using the first buffer for transmission,
 	 * the second will be empty and only used to stop the DMA engine
 	 */
+	if (cpu_is_mx28())
+		eth_data = imx28_fix_endianess_wr(eth_data, (data_length + 3) >> 2);
+
 	writew(data_length, &fec->tbd_base[fec->tbd_index].data_length);
 
 	writel((uint32_t)(eth_data), &fec->tbd_base[fec->tbd_index].data_pointer);
@@ -483,10 +537,12 @@ static int fec_recv(struct eth_device *dev)
 		printf("some error: 0x%08x\n", ievent);
 		return 0;
 	}
-	if (ievent & FEC_IEVENT_HBERR) {
-		/* Heartbeat error */
-		writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
-				fec->regs + FEC_X_CNTRL);
+	if (!cpu_is_mx28()) {
+		if (ievent & FEC_IEVENT_HBERR) {
+			/* Heartbeat error */
+			writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
+					fec->regs + FEC_X_CNTRL);
+		}
 	}
 	if (ievent & FEC_IEVENT_GRA) {
 		/* Graceful stop complete */
@@ -506,6 +562,12 @@ static int fec_recv(struct eth_device *dev)
 	if (!(bd_status & FEC_RBD_EMPTY)) {
 		if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
 			((readw(&rbd->data_length) - 4) > 14)) {
+
+			if (cpu_is_mx28())
+				imx28_fix_endianess_rd(
+					(void *)readl(&rbd->data_pointer),
+					(readw(&rbd->data_length) + 3) >> 2);
+
 			/*
 			 * Get buffer address and size
 			 */
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index f7fbdc9..e07071a 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -63,8 +63,19 @@
 #define FEC_MIIGSK_ENR_READY		(1 << 2)
 #define FEC_MIIGSK_ENR_EN		(1 << 1)
 
-
-#define FEC_IEVENT_HBERR                0x80000000
+#define FEC_R_CNTRL_GRS			(1 << 31)
+#define FEC_R_CNTRL_NO_LGTH_CHECK	(1 << 30)
+#ifdef CONFIG_ARCH_IMX28
+# define FEC_R_CNTRL_MAX_FL(x)		(((x) & 0x3fff) << 16)
+#else
+# define FEC_R_CNTRL_MAX_FL(x)		(((x) & 0x7ff) << 16)
+#endif
+#define FEC_R_CNTRL_RMII_10T		(1 << 9) /* i.MX28 specific */
+#define FEC_R_CNTRL_RMII_MODE		(1 << 8) /* i.MX28 specific */
+#define FEC_R_CNTRL_FCE			(1 << 5)
+#define FEC_R_CNTRL_MII_MODE		(1 << 2)
+
+#define FEC_IEVENT_HBERR                0x80000000 /* Note: Not on i.MX28 */
 #define FEC_IEVENT_BABR                 0x40000000
 #define FEC_IEVENT_BABT                 0x20000000
 #define FEC_IEVENT_GRA                  0x10000000
@@ -74,7 +85,7 @@
 #define FEC_IEVENT_COL_RETRY_LIM        0x00100000
 #define FEC_IEVENT_XFIFO_UN             0x00080000
 
-#define FEC_IMASK_HBERR                 0x80000000
+#define FEC_IMASK_HBERR                 0x80000000 /* Note: Not on i.MX28 */
 #define FEC_IMASK_BABR                  0x40000000
 #define FEC_IMASK_BABT                  0x20000000
 #define FEC_IMASK_GRA                   0x10000000
@@ -120,6 +131,8 @@
  * @brief Receive & Transmit Buffer Descriptor definitions
  *
  * Note: The first BD must be aligned (see DB_ALIGNMENT)
+ *
+ * BTW: Don't trust the i.MX27 and i.MX28 data sheet
  */
 struct buffer_descriptor {
 	uint16_t data_length;		/**< payload's length in bytes */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:33 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:33 +0100
Subject: [PATCH 10/14] STM378x: Adapt the MCI driver to support i.MX23 and
	i.MX28
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-11-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/mci/Kconfig   |    4 +-
 drivers/mci/stm378x.c |  139 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 124 insertions(+), 19 deletions(-)

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index b1f2773..ee04079 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -28,11 +28,11 @@ config MCI_INFO
 comment "--- MCI host drivers ---"
 
 config MCI_STM378X
-	bool "i.MX23"
+	bool "i.MX23/i.MX28"
 	depends on ARCH_STM
 	help
 	  Enable this entry to add support to read and write SD cards on a
-	  i.MX23 based system.
+	  i.MX23/i.MX28 based system.
 
 config MCI_S3C
 	bool "S3C"
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index fb74822..94b0f4a 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -61,37 +61,77 @@
 # define SSP_CTRL0_LONG_RESP (1 << 19)
 # define SSP_CTRL0_GET_RESP (1 << 17)
 # define SSP_CTRL0_ENABLE (1 << 16)
+#ifdef CONFIG_ARCH_IMX23
 # define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+#endif
 
 #define HW_SSP_CMD0 0x010
 # define SSP_CMD0_SLOW_CLK (1 << 22)
 # define SSP_CMD0_CONT_CLK (1 << 21)
 # define SSP_CMD0_APPEND_8CYC (1 << 20)
+#ifdef CONFIG_ARCH_IMX23
 # define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
 # define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+#endif
 # define SSP_CMD0_CMD(x) ((x) & 0xff)
 
 #define HW_SSP_CMD1 0x020
-#define HW_SSP_COMPREF 0x030
-#define HW_SSP_COMPMASK 0x040
-#define HW_SSP_TIMING 0x050
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_COMPREF 0x030
+# define HW_SSP_COMPMASK 0x040
+# define HW_SSP_TIMING 0x050
+# define HW_SSP_CTRL1 0x060
+# define HW_SSP_DATA 0x070
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_XFER_COUNT 0x30
+# define HW_SSP_BLOCK_SIZE 0x40
+#  define SSP_BLOCK_SIZE(x) ((x) & 0xf)
+#  define SSP_BLOCK_COUNT(x) (((x) & 0xffffff) << 4)
+# define HW_SSP_COMPREF 0x050
+# define HW_SSP_COMPMASK 0x060
+# define HW_SSP_TIMING 0x070
+# define HW_SSP_CTRL1 0x080
+# define HW_SSP_DATA 0x090
+#endif
+/* bit definition for register HW_SSP_TIMING */
 # define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
 # define SSP_TIMING_TIMEOUT(x) ((x) << 16)
 # define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
 # define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
 
-#define HW_SSP_CTRL1 0x060
+/* bit definition for register HW_SSP_CTRL1 */
 # define SSP_CTRL1_POLARITY (1 << 9)
 # define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
 # define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
 
-#define HW_SSP_DATA 0x070
-#define HW_SSP_SDRESP0 0x080
-#define HW_SSP_SDRESP1 0x090
-#define HW_SSP_SDRESP2 0x0A0
-#define HW_SSP_SDRESP3 0x0B0
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_SDRESP0 0x080
+# define HW_SSP_SDRESP1 0x090
+# define HW_SSP_SDRESP2 0x0A0
+# define HW_SSP_SDRESP3 0x0B0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_SDRESP0 0x0A0
+# define HW_SSP_SDRESP1 0x0B0
+# define HW_SSP_SDRESP2 0x0C0
+# define HW_SSP_SDRESP3 0x0D0
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DDR_CTRL 0x0E0
+# define HW_SSP_DLL_CTRL 0x0F0
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_STATUS 0x0C0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_STATUS 0x100
+#endif
 
-#define HW_SSP_STATUS 0x0C0
+/* bit definition for register HW_SSP_STATUS */
 # define SSP_STATUS_PRESENT (1 << 31)
 # define SSP_STATUS_SD_PRESENT (1 << 29)
 # define SSP_STATUS_CARD_DETECT (1 << 28)
@@ -111,11 +151,23 @@
 	SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | \
 	SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
 
-#define HW_SSP_DEBUG 0x100
-#define HW_SSP_VERSION 0x110
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DLL_STS 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_DEBUG 0x100
+# define HW_SSP_VERSION 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DEBUG 0x120
+# define HW_SSP_VERSION 0x130
+#endif
 
 struct stm_mci_host {
 	unsigned	clock;	/* current clock speed in Hz ("0" if disabled) */
+	unsigned	index;
 #ifdef CONFIG_MCI_INFO
 	unsigned	f_min;
 	unsigned	f_max;
@@ -124,6 +176,18 @@ struct stm_mci_host {
 };
 
 /**
+ * Get the SSP clock rate
+ * @param hw_dev Host interface device instance
+ * @return Unit's clock in [Hz]
+ */
+static unsigned get_unit_clock(struct device_d *hw_dev)
+{
+	struct stm_mci_host *host_data = GET_HOST_DATA(hw_dev);
+
+	return imx_get_sspclk(host_data->index);
+}
+
+/**
  * Get MCI cards response if defined for the type of command
  * @param hw_dev Host interface device instance
  * @param cmd Command description
@@ -417,6 +481,7 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
 		xfer_cnt = log2blocksize = block_cnt = 0;
 
 	/* setup command and transfer parameters */
+#ifdef CONFIG_ARCH_IMX23
 	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
 		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
 		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
@@ -430,6 +495,23 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
 		SSP_CMD0_BLOCK_COUNT(block_cnt) |
 		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
 		hw_dev->map_base + HW_SSP_CMD0);
+#endif
+#ifdef CONFIG_ARCH_IMX28
+	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+		SSP_CTRL0_ENABLE,
+		hw_dev->map_base + HW_SSP_CTRL0);
+	writel(xfer_cnt, hw_dev->map_base + HW_SSP_XFER_COUNT);
+
+	/* prepare the command and the transfered data count */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+		hw_dev->map_base + HW_SSP_CMD0);
+	writel(SSP_BLOCK_SIZE(log2blocksize) |
+		SSP_BLOCK_COUNT(block_cnt),
+		hw_dev->map_base + HW_SSP_BLOCK_SIZE);
+#endif
 
 	/* prepare command's arguments */
 	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
@@ -481,7 +563,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 		return 0;
 	}
 
-	ssp = imx_get_sspclk(0);
+	ssp = get_unit_clock(hw_dev);
 
 	for (div = 2; div < 255; div += 2) {
 		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
@@ -657,21 +739,44 @@ static int stm_mci_probe(struct device_d *hw_dev)
 	host->voltages = pd->voltages;
 	host->host_caps = pd->caps;
 
+#ifdef CONFIG_ARCH_IMX23
+	host_data->index = 0;	/* there is only one clock for all */
+#endif
+#ifdef CONFIG_ARCH_IMX28
+	/* one dedicated clock per unit */
+	switch (hw_dev->map_base) {
+	case IMX_SSP0_BASE:
+		host_data->index = 0;
+		break;
+	case IMX_SSP1_BASE:
+		host_data->index = 1;
+		break;
+	case IMX_SSP2_BASE:
+		host_data->index = 2;
+		break;
+	case IMX_SSP3_BASE:
+		host_data->index = 3;
+		break;
+	default:
+		pr_debug("Unknown SSP unit at address 0x%08x\n", hw_dev->map_base);
+		return 0;
+	}
+#endif
 	if (pd->f_min == 0) {
-		host->f_min = imx_get_sspclk(0) / 254U / 256U;
+		host->f_min = get_unit_clock(hw_dev) / 254 / 256;
 		pr_debug("Min. frequency is %u Hz\n", host->f_min);
 	} else {
 		host->f_min = pd->f_min;
 		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
-			host->f_min, imx_get_sspclk(0) / 254U / 256U);
+			host->f_min, get_unit_clock(hw_dev) / 254 / 256);
 	}
 	if (pd->f_max == 0) {
-		host->f_max = imx_get_sspclk(0) / 2U / 1U;
+		host->f_max = get_unit_clock(hw_dev) / 2 / 1;
 		pr_debug("Max. frequency is %u Hz\n", host->f_max);
 	} else {
 		host->f_max =  pd->f_max;
 		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
-			host->f_max, imx_get_sspclk(0) / 2U / 1U);
+			host->f_max, get_unit_clock(hw_dev) / 2 / 1);
 	}
 
 #ifdef CONFIG_MCI_INFO
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:28 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:28 +0100
Subject: [PATCH 05/14] STM378x: Parameterize the max. possible GPIO number
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-6-git-send-email-jbe@pengutronix.de>

This is for easier integration of the i.MX28 architecture (to share the code
later on).

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx23.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
index b0f4046..5d4465e 100644
--- a/arch/arm/mach-stm/iomux-imx23.c
+++ b/arch/arm/mach-stm/iomux-imx23.c
@@ -31,6 +31,8 @@
 #define HW_PINCTRL_DIN0 0x600
 #define HW_PINCTRL_DOE0 0x700
 
+#define MAX_GPIO_NO 95
+
 static uint32_t calc_mux_reg(uint32_t no)
 {
 	/* each register controls 16 pads */
@@ -77,7 +79,7 @@ void imx_gpio_mode(unsigned m)
 	writel(reg, IMX_IOMUXC_BASE + reg_offset);
 
 	/* some pins are disabled when configured for GPIO */
-	if ((gpio_pin > 95) && (GET_FUNC(m) == IS_GPIO)) {
+	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
 		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
 		return;
 	}
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:37 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:37 +0100
Subject: [PATCH 14/14] STM378x: Add the TX28 Starterkit-5 baseboard
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-15-git-send-email-jbe@pengutronix.de>

This file is to be used in conjunction with the TX28 CPU module.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/karo-tx28/Makefile    |    1 +
 arch/arm/boards/karo-tx28/env/config  |   47 +++++++
 arch/arm/boards/karo-tx28/tx28-stk5.c |  229 +++++++++++++++++++++++++++++++++
 arch/arm/boards/karo-tx28/tx28.c      |   37 ++++++
 arch/arm/configs/tx28stk5_defconfig   |   38 ++++++
 arch/arm/mach-stm/Kconfig             |   15 ++
 6 files changed, 367 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/karo-tx28/env/config
 create mode 100644 arch/arm/boards/karo-tx28/tx28-stk5.c
 create mode 100644 arch/arm/configs/tx28stk5_defconfig

diff --git a/arch/arm/boards/karo-tx28/Makefile b/arch/arm/boards/karo-tx28/Makefile
index 6f7e865..d80ba17 100644
--- a/arch/arm/boards/karo-tx28/Makefile
+++ b/arch/arm/boards/karo-tx28/Makefile
@@ -1 +1,2 @@
 obj-y += tx28.o
+obj-$(CONFIG_MACH_TX28STK5) += tx28-stk5.o
diff --git a/arch/arm/boards/karo-tx28/env/config b/arch/arm/boards/karo-tx28/env/config
new file mode 100644
index 0000000..9b302b8
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/env/config
@@ -0,0 +1,47 @@
+#
+#
+
+machine=tx28
+baseboard=tx28stk5
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.ethaddr=de:ad:be:ef:00:00
+#eth0.netmask=a.b.c.d
+#eth0.serverip=a.b.c.d
+#eth0.gateway=a.b.c.d
+
+# can be either 'net'
+kernel_loc=net
+# can be either 'net' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root-$machine.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+if [ -n $user ]; then
+	kernelimage="$user"-"$kernelimage"
+	nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine"
+	rootfsimage="$user"-"$rootfsimage"
+else
+	nfsroot="$eth0.serverip:/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttyAM0,115200 tx28_base=$baseboard"
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
new file mode 100644
index 0000000..a032e6a
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <kernel at pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <mci.h>
+#include <fec.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/mci.h>
+
+static struct stm_mci_platform_data mci_pdata = {
+	.caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz,
+	.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,	/* fixed to 3.3 V */
+	.f_min = 400 * 1000,
+};
+
+static struct device_d mci_socket = {
+	.name = "stm_mci",
+	.map_base = IMX_SSP0_BASE,
+	.platform_data = &mci_pdata,
+};
+
+/* PhyAD[0..2]=0, RMIISEL=1 */
+static struct fec_platform_data fec_info = {
+	.xcv_type = RMII,
+	.phy_addr = 0,
+};
+
+static struct device_d fec_dev = {
+	.name = "fec_imx",
+	.map_base = IMX_FEC0_BASE,
+	.platform_data = &fec_info,
+};
+
+static const uint32_t tx28_starterkit_pad_setup[] = {
+	/*
+	 * Part II of phy's initialization
+	 * Setup phy's mode to '111'
+	 */
+
+	/*
+	 * force the mod pins to a specific level
+	 * '111' means: "All capable. Auto-negotiation enabled".
+	 * For other values refer LAN8710's datasheet,
+	 * chapter "Mode Bus - MODE[2:0]"
+	 */
+	ENET0_RXD0_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD0 */
+	ENET0_RXD1_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD1 */
+	ENET0_RX_EN_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD2 */
+
+	/* release the reset ('mod' pins get latched) */
+	ENET0_RX_CLK_GPIO | VE_3_3V | BITKEEPER(0) | GPIO_OUT | GPIO_VALUE(1),
+
+	/* right now the 'mod' pins are in their native mode */
+	ENET0_RXD0 | VE_3_3V | PULLUP(0),
+	ENET0_RXD1 | VE_3_3V | PULLUP(0),
+	ENET0_RX_EN | VE_3_3V | PULLUP(0),
+
+	/* Debug UART, available at card connector UART1 */
+	AUART0_CTS_DUART_RX | VE_3_3V | STRENGTH(S8MA),
+	AUART0_RTS_DUART_TX | VE_3_3V | STRENGTH(S8MA),
+	AUART0_RX_DUART_CTS | VE_3_3V | STRENGTH(S8MA),
+	AUART0_TX_DUART_RTS | VE_3_3V | STRENGTH(S8MA),
+	/* Application UART, available at connector UART2 */
+	AUART1_RX | VE_3_3V | BITKEEPER(0),
+	AUART1_TX | VE_3_3V | BITKEEPER(0),
+	AUART1_CTS | VE_3_3V | PULLUP(1),
+	AUART1_RTS | VE_3_3V | PULLUP(1),
+	/* Application UART, available at connector FIXME */
+	AUART2_RX | VE_3_3V | PULLUP(1),
+	AUART2_TX | VE_3_3V | PULLUP(1),
+	AUART2_CTS | VE_3_3V | BITKEEPER(0),
+	AUART2_RTS | VE_3_3V | BITKEEPER(0),
+
+	/* MCI interface */
+	SSP0_D0 | VE_3_3V | PULLUP(1),
+	SSP0_D1 | VE_3_3V | PULLUP(1),
+	SSP0_D2 | VE_3_3V | PULLUP(1),
+	SSP0_D3 | VE_3_3V | PULLUP(1),
+	SSP0_CMD | VE_3_3V | PULLUP(1),
+	SSP0_CD | VE_3_3V | PULLUP(1),
+	SSP0_SCK | VE_3_3V | BITKEEPER(0),
+
+	/* MCI slot power control 1 = off */
+	PWM3_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+	/* MCI write protect 1 = not protected */
+	SSP1_SCK_GPIO | VE_3_3V | GPIO_IN,	/* FIXME pull up ? */
+
+	/* LED */
+	ENET0_RXD3_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1),
+
+	/*
+	 * The backlight is on, if:
+	 * - the PWM0 pin outputs a low level
+	 *   * AND *
+	 * - the LCD_ENABLE is at high level.
+	 * In all other combinations the backlight is off.
+	 *
+	 * Switch it off here to avoid flickering.
+	 */
+	PWM0_GPIO | VE_3_3V | PULLUP(0) | GPIO_OUT | GPIO_VALUE(1),
+
+	/* LCD interface to the VGA connector */
+	/* sync signals */
+	LCD_WR_RWN_LCD_HSYNC | VE_3_3V | BITKEEPER(0),
+	LCD_RD_E_LCD_VSYNC | VE_3_3V | BITKEEPER(0),
+	LCD_CS_LCD_ENABLE | VE_3_3V | BITKEEPER(0),
+	LCD_RS_LCD_DOTCLK | VE_3_3V | BITKEEPER(0),
+	/* data signals */
+	LCD_D0 | VE_3_3V | BITKEEPER(0),
+	LCD_D1 | VE_3_3V | BITKEEPER(0),
+	LCD_D2 | VE_3_3V | BITKEEPER(0),
+	LCD_D3 | VE_3_3V | BITKEEPER(0),
+	LCD_D4 | VE_3_3V | BITKEEPER(0),
+	LCD_D5 | VE_3_3V | BITKEEPER(0),
+	LCD_D6 | VE_3_3V | BITKEEPER(0),
+	LCD_D7 | VE_3_3V | BITKEEPER(0),
+	LCD_D8 | VE_3_3V | BITKEEPER(0),
+	LCD_D9 | VE_3_3V | BITKEEPER(0),
+	LCD_D10 | VE_3_3V | BITKEEPER(0),
+	LCD_D11 | VE_3_3V | BITKEEPER(0),
+	LCD_D12 | VE_3_3V | BITKEEPER(0),
+	LCD_D13 | VE_3_3V | BITKEEPER(0),
+	LCD_D14 | VE_3_3V | BITKEEPER(0),
+	LCD_D15 | VE_3_3V | BITKEEPER(0),
+	LCD_D16 | VE_3_3V | BITKEEPER(0),
+	LCD_D17 | VE_3_3V | BITKEEPER(0),
+	LCD_D18 | VE_3_3V | BITKEEPER(0),
+	LCD_D19 | VE_3_3V | BITKEEPER(0),
+	LCD_D20 | VE_3_3V | BITKEEPER(0),
+	LCD_D21 | VE_3_3V | BITKEEPER(0),
+	LCD_D22 | VE_3_3V | BITKEEPER(0),
+	LCD_D23 | VE_3_3V | BITKEEPER(0),
+
+	/* keep display's reset at low */
+	LCD_RESET_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+	/* keep display's power off */
+	LCD_ENABLE_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+};
+
+/**
+ * Try to register an environment storage on the attached MCI card
+ * @return 0 on success
+ *
+ * We rely on the existance of a usable SD card, already attached to
+ * our system, to get a persistent memory for our environment.
+ * If this SD card is also the boot medium, we can use the second partition
+ * for our environment purpose (if present!).
+ */
+static int register_persistent_environment(void)
+{
+	struct cdev *cdev;
+
+	/*
+	 * The TX28 STK5 has only one usable MCI card socket.
+	 * So, we expect its name as "disk0".
+	 */
+	cdev = cdev_by_name("disk0");
+	if (cdev == NULL) {
+		pr_err("No MCI card preset\n");
+		return -ENODEV;
+	}
+
+	/* MCI card is present, also a usable partition on it? */
+	cdev = cdev_by_name("disk0.1");
+	if (cdev == NULL) {
+		pr_err("No second partition available\n");
+		pr_info("Please create at least a second partition with"
+			" 256 kiB...512 kiB in size (your choice)\n");
+		return -ENODEV;
+	}
+
+	/* use the full partition as our persistent environment storage */
+	return devfs_add_partition("disk0.1", 0, cdev->size,
+					DEVFS_PARTITION_FIXED, "env0");
+}
+
+void base_board_init(void)
+{
+	int i, ret;
+
+	/* initialize gpios */
+	for (i = 0; i < ARRAY_SIZE(tx28_starterkit_pad_setup); i++)
+		imx_gpio_mode(tx28_starterkit_pad_setup[i]);
+
+	/* enable IOCLK0 to run at the PLL frequency */
+	imx_set_ioclk(0, 480000000);
+	/* run the SSP unit clock at 100 MHz */
+	imx_set_sspclk(0, 100000000, 1);
+
+	register_device(&mci_socket);
+
+	imx_enable_enetclk();
+	register_device(&fec_dev);
+
+	ret = register_persistent_environment();
+	if (ret != 0)
+		printf("Cannot create the 'env0' persistent environment "
+				"storage (%d)\n", ret);
+}
+
+static struct device_d tx28kit_serial_device = {
+	.name     = "stm_serial",
+	.map_base = IMX_DBGUART_BASE,
+	.size     = 8192,
+};
+
+static int tx28kit_console_init(void)
+{
+	return register_device(&tx28kit_serial_device);
+}
+
+console_initcall(tx28kit_console_init);
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
index d5edf5d..6f4ef4e 100644
--- a/arch/arm/boards/karo-tx28/tx28.c
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -106,6 +106,8 @@ device_initcall(tx28_devices_init);
 /**
 @page tx28 KARO's TX28 CPU module
 
+ at section tx28_cpu_card The CPU module
+
 http://www.karo-electronics.de/
 
 This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
@@ -116,4 +118,39 @@ This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
 - DS1339 RTC
 - LAN8710 Phy
 
+ at section tx28_basboards Supported baseboards
+
+Supported baseboards are:
+- KARO's Starterkit 5
+
+ at section tx28_stk5_howto How to get barebox for 'KARO's Starterkit 5'
+
+Using the default configuration:
+
+ at verbatim
+make ARCH=arm tx28stk5_defconfig
+ at endverbatim
+
+Build the binary image:
+
+ at verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+ at endverbatim
+
+ at note replace the armv5compiler with your ARM v5 cross compiler.
+
+ at note To use the result, you also need the following resources from Freescale:
+- the 'bootlets' archive
+- the 'elftosb2' encryption tool
+- in the case you want to start @b barebox from an attached SD card the
+  'sdimage' tool from Freescale's 'uuc' archive.
+
+ at section tx28_mlayout Memory layout when barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+  - below malloc area: stack area
+  - below barebox: malloc area
+- 0x47000000 start of @b barebox
+
 */
diff --git a/arch/arm/configs/tx28stk5_defconfig b/arch/arm/configs/tx28stk5_defconfig
new file mode 100644
index 0000000..17534f5
--- /dev/null
+++ b/arch/arm/configs/tx28stk5_defconfig
@@ -0,0 +1,38 @@
+CONFIG_ARCH_STM=y
+CONFIG_ARCH_IMX28=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_BROKEN=y
+CONFIG_LONGHELP=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/karo-tx28/env"
+CONFIG_DEBUG_INFO=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+# CONFIG_SPI is not set
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_STM378X=y
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 824b2cf..e47d9f1 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -64,6 +64,21 @@ endif
 
 menu "Board specific settings       "
 
+if MACH_TX28
+
+choice
+	prompt "TX28 Base Board Type"
+
+config MACH_TX28STK5
+	bool "TX28-stk5"
+	help
+	  Select this entry if you are running the TX28 CPU module on the
+	  KARO TX28 Starterkit5.
+
+endchoice
+
+endif
+
 endmenu
 
 endif
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 13 05:53:31 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 13 Dec 2010 11:53:31 +0100
Subject: [PATCH 08/14] STM378x: Add i.MX28 architecture
In-Reply-To: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
References: <1292237617-7064-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292237617-7064-9-git-send-email-jbe@pengutronix.de>

The i.MX28 shares a lot of functionality with its predecessor, the
i.MX23 (formerly known as stm378x). This patch adds some files to support
both CPUs.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/Kconfig                    |    4 +
 arch/arm/mach-stm/Makefile                   |    5 +-
 arch/arm/mach-stm/clocksource-imx28.c        |   73 ++++
 arch/arm/mach-stm/imx.c                      |   35 ++
 arch/arm/mach-stm/imx23.c                    |   35 --
 arch/arm/mach-stm/include/mach/clock-imx28.h |   29 ++
 arch/arm/mach-stm/include/mach/clock.h       |    3 +
 arch/arm/mach-stm/include/mach/generic.h     |    6 +
 arch/arm/mach-stm/include/mach/gpio.h        |    3 +
 arch/arm/mach-stm/include/mach/imx-regs.h    |    9 +
 arch/arm/mach-stm/include/mach/imx28-regs.h  |   47 +++
 arch/arm/mach-stm/include/mach/iomux-imx28.h |  552 ++++++++++++++++++++++++++
 arch/arm/mach-stm/iomux-imx.c                |  136 +++++++
 arch/arm/mach-stm/iomux-imx23.c              |  119 ------
 arch/arm/mach-stm/reset-imx.c                |   61 +++
 arch/arm/mach-stm/reset-imx23.c              |   61 ---
 arch/arm/mach-stm/speed-imx28.c              |  392 ++++++++++++++++++
 17 files changed, 1353 insertions(+), 217 deletions(-)
 create mode 100644 arch/arm/mach-stm/clocksource-imx28.c
 create mode 100644 arch/arm/mach-stm/imx.c
 delete mode 100644 arch/arm/mach-stm/imx23.c
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx28.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx28-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx28.h
 create mode 100644 arch/arm/mach-stm/iomux-imx.c
 delete mode 100644 arch/arm/mach-stm/iomux-imx23.c
 create mode 100644 arch/arm/mach-stm/reset-imx.c
 delete mode 100644 arch/arm/mach-stm/reset-imx23.c
 create mode 100644 arch/arm/mach-stm/speed-imx28.c

diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 021919a..15765fd 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -18,6 +18,10 @@ config ARCH_IMX23
 	bool "i.MX23"
 	select CPU_ARM926T
 
+config ARCH_IMX28
+	bool "i.MX28"
+	select CPU_ARM926T
+
 endchoice
 
 if ARCH_IMX23
diff --git a/arch/arm/mach-stm/Makefile b/arch/arm/mach-stm/Makefile
index 59d70b6..3c7ce09 100644
--- a/arch/arm/mach-stm/Makefile
+++ b/arch/arm/mach-stm/Makefile
@@ -1,2 +1,3 @@
-obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o imx23.o iomux-imx23.o clocksource-imx23.o reset-imx23.o
-
+obj-y += imx.o iomux-imx.o reset-imx.o
+obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o
+obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o
diff --git a/arch/arm/mach-stm/clocksource-imx28.c b/arch/arm/mach-stm/clocksource-imx28.c
new file mode 100644
index 0000000..15ae951
--- /dev/null
+++ b/arch/arm/mach-stm/clocksource-imx28.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel at pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define TIMROTCTRL 0x00
+# define TIMROTCTRL_SFTRST
+# define TIMROTCTRL_CLKGATE
+# define TIMROTCTRL_DIVIDER(x) ((x & 0x3f) << 16)
+
+#define TIMCTRL1 0x60
+#define TIMCTRL1_SET 0x64
+#define TIMCTRL1_CLR 0x68
+#define TIMCTRL1_TOG 0x6c
+# define TIMCTRL_RELOAD (1 << 6)
+# define TIMCTRL_UPDATE (1 << 7)
+# define TIMCTRL_PRESCALE(x) ((x & 0x3) << 4)
+# define TIMCTRL_SELECT(x) (x & 0xf)
+#define TIMCOUNT1 0x70
+#define TIMFIX1 0x80
+
+static const void __iomem * timer_base = (void *)IMX_TIM1_BASE;
+
+/* we are using the 32 kHz reference */
+#define CLOCK_TICK_RATE 32000
+
+static uint64_t imx28_clocksource_read(void)
+{
+	return ~(readl(timer_base + TIMCOUNT1));
+}
+
+static struct clocksource imx28_cs = {
+	.read	= imx28_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.shift	= 17,
+};
+
+static int imx28_clocksource_init(void)
+{
+	/* enable the whole timer block */
+	writel(0x00000000, timer_base + TIMROTCTRL);
+	/* setup start value of the general purpose timer */
+	writel(0x00000000, timer_base + TIMCTRL1);
+	writel(TIMCTRL_UPDATE, timer_base + TIMCTRL1);
+	/* setup the reload value of the general purpose timer */
+	writel(0xffffffff, timer_base + TIMFIX1);
+
+	writel(TIMCTRL_UPDATE | TIMCTRL_RELOAD | TIMCTRL_PRESCALE(0) |
+			TIMCTRL_SELECT(0xb), timer_base + TIMCTRL1);
+	imx28_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, imx28_cs.shift);
+	init_clock(&imx28_cs);
+
+	return 0;
+}
+
+core_initcall(imx28_clocksource_init);
diff --git a/arch/arm/mach-stm/imx.c b/arch/arm/mach-stm/imx.c
new file mode 100644
index 0000000..14a4249
--- /dev/null
+++ b/arch/arm/mach-stm/imx.c
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+extern void imx_dump_clocks(void);
+
+static int do_clocks(struct command *cmdtp, int argc, char *argv[])
+{
+	imx_dump_clocks();
+
+	return 0;
+}
+
+BAREBOX_CMD_START(dump_clocks)
+	.cmd		= do_clocks,
+	.usage		= "show clock frequencies",
+BAREBOX_CMD_END
diff --git a/arch/arm/mach-stm/imx23.c b/arch/arm/mach-stm/imx23.c
deleted file mode 100644
index 14a4249..0000000
--- a/arch/arm/mach-stm/imx23.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * 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, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <command.h>
-
-extern void imx_dump_clocks(void);
-
-static int do_clocks(struct command *cmdtp, int argc, char *argv[])
-{
-	imx_dump_clocks();
-
-	return 0;
-}
-
-BAREBOX_CMD_START(dump_clocks)
-	.cmd		= do_clocks,
-	.usage		= "show clock frequencies",
-BAREBOX_CMD_END
diff --git a/arch/arm/mach-stm/include/mach/clock-imx28.h b/arch/arm/mach-stm/include/mach/clock-imx28.h
new file mode 100644
index 0000000..afc9fb6
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx28.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#ifndef MACH_CLOCK_IMX28_H
+#define MACH_CLOCK_IMX28_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(unsigned);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned, unsigned);
+unsigned imx_get_fecclk(void);
+void imx_enable_enetclk(void);
+
+#endif /* MACH_CLOCK_IMX28_H */
+
diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h
index 5200e89..bd1fa7c 100644
--- a/arch/arm/mach-stm/include/mach/clock.h
+++ b/arch/arm/mach-stm/include/mach/clock.h
@@ -23,5 +23,8 @@
 #if defined CONFIG_ARCH_IMX23
 # include <mach/clock-imx23.h>
 #endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/clock-imx28.h>
+#endif
 
 #endif /* __MACH_CLOCK_H */
diff --git a/arch/arm/mach-stm/include/mach/generic.h b/arch/arm/mach-stm/include/mach/generic.h
index 3a552a8..50f25c5 100644
--- a/arch/arm/mach-stm/include/mach/generic.h
+++ b/arch/arm/mach-stm/include/mach/generic.h
@@ -22,3 +22,9 @@
 #else
 # define cpu_is_mx23()	(0)
 #endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define cpu_is_mx28()	(1)
+#else
+# define cpu_is_mx28()	(0)
+#endif
diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
index fa8263c..5615b67 100644
--- a/arch/arm/mach-stm/include/mach/gpio.h
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -23,6 +23,9 @@
 #if defined CONFIG_ARCH_IMX23
 # include <mach/iomux-imx23.h>
 #endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/iomux-imx28.h>
+#endif
 
 void imx_gpio_mode(unsigned);
 
diff --git a/arch/arm/mach-stm/include/mach/imx-regs.h b/arch/arm/mach-stm/include/mach/imx-regs.h
index 40dc742..9b33a06 100644
--- a/arch/arm/mach-stm/include/mach/imx-regs.h
+++ b/arch/arm/mach-stm/include/mach/imx-regs.h
@@ -20,8 +20,17 @@
 #ifndef _IMX_REGS_H
 # define _IMX_REGS_H
 
+/* Note: Some registers do not support this bit change feature! */
+#define BIT_SET 0x04
+#define BIT_CLR 0x08
+#define BIT_TGL 0x0C
+
 #if defined CONFIG_ARCH_IMX23
 # include <mach/imx23-regs.h>
 #endif
 
+#if defined CONFIG_ARCH_IMX28
+# include <mach/imx28-regs.h>
+#endif
+
 #endif /* _IMX_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/imx28-regs.h b/arch/arm/mach-stm/include/mach/imx28-regs.h
new file mode 100644
index 0000000..0c97c4c
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx28-regs.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MX28_REGS_H
+#define __ASM_ARCH_MX28_REGS_H
+
+/*
+ * sanity check
+ */
+#ifndef _IMX_REGS_H
+# error "Please do not include directly. Use imx-regs.h instead."
+#endif
+
+#define IMX_SRAM_BASE		0x00000000
+#define IMX_MEMORY_BASE		0x40000000
+
+#define IMX_NFC_BASE		0x8000C000
+#define IMX_SSP0_BASE		0x80010000
+#define IMX_SSP1_BASE		0x80012000
+#define IMX_SSP2_BASE		0x80014000
+#define IMX_SSP3_BASE		0x80016000
+#define IMX_IOMUXC_BASE		0x80018000
+#define IMX_FB_BASE		0x80030000
+#define IMX_CCM_BASE		0x80040000
+#define IMX_WDT_BASE		0x80056000
+#define IMX_I2C0_BASE		0x80058000
+#define IMX_I2C1_BASE		0x8005a000
+#define IMX_TIM1_BASE		0x80068000
+#define IMX_UART0_BASE		0x8006a000
+#define IMX_UART1_BASE		0x8006c000
+#define IMX_UART2_BASE		0x8006e000
+#define IMX_UART3_BASE		0x80070000
+#define IMX_UART4_BASE		0x80072000
+#define IMX_DBGUART_BASE	0x80074000
+#define IMX_FEC0_BASE		0x800F0000
+#define IMX_FEC1_BASE		0x800F4000
+
+#endif /* __ASM_ARCH_MX28_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/iomux-imx28.h b/arch/arm/mach-stm/include/mach/iomux-imx28.h
new file mode 100644
index 0000000..1e6d421
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/iomux-imx28.h
@@ -0,0 +1,552 @@
+/*
+ * 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.
+ */
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ *                            ^^^^^_ Bit offset
+ *                         ^^^______ Register Number
+ *                       ^^_________ Function
+ *                      ^___________ Drive strength feature present
+ *                     ^____________ Pull up / bit keeper present
+ *                   ^^_____________ Drive strength setting
+ *                  ^_______________ Pull up / bit keeper setting
+ *                 ^________________ Voltage select present
+ *                ^_________________ Voltage selection
+ *            ^_____________________ direction if enabled as GPIO (1 = output)
+ *           ^______________________ initial output value if enabled as GPIO
+ *                                   and configured as output
+ */
+#ifndef __MACH_IOMUX_IMX28_H
+#define __MACH_IOMUX_IMX28_H
+
+/* control pad's function */
+#define FBANK_SHIFT (5)
+#define PORTF(bank,bit)	(((bank) << FBANK_SHIFT) | (bit))
+#define GET_GPIO_NO(x) ((x) & 0xff)
+#define FUNC_SHIFT 8
+#define FUNC(x)	((x) << FUNC_SHIFT)
+#define GET_FUNC(x) (((x) >> FUNC_SHIFT) & 3)
+#define IS_GPIO (3)
+
+/* control pad's GPIO feature if enabled */
+#define GPIO_OUT (1 << 20)
+#define GPIO_VALUE(x) ((x) << 21)
+#define GPIO_IN (0 << 20)
+#define GET_GPIODIR(x) (!!((x) & (1 << 20)))
+#define GET_GPIOVAL(x) (!!((x) & (1 << 21)))
+
+/* control pad's drive strength */
+#define SE (1 << 10)
+#define SE_PRESENT(x) (!!((x) & SE))
+#define STRENGTH(x) ((x) << 12)
+#define S4MA 0	/* used to define a 4 mA drive strength */
+#define S8MA 1	/* used to define a 8 mA drive strength */
+#define S12MA 2	/* used to define a 12 mA drive strength */
+#define S16MA 3	/* used to define a 16 mA drive strength,
+		   not all pads can drive this current! */
+#define GET_STRENGTH(x) (((x) >> 12) & 0x3)
+
+/* control pad's pull up / bit keeper feature */
+#define PE (1 << 11)
+#define BK (1 << 11)	/* FIXME useful to distinguish? */
+#define PE_PRESENT(x) (!!((x) & PE))
+#define BK_PRESENT(x) (!!((x) & BK))
+#define PULLUP(x) ((x) << 14)
+#define BITKEEPER(x) ((x) << 14)
+#define GET_PULLUP(x) (!!((x) & PULLUP(1)))
+#define GET_BITKEEPER(x) (!!((x) & BITKEEPER(1)))
+
+/* control pad's voltage feature */
+#define VE (1 << 15)
+#define VE_PRESENT(x) (!!((x) & VE))
+#define VE_1_8V (0 << 16)
+#define VE_3_3V (1 << 16)
+#define GET_VOLTAGE(x) (!!((x) & (1 << 16)))
+
+/* Bank 0, GPIO pins 0 ... 31 */
+#define GPMI_RESETN		(FUNC(0) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_RESETN_SSP3_CMD	(FUNC(1) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_RESETN_GPIO	(FUNC(3) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_CLE		(FUNC(0) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_SSP3_D2	(FUNC(1) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_SSP3_D5	(FUNC(2) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_GPIO		(FUNC(3) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_ALE		(FUNC(0) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_SSP3_D1	(FUNC(1) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_SSP3_D4	(FUNC(2) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_GPIO		(FUNC(3) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_WRN		(FUNC(0) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_WRN_SSP1_SCK	(FUNC(1) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_WRN_GPIO		(FUNC(3) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_RDN		(FUNC(0) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_RDN_SSP3_SCK	(FUNC(1) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_RDN_GPIO		(FUNC(3) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_READY3		(FUNC(0) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_CAN0_RX	(FUNC(1) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_HSDAC_TRIG	(FUNC(2) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_GPIO	(FUNC(3) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY2		(FUNC(0) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_CAN0_TX	(FUNC(1) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_ENET0_TX_ER	(FUNC(2) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_GPIO	(FUNC(3) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY1		(FUNC(0) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY1_SSP1_CMD	(FUNC(1) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY1_GPIO	(FUNC(3) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY0		(FUNC(0) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_SSP1_CD	(FUNC(1) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_USB0_ID	(FUNC(2) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_GPIO	(FUNC(3) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_CE3N		(FUNC(0) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_CAN1_RX	(FUNC(1) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_SAIF1_MCLK	(FUNC(2) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_GPIO		(FUNC(3) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE2N		(FUNC(0) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_CAN1_TX	(FUNC(1) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_ENET0_RX_ER	(FUNC(2) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_GPIO		(FUNC(3) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE1N		(FUNC(0) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE1N_SSP3_D3	(FUNC(1) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE1N_GPIO		(FUNC(3) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE0N		(FUNC(0) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_CE0N_SSP3_D0	(FUNC(1) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_CE0N_GPIO		(FUNC(3) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_D7			(FUNC(0) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D7_SSP1_D7		(FUNC(1) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D7_GPIO		(FUNC(3) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D6			(FUNC(0) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D6_SSP1_D6		(FUNC(1) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D6_GPIO		(FUNC(3) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D5			(FUNC(0) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D5_SSP1_D5		(FUNC(1) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D5_GPIO		(FUNC(3) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D4			(FUNC(0) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D4_SSP1_D4		(FUNC(1) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D4_GPIO		(FUNC(3) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D3			(FUNC(0) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D3_SSP1_D3		(FUNC(1) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D3_GPIO		(FUNC(3) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D2			(FUNC(0) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D2_SSP1_D2		(FUNC(1) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D2_GPIO		(FUNC(3) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D1			(FUNC(0) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D1_SSP1_D1		(FUNC(1) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D1_GPIO		(FUNC(3) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D0			(FUNC(0) | PORTF(0, 0) | SE | VE | PE)
+#define GPMI_D0_SSP1_D0		(FUNC(1) | PORTF(0, 0) | SE | VE | PE)
+#define GPMI_D0_GPIO		(FUNC(3) | PORTF(0, 0) | SE | VE | PE)
+
+/* Bank 1, GPIO pins 32 ... 63 */
+
+#define LCD_ENABLE		(FUNC(0) | PORTF(1, 31) | SE | VE | BK)
+#define LCD_ENABLE_GPIO		(FUNC(3) | PORTF(1, 31) | SE | VE | BK)
+
+#define LCD_DOTCLK		(FUNC(0) | PORTF(1, 30) | SE | VE | BK)
+
+#define LCD_HSYNC		(FUNC(0) | PORTF(1, 29) | SE | VE | BK)
+
+#define LCD_VSYNC		(FUNC(0) | PORTF(1, 28) | SE | VE | BK)
+
+#define LCD_CS			(FUNC(0) | PORTF(1, 27) | SE | VE | BK)
+#define LCD_CS_LCD_ENABLE	(FUNC(1) | PORTF(1, 27) | SE | VE | BK)
+#define LCD_CS_GPIO		(FUNC(3) | PORTF(1, 27) | SE | VE | BK)
+
+#define LCD_RS			(FUNC(0) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_RS_LCD_DOTCLK	(FUNC(1) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_RS_GPIO		(FUNC(3) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_WR_RWN		(FUNC(0) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_LCD_HSYNC	(FUNC(1) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_ETM_TCLK	(FUNC(2) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_GPIO		(FUNC(3) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_RD_E		(FUNC(0) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_LCD_VSYNC	(FUNC(1) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_ETM_TCTL	(FUNC(2) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_GPIO		(FUNC(3) | PORTF(1, 24) | SE | VE | BK)
+
+#define LCD_D23			(FUNC(0) | PORTF(1, 23) | SE | VE | BK)
+
+#define LCD_D22			(FUNC(0) | PORTF(1, 22) | SE | VE | BK)
+
+#define LCD_D21			(FUNC(0) | PORTF(1, 21) | SE | VE | BK)
+
+#define LCD_D20			(FUNC(0) | PORTF(1, 20) | SE | VE | BK)
+
+#define LCD_D19			(FUNC(0) | PORTF(1, 19) | SE | VE | BK)
+
+#define LCD_D18			(FUNC(0) | PORTF(1, 18) | SE | VE | BK)
+
+#define LCD_D17			(FUNC(0) | PORTF(1, 17) | SE | VE | BK)
+
+#define LCD_D16			(FUNC(0) | PORTF(1, 16) | SE | VE | BK)
+
+#define LCD_D15			(FUNC(0) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D15_ETM_DA15	(FUNC(2) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D15_GPIO		(FUNC(3) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D14			(FUNC(0) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D14_ETM_DA14	(FUNC(2) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D14_GPIO		(FUNC(3) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D13			(FUNC(0) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D13_ETM_DA13	(FUNC(2) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D13_GPIO		(FUNC(3) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D12			(FUNC(0) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D12_ETM_DA12	(FUNC(2) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D12_GPIO		(FUNC(3) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D11			(FUNC(0) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D11_ETM_DA11	(FUNC(2) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D11_GPIO		(FUNC(3) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D10			(FUNC(0) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D10_ETM_DA10	(FUNC(2) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D10_GPIO		(FUNC(3) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D9			(FUNC(0) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_ETM_DA4		(FUNC(1) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_ETM_DA9		(FUNC(2) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_GPIO		(FUNC(3) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D8			(FUNC(0) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_ETM_DA3		(FUNC(1) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_ETM_DA8		(FUNC(2) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_GPIO		(FUNC(3) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D7			(FUNC(0) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D7_ETM_DA7		(FUNC(2) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D7_GPIO		(FUNC(3) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D6			(FUNC(0) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D6_ETM_DA6		(FUNC(2) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D6_GPIO		(FUNC(3) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D5			(FUNC(0) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D5_ETM_DA5		(FUNC(2) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D5_GPIO		(FUNC(3) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D4			(FUNC(0) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_ETM_DA9		(FUNC(1) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_ETM_DA4		(FUNC(2) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_GPIO		(FUNC(3) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D3			(FUNC(0) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_ETM_DA8		(FUNC(1) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_ETM_DA3		(FUNC(2) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_GPIO		(FUNC(3) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D2			(FUNC(0) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D2_ETM_DA2		(FUNC(2) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D2_GPIO		(FUNC(3) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D1			(FUNC(0) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D1_ETM_DA1		(FUNC(2) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D1_GPIO		(FUNC(3) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D0			(FUNC(0) | PORTF(1, 0) | SE | VE | BK)
+#define LCD_D0_ETM_DA0		(FUNC(2) | PORTF(1, 0) | SE | VE | BK)
+#define LCD_D0_GPIO		(FUNC(3) | PORTF(1, 0) | SE | VE | BK)
+
+/* TODO */
+
+/* Bank 2, GPIO pins 64 ... 95 */
+
+/* TODO */
+
+#define SSP1_D3			(FUNC(0) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D3_SSP2_D7		(FUNC(1) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D3_ENET_1588_EVENT3_IN (FUNC(2) | PORTF(4, 15) | SE | VE | PE)
+#define SSP1_D3_GPIO		(FUNC(3) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D0			(FUNC(0) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_SSP2_D6		(FUNC(1) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_ENET_1588_EVENT3_OUT (FUNC(2) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_GPIO		(FUNC(3) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_CMD		(FUNC(0) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_SSP2_D2	(FUNC(1) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_ENET_1588_EVENT2_IN (FUNC(2) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_GPIO		(FUNC(3) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_SCK		(FUNC(0) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_SSP2_D1	(FUNC(1) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_ENET_1588_EVENT2_OUT (FUNC(2) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_GPIO		(FUNC(3) | PORTF(2, 12) | SE | VE | PE)
+#define SSP0_SCK		(FUNC(0) | PORTF(2, 10) | SE | VE | BK)
+#define SSP0_SCK_GPIO		(FUNC(3) | PORTF(2, 10) | SE | VE | BK)
+#define SSP0_CD			(FUNC(0) | PORTF(2, 9) | SE | VE | PE)
+#define SSP0_CD_GPIO		(FUNC(3) | PORTF(2, 9) | SE | VE | PE)
+#define SSP0_CMD		(FUNC(0) | PORTF(2, 8) | SE | VE | PE)
+#define SSP0_CMD_GPIO		(FUNC(3) | PORTF(2, 8) | SE | VE | PE)
+#define SSP0_D7			(FUNC(0) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D7_SSP2_SCK	(FUNC(1) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D7_GPIO		(FUNC(3) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D6			(FUNC(0) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D6_SSP2_CMD	(FUNC(1) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D6_GPIO		(FUNC(3) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D5			(FUNC(0) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D5_SSP2_D3		(FUNC(1) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D5_GPIO		(FUNC(3) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D4			(FUNC(0) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D4_SSP2_D0		(FUNC(1) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D4_GPIO		(FUNC(3) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D3			(FUNC(0) | PORTF(2, 3) | SE | VE | PE)
+#define SSP0_D3_GPIO		(FUNC(3) | PORTF(2, 3) | SE | VE | PE)
+#define SSP0_D2			(FUNC(0) | PORTF(2, 2) | SE | VE | PE)
+#define SSP0_D2_GPIO		(FUNC(3) | PORTF(2, 2) | SE | VE | PE)
+#define SSP0_D1			(FUNC(0) | PORTF(2, 1) | SE | VE | PE)
+#define SSP0_D1_GPIO		(FUNC(3) | PORTF(2, 1) | SE | VE | PE)
+#define SSP0_D0			(FUNC(0) | PORTF(2, 0) | SE | VE | PE)
+#define SSP0_D0_GPIO		(FUNC(3) | PORTF(2, 0) | SE | VE | PE)
+
+/* Bank 3, GPIO pins 96 ... 127 */
+
+#define LCD_RESET		(FUNC(0) | PORTF(3, 30))
+#define LCD_RESET_LCD_VSYNC	(FUNC(1) | PORTF(3, 30))
+#define LCD_RESET_GPIO		(FUNC(3) | PORTF(3, 30))
+#define PWM4			(FUNC(0) | PORTF(3, 29))
+#define PWM4_GPIO		(FUNC(3) | PORTF(3, 29))
+#define PWM3			(FUNC(0) | PORTF(3 28))
+#define PWM3_GPIO		(FUNC(3) | PORTF(3, 28))
+
+#define PWM2			(FUNC(0) | PORTF(3, 18))
+
+#define PWM1			(FUNC(0) | PORTF(3, 17))
+
+#define PWM0			(FUNC(0) | PORTF(3, 16))
+#define PWM0_I2C1_SCL		(FUNC(1) | PORTF(3, 16))
+#define PWM0_DUART_RX		(FUNC(2) | PORTF(3, 16))
+#define PWM0_GPIO		(FUNC(3) | PORTF(3, 16))
+#define AUART3_RTS		(FUNC(0) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_CAN1_RX	(FUNC(1) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_ENET0_1588_EVENT1_IN	(FUNC(2) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_GPIO		(FUNC(3) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_CTS		(FUNC(0) | PORTF(3, 14) | SE | VE | BK | BK)
+#define AUART3_CTS_CAN1_TX	(FUNC(1) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_CTS_ENET0_1588_EVENT1_OUT (FUNC(2) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_CTS_GPIO		(FUNC(3) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_TX		(FUNC(0) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_CAN0_RX	(FUNC(1) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_ENET0_1588_EVENT0_IN	(FUNC(2) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_GPIO		(FUNC(3) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_RX		(FUNC(0) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_CAN0_TX	(FUNC(1) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_ENET0_1588_EVENT0_OUT	(FUNC(2) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_GPIO		(FUNC(3) | PORTF(3, 12) | SE | VE | BK)
+#define AUART2_RTS		(FUNC(0) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_I2C1_SDA	(FUNC(1) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_SAIF1_IRCLK	(FUNC(2) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_GPIO		(FUNC(3) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_CTS		(FUNC(0) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_I2C1_SCL	(FUNC(1) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_SAIF1_BITCLK	(FUNC(2) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_GPIO		(FUNC(3) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_TX		(FUNC(0) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_SSP3_D2	(FUNC(1) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_SSP3_D5	(FUNC(2) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_GPIO		(FUNC(3) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_RX		(FUNC(0) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_SSP3_D1	(FUNC(1) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_SSP3_D4	(FUNC(2) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_GPIO		(FUNC(3) | PORTF(3, 8) | SE | VE | PE)
+#define AUART1_RTS		(FUNC(0) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_USB0_ID	(FUNC(1) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_ROTARYB	(FUNC(2) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_GPIO		(FUNC(3) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_CTS		(FUNC(0) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_USB0_OC	(FUNC(1) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_ROTARYA	(FUNC(2) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_GPIO		(FUNC(3) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_TX		(FUNC(0) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_SSP3_CD	(FUNC(1) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_PWM1		(FUNC(2) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_GPIO		(FUNC(3) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_RX		(FUNC(0) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_SSP2_CD	(FUNC(1) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_PWM0		(FUNC(2) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_GPIO		(FUNC(3) | PORTF(3, 4) | SE | VE | BK)
+#define AUART0_RTS		(FUNC(0) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_AUART4_TX	(FUNC(1) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_DUART_TX	(FUNC(2) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_GPIO		(FUNC(3) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_CTS		(FUNC(0) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_AUART4_RX	(FUNC(1) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_DUART_RX	(FUNC(2) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_GPIO		(FUNC(3) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_TX		(FUNC(0) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_I2C0_SDA	(FUNC(1) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_DUART_RTS	(FUNC(2) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_GPIO		(FUNC(3) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_RX		(FUNC(0) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_I2C0_SCL	(FUNC(1) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_DUART_CTS	(FUNC(2) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_GPIO		(FUNC(3) | PORTF(3, 0) | SE | VE | BK)
+
+/* Bank 4, GPIO pins 128 ... 159 */
+
+#define JTAG_RTCK		(FUNC(0) | PORTF(4, 20) | SE | VE | BK)
+#define JTAG_RTCK_GPIO		(FUNC(3) | PORTF(4, 20) | SE | VE | BK)
+#define ENET_CLK		(FUNC(0) | PORTF(4, 16) | SE | VE | BK)
+#define ENET_CLK_GPIO		(FUNC(3) | PORTF(4, 16) | SE | VE | BK)
+
+#define ENET0_CRS		(FUNC(0) | PORTF(4, 15) | SE | VE | BK)
+
+#define ENET0_COL		(FUNC(0) | PORTF(4, 14) | SE | VE | BK)
+
+#define ENET0_RX_CLK		(FUNC(0) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_CLK_RX_ER	(FUNC(1) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_ENET0_1588_EVENT2_IN (FUNC(2) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_CLK_GPIO	(FUNC(3) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_TXD3		(FUNC(0) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_ENET1_TXD1	(FUNC(1) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_ENET0_1588_EVENT1_IN (FUNC(2) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_GPIO		(FUNC(3) | PORTF(4, 12) | SE | VE | BK)
+
+#define ENET0_TXD2		(FUNC(0) | PORTF(4, 11) | SE | VE | BK)
+
+#define ENET0_TXD2_GPIO		(FUNC(3) | PORTF(4, 11) | SE | VE | BK)
+
+#define ENET0_RXD3		(FUNC(0) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_ENET1_RXD1	(FUNC(1) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_ENET0_1588_EVENT0_IN (FUNC(2) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_GPIO		(FUNC(3) | PORTF(4, 10) | SE | VE | BK)
+
+#define ENET0_RXD2		(FUNC(0) | PORTF(4, 9) | SE | VE | BK)
+
+#define ENET0_RXD2_GPIO		(FUNC(3) | PORTF(4, 9) | SE | VE | BK)
+
+#define ENET0_TXD1		(FUNC(0) | PORTF(4, 8) | SE | VE | PE)
+
+#define ENET0_TXD1_GPIO		(FUNC(3) | PORTF(4, 8) | SE | VE | PE)
+
+#define ENET0_TXD0		(FUNC(0) | PORTF(4, 7) | SE | VE | PE)
+
+#define ENET0_TXD0_GPIO		(FUNC(3) | PORTF(4, 7) | SE | VE | PE)
+
+#define ENET0_TX_EN		(FUNC(0) | PORTF(4, 6) | SE | VE | PE)
+
+#define ENET0_TX_EN_GPIO	(FUNC(3) | PORTF(4, 6) | SE | VE | PE)
+
+#define ENET0_TX_CLK		(FUNC(0) | PORTF(4, 5) | SE | VE | BK)
+
+#define ENET0_TX_CLK_GPIO	(FUNC(3) | PORTF(4, 5) | SE | VE | BK)
+
+#define ENET0_RXD1		(FUNC(0) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD1_GPMI_READY4	(FUNC(1) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD1_GPIO		(FUNC(3) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD0		(FUNC(0) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_GPMI_CE7N	(FUNC(1) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_SAIF1_SDATA2	(FUNC(2) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_GPIO		(FUNC(3) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RX_EN		(FUNC(0) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_GPMI_CE6N	(FUNC(1) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_SAIF1_SDATA1 (FUNC(2) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_GPIO	(FUNC(3) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_MDIO		(FUNC(0) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_GPMI_CE5N	(FUNC(1) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_SAIF0_SDATA2	(FUNC(2) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_GPIO		(FUNC(3) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDC		(FUNC(0) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_GPMI_CE4N	(FUNC(1) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_SAIF0_SDATA1	(FUNC(2) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_GPIO		(FUNC(3) | PORTF(4, 0) | SE | VE | PE)
+
+/*
+ * Bank 5, GPIO pins 160 ... 191
+ * Note: These pins are disabled instead of being GPIOs
+ */
+#define EMI_DDR_OPEN		(FUNC(0) | PORTF(5, 26) | BK)
+#define EMI_DDR_OPEN_OFF	(FUNC(3) | PORTF(5, 26) | BK)
+#define EMI_DSQ1		(FUNC(0) | PORTF(5, 23) | BK)
+#define EMI_DSQ1_OFF		(FUNC(3) | PORTF(5, 23) | BK)
+#define EMI_DSQ0		(FUNC(0) | PORTF(5, 22) | BK)
+#define EMI_DSQ0_OFF		(FUNC(3) | PORTF(5, 22) | BK)
+#define EMI_CLK			(FUNC(0) | PORTF(5, 21) | BK)
+#define EMI_CLK_OFF		(FUNC(3) | PORTF(5, 21) | BK)
+#define EMI_DDR_OPEN_FB		(FUNC(0) | PORTF(5, 20) | BK)
+#define EMI_DDR_OPEN_FB_OFF	(FUNC(3) | PORTF(5, 20) | BK)
+#define EMI_DQM1		(FUNC(0) | PORTF(5, 19) | BK)
+#define EMI_DQM1_OFF		(FUNC(3) | PORTF(5, 19) | BK)
+#define EMI_ODT1		(FUNC(0) | PORTF(5, 18) | BK)
+#define EMI_ODT1_OFF		(FUNC(3) | PORTF(5, 18) | BK)
+#define EMI_DQM0		(FUNC(0) | PORTF(5, 17) | BK)
+#define EMI_DQM0_OFF		(FUNC(3) | PORTF(5, 17) | BK)
+#define EMI_ODT0		(FUNC(0) | PORTF(5, 16) | BK)
+#define EMI_ODT0_OFF		(FUNC(3) | PORTF(5, 16) | BK)
+#define EMI_DATA15		(FUNC(0) | PORTF(5, 15) | BK)
+#define EMI_DATA15_OFF		(FUNC(3) | PORTF(5, 15) | BK)
+#define EMI_DATA14		(FUNC(0) | PORTF(5, 14) | BK)
+#define EMI_DATA14_OFF		(FUNC(3) | PORTF(5, 14) | BK)
+#define EMI_DATA13		(FUNC(0) | PORTF(5, 13) | BK)
+#define EMI_DATA13_OFF		(FUNC(3) | PORTF(5, 13) | BK)
+#define EMI_DATA12		(FUNC(0) | PORTF(5, 12) | BK)
+#define EMI_DATA12_OFF		(FUNC(3) | PORTF(5, 12) | BK)
+#define EMI_DATA11		(FUNC(0) | PORTF(5, 11) | BK)
+#define EMI_DATA10_OFF		(FUNC(3) | PORTF(5, 10) | BK)
+#define EMI_DATA10		(FUNC(0) | PORTF(5, 10) | BK)
+#define EMI_DATA10_OFF		(FUNC(3) | PORTF(5, 10) | BK)
+#define EMI_DATA9		(FUNC(0) | PORTF(5, 9) | BK)
+#define EMI_DATA9_OFF		(FUNC(3) | PORTF(5, 9) | BK)
+#define EMI_DATA8		(FUNC(0) | PORTF(5, 8) | BK)
+#define EMI_DATA8_OFF		(FUNC(3) | PORTF(5, 8) | BK)
+#define EMI_DATA7		(FUNC(0) | PORTF(5, 7) | BK)
+#define EMI_DATA7_OFF		(FUNC(3) | PORTF(5, 7) | BK)
+#define EMI_DATA6		(FUNC(0) | PORTF(5, 6) | BK)
+#define EMI_DATA6_OFF		(FUNC(3) | PORTF(5, 6) | BK)
+#define EMI_DATA5		(FUNC(0) | PORTF(5, 5) | BK)
+#define EMI_DATA5_OFF		(FUNC(3) | PORTF(5, 5) | BK)
+#define EMI_DATA4		(FUNC(0) | PORTF(5, 4) | BK)
+#define EMI_DATA4_OFF		(FUNC(3) | PORTF(5, 4) | BK)
+#define EMI_DATA3		(FUNC(0) | PORTF(5, 3) | BK)
+#define EMI_DATA3_OFF		(FUNC(3) | PORTF(5, 3) | BK)
+#define EMI_DATA2		(FUNC(0) | PORTF(5, 2) | BK)
+#define EMI_DATA2_OFF		(FUNC(3) | PORTF(5, 2) | BK)
+#define EMI_DATA1		(FUNC(0) | PORTF(5, 1) | BK)
+#define EMI_DATA1_OFF		(FUNC(3) | PORTF(5, 1) | BK)
+#define EMI_DATA0		(FUNC(0) | PORTF(5, 0) | BK)
+#define EMI_DATA0_OFF		(FUNC(3) | PORTF(5, 0) | BK)
+
+/*
+ * Bank 6, GPIO pins 192 ... 223
+ * Note: This pins are disabled instead of being GPIOs
+ */
+#define EMI_CKE			(FUNC(0) | PORTF(6, 24) | BK)
+#define EMI_CKE_OFF		(FUNC(3) | PORTF(6, 24) | BK)
+#define EMI_CE1N		(FUNC(0) | PORTF(6, 23) | BK)
+#define EMI_CE1N_OFF		(FUNC(3) | PORTF(6, 23) | BK)
+#define EMI_CE0N		(FUNC(0) | PORTF(6, 22) | BK)
+#define EMI_CE0N_OFF		(FUNC(3) | PORTF(6, 22) | BK)
+#define EMI_WEN			(FUNC(0) | PORTF(6, 21) | BK)
+#define EMI_WEN_OFF		(FUNC(3) | PORTF(6, 21) | BK)
+#define EMI_RASN		(FUNC(0) | PORTF(6, 20) | BK)
+#define EMI_RASN_OFF		(FUNC(3) | PORTF(6, 20) | BK)
+#define EMI_CASN		(FUNC(0) | PORTF(6, 19) | BK)
+#define EMI_CASN_OFF		(FUNC(3) | PORTF(6, 19) | BK)
+#define EMI_BA2			(FUNC(0) | PORTF(6, 18) | BK)
+#define EMI_BA2_OFF		(FUNC(3) | PORTF(6, 18) | BK)
+#define EMI_BA1			(FUNC(0) | PORTF(6, 17) | BK)
+#define EMI_BA1_OFF		(FUNC(3) | PORTF(6, 17) | BK)
+#define EMI_BA0			(FUNC(0) | PORTF(6, 16) | BK)
+#define EMI_BA0_OFF		(FUNC(3) | PORTF(6, 16) | BK)
+#define EMI_A14			(FUNC(0) | PORTF(6, 14) | BK)
+#define EMI_A14_OFF		(FUNC(3) | PORTF(6, 14) | BK)
+#define EMI_A13			(FUNC(0) | PORTF(6, 13) | BK)
+#define EMI_A13_OFF		(FUNC(3) | PORTF(6, 13) | BK)
+#define EMI_A12			(FUNC(0) | PORTF(6, 12) | BK)
+#define EMI_A12_OFF		(FUNC(3) | PORTF(6, 12) | BK)
+#define EMI_A11			(FUNC(0) | PORTF(6, 11) | BK)
+#define EMI_A11_OFF		(FUNC(3) | PORTF(6, 11) | BK)
+#define EMI_A10			(FUNC(0) | PORTF(6, 10) | BK)
+#define EMI_A10_OFF		(FUNC(3) | PORTF(6, 10) | BK)
+#define EMI_A9			(FUNC(0) | PORTF(6, 9) | BK)
+#define EMI_A9_OFF		(FUNC(3) | PORTF(6, 9) | BK)
+#define EMI_A8			(FUNC(0) | PORTF(6, 8) | BK)
+#define EMI_A8_OFF		(FUNC(3) | PORTF(6, 8) | BK)
+#define EMI_A7			(FUNC(0) | PORTF(6, 7) | BK)
+#define EMI_A7_OFF		(FUNC(3) | PORTF(6, 7) | BK)
+#define EMI_A6			(FUNC(0) | PORTF(6, 6) | BK)
+#define EMI_A6_OFF		(FUNC(3) | PORTF(6, 6) | BK)
+#define EMI_A5			(FUNC(0) | PORTF(6, 5) | BK)
+#define EMI_A5_OFF		(FUNC(3) | PORTF(6, 5) | BK)
+#define EMI_A4			(FUNC(0) | PORTF(6, 4) | BK)
+#define EMI_A4_OFF		(FUNC(3) | PORTF(6, 4) | BK)
+#define EMI_A3			(FUNC(0) | PORTF(6, 3) | BK)
+#define EMI_A3_OFF		(FUNC(3) | PORTF(6, 3) | BK)
+#define EMI_A2			(FUNC(0) | PORTF(6, 2) | BK)
+#define EMI_A2_OFF		(FUNC(3) | PORTF(6, 2) | BK)
+#define EMI_A1			(FUNC(0) | PORTF(6, 1) | BK)
+#define EMI_A1_OFF		(FUNC(3) | PORTF(6, 1) | BK)
+#define EMI_A0			(FUNC(0) | PORTF(6, 0) | BK)
+#define EMI_A0_OFF		(FUNC(3) | PORTF(6, 0) | BK)
+
+#endif /* __MACH_IOMUX_IMX28_H */
diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
new file mode 100644
index 0000000..2c68ebf
--- /dev/null
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+
+#define HW_PINCTRL_CTRL 0x000
+#define HW_PINCTRL_MUXSEL0 0x100
+
+#ifdef CONFIG_ARCH_IMX23
+#define HW_PINCTRL_DRIVE0 0x200
+#define HW_PINCTRL_PULL0 0x400
+#define HW_PINCTRL_DOUT0 0x500
+#define HW_PINCTRL_DIN0 0x600
+#define HW_PINCTRL_DOE0 0x700
+
+#define MAX_GPIO_NO 95
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+#define HW_PINCTRL_DRIVE0 0x300
+#define HW_PINCTRL_PULL0 0x600
+#define HW_PINCTRL_DOUT0 0x700
+#define HW_PINCTRL_DIN0 0x900
+#define HW_PINCTRL_DOE0 0xb00
+
+#define MAX_GPIO_NO 159
+#endif
+
+static uint32_t calc_mux_reg(uint32_t no)
+{
+	/* each register controls 16 pads */
+	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
+}
+
+static uint32_t calc_strength_reg(uint32_t no)
+{
+	/* each register controls 8 pads */
+	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
+}
+
+static uint32_t calc_pullup_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
+}
+
+static uint32_t calc_output_enable_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
+}
+
+static uint32_t calc_output_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
+}
+
+/**
+ * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
+ */
+void imx_gpio_mode(unsigned m)
+{
+	uint32_t reg_offset, gpio_pin, reg;
+
+	gpio_pin = GET_GPIO_NO(m);
+
+	/* configure the pad to its function (always) */
+	reg_offset = calc_mux_reg(gpio_pin);
+	reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1));
+	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
+	writel(reg, IMX_IOMUXC_BASE + reg_offset);
+
+	/* some pins are disabled when configured for GPIO */
+	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
+		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
+		return;
+	}
+
+	if (SE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2));
+		reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2);
+		writel(reg, IMX_IOMUXC_BASE + reg_offset);
+	}
+
+	if (VE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		if (GET_VOLTAGE(m) == 1)
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2),
+				IMX_IOMUXC_BASE + reg_offset + BIT_SET);
+		else
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2),
+				IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
+	}
+
+	if (PE_PRESENT(m)) {
+		reg_offset = calc_pullup_reg(gpio_pin);
+		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
+	}
+
+	if (GET_FUNC(m) == IS_GPIO) {
+		if (GET_GPIODIR(m) == 1) {
+			/* first set the output value */
+			reg_offset = calc_output_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+			/* then the direction */
+			reg_offset = calc_output_enable_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32),
+				IMX_IOMUXC_BASE + reg_offset + BIT_SET);
+		} else {
+			writel(0x1 << (gpio_pin % 32),
+				IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
+		}
+	}
+}
diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
deleted file mode 100644
index 5d4465e..0000000
--- a/arch/arm/mach-stm/iomux-imx23.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * 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, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <init.h>
-#include <gpio.h>
-#include <asm/io.h>
-#include <mach/imx-regs.h>
-
-#define HW_PINCTRL_CTRL 0x000
-#define HW_PINCTRL_MUXSEL0 0x100
-#define HW_PINCTRL_DRIVE0 0x200
-#define HW_PINCTRL_PULL0 0x400
-#define HW_PINCTRL_DOUT0 0x500
-#define HW_PINCTRL_DIN0 0x600
-#define HW_PINCTRL_DOE0 0x700
-
-#define MAX_GPIO_NO 95
-
-static uint32_t calc_mux_reg(uint32_t no)
-{
-	/* each register controls 16 pads */
-	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
-}
-
-static uint32_t calc_strength_reg(uint32_t no)
-{
-	/* each register controls 8 pads */
-	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
-}
-
-static uint32_t calc_pullup_reg(uint32_t no)
-{
-	/* each register controls 32 pads */
-	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
-}
-
-static uint32_t calc_output_enable_reg(uint32_t no)
-{
-	/* each register controls 32 pads */
-	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
-}
-
-static uint32_t calc_output_reg(uint32_t no)
-{
-	/* each register controls 32 pads */
-	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
-}
-
-/**
- * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
- */
-void imx_gpio_mode(unsigned m)
-{
-	uint32_t reg_offset, gpio_pin, reg;
-
-	gpio_pin = GET_GPIO_NO(m);
-
-	/* configure the pad to its function (always) */
-	reg_offset = calc_mux_reg(gpio_pin);
-	reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1));
-	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
-	writel(reg, IMX_IOMUXC_BASE + reg_offset);
-
-	/* some pins are disabled when configured for GPIO */
-	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
-		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
-		return;
-	}
-
-	if (SE_PRESENT(m)) {
-		reg_offset = calc_strength_reg(gpio_pin);
-		reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2));
-		reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2);
-		writel(reg, IMX_IOMUXC_BASE + reg_offset);
-	}
-
-	if (VE_PRESENT(m)) {
-		reg_offset = calc_strength_reg(gpio_pin);
-		if (GET_VOLTAGE(m) == 1)
-			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 4);
-		else
-			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 8);
-	}
-
-	if (PE_PRESENT(m)) {
-		reg_offset = calc_pullup_reg(gpio_pin);
-		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
-	}
-
-	if (GET_FUNC(m) == IS_GPIO) {
-		if (GET_GPIODIR(m) == 1) {
-			/* first set the output value */
-			reg_offset = calc_output_reg(gpio_pin);
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
-			/* then the direction */
-			reg_offset = calc_output_enable_reg(gpio_pin);
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 4);
-		} else {
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 8);
-		}
-	}
-}
diff --git a/arch/arm/mach-stm/reset-imx.c b/arch/arm/mach-stm/reset-imx.c
new file mode 100644
index 0000000..b35f796
--- /dev/null
+++ b/arch/arm/mach-stm/reset-imx.c
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <asm/io.h>
+
+#define HW_RTC_CTRL     0x000
+# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
+#define HW_RTC_CTRL_SET 0x004
+#define HW_RTC_CTRL_CLR 0x008
+#define HW_RTC_CTRL_TOG 0x00C
+
+#define HW_RTC_WATCHDOG     0x050
+#define HW_RTC_WATCHDOG_SET 0x054
+#define HW_RTC_WATCHDOG_CLR 0x058
+#define HW_RTC_WATCHDOG_TOG 0x05C
+
+#define WDOG_COUNTER_RATE	1000 /* 1 kHz clock */
+
+#define HW_RTC_PERSISTENT1     0x070
+# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
+#define HW_RTC_PERSISTENT1_SET 0x074
+#define HW_RTC_PERSISTENT1_CLR 0x078
+#define HW_RTC_PERSISTENT1_TOG 0x07C
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ *
+ * TODO There is a much easier way to reset the CPU: Refer bit 2 in
+ *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
+ */
+void __noreturn reset_cpu (unsigned long addr)
+{
+	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
+	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
+	writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
+
+	while (1)
+		;
+	/*NOTREACHED*/
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx23.c
deleted file mode 100644
index b35f796..0000000
--- a/arch/arm/mach-stm/reset-imx23.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * 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, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <init.h>
-#include <notifier.h>
-#include <mach/imx-regs.h>
-#include <asm/io.h>
-
-#define HW_RTC_CTRL     0x000
-# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
-#define HW_RTC_CTRL_SET 0x004
-#define HW_RTC_CTRL_CLR 0x008
-#define HW_RTC_CTRL_TOG 0x00C
-
-#define HW_RTC_WATCHDOG     0x050
-#define HW_RTC_WATCHDOG_SET 0x054
-#define HW_RTC_WATCHDOG_CLR 0x058
-#define HW_RTC_WATCHDOG_TOG 0x05C
-
-#define WDOG_COUNTER_RATE	1000 /* 1 kHz clock */
-
-#define HW_RTC_PERSISTENT1     0x070
-# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
-#define HW_RTC_PERSISTENT1_SET 0x074
-#define HW_RTC_PERSISTENT1_CLR 0x078
-#define HW_RTC_PERSISTENT1_TOG 0x07C
-
-/*
- * Reset the cpu by setting up the watchdog timer and let it time out
- *
- * TODO There is a much easier way to reset the CPU: Refer bit 2 in
- *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
- */
-void __noreturn reset_cpu (unsigned long addr)
-{
-	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
-	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
-	writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
-
-	while (1)
-		;
-	/*NOTREACHED*/
-}
-EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-stm/speed-imx28.c b/arch/arm/mach-stm/speed-imx28.c
new file mode 100644
index 0000000..63c6b07
--- /dev/null
+++ b/arch/arm/mach-stm/speed-imx28.c
@@ -0,0 +1,392 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel at pengutronix.de>
+ *
+ * This code is based partially on code that has:
+ *
+ * (c) 2008 Embedded Alley Solutions, Inc.
+ * (C) Copyright 2009-2010 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 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.
+ */
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/generic.h>
+#include <mach/clock.h>
+
+#define HW_CLKCTRL_PLL0CTRL0 0x000
+#define HW_CLKCTRL_PLL0CTRL1 0x010
+#define HW_CLKCTRL_PLL1CTRL0 0x020
+#define HW_CLKCTRL_PLL1CTRL1 0x030
+#define HW_CLKCTRL_PLL2CTRL0 0x040
+# define CLKCTRL_PLL2CTRL0_CLKGATE (1 << 31)
+# define CLKCTRL_PLL2CTRL0_POWER (1 << 23)
+#define HW_CLKCTRL_CPU 0x50
+# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
+# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_HBUS 0x60
+#define HW_CLKCTRL_XBUS 0x70
+#define HW_CLKCTRL_XTAL 0x080
+#define HW_CLKCTRL_SSP0 0x090
+#define HW_CLKCTRL_SSP1 0x0a0
+#define HW_CLKCTRL_SSP2 0x0b0
+#define HW_CLKCTRL_SSP3 0x0c0
+/* note: no set/clear register! */
+# define CLKCTRL_SSP_CLKGATE (1 << 31)
+# define CLKCTRL_SSP_BUSY (1 << 29)
+# define CLKCTRL_SSP_DIV_FRAC_EN (1 << 9)
+# define CLKCTRL_SSP_DIV_MASK 0x1ff
+# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+#define HW_CLKCTRL_GPMI 0x0d0
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SPDIF 0x0e0
+/* note: no set/clear register! */
+#define HW_CLKCTRL_EMI	0xf0
+/* note: no set/clear register! */
+# define CLKCTRL_EMI_CLKGATE (1 << 31)
+# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
+# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_SAIF0 0x100
+#define HW_CLKCTRL_SAIF1 0x110
+#define HW_CLKCTRL_DIS_LCDIF 0x120
+# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+# define SET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
+# define GET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
+#define HW_CLKCTRL_ETM 0x130
+#define HW_CLKCTRL_ENET 0x140
+# define SET_CLKCTRL_ENET_DIV(x) (((x) & 0x3f) << 21)
+# define SET_CLKCTRL_ENET_SEL(x) (((x) & 0x3) << 19)
+# define CLKCTRL_ENET_CLK_OUT_EN (1 << 18)
+#define HW_CLKCTRL_HSADC 0x150
+#define HW_CLKCTRL_FLEXCAN 0x160
+#define HW_CLKCTRL_FRAC0 0x1b0
+# define CLKCTRL_FRAC_CLKGATEIO0 (1 << 31)
+# define GET_IO0FRAC(x) (((x) >> 24) & 0x3f)
+# define SET_IO0FRAC(x) (((x) & 0x3f) << 24)
+# define CLKCTRL_FRAC_CLKGATEIO1 (1 << 23)
+# define GET_IO1FRAC(x) (((x) >> 16) & 0x3f)
+# define SET_IO1FRAC(x) (((x) & 0x3f) << 16)
+# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
+# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
+# define GET_CPUFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_FRAC1 0x1c0
+# define CLKCTRL_FRAC_CLKGATEGPMI (1 << 23)
+# define GET_GPMIFRAC(x) (((x) >> 16) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEHSADC (1 << 15)
+# define GET_HSADCFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
+# define GET_PIXFRAC(x) ((x) & 0x3f)
+# define SET_PIXFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_CLKSEQ 0x1d0
+# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 18)
+# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
+# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
+# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 7)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP3 (1 << 6)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP2 (1 << 5)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP1 (1 << 4)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP0 (1 << 3)
+# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 2)
+# define CLKCTRL_CLKSEQ_BYPASS_SAIF1 (1 << 1)
+# define CLKCTRL_CLKSEQ_BYPASS_SAIF0 (1 << 0)
+#define HW_CLKCTRL_RESET 0x1e0
+#define HW_CLKCTRL_STATUS 0x1f0
+#define HW_CLKCTRL_VERSION 0x200
+
+unsigned imx_get_mpllclk(void)
+{
+	/* the main PLL runs at 480 MHz */
+	return 480000000;
+}
+
+unsigned imx_get_xtalclk(void)
+{
+	/* the external reference runs at 24 MHz */
+	return 24000000;
+}
+
+unsigned imx_get_fecclk(void)
+{
+	/* this PLL always runs at 50 MHz */
+	return 50000000;
+}
+
+
+/* used for the SDRAM controller */
+unsigned imx_get_emiclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
+		return 0;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
+		return imx_get_xtalclk() /
+			GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+
+	rate = imx_get_mpllclk() / 1000;
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+	if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
+		rate *= 18;
+		rate /= GET_EMIFRAC(reg);
+	}
+
+	return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
+				* 1000;
+}
+
+/*
+ * Source of ssp, gpmi, ir
+ * @param index 0 or 1 for ioclk0 or ioclock1
+ */
+unsigned imx_get_ioclk(unsigned index)
+{
+	uint32_t reg;
+	unsigned rate = imx_get_mpllclk() / 1000;
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+	switch (index) {
+	case 0:
+		if (reg & CLKCTRL_FRAC_CLKGATEIO0)
+			return 0;	/* clock is off */
+
+		rate *= 18;
+		rate /= GET_IO0FRAC(reg);
+		break;
+	case 1:
+		if (reg & CLKCTRL_FRAC_CLKGATEIO1)
+			return 0;	/* clock is off */
+
+		rate *= 18;
+		rate /= GET_IO1FRAC(reg);
+		break;
+	}
+
+	return rate * 1000;
+}
+
+/**
+ * Setup a new frequency to the IOCLK domain.
+ * @param index 0 or 1 for ioclk0 or ioclock1
+ * @param nc New frequency in [Hz]
+ *
+ * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
+ *
+ * ioclock0 is the shared clock source of SSP0/SSP1, ioclock1 the shared clock
+ * source of SSP2/SSP3
+ */
+unsigned imx_set_ioclk(unsigned index, unsigned nc)
+{
+	uint32_t reg;
+	unsigned div;
+
+	nc /= 1000;
+	div = (imx_get_mpllclk() / 1000) * 18;
+	div = DIV_ROUND_CLOSEST(div, nc);
+	if (div > 0x3f)
+		div = 0x3f;
+
+	switch (index) {
+	case 0:
+		reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
+				~(SET_IO0FRAC(0x3f));
+		/* mask the current settings */
+		writel(reg | SET_IO0FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+		/* enable the IO clock at its new frequency */
+		writel(CLKCTRL_FRAC_CLKGATEIO0,
+				IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
+		break;
+	case 1:
+		reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
+				~(SET_IO1FRAC(0x3f));
+		/* mask the current settings */
+		writel(reg | SET_IO1FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+		/* enable the IO clock at its new frequency */
+		writel(CLKCTRL_FRAC_CLKGATEIO1,
+				IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
+		break;
+	}
+
+	return imx_get_ioclk(index);
+}
+
+/* this is CPU core clock */
+unsigned imx_get_armclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
+		return imx_get_xtalclk() /
+			GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+	if (reg & CLKCTRL_FRAC_CLKGATECPU)
+		return 0;	/* should not possible, shouldn't it? */
+
+	rate = (imx_get_mpllclk() / 1000) * 18;
+	rate /= GET_CPUFRAC(reg);
+
+	return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
+			* 1000;
+}
+
+/* this is the AHB and APBH bus clock */
+unsigned imx_get_hclk(void)
+{
+	unsigned rate = imx_get_armclk() / 1000;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+		rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+		rate /= 32;
+	} else
+		rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+	return rate * 1000;
+}
+
+/*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+unsigned imx_get_xclk(void)
+{
+	/* runs from the 24 MHz crystal reference */
+	unsigned rate = imx_get_xtalclk();
+
+	return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
+}
+
+/**
+ * @param index The SSP unit (0...3)
+ */
+unsigned imx_get_sspclk(unsigned index)
+{
+	unsigned rate, offset, shift, ioclk_index;
+
+	if (index > 3) {
+		pr_debug("Unknown SSP unit: %u\n", index);
+		return 0;
+	}
+
+	ioclk_index = index >> 1;
+
+	offset = HW_CLKCTRL_SSP0 + (0x10 * index);
+	shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
+
+	if (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
+		return 0;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & shift)
+		rate = imx_get_xtalclk();
+	else
+		rate = imx_get_ioclk(ioclk_index);
+
+	return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + offset));
+}
+
+/**
+ * @param index The SSP unit (0...3)
+ * @param nc New frequency in [Hz]
+ * @param high != 0 if ioclk should be the source
+ * @return The new possible frequency
+ */
+unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
+{
+	uint32_t reg;
+	unsigned ssp_div, offset, shift, ioclk_index;
+
+	if (index > 3) {
+		pr_debug("Unknown SSP unit: %u\n", index);
+		return 0;
+	}
+
+	ioclk_index = index >> 1;
+
+	offset = HW_CLKCTRL_SSP0 + (0x10 * index);
+	shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
+
+	reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_CLKGATE;
+	/* Datasheet says: Do not change the DIV setting if the clock is off */
+	writel(reg, IMX_CCM_BASE + offset);
+	/* Wait while clock is gated */
+	while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
+		;
+
+	if (high)
+		ssp_div = imx_get_ioclk(ioclk_index);
+	else
+		ssp_div = imx_get_xtalclk();
+
+	if (nc > ssp_div) {
+		printf("Cannot setup SSP unit clock to %u kHz, base clock is "
+						"only %u kHz\n", nc, ssp_div);
+		ssp_div = 1;
+	} else {
+		ssp_div = DIV_ROUND_UP(ssp_div, nc);
+		if (ssp_div > CLKCTRL_SSP_DIV_MASK)
+			ssp_div = CLKCTRL_SSP_DIV_MASK;
+	}
+
+	/* Set new divider value */
+	reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_DIV_MASK;
+	writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + offset);
+
+	/* Wait until new divider value is set */
+	while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_BUSY)
+		;
+
+	if (high)
+		/* switch to ioclock */
+		writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
+	else
+		/* switch to 24 MHz crystal */
+		writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
+
+	return imx_get_sspclk(index);
+}
+
+void imx_enable_enetclk(void)
+{
+	uint32_t reg;
+
+	/* wake up main enet PLL */
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+	if (!(reg & CLKCTRL_PLL2CTRL0_POWER)) {
+		reg |= CLKCTRL_PLL2CTRL0_POWER;
+		writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+		udelay(50);	/* wait until this PLL locks */
+	}
+	reg &= ~CLKCTRL_PLL2CTRL0_CLKGATE;
+	writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+
+	writel(SET_CLKCTRL_ENET_DIV(1) | SET_CLKCTRL_ENET_SEL(0) |
+		CLKCTRL_ENET_CLK_OUT_EN, /* FIXME may be platform specific */
+		IMX_CCM_BASE + HW_CLKCTRL_ENET);
+}
+
+void imx_dump_clocks(void)
+{
+	printf("mpll:    %10u kHz\n", imx_get_mpllclk() / 1000);
+	printf("arm:     %10u kHz\n", imx_get_armclk() / 1000);
+	printf("ioclk0:  %10u kHz\n", imx_get_ioclk(0) / 1000);
+	printf("ioclk1:  %10u kHz\n", imx_get_ioclk(1) / 1000);
+	printf("emiclk:  %10u kHz\n", imx_get_emiclk() / 1000);
+	printf("hclk:    %10u kHz\n", imx_get_hclk() / 1000);
+	printf("xclk:    %10u kHz\n", imx_get_xclk() / 1000);
+	printf("ssp0:    %10u kHz\n", imx_get_sspclk(0) / 1000);
+	printf("ssp1:    %10u kHz\n", imx_get_sspclk(1) / 1000);
+	printf("ssp2:    %10u kHz\n", imx_get_sspclk(2) / 1000);
+	printf("ssp3:    %10u kHz\n", imx_get_sspclk(3) / 1000);
+}
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 13 07:08:57 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 13 Dec 2010 13:08:57 +0100
Subject: [PATCH] remove redundant .gitignore entries
In-Reply-To: <13507e3e1f3a5dfa2e79be2ffcfbe6d7b9e84bb3.1292219932.git.baruch@tkos.co.il>
References: <13507e3e1f3a5dfa2e79be2ffcfbe6d7b9e84bb3.1292219932.git.baruch@tkos.co.il>
Message-ID: <20101213120857.GH6017@pengutronix.de>

Hi Baruch,

On Mon, Dec 13, 2010 at 08:00:10AM +0200, Baruch Siach wrote:
> The ARCH and CROSS_COMPILE entries were introduced in commit cdfd8bdd, probably
> by mistake.

'redundant' seems to imply that these are duplicates, but they are not.
They were also not introduced by accident. I use a wrapper script for
make which evaluates these files, so I'd like to keep them, although
they are only for my personal use.

Sascha

> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  .gitignore |    2 --
>  1 files changed, 0 insertions(+), 2 deletions(-)
> 
> diff --git a/.gitignore b/.gitignore
> index 6f04601..cdc4df0 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -34,8 +34,6 @@ barebox.netx
>  barebox.map
>  System.map
>  Module.symvers
> -ARCH
> -CROSS_COMPILE
>  barebox_default_env
>  
>  #
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From baruch at tkos.co.il  Mon Dec 13 07:33:28 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 13 Dec 2010 14:33:28 +0200
Subject: [PATCH] remove redundant .gitignore entries
In-Reply-To: <20101213120857.GH6017@pengutronix.de>
References: <13507e3e1f3a5dfa2e79be2ffcfbe6d7b9e84bb3.1292219932.git.baruch@tkos.co.il>
	<20101213120857.GH6017@pengutronix.de>
Message-ID: <20101213123328.GD5766@jasper.tkos.co.il>

Hi Sascha,

On Mon, Dec 13, 2010 at 01:08:57PM +0100, Sascha Hauer wrote:
> On Mon, Dec 13, 2010 at 08:00:10AM +0200, Baruch Siach wrote:
> > The ARCH and CROSS_COMPILE entries were introduced in commit cdfd8bdd, probably
> > by mistake.
> 
> 'redundant' seems to imply that these are duplicates, but they are not.

English is not my native language. I couldn't come up with anything better.

> They were also not introduced by accident. I use a wrapper script for
> make which evaluates these files, so I'd like to keep them, although
> they are only for my personal use.

The .git/info/exclude file is a better place for local excludes, IMHO. I use 
it myself for this.

baruch

> > Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> > ---
> >  .gitignore |    2 --
> >  1 files changed, 0 insertions(+), 2 deletions(-)
> > 
> > diff --git a/.gitignore b/.gitignore
> > index 6f04601..cdc4df0 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -34,8 +34,6 @@ barebox.netx
> >  barebox.map
> >  System.map
> >  Module.symvers
> > -ARCH
> > -CROSS_COMPILE
> >  barebox_default_env
> >  
> >  #
> > -- 
> > 1.7.2.3

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From s.hauer at pengutronix.de  Mon Dec 13 08:10:05 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 13 Dec 2010 14:10:05 +0100
Subject: [PATCH] remove redundant .gitignore entries
In-Reply-To: <20101213123328.GD5766@jasper.tkos.co.il>
References: <13507e3e1f3a5dfa2e79be2ffcfbe6d7b9e84bb3.1292219932.git.baruch@tkos.co.il>
	<20101213120857.GH6017@pengutronix.de>
	<20101213123328.GD5766@jasper.tkos.co.il>
Message-ID: <20101213131005.GK6017@pengutronix.de>

On Mon, Dec 13, 2010 at 02:33:28PM +0200, Baruch Siach wrote:
> Hi Sascha,
> 
> On Mon, Dec 13, 2010 at 01:08:57PM +0100, Sascha Hauer wrote:
> > On Mon, Dec 13, 2010 at 08:00:10AM +0200, Baruch Siach wrote:
> > > The ARCH and CROSS_COMPILE entries were introduced in commit cdfd8bdd, probably
> > > by mistake.
> > 
> > 'redundant' seems to imply that these are duplicates, but they are not.
> 
> English is not my native language. I couldn't come up with anything better.
> 
> > They were also not introduced by accident. I use a wrapper script for
> > make which evaluates these files, so I'd like to keep them, although
> > they are only for my personal use.
> 
> The .git/info/exclude file is a better place for local excludes, IMHO. I use 
> it myself for this.

Ok, works good. I applied your patch.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From Fabio.Porcedda at telit.com  Tue Dec 14 08:20:37 2010
From: Fabio.Porcedda at telit.com (Fabio Porcedda)
Date: Tue, 14 Dec 2010 14:20:37 +0100
Subject: loady command failure
Message-ID: <24A9345B397CD24AA76A4E82E237956545F839C951@XCHTS.tmt.telital.com>

Hi all,
I'm using Barebox v2010.12.0 (at91sam9260ek_defconfig + loadb + loady)
compiled with codesourcery 2010.q1 on the board Atmel AT91SAM9260-EK,

the loadb command it's woking fine,
but the loady command fails every time, with ckermit and minicom (Ubuntu 10.10):

kermit log:"
Retry 0: NAK on sector
...
Retry 0: NAK on sector
Retry 0: Retry Count Exceeded

Transfer incomplete

*************************
SEND-class command failed.
 Packets sent: 166
 Retransmissions: 0
 Timeouts: 0
 Damaged packets: 0
"

The loadb/loady command of U-Boot v2010.09 on the same AT91SAM9260-EK is working fine.

HW/SW Configuration:
PC: Ubuntu 10.10 + ckermit (211-14) + minicom (2.4-2ubuntu1)

.kermrc:
set line /dev/ttyS0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5

minicom config:
Bps/Par/Bits       : 115200 8N1
Hardware Flow Control : No
Software Flow Control : No


Thanks in advance for any help
Fabio Porcedda
Software Devoloper - R&D Cagliari
Telit Communications S.p.A.


From baruch at tkos.co.il  Wed Dec 15 03:04:36 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 15 Dec 2010 10:04:36 +0200
Subject: [PATCH] eth: fix 'warning: No MAC address set' when using EEPROM MAC
Message-ID: <ddb18a8573b9f5daac2cc3d8ef53da7ee41dbbc0.1292400209.git.baruch@tkos.co.il>

When retrieving the MAC address from EEPROM, we must notify the networking core
at eth registration time. Otherwise we get the 'No MAC address set' warning on
the first network access, and the MAC address is set to a random value instead
of the real one.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 net/eth.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/eth.c b/net/eth.c
index 4d58191..dafd392 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -168,8 +168,10 @@ int eth_register(struct eth_device *edev)
 		dev_set_param(dev, "ethaddr", ethaddr_str);
 	}
 
-	if (!eth_current)
+	if (!eth_current) {
 		eth_current = edev;
+		net_update_env();
+	}
 
 	return 0;
 }
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:26 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:26 +0100
Subject: [PATCH 12/34] doc: add documentation for 'mkdir' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-13-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/mkdir.c           |   16 +++++++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index db3be1a..45947e9 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -71,7 +71,7 @@ available in @a Barebox:
 @li @subpage meminfo
 @li @subpage memset
 @li @subpage menu
- at li @subpage mkdir
+ at li @subpage mkdir_command
 @li @subpage mount_command
 @li @subpage mtest
 @li @subpage mw
diff --git a/commands/mkdir.c b/commands/mkdir.c
index b66795b..9e37775 100644
--- a/commands/mkdir.c
+++ b/commands/mkdir.c
@@ -59,9 +59,19 @@ static int do_mkdir(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_mkdir_help[] =
-"Usage: mkdir [directories]\n"
-"Create new directories\n";
+BAREBOX_CMD_HELP_START(mkdir)
+BAREBOX_CMD_HELP_USAGE("mkdir DIRECTORIES\n")
+BAREBOX_CMD_HELP_SHORT("Create new directories.\n")
+BAREBOX_CMD_HELP_OPT  ("-p", "create all parent directories\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page mkdir_command
+
+When called with the '-p' option, mkdir creates all non-existing parent
+directories.
+
+ */
 
 BAREBOX_CMD_START(mkdir)
 	.cmd		= do_mkdir,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:17 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:17 +0100
Subject: [PATCH 03/34] doc: add documentation for 'unlzo' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-4-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/unlzo.c           |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 6c2f59d..cc892d4 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -103,7 +103,7 @@ available in @a Barebox:
 @li @subpage ubimkvol
 @li @subpage ubirmvol
 @li @subpage umount
- at li @subpage unlzo
+ at li @subpage unlzo_command
 @li @subpage unprotect_command
 @li @subpage usb
 @li @subpage version_command
diff --git a/commands/unlzo.c b/commands/unlzo.c
index 0b6dd4b..40225e6 100644
--- a/commands/unlzo.c
+++ b/commands/unlzo.c
@@ -57,9 +57,17 @@ exit_close:
 	return ret;
 }
 
-static const __maybe_unused char cmd_unlzo_help[] =
-"Usage: unlzo <infile> <outfile>\n"
-"Uncompress a lzo compressed file\n";
+BAREBOX_CMD_HELP_START(unlzo)
+BAREBOX_CMD_HELP_USAGE("unlzo <infile> <outfile>\n")
+BAREBOX_CMD_HELP_SHORT("Uncompress a lzo compressed file.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page unlzo_command
+
+\todo Add an example, how to handle LZO files in RAM.
+
+ */
 
 BAREBOX_CMD_START(unlzo)
         .cmd            = do_unlzo,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:15 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:15 +0100
Subject: [PATCH 01/34] doc: remove non-existing references
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-2-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 arch/arm/mach-omap/syslib.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap/syslib.c b/arch/arm/mach-omap/syslib.c
index 2b25dc1..5757574 100644
--- a/arch/arm/mach-omap/syslib.c
+++ b/arch/arm/mach-omap/syslib.c
@@ -40,7 +40,7 @@
  *
  * Will be constant time as its generally used in bypass conditions only.
  * This is necessary until timers are accessible. if you need timed delays
- * use @ref mdelay or @ref udelay instead
+ * use mdelay or udelay instead
  *
  * @param[in] loops number of loops
  *
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:22 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:22 +0100
Subject: [PATCH 08/34] doc: add documentation for 'true' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-9-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/true.c            |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index e25dda0..9348743 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -97,7 +97,7 @@ available in @a Barebox:
 @li @subpage source
 @li @subpage test
 @li @subpage timeout_command
- at li @subpage true
+ at li @subpage true_command
 @li @subpage tftp_command
 @li @subpage ubiattach_command
 @li @subpage ubimkvol_command
diff --git a/commands/true.c b/commands/true.c
index 8c77dec..d77a365 100644
--- a/commands/true.c
+++ b/commands/true.c
@@ -29,6 +29,11 @@ static int do_true(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(true)
+BAREBOX_CMD_HELP_USAGE("true\n")
+BAREBOX_CMD_HELP_SHORT("Do nothing, successfully.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(true)
 	.cmd		= do_true,
 	.usage		= "do nothing, successfully",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:16 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:16 +0100
Subject: [PATCH 02/34] doc: add documentation for 'version' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-3-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/version.c         |   15 ++++++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 5ef7829..6c2f59d 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -106,6 +106,6 @@ available in @a Barebox:
 @li @subpage unlzo
 @li @subpage unprotect_command
 @li @subpage usb
- at li @subpage version
+ at li @subpage version_command
 
 */
diff --git a/commands/version.c b/commands/version.c
index 2b3ac05..baec60f 100644
--- a/commands/version.c
+++ b/commands/version.c
@@ -29,9 +29,22 @@ static int do_version(struct command *cmdtp, int argc, char *argv[])
 	printf ("\n%s\n", version_string);
 	return 0;
 }
+BAREBOX_CMD_HELP_START(version)
+BAREBOX_CMD_HELP_USAGE("version\n")
+BAREBOX_CMD_HELP_SHORT("Print the Barebox version.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page version_command
+
+The version string follows the version information from the Linux
+kernel, so for code coming from git you get an information about the
+commit ID and the number of patches applied ontop of the last release.
+
+ */
 
 BAREBOX_CMD_START(version)
 	.cmd		= do_version,
-	.usage		= "print monitor version",
+	.usage		= "print barebox version",
 BAREBOX_CMD_END
 
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:20 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:20 +0100
Subject: [PATCH 06/34] doc: add documentation for ubi commands
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-7-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    6 +++---
 commands/ubi.c             |   39 +++++++++++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index d5536d3..56edb43 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -99,9 +99,9 @@ available in @a Barebox:
 @li @subpage timeout
 @li @subpage true
 @li @subpage tftp_command
- at li @subpage ubiattach
- at li @subpage ubimkvol
- at li @subpage ubirmvol
+ at li @subpage ubiattach_command
+ at li @subpage ubimkvol_command
+ at li @subpage ubirmvol_command
 @li @subpage umount_command
 @li @subpage unlzo_command
 @li @subpage unprotect_command
diff --git a/commands/ubi.c b/commands/ubi.c
index 3da0835..d896385 100644
--- a/commands/ubi.c
+++ b/commands/ubi.c
@@ -44,10 +44,17 @@ static int do_ubimkvol(struct command *cmdtp, int argc, char *argv[])
 	return ret ? 1 : 0;
 }
 
-static const __maybe_unused char cmd_ubimkvol_help[] =
-"Usage: ubimkvol <ubidev> <name> <size>\n"
-"Create an ubi volume on <ubidev> with name <name> and size <size>\n"
-"If size os zero all available space is used for the volume\n";
+BAREBOX_CMD_HELP_START(ubimkvol)
+BAREBOX_CMD_HELP_USAGE("ubimkvol <ubidev> <name> <size>\n")
+BAREBOX_CMD_HELP_SHORT("Create an ubi volume on <ubidev> with <name> and <size>.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page ubimkvol_command
+
+If size is zero, all available space is used for the volume.
+
+ */
 
 BAREBOX_CMD_START(ubimkvol)
 	.cmd		= do_ubimkvol,
@@ -82,9 +89,15 @@ static int do_ubiattach(struct command *cmdtp, int argc, char *argv[])
 	return ret ? 1 : 0;
 }
 
-static const __maybe_unused char cmd_ubiattach_help[] =
-"Usage: ubiattach <mtddev>\n"
-"Attach <mtddev> to ubi\n";
+BAREBOX_CMD_HELP_START(ubiattach)
+BAREBOX_CMD_HELP_USAGE("ubiattach <mtddev>\n")
+BAREBOX_CMD_HELP_SHORT("Attach <mtddev> to ubi.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page ubiattach_command
+
+ */
 
 BAREBOX_CMD_START(ubiattach)
 	.cmd		= do_ubiattach,
@@ -117,9 +130,15 @@ static int do_ubirmvol(struct command *cmdtp, int argc, char *argv[])
 	return ret ? 1 : 0;
 }
 
-static const __maybe_unused char cmd_ubirmvol_help[] =
-"Usage: ubirmvol <ubidev> <name>\n"
-"Delete ubi volume <name> from <ubidev>\n";
+BAREBOX_CMD_HELP_START(ubirmvol)
+BAREBOX_CMD_HELP_USAGE("ubirmvol <ubidev> <name>\n")
+BAREBOX_CMD_HELP_SHORT("Delete ubi volume <name> from <ubidev>.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page ubirmvol_command
+
+ */
 
 BAREBOX_CMD_START(ubirmvol)
 	.cmd		= do_ubirmvol,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:14 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:14 +0100
Subject: More Documentation Patches
Message-ID: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>

Hi,

I've added more documentation for the commands available in Barebox.
While being there, I'm collecting things where I think we should add
more examples etc; those are marked with \todos in order to find them
quickly. The series is not complete yet, more patches will follow.

The following changes since commit 615076e1fc11a86efdc76c64ce65cd336684c742:

  cfi_flash_amd: Add manufacturer-specific fixups (2010-12-03 01:53:14 +0800)

are available in the git repository at:
  git://git.pengutronix.de/git/rsc/barebox.git for-mainline-doc

Robert Schwebel (34):
      doc: remove non-existing references
      doc: add documentation for 'version' command
      doc: add documentation for 'unlzo' command
      doc: add documentation for 'umount' command
      doc: add documentation for 'usb' command
      doc: add documentation for ubi commands
      doc: add documentation for 'timeout' command
      doc: add documentation for 'true' command
      doc: add documentation for 'sleep' command
      doc: add documentation for 'rm' command
      doc: add documentation for 'rmdir' command
      doc: add documentation for 'mkdir' command
      doc: add documentation for 'test' command
      doc: add documentation for 'lsmod' command
      doc: add documentation for 'readline' command
      doc: add documentation for 'insmod' command
      doc: add documentation for 'help' command
      doc: add documentation for 'pwd' command
      doc: add documentation for 'false' command
      doc: add documentation for 'exec' command
      doc: add documentation for 'reset' command
      doc: add documentation for 'reginfo' command
      doc: add documentation for 'meminfo' command
      doc: add documentation for 'go' command
      doc: add documentation for 'source' command
      doc: add documentation for 'sh' command
      doc: add documentation for 'ping' command
      doc: add documentation for 'nfs' command
      doc: add documentation for 'rarpboot' command
      doc: add documentation for 'passwd' command
      doc: add documentation for 'nand' command
      doc: add documentation for 'mw' command
      doc: add documentation for 'memcmp' command
      doc: add documentation for 'md' command

 Documentation/commands.dox  |   70 +++++++++++++++++-----------------
 Doxyfile                    |    3 +-
 arch/arm/mach-omap/syslib.c |    2 +-
 commands/exec.c             |    5 ++
 commands/false.c            |    5 ++
 commands/go.c               |   17 ++++++--
 commands/help.c             |   22 +++++++---
 commands/insmod.c           |   13 +++++-
 commands/lsmod.c            |    5 ++
 commands/mem.c              |   90 +++++++++++++++++++++++++-----------------
 commands/meminfo.c          |    5 ++
 commands/mkdir.c            |   16 ++++++-
 commands/nand.c             |   22 +++++++---
 commands/net.c              |   19 ++++++++-
 commands/passwd.c           |   18 ++++++--
 commands/pwd.c              |    5 ++
 commands/readline.c         |   14 +++++-
 commands/reginfo.c          |   12 ++++++
 commands/reset.c            |    5 ++
 commands/rm.c               |    7 ++-
 commands/rmdir.c            |    7 ++-
 commands/sleep.c            |    5 ++
 commands/test.c             |   16 +++++---
 commands/timeout.c          |   23 +++++++----
 commands/true.c             |    5 ++
 commands/ubi.c              |   39 ++++++++++++++-----
 commands/umount.c           |   14 +++++-
 commands/unlzo.c            |   14 +++++-
 commands/version.c          |   15 +++++++-
 common/hush.c               |   37 ++++++++++-------
 drivers/usb/core/usb.c      |   14 +++++-
 net/nfs.c                   |   14 +++++-
 net/ping.c                  |   16 ++++++++
 33 files changed, 407 insertions(+), 167 deletions(-)




From r.schwebel at pengutronix.de  Wed Dec 15 06:51:37 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:37 +0100
Subject: [PATCH 23/34] doc: add documentation for 'meminfo' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-24-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/meminfo.c         |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index c26abc2..907818e 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -68,7 +68,7 @@ available in @a Barebox:
 @li @subpage lsmod_command
 @li @subpage md
 @li @subpage memcmp
- at li @subpage meminfo
+ at li @subpage meminfo_command
 @li @subpage memset
 @li @subpage menu
 @li @subpage mkdir_command
diff --git a/commands/meminfo.c b/commands/meminfo.c
index abbaf9c..176a636 100644
--- a/commands/meminfo.c
+++ b/commands/meminfo.c
@@ -30,6 +30,11 @@ static int do_meminfo(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(meminfo)
+BAREBOX_CMD_HELP_USAGE("meminfo\n")
+BAREBOX_CMD_HELP_SHORT("Print info about memory usage.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(meminfo)
 	.cmd		= do_meminfo,
 	.usage		= "print info about memory usage",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:35 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:35 +0100
Subject: [PATCH 21/34] doc: add documentation for 'reset' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-22-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/reset.c           |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 023a559..2d3d5f2 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -85,7 +85,7 @@ available in @a Barebox:
 @li @subpage protect_command
 @li @subpage pwd_command
 @li @subpage readline_command
- at li @subpage reset
+ at li @subpage reset_command
 @li @subpage rarpboot
 @li @subpage reginfo
 @li @subpage rm_command
diff --git a/commands/reset.c b/commands/reset.c
index 46ab901..64c7f87 100644
--- a/commands/reset.c
+++ b/commands/reset.c
@@ -31,6 +31,11 @@ static int cmd_reset(struct command *cmdtp, int argc, char *argv[])
 	return 1;
 }
 
+BAREBOX_CMD_HELP_START(reset)
+BAREBOX_CMD_HELP_USAGE("reset\n")
+BAREBOX_CMD_HELP_SHORT("Perform a reset on the cpu.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(reset)
 	.cmd		= cmd_reset,
 	.usage		= "Perform RESET of the CPU",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:39 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:39 +0100
Subject: [PATCH 25/34] doc: add documentation for 'source' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-26-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 common/hush.c              |   22 ++++++++++++----------
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 430cc52..7f4e489 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -94,7 +94,7 @@ available in @a Barebox:
 @li @subpage setenv_command
 @li @subpage sh
 @li @subpage sleep_command
- at li @subpage source
+ at li @subpage source_command
 @li @subpage test_command
 @li @subpage timeout_command
 @li @subpage true_command
diff --git a/common/hush.c b/common/hush.c
index 77610bb..4947173 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -1691,21 +1691,23 @@ static int do_source(struct command *cmdtp, int argc, char *argv[])
 
 static const char *source_aliases[] = { ".", NULL};
 
-static const __maybe_unused char cmd_source_help[] =
-"Usage: .  filename [arguments]\n"
-"or     source filename [arguments]\n"
-"\n"
-"Read  and  execute  commands  from filename in the current shell\n"
-"environment and return the exit status of the last command  exe-\n"
-"cuted from filename\n";
+BAREBOX_CMD_HELP_START(source)
+BAREBOX_CMD_HELP_USAGE(". FILE [ARGS], source FILE [ARGS]\n")
+BAREBOX_CMD_HELP_SHORT("Read and execute shell commands in the current shell.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page source_command
 
-static const __maybe_unused char cmd_source_usage[] =
-"execute shell script in current shell environment";
+The commands are executed in the current shell environment and return
+the exit status of the last command executed from FILE.
+
+ */
 
 BAREBOX_CMD_START(source)
 	.aliases	= source_aliases,
 	.cmd		= do_source,
-	.usage		= cmd_source_usage,
+	.usage		= "execute shell script in current shell environment"
 	BAREBOX_CMD_HELP(cmd_source_help)
 BAREBOX_CMD_END
 
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:24 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:24 +0100
Subject: [PATCH 10/34] doc: add documentation for 'rm' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-11-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/rm.c              |    7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 6598002..b0919d0 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -88,7 +88,7 @@ available in @a Barebox:
 @li @subpage reset
 @li @subpage rarpboot
 @li @subpage reginfo
- at li @subpage rm
+ at li @subpage rm_command
 @li @subpage rmdir
 @li @subpage saveenv_command
 @li @subpage setenv_command
diff --git a/commands/rm.c b/commands/rm.c
index 3437ae5..4a45fee 100644
--- a/commands/rm.c
+++ b/commands/rm.c
@@ -42,9 +42,10 @@ static int do_rm(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_rm_help[] =
-"Usage: rm [FILES]\n"
-"Remove files\n";
+BAREBOX_CMD_HELP_START(rm)
+BAREBOX_CMD_HELP_USAGE("rm FILE\n")
+BAREBOX_CMD_HELP_SHORT("Remove files.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(rm)
 	.cmd		= do_rm,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:38 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:38 +0100
Subject: [PATCH 24/34] doc: add documentation for 'go' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-25-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/go.c              |   17 ++++++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 907818e..430cc52 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -49,7 +49,7 @@ available in @a Barebox:
 @li @subpage gpio_set_value_command
 @li @subpage gpio_direction_input_command
 @li @subpage gpio_direction_output_command
- at li @subpage go
+ at li @subpage go_command
 @li @subpage help_command
 @li @subpage host
 @li @subpage i2c_probe
diff --git a/commands/go.c b/commands/go.c
index 0262940..cb0b72b 100644
--- a/commands/go.c
+++ b/commands/go.c
@@ -77,11 +77,18 @@ out:
 	return rcode;
 }
 
-static const __maybe_unused char cmd_go_help[] =
-"Usage: go addr [arg ...]\n"
-"Start application at address 'addr' passing 'arg' as arguments.\n"
-"If addr does not start with a digit it is interpreted as a filename\n"
-"in which case the file is memmapped and executed\n";
+BAREBOX_CMD_HELP_START(go)
+BAREBOX_CMD_HELP_USAGE("go ADDR [ARGS]\n")
+BAREBOX_CMD_HELP_SHORT("Start application at address ADDR, passing ARGS as arguments.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page go_command
+
+If ADDR does not start with a digit, it is interpreted as a filename. In
+this case the file is memory mapped and executed.
+
+ */
 
 BAREBOX_CMD_START(go)
 	.cmd		= do_go,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:47 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:47 +0100
Subject: [PATCH 33/34] doc: add documentation for 'memcmp' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-34-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/mem.c             |   33 +++++++++++++++++++--------------
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index c9a786d..7f5c4f7 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -67,7 +67,7 @@ available in @a Barebox:
 @li @subpage ls_command
 @li @subpage lsmod_command
 @li @subpage md
- at li @subpage memcmp
+ at li @subpage memcmp_command
 @li @subpage meminfo_command
 @li @subpage memset
 @li @subpage menu
diff --git a/commands/mem.c b/commands/mem.c
index dc778d3..f9f71a7 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -310,7 +310,7 @@ BAREBOX_CMD_START(mw)
 	BAREBOX_CMD_HELP(cmd_mw_help)
 BAREBOX_CMD_END
 
-static int do_mem_cmp(struct command *cmdtp, int argc, char *argv[])
+static int do_memcmp(struct command *cmdtp, int argc, char *argv[])
 {
 	ulong	addr1, addr2, count = ~0;
 	int	mode  = O_RWSIZE_1;
@@ -400,21 +400,26 @@ out:
 	return ret;
 }
 
-static const __maybe_unused char cmd_memcmp_help[] =
-"Usage: memcmp [OPTIONS] <addr1> <addr2> <count>\n"
-"\n"
-"options:\n"
-"  -b, -w, -l	use byte, halfword, or word accesses\n"
-"  -s <file>    source file (default /dev/mem)\n"
-"  -d <file>    destination file (default /dev/mem)\n"
-"\n"
-"Compare memory regions specified with addr1 and addr2\n"
-"of size <count> bytes. If source is a file count can\n"
-"be left unspecified in which case the whole file is\n"
-"compared\n";
+BAREBOX_CMD_HELP_START(memcmp)
+BAREBOX_CMD_HELP_USAGE("memcmp [OPTIONS] ADDR1 ADDR2 COUNT\n")
+BAREBOX_CMD_HELP_SHORT("Compare memory regions ADDR1 and ADDR2 of COUNT bytes.\n")
+BAREBOX_CMD_HELP_OPT  ("-b, -w, -l", "use byte, halfword or word accesses\n")
+BAREBOX_CMD_HELP_OPT  ("-s <file>", "source file (default: /dev/mem)\n")
+BAREBOX_CMD_HELP_OPT  ("-d <file>", "destination file (default: /dev/mem)\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page memcmp_command
+
+<p> If source is a file, count can be left unspecified. In this case the
+whole file is compared.</p>
+
+\todo Add example.
+
+ */
 
 BAREBOX_CMD_START(memcmp)
-	.cmd		= do_mem_cmp,
+	.cmd		= do_memcmp,
 	.usage		= "memory compare",
 	BAREBOX_CMD_HELP(cmd_memcmp_help)
 BAREBOX_CMD_END
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:33 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:33 +0100
Subject: [PATCH 19/34] doc: add documentation for 'false' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-20-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/false.c           |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index cf91a49..087ab4e 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -43,7 +43,7 @@ available in @a Barebox:
 @li @subpage exec
 @li @subpage exit
 @li @subpage export_command
- at li @subpage false
+ at li @subpage false_command
 @li @subpage getopt
 @li @subpage gpio_get_value_command
 @li @subpage gpio_set_value_command
diff --git a/commands/false.c b/commands/false.c
index a90eadc..b7e3983 100644
--- a/commands/false.c
+++ b/commands/false.c
@@ -29,6 +29,11 @@ static int do_false(struct command *cmdtp, int argc, char *argv[])
 	return 1;
 }
 
+BAREBOX_CMD_HELP_START(false)
+BAREBOX_CMD_HELP_USAGE("false\n")
+BAREBOX_CMD_HELP_SHORT("Do nothing, unsuccessfully.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(false)
 	.cmd		= do_false,
 	.usage		= "do nothing, unsuccessfully",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:25 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:25 +0100
Subject: [PATCH 11/34] doc: add documentation for 'rmdir' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-12-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/rmdir.c           |    7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index b0919d0..db3be1a 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -89,7 +89,7 @@ available in @a Barebox:
 @li @subpage rarpboot
 @li @subpage reginfo
 @li @subpage rm_command
- at li @subpage rmdir
+ at li @subpage rmdir_command
 @li @subpage saveenv_command
 @li @subpage setenv_command
 @li @subpage sh
diff --git a/commands/rmdir.c b/commands/rmdir.c
index 83a0b02..0a8838b 100644
--- a/commands/rmdir.c
+++ b/commands/rmdir.c
@@ -21,9 +21,10 @@ static int do_rmdir(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_rmdir_help[] =
-"Usage: rmdir [directories]\n"
-"Remove directories. The directories have to be empty.\n";
+BAREBOX_CMD_HELP_START(rmdir)
+BAREBOX_CMD_HELP_USAGE("rmdir DIRECTORIES\n")
+BAREBOX_CMD_HELP_SHORT("Remove directories. The directories have to be empty.\n")
+BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(rmdir)
 	.cmd		= do_rmdir,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:18 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:18 +0100
Subject: [PATCH 04/34] doc: add documentation for 'umount' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-5-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/umount.c          |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index cc892d4..07ae9d2 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -102,7 +102,7 @@ available in @a Barebox:
 @li @subpage ubiattach
 @li @subpage ubimkvol
 @li @subpage ubirmvol
- at li @subpage umount
+ at li @subpage umount_command
 @li @subpage unlzo_command
 @li @subpage unprotect_command
 @li @subpage usb
diff --git a/commands/umount.c b/commands/umount.c
index 6ae5844..5295604 100644
--- a/commands/umount.c
+++ b/commands/umount.c
@@ -38,9 +38,17 @@ static int do_umount(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_umount_help[] =
-"Usage: umount <mountpoint>\n"
-"umount a filesystem mounted on a specific mountpoint\n";
+BAREBOX_CMD_HELP_START(umount)
+BAREBOX_CMD_HELP_USAGE("umount <mountpoint>\n")
+BAREBOX_CMD_HELP_SHORT("Unmount a filesystem mounted on a specific mountpoint.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page umount_command
+
+\todo Add an example
+
+ */
 
 BAREBOX_CMD_START(umount)
 	.cmd		= do_umount,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:27 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:27 +0100
Subject: [PATCH 13/34] doc: add documentation for 'test' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-14-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/test.c            |   16 ++++++++++------
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 45947e9..0293edc 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -95,7 +95,7 @@ available in @a Barebox:
 @li @subpage sh
 @li @subpage sleep_command
 @li @subpage source
- at li @subpage test
+ at li @subpage test_command
 @li @subpage timeout_command
 @li @subpage true_command
 @li @subpage tftp_command
diff --git a/commands/test.c b/commands/test.c
index 4af3515..89a1764 100644
--- a/commands/test.c
+++ b/commands/test.c
@@ -222,16 +222,20 @@ out:
 
 static const char *test_aliases[] = { "[", NULL};
 
-static const __maybe_unused char cmd_test_help[] =
-"Usage: test [OPTIONS]\n"
-"options: !, =, !=, -eq, -ne, -ge, -gt, -le, -lt, -o, -a, -z, -n, -d, -e, -f\n"
-"see 'man test' on your PC for more information.\n";
+BAREBOX_CMD_HELP_START(test)
+BAREBOX_CMD_HELP_USAGE("test [OPTIONS]\n")
+BAREBOX_CMD_HELP_SHORT("!, =, !=, -eq, -ne, -ge, -gt, -le, -lt, -o, -a, -z, -n, -d, -e, -f\n")
+BAREBOX_CMD_HELP_END
 
-static const __maybe_unused char cmd_test_usage[] = "minimal test like /bin/sh";
+/**
+ * @page test_command
+
+See 'man test' on your PC for more information.
+ */
 
 BAREBOX_CMD_START(test)
 	.aliases	= test_aliases,
 	.cmd		= do_test,
-	.usage		= cmd_test_usage,
+	.usage		= "test for a condition",
 	BAREBOX_CMD_HELP(cmd_test_help)
 BAREBOX_CMD_END
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:36 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:36 +0100
Subject: [PATCH 22/34] doc: add documentation for 'reginfo' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-23-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/reginfo.c         |   12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 2d3d5f2..c26abc2 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -87,7 +87,7 @@ available in @a Barebox:
 @li @subpage readline_command
 @li @subpage reset_command
 @li @subpage rarpboot
- at li @subpage reginfo
+ at li @subpage reginfo_command
 @li @subpage rm_command
 @li @subpage rmdir_command
 @li @subpage saveenv_command
diff --git a/commands/reginfo.c b/commands/reginfo.c
index 90651d5..6e5be31 100644
--- a/commands/reginfo.c
+++ b/commands/reginfo.c
@@ -29,6 +29,18 @@ static int do_reginfo(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(reginfo)
+BAREBOX_CMD_HELP_USAGE("reginfo\n")
+BAREBOX_CMD_HELP_SHORT("Print register information.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page reginfo_command
+
+\todo Add more reginfo documentation.
+
+ */
+
 BAREBOX_CMD_START(reginfo)
 	.cmd		= do_reginfo,
 	.usage		= "print register information",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:48 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:48 +0100
Subject: [PATCH 34/34] doc: add documentation for 'md' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-35-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/mem.c             |   37 ++++++++++++++++++++-----------------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 7f5c4f7..1148e3d 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -66,7 +66,7 @@ available in @a Barebox:
 @li @subpage login
 @li @subpage ls_command
 @li @subpage lsmod_command
- at li @subpage md
+ at li @subpage md_command
 @li @subpage memcmp_command
 @li @subpage meminfo_command
 @li @subpage memset
diff --git a/commands/mem.c b/commands/mem.c
index f9f71a7..76bfa0a 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -212,24 +212,27 @@ out:
 	return errno;
 }
 
-static const __maybe_unused char cmd_md_help[] =
-"Usage md [OPTIONS] <region>\n"
-"display (hexdump) a memory region.\n"
-"options:\n"
-"  -s <file>   display file (default /dev/mem)\n"
-"  -b          output in bytes\n"
-"  -w          output in halfwords (16bit)\n"
-"  -l          output in words (32bit)\n"
-"\n"
-"Memory regions:\n"
-"Memory regions can be specified in two different forms: start+size\n"
-"or start-end, If <start> is ommitted it defaults to 0. If end is ommited it\n"
-"defaults to the end of the device, except for interactive commands like md\n"
-"and mw for which it defaults to 0x100.\n"
-"Sizes can be specified as decimal, or if prefixed with 0x as hexadecimal.\n"
-"an optional suffix of k, M or G is for kibibytes, Megabytes or Gigabytes,\n"
-"respectively\n";
 
+BAREBOX_CMD_HELP_START(md)
+BAREBOX_CMD_HELP_USAGE("md [OPTIONS] <region>\n")
+BAREBOX_CMD_HELP_SHORT("Display (hexdump) a memory region.\n")
+BAREBOX_CMD_HELP_OPT  ("-s <file>", "display file (default: /dev/mem)\n")
+BAREBOX_CMD_HELP_OPT  ("-b", "output in bytes\n")
+BAREBOX_CMD_HELP_OPT  ("-w", "output in halfwords (16 bit)\n")
+BAREBOX_CMD_HELP_OPT  ("-l", "output in words (32 bit)\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page md_command
+
+<p> Memory regions can be specified in two different forms: start+size
+or start-end, If <start> is ommitted it defaults to 0. If end is ommited
+it defaults to the end of the device, except for interactive commands
+like md and mw for which it defaults to 0x100. Sizes can be specified as
+decimal, or if prefixed with 0x as hexadecimal. an optional suffix of k,
+M or G is for kibibytes, Megabytes or Gigabytes, respectively. </p>
+
+ */
 
 BAREBOX_CMD_START(md)
 	.cmd		= do_mem_md,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:44 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:44 +0100
Subject: [PATCH 30/34] doc: add documentation for 'passwd' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-31-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/passwd.c          |   18 +++++++++++++-----
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 7a515c5..44a72da 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -79,7 +79,7 @@ available in @a Barebox:
 @li @subpage nand
 @li @subpage nand_boot_test
 @li @subpage nfs_command
- at li @subpage passwd
+ at li @subpage passwd_command
 @li @subpage ping_command
 @li @subpage printenv_command
 @li @subpage protect_command
diff --git a/commands/passwd.c b/commands/passwd.c
index 9435091..092d7e9 100644
--- a/commands/passwd.c
+++ b/commands/passwd.c
@@ -85,11 +85,19 @@ disable:
 	return ret;
 }
 
-static const __maybe_unused char cmd_passwd_help[] =
-"Usage: passwd\n"
-"passwd allow you to specify a password\n"
-"to disable it put an empty password\n"
-;
+BAREBOX_CMD_HELP_START(passwd)
+BAREBOX_CMD_HELP_USAGE("passwd\n")
+BAREBOX_CMD_HELP_SHORT("Allows you to specify a password.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page passwd_command
+
+To disable the password, specify an empty one.
+
+\todo Add an example.
+
+ */
 
 BAREBOX_CMD_START(passwd)
 	.cmd		= do_passwd,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:42 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:42 +0100
Subject: [PATCH 28/34] doc: add documentation for 'nfs' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-29-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 net/nfs.c                  |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 9638728..8895e0e 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -78,7 +78,7 @@ available in @a Barebox:
 @li @subpage mycdev
 @li @subpage nand
 @li @subpage nand_boot_test
- at li @subpage nfs
+ at li @subpage nfs_command
 @li @subpage passwd
 @li @subpage ping_command
 @li @subpage printenv_command
diff --git a/net/nfs.c b/net/nfs.c
index 4ca1d6e..d8e0bcc 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -725,9 +725,17 @@ err_udp:
 	return nfs_err == 0 ? 0 : 1;
 }
 
-static const __maybe_unused char cmd_nfs_help[] =
-"Usage: nfs <file> [localfile]\n"
-"Load a file via network using nfs protocol.\n";
+BAREBOX_CMD_HELP_START(nfs)
+BAREBOX_CMD_HELP_USAGE("nfs FILE [LOCALFILE]\n")
+BAREBOX_CMD_HELP_SHORT("Load a file via network, using the NFS protocol.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page nfs_command
+
+\todo Add more details and examples.
+
+ */
 
 BAREBOX_CMD_START(nfs)
 	.cmd		= do_nfs,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:19 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:19 +0100
Subject: [PATCH 05/34] doc: add documentation for 'usb' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-6-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 drivers/usb/core/usb.c     |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 07ae9d2..d5536d3 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -105,7 +105,7 @@ available in @a Barebox:
 @li @subpage umount_command
 @li @subpage unlzo_command
 @li @subpage unprotect_command
- at li @subpage usb
+ at li @subpage usb_command
 @li @subpage version_command
 
 */
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 76e033e..38042a5 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -488,9 +488,17 @@ static int do_usb(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_usb_help[] =
-"Usage: usb\n"
-"(re-)detect USB devices\n";
+BAREBOX_CMD_HELP_START(usb)
+BAREBOX_CMD_HELP_USAGE("usb\n")
+BAREBOX_CMD_HELP_SHORT("(re-)detect USB devices.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page usb_command
+
+\todo add examples
+
+ */
 
 BAREBOX_CMD_START(usb)
 	.cmd		= do_usb,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:41 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:41 +0100
Subject: [PATCH 27/34] doc: add documentation for 'ping' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-28-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 net/ping.c                 |   16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 438d33e..9638728 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -80,7 +80,7 @@ available in @a Barebox:
 @li @subpage nand_boot_test
 @li @subpage nfs
 @li @subpage passwd
- at li @subpage ping
+ at li @subpage ping_command
 @li @subpage printenv_command
 @li @subpage protect_command
 @li @subpage pwd_command
diff --git a/net/ping.c b/net/ping.c
index d414784..c46a114 100644
--- a/net/ping.c
+++ b/net/ping.c
@@ -107,7 +107,23 @@ out:
 	return ping_state == PING_STATE_SUCCESS ? 0 : 1;
 }
 
+BAREBOX_CMD_HELP_START(ping)
+BAREBOX_CMD_HELP_USAGE("ping HOST\n")
+BAREBOX_CMD_HELP_SHORT("Send ICMP echo request to network host.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page ping_command
+
+<p> HOST can be an IP address or a host name. If a host name is
+specified, barebox tries to resolve that host name and exits with a
+failure if not successful. If the host didn't answer for 10 seconds,
+ping exits with a failure. </p>
+
+ */
+
 BAREBOX_CMD_START(ping)
 	.cmd		= do_ping,
 	.usage		= "ping <destination>",
+	BAREBOX_CMD_HELP(cmd_ping_help)
 BAREBOX_CMD_END
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:28 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:28 +0100
Subject: [PATCH 14/34] doc: add documentation for 'lsmod' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-15-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/lsmod.c           |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 0293edc..04718b8 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -65,7 +65,7 @@ available in @a Barebox:
 @li @subpage loadxc
 @li @subpage login
 @li @subpage ls_command
- at li @subpage lsmod
+ at li @subpage lsmod_command
 @li @subpage md
 @li @subpage memcmp
 @li @subpage meminfo
diff --git a/commands/lsmod.c b/commands/lsmod.c
index 26d2fe4..9a90e88 100644
--- a/commands/lsmod.c
+++ b/commands/lsmod.c
@@ -12,6 +12,11 @@ static int do_lsmod(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(lsmod)
+BAREBOX_CMD_HELP_USAGE("lsmod\n")
+BAREBOX_CMD_HELP_SHORT("List modules.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(lsmod)
 	.cmd		= do_lsmod,
 	.usage		= "list modules",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:45 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:45 +0100
Subject: [PATCH 31/34] doc: add documentation for 'nand' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-32-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/nand.c            |   22 +++++++++++++++-------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 44a72da..881fc2c 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -76,7 +76,7 @@ available in @a Barebox:
 @li @subpage mtest
 @li @subpage mw
 @li @subpage mycdev
- at li @subpage nand
+ at li @subpage nand_command
 @li @subpage nand_boot_test
 @li @subpage nfs_command
 @li @subpage passwd_command
diff --git a/commands/nand.c b/commands/nand.c
index 0902f21..18c6bd3 100644
--- a/commands/nand.c
+++ b/commands/nand.c
@@ -354,15 +354,23 @@ static int do_nand(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_nand_help[] =
-"Usage: nand [OPTION]...\n"
-"nand related commands\n"
-"  -a  <dev>  register a bad block aware device ontop of a normal nand device\n"
-"  -d  <dev>  deregister a bad block aware device\n"
-"  -b  <ofs> <dev> mark block at offset ofs as bad\n";
+BAREBOX_CMD_HELP_START(nand)
+BAREBOX_CMD_HELP_USAGE("nand [OPTIONS]\n")
+BAREBOX_CMD_HELP_SHORT("NAND related commands.\n")
+BAREBOX_CMD_HELP_OPT  ("-a <dev>", "register a bad block aware device ontop of a normal nand device\n")
+BAREBOX_CMD_HELP_OPT  ("-d <dev>", "deregister a bad block aware device\n")
+BAREBOX_CMD_HELP_OPT  ("-b <ofs> <dev>", "mark block at offset ofs as bad\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page nand_command
+
+\todo This does definitely need more documentation.
+
+ */
 
 BAREBOX_CMD_START(nand)
 	.cmd		= do_nand,
-	.usage		= "NAND specific handling",
+	.usage		= "NAND related commands",
 	BAREBOX_CMD_HELP(cmd_nand_help)
 BAREBOX_CMD_END
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:23 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:23 +0100
Subject: [PATCH 09/34] doc: add documentation for 'sleep' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-10-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/sleep.c           |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 9348743..6598002 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -93,7 +93,7 @@ available in @a Barebox:
 @li @subpage saveenv_command
 @li @subpage setenv_command
 @li @subpage sh
- at li @subpage sleep
+ at li @subpage sleep_command
 @li @subpage source
 @li @subpage test
 @li @subpage timeout_command
diff --git a/commands/sleep.c b/commands/sleep.c
index 40a3a47..972afd6 100644
--- a/commands/sleep.c
+++ b/commands/sleep.c
@@ -43,6 +43,11 @@ static int do_sleep(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(sleep)
+BAREBOX_CMD_HELP_USAGE("sleep <n>\n")
+BAREBOX_CMD_HELP_SHORT("Delay execution for <n> seconds.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(sleep)
 	.cmd		= do_sleep,
 	.usage		= "delay execution for n seconds",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:21 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:21 +0100
Subject: [PATCH 07/34] doc: add documentation for 'timeout' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-8-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/timeout.c         |   23 +++++++++++++++--------
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 56edb43..e25dda0 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -96,7 +96,7 @@ available in @a Barebox:
 @li @subpage sleep
 @li @subpage source
 @li @subpage test
- at li @subpage timeout
+ at li @subpage timeout_command
 @li @subpage true
 @li @subpage tftp_command
 @li @subpage ubiattach_command
diff --git a/commands/timeout.c b/commands/timeout.c
index 5f2ab9a..71a7716 100644
--- a/commands/timeout.c
+++ b/commands/timeout.c
@@ -93,14 +93,21 @@ out:
 	return ret;
 }
 
-static const __maybe_unused char cmd_timeout_help[] =
-"Usage: timeout [OPTION]... <timeout>\n"
-"Wait <timeout> seconds for a timeout. Return 1 if the user intervented\n"
-"or 0 if a timeout occured\n"
-"  -a  interrupt on any key\n"
-"  -c  interrupt on ctrl-c\n"
-"  -r  interrupt on return\n"
-"  -s  silent mode\n";
+BAREBOX_CMD_HELP_START(timeout)
+BAREBOX_CMD_HELP_USAGE("timeout [OPTIONS] <timeout>\n")
+BAREBOX_CMD_HELP_SHORT("Wait <timeout> seconds for a timeout, return 1 on user intervention and 0 on timeout.\n")
+BAREBOX_CMD_HELP_OPT  ("-a",        "interrupt on any key\n")
+BAREBOX_CMD_HELP_OPT  ("-c",        "interrupt on ctrl-c\n")
+BAREBOX_CMD_HELP_OPT  ("-r",        "interrupt on return\n")
+BAREBOX_CMD_HELP_OPT  ("-s",        "silent mode\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page timeout_command
+
+\todo Add an example
+
+ */
 
 BAREBOX_CMD_START(timeout)
 	.cmd		= do_timeout,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:30 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:30 +0100
Subject: [PATCH 16/34] doc: add documentation for 'insmod' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-17-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/insmod.c          |   13 +++++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 2775b2d..cf45b14 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -57,7 +57,7 @@ available in @a Barebox:
 @li @subpage i2c_write
 @li @subpage icache
 @li @subpage iminfo
- at li @subpage insmod
+ at li @subpage insmod_command
 @li @subpage linux16_command
 @li @subpage loadenv_command
 @li @subpage loadb
diff --git a/commands/insmod.c b/commands/insmod.c
index d3b4d1a..65a7d36 100644
--- a/commands/insmod.c
+++ b/commands/insmod.c
@@ -32,8 +32,17 @@ static int do_insmod(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_insmod_help[] =
-"Usage: insmod <module>\n"; 
+BAREBOX_CMD_HELP_START(insmod)
+BAREBOX_CMD_HELP_USAGE("insmod MODULE\n")
+BAREBOX_CMD_HELP_SHORT("Insert a module.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page insmod_command
+
+\todo Add example for module handling.
+
+ */
 
 BAREBOX_CMD_START(insmod)
 	.cmd		= do_insmod,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:32 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:32 +0100
Subject: [PATCH 18/34] doc: add documentation for 'pwd' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-19-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/pwd.c             |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 887c58f..cf91a49 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -83,7 +83,7 @@ available in @a Barebox:
 @li @subpage ping
 @li @subpage printenv_command
 @li @subpage protect_command
- at li @subpage pwd
+ at li @subpage pwd_command
 @li @subpage readline_command
 @li @subpage reset
 @li @subpage rarpboot
diff --git a/commands/pwd.c b/commands/pwd.c
index d51fa1a..2d5afb5 100644
--- a/commands/pwd.c
+++ b/commands/pwd.c
@@ -29,6 +29,11 @@ static int do_pwd(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(pwd)
+BAREBOX_CMD_HELP_USAGE("pwd\n")
+BAREBOX_CMD_HELP_SHORT("Print working directory.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(pwd)
 	.cmd		= do_pwd,
 	.usage		= "print working directory",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:29 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:29 +0100
Subject: [PATCH 15/34] doc: add documentation for 'readline' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-16-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/readline.c        |   14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 04718b8..2775b2d 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -84,7 +84,7 @@ available in @a Barebox:
 @li @subpage printenv_command
 @li @subpage protect_command
 @li @subpage pwd
- at li @subpage readline
+ at li @subpage readline_command
 @li @subpage reset
 @li @subpage rarpboot
 @li @subpage reginfo
diff --git a/commands/readline.c b/commands/readline.c
index cf2625f..14f62dd 100644
--- a/commands/readline.c
+++ b/commands/readline.c
@@ -45,9 +45,17 @@ static int do_readline(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
-static const __maybe_unused char cmd_readline_help[] =
-"Usage: readline <prompt> VAR\n"
-"readline reads a line of user input into variable VAR.\n";
+BAREBOX_CMD_HELP_START(readline)
+BAREBOX_CMD_HELP_USAGE("readline [PROMPT] VAR\n")
+BAREBOX_CMD_HELP_SHORT("Read a line of user input into variable VAR.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page readline_command
+
+\todo Add example.
+
+ */
 
 BAREBOX_CMD_START(readline)
 	.cmd		= do_readline,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:31 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:31 +0100
Subject: [PATCH 17/34] doc: add documentation for 'help' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-18-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/help.c            |   22 +++++++++++++++-------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index cf45b14..887c58f 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -50,7 +50,7 @@ available in @a Barebox:
 @li @subpage gpio_direction_input_command
 @li @subpage gpio_direction_output_command
 @li @subpage go
- at li @subpage help
+ at li @subpage help_command
 @li @subpage host
 @li @subpage i2c_probe
 @li @subpage i2c_read
diff --git a/commands/help.c b/commands/help.c
index f8387bd..6d6e8e6 100644
--- a/commands/help.c
+++ b/commands/help.c
@@ -52,15 +52,23 @@ static int do_help(struct command * cmdtp, int argc, char *argv[])
 	}
 }
 
-static const __maybe_unused char cmd_help_help[] =
-"Show help information (for 'command')\n"
-"'help' prints online help for the monitor commands.\n\n"
-"Without arguments, it prints a short usage message for all commands.\n\n"
-"To get detailed help information for specific commands you can type\n"
-"'help' with one or more command names as arguments.\n";
-
 static const char *help_aliases[] = { "?", NULL};
 
+BAREBOX_CMD_HELP_START(help)
+BAREBOX_CMD_HELP_USAGE("help COMMAND\n")
+BAREBOX_CMD_HELP_SHORT("Show help information for 'command'.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page help_command
+
+'help' prints online help for the barebox commands. Without arguments,
+it prints a shoft usage message for all commands. To get detailed help
+information for specific commands, you can type 'help' with one or more
+command names as arguments.
+
+ */
+
 BAREBOX_CMD_START(help)
 	.cmd		= do_help,
 	.aliases	= help_aliases,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:34 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:34 +0100
Subject: [PATCH 20/34] doc: add documentation for 'exec' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-21-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/exec.c            |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 087ab4e..023a559 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -40,7 +40,7 @@ available in @a Barebox:
 @li @subpage edit_command
 @li @subpage erase_command
 @li @subpage ethact
- at li @subpage exec
+ at li @subpage exec_command
 @li @subpage exit
 @li @subpage export_command
 @li @subpage false_command
diff --git a/commands/exec.c b/commands/exec.c
index 5f093b7..7f655b6 100644
--- a/commands/exec.c
+++ b/commands/exec.c
@@ -53,6 +53,11 @@ out:
 	return 1;
 }
 
+BAREBOX_CMD_HELP_START(exec)
+BAREBOX_CMD_HELP_USAGE("exec SCRIPT\n")
+BAREBOX_CMD_HELP_SHORT("Execute a script.\n")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(exec)
 	.cmd		= do_exec,
 	.usage		= "execute a script",
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:46 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:46 +0100
Subject: [PATCH 32/34] doc: add documentation for 'mw' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-33-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 commands/mem.c             |   20 ++++++++++++++------
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 881fc2c..c9a786d 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -74,7 +74,7 @@ available in @a Barebox:
 @li @subpage mkdir_command
 @li @subpage mount_command
 @li @subpage mtest
- at li @subpage mw
+ at li @subpage mw_command
 @li @subpage mycdev
 @li @subpage nand_command
 @li @subpage nand_boot_test
diff --git a/commands/mem.c b/commands/mem.c
index 73bf915..dc778d3 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -289,12 +289,20 @@ static int do_mem_mw(struct command *cmdtp, int argc, char *argv[])
 	return errno;
 }
 
-static const __maybe_unused char cmd_mw_help[] =
-"Usage: mw [OPTIONS] <region> <value(s)>\n"
-"Write value(s) to the specifies region.\n"
-"options:\n"
-"  -b, -w, -l	use byte, halfword, or word accesses\n"
-"  -d <file>	write file (default /dev/mem)\n";
+BAREBOX_CMD_HELP_START(mw)
+BAREBOX_CMD_HELP_USAGE("mw [OPTIONS] REGION VALUE(s)\n")
+BAREBOX_CMD_HELP_SHORT("Write value(s) to the specified region.\n")
+BAREBOX_CMD_HELP_OPT  ("-b, -w, -l", "use byte, halfword or word accesses\n")
+BAREBOX_CMD_HELP_OPT  ("-d <file>", "write file (default: /dev/mem)\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page mw_command
+
+\todo Add more documentation, especially an example and more info about <region>
+
+ */
+
 
 BAREBOX_CMD_START(mw)
 	.cmd		= do_mem_mw,
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:40 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:40 +0100
Subject: [PATCH 26/34] doc: add documentation for 'sh' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-27-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 common/hush.c              |   15 ++++++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 7f4e489..438d33e 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -92,7 +92,7 @@ available in @a Barebox:
 @li @subpage rmdir_command
 @li @subpage saveenv_command
 @li @subpage setenv_command
- at li @subpage sh
+ at li @subpage sh_command
 @li @subpage sleep_command
 @li @subpage source_command
 @li @subpage test_command
diff --git a/common/hush.c b/common/hush.c
index 4947173..e269836 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -1670,14 +1670,19 @@ static int do_sh(struct command *cmdtp, int argc, char *argv[])
 	return execute_script(argv[1], argc - 1, argv + 1);
 }
 
-static const __maybe_unused char cmd_sh_help[] =
-"Usage: sh filename [arguments]\n"
-"\n"
-"Execute a shell script\n";
+BAREBOX_CMD_HELP_START(sh)
+BAREBOX_CMD_HELP_USAGE("sh FILE [ARGS]\n")
+BAREBOX_CMD_HELP_SHORT("Execute a shell script.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page sh_command
+
+ */
 
 BAREBOX_CMD_START(sh)
 	.cmd		= do_sh,
-	.usage		= "run shell script",
+	.usage		= "execute a shell script",
 	BAREBOX_CMD_HELP(cmd_sh_help)
 BAREBOX_CMD_END
 
-- 
1.7.2.3



From r.schwebel at pengutronix.de  Wed Dec 15 06:51:43 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Wed, 15 Dec 2010 12:51:43 +0100
Subject: [PATCH 29/34] doc: add documentation for 'rarpboot' command
In-Reply-To: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <1292413908-464-30-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/commands.dox |    2 +-
 Doxyfile                   |    3 ++-
 commands/net.c             |   19 ++++++++++++++++---
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/Documentation/commands.dox b/Documentation/commands.dox
index 8895e0e..7a515c5 100644
--- a/Documentation/commands.dox
+++ b/Documentation/commands.dox
@@ -86,7 +86,7 @@ available in @a Barebox:
 @li @subpage pwd_command
 @li @subpage readline_command
 @li @subpage reset_command
- at li @subpage rarpboot
+ at li @subpage rarpboot_command
 @li @subpage reginfo_command
 @li @subpage rm_command
 @li @subpage rmdir_command
diff --git a/Doxyfile b/Doxyfile
index 89151e3..73dbb6d 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -1070,7 +1070,8 @@ INCLUDE_FILE_PATTERNS  =
 PREDEFINED             = \
 			DOXYGEN_SHOULD_SKIP_THIS \
 			CONFIG_CMD_DEVINFO \
-			CONFIG_NET_TFTP_PUSH
+			CONFIG_NET_TFTP_PUSH \
+			CONFIG_NET_RARP
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
 # this tag can be used to specify a list of macro names that should be expanded.
diff --git a/commands/net.c b/commands/net.c
index 938463c..3adf537 100644
--- a/commands/net.c
+++ b/commands/net.c
@@ -38,7 +38,7 @@
 #ifdef CONFIG_NET_RARP
 extern void RarpRequest(void);
 
-static int do_rarpb(struct command *cmdtp, int argc, char *argv[])
+static int do_rarpboot(struct command *cmdtp, int argc, char *argv[])
 {
 	int size;
 
@@ -57,11 +57,24 @@ static int do_rarpb(struct command *cmdtp, int argc, char *argv[])
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(rarpboot)
+BAREBOX_CMD_HELP_USAGE("rarpboot [LOADADDR] [BOOTFILENAME]\n")
+BAREBOX_CMD_HELP_SHORT("Boot an image via network using rarp/tftp protocol.\n")
+BAREBOX_CMD_HELP_END
+
+/**
+ * @page rarpboot_command
+
+\todo Discuss this command with sha. The signature looks wrong.
+
+ */
+
 BAREBOX_CMD_START(rarpboot)
-	.cmd		= do_rarpb,
+	.cmd		= do_rarpboot,
 	.usage		= "boot image via network using rarp/tftp protocol",
-	BAREBOX_CMD_HELP("[loadAddress] [bootfilename]\n")
+	BAREBOX_CMD_HELP(cmd_rarpboot_help)
 BAREBOX_CMD_END
+
 #endif /* CONFIG_NET_RARP */
 
 static int do_ethact(struct command *cmdtp, int argc, char *argv[])
-- 
1.7.2.3



From s.hauer at pengutronix.de  Wed Dec 15 14:16:41 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 15 Dec 2010 20:16:41 +0100
Subject: [PATCH 03/34] doc: add documentation for 'unlzo' command
In-Reply-To: <1292413908-464-4-git-send-email-r.schwebel@pengutronix.de>
References: <1292413908-464-1-git-send-email-r.schwebel@pengutronix.de>
	<1292413908-464-4-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <20101215191641.GG6017@pengutronix.de>

On Wed, Dec 15, 2010 at 12:51:17PM +0100, Robert Schwebel wrote:
> Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
> ---
>  Documentation/commands.dox |    2 +-
>  commands/unlzo.c           |   14 +++++++++++---
>  2 files changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/commands.dox b/Documentation/commands.dox
> index 6c2f59d..cc892d4 100644
> --- a/Documentation/commands.dox
> +++ b/Documentation/commands.dox
> @@ -103,7 +103,7 @@ available in @a Barebox:
>  @li @subpage ubimkvol
>  @li @subpage ubirmvol
>  @li @subpage umount
> - at li @subpage unlzo
> + at li @subpage unlzo_command
>  @li @subpage unprotect_command
>  @li @subpage usb
>  @li @subpage version_command
> diff --git a/commands/unlzo.c b/commands/unlzo.c
> index 0b6dd4b..40225e6 100644
> --- a/commands/unlzo.c
> +++ b/commands/unlzo.c
> @@ -57,9 +57,17 @@ exit_close:
>  	return ret;
>  }
>  
> -static const __maybe_unused char cmd_unlzo_help[] =
> -"Usage: unlzo <infile> <outfile>\n"
> -"Uncompress a lzo compressed file\n";
> +BAREBOX_CMD_HELP_START(unlzo)
> +BAREBOX_CMD_HELP_USAGE("unlzo <infile> <outfile>\n")
> +BAREBOX_CMD_HELP_SHORT("Uncompress a lzo compressed file.\n")
> +BAREBOX_CMD_HELP_END
> +
> +/**
> + * @page unlzo_command
> +
> +\todo Add an example, how to handle LZO files in RAM.

That's simple: unlzo <src> <target>, where src and target are valid files
including devices or partitions.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From stephane.list at lilotux.net  Thu Dec 16 05:01:13 2010
From: stephane.list at lilotux.net (Stephane List)
Date: Thu, 16 Dec 2010 11:01:13 +0100
Subject: Phytec's phyCARD-S-i.MX27
Message-ID: <20101216100113.GB5922@lilotux.net>

Hi,

I'm looking at barebox to use it on a phyCARD-S iMX27. I'm still in the
doc ;-)

The file arch/arm/boards/phycard-i.MX27/pca100.dox is not relevant to
the phyCARD-S. It talks about phyCORE. On phyCARD-S, there's a NAND
flash.

Regards

Stephane

-- 
Stephane List
http://slist.lilotux.net


From s.hauer at pengutronix.de  Sat Dec 18 10:15:09 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:09 +0100
Subject: [PATCH 7/7] pcm038: led testing. Not to be committed
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-8-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/pcm038/pcm038.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 1dbc6b6..cfca7d3 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -44,6 +44,7 @@
 #include <mach/spi.h>
 #include <mach/iomux-mx27.h>
 #include <mach/devices-imx27.h>
+#include <led.h>
 
 #include "pll.h"
 
@@ -192,11 +193,26 @@ static void pcm038_mmu_init(void)
 }
 #endif
 
+struct gpio_led led1 = {
+	.gpio = 10,
+};
+
+struct gpio_led led2 = {
+	.gpio = 11,
+	.active_low = 1,
+};
+
+struct gpio_rgb_led led3 = {
+	.gpio_r = 12,
+	.gpio_g = 13,
+	.gpio_b = 14,
+	.active_low = 1,
+};
+
 static int pcm038_devices_init(void)
 {
 	int i;
 	char *envdev;
-
 	unsigned int mode[] = {
 		PD0_AIN_FEC_TXD0,
 		PD1_AIN_FEC_TXD1,
@@ -270,6 +286,12 @@ static int pcm038_devices_init(void)
 
 	pcm038_mmu_init();
 
+	led_gpio_register(&led1);
+	led_gpio_register(&led2);
+	led_gpio_rgb_register(&led3);
+	led_set_trigger(led_trigger_net_tx, &led1.led);
+	led_set_trigger(led_trigger_net_rx, &led2.led);
+
 	/* configure 16 bit nor flash on cs0 */
 	CS0U = 0x0000CC03;
 	CS0L = 0xa0330D01;
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:15:02 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:02 +0100
Subject: LED framework
Message-ID: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>

Hi All,

The following series adds generic LED support for barebox.
Included is an infrastructure to register gpios as LEDs and
generic triggers for LEDs (Heartbeat, network activity). LEDs and
triggers can be controlled in C code and also on the command line.

The last patch only contains a small usage example, I'm not going
to commit it.

I have implemented this patchset completely remote with printfs in
the gpio functions, so I haven't seen any LED blinking. I hope that
the triggers are not too short for a LED to actually blink.

Sascha

The following changes since commit fad11e85641d27f683e2866ec5700cafd5868179:

  eth: fix 'warning: No MAC address set' when using EEPROM MAC (2010-12-16 08:30:14 +0100)

are available in the git repository at:
  git://git.pengutronix.de/git/barebox.git led

Marc Kleine-Budde (1):
      Add generic poll infrastructure

Sascha Hauer (6):
      basic LED support
      LED: Add gpio LED support
      LED: Add LED trigger support
      LED: Add led command
      LED: Add trigger command
      pcm038: led testing. Not to be committed

 arch/arm/boards/pcm038/pcm038.c |   24 ++++++++-
 commands/Kconfig                |   15 +++++
 commands/Makefile               |    2 +
 commands/led.c                  |   60 ++++++++++++++++++++
 commands/trigger.c              |  106 ++++++++++++++++++++++++++++++++++
 common/Kconfig                  |    3 +
 common/Makefile                 |    1 +
 common/console.c                |    5 ++
 common/poller.c                 |   45 +++++++++++++++
 drivers/Kconfig                 |    1 +
 drivers/Makefile                |    1 +
 drivers/led/Kconfig             |   13 ++++
 drivers/led/Makefile            |    3 +
 drivers/led/core.c              |  119 +++++++++++++++++++++++++++++++++++++++
 drivers/led/led-gpio.c          |   92 ++++++++++++++++++++++++++++++
 include/led.h                   |   69 ++++++++++++++++++++++
 include/net.h                   |    3 +
 include/poller.h                |   31 ++++++++++
 lib/vsprintf.c                  |    4 +
 net/eth.c                       |   20 ++++++-
 net/net.c                       |   21 +++++--
 21 files changed, 631 insertions(+), 7 deletions(-)
 create mode 100644 commands/led.c
 create mode 100644 commands/trigger.c
 create mode 100644 common/poller.c
 create mode 100644 drivers/led/Kconfig
 create mode 100644 drivers/led/Makefile
 create mode 100644 drivers/led/core.c
 create mode 100644 drivers/led/led-gpio.c
 create mode 100644 include/led.h
 create mode 100644 include/poller.h



From s.hauer at pengutronix.de  Sat Dec 18 10:15:08 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:08 +0100
Subject: [PATCH 6/7] LED: Add trigger command
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-7-git-send-email-s.hauer@pengutronix.de>

This patch allows controlling LED triggers vie the command line.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/Kconfig   |    8 ++++
 commands/Makefile  |    1 +
 commands/trigger.c |  106 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 commands/trigger.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 64e08bb..f137f47 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -379,4 +379,12 @@ config CMD_LED
 	help
 	  include led command to control LEDs
 
+config CMD_LED_TRIGGER
+	bool
+	depends on LED_TRIGGERS
+	prompt "trigger command"
+	help
+	  The trigger command allows to control LED triggers from the command
+	  line.
+
 endmenu
diff --git a/commands/Makefile b/commands/Makefile
index 0820483..c89adcf 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_CMD_MENU)		+= menu.o
 obj-$(CONFIG_CMD_PASSWD)	+= passwd.o
 obj-$(CONFIG_CMD_LOGIN)		+= login.o
 obj-$(CONFIG_CMD_LED)		+= led.o
+obj-$(CONFIG_CMD_LED_TRIGGER)	+= trigger.o
diff --git a/commands/trigger.c b/commands/trigger.c
new file mode 100644
index 0000000..51d4ce3
--- /dev/null
+++ b/commands/trigger.c
@@ -0,0 +1,106 @@
+/*
+ * LED trigger command support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <led.h>
+#include <command.h>
+#include <getopt.h>
+#include <errno.h>
+
+#define LED_COMMAND_SET_TRIGGER		1
+#define LED_COMMAND_SHOW_INFO		2
+#define	LED_COMMAND_DISABLE_TRIGGER	3
+
+static char *trigger_names[] = {
+	[led_trigger_panic] = "panic",
+	[led_trigger_heartbeat] = "heartbeat",
+	[led_trigger_net_rx] = "net rx",
+	[led_trigger_net_tx] = "net tx",
+	[led_trigger_net_txrx] = "net",
+};
+
+static int do_trigger(struct command *cmdtp, int argc, char *argv[])
+{
+	struct led *led;
+	int i, opt, ret = 0;
+	int cmd = LED_COMMAND_SHOW_INFO;
+	unsigned long trigger = 0, ledno;
+
+	while((opt = getopt(argc, argv, "t:d:")) > 0) {
+		switch(opt) {
+		case 't':
+			trigger = simple_strtoul(optarg, NULL, 0);
+			cmd = LED_COMMAND_SET_TRIGGER;
+			break;
+		case 'd':
+			trigger = simple_strtoul(optarg, NULL, 0);
+			cmd = LED_COMMAND_DISABLE_TRIGGER;
+		}
+	}
+
+	switch (cmd) {
+	case LED_COMMAND_SHOW_INFO:
+		for (i = 0; i < led_trigger_max; i++) {
+			int led = led_get_trigger(i);
+			printf("%d: %s", i, trigger_names[i]);
+			if (led >= 0)
+				printf(" (led %d)", led);
+			printf("\n");
+		}
+		break;
+
+	case LED_COMMAND_DISABLE_TRIGGER:
+		led_set_trigger(trigger, NULL);
+		return 0;
+	case LED_COMMAND_SET_TRIGGER:
+		if (argc - optind != 1)
+			return COMMAND_ERROR_USAGE;
+		ledno = simple_strtoul(argv[optind], NULL, 0);
+		led = led_by_number(ledno);
+
+		if (!led) {
+			printf("no such led: %d\n", ledno);
+			return 1;
+		}
+
+		ret = led_set_trigger(trigger, led);
+		break;
+	}
+
+	return ret ? 1 : 0;
+}
+
+BAREBOX_CMD_HELP_START(trigger)
+BAREBOX_CMD_HELP_USAGE("trigger [OPTIONS]\n")
+BAREBOX_CMD_HELP_SHORT("control a LED trigger. Without options the currently assigned triggers are shown.\n")
+BAREBOX_CMD_HELP_OPT  ("-t <trigger> <led>",  "set a trigger for a led\n")
+BAREBOX_CMD_HELP_OPT  ("-d <trigger>",  "disable a trigger\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(trigger)
+	.cmd		= do_trigger,
+	.usage		= "handle LED triggers",
+	BAREBOX_CMD_HELP(cmd_trigger_help)
+BAREBOX_CMD_END
+
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:15:05 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:05 +0100
Subject: [PATCH 3/7] LED: Add gpio LED support
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-4-git-send-email-s.hauer@pengutronix.de>

This patch adds support for registering gpios as LEDs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/led/Kconfig    |    4 ++
 drivers/led/Makefile   |    1 +
 drivers/led/led-gpio.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/led.h          |   18 +++++++++
 4 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 drivers/led/led-gpio.c

diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 964626c..b5e2f97 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -3,4 +3,8 @@ menuconfig LED
 
 if LED
 
+config LED_GPIO
+	bool "gpio LED support"
+	depends on GENERIC_GPIO
+
 endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 0c1a6b6..29b9fd5 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_LED) += core.o
+obj-$(CONFIG_LED_GPIO) += led-gpio.o
diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c
new file mode 100644
index 0000000..d4505d1
--- /dev/null
+++ b/drivers/led/led-gpio.c
@@ -0,0 +1,92 @@
+/*
+ * gpio LED support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <led.h>
+#include <asm/gpio.h>
+
+static void led_gpio_set(struct led *led, unsigned int value)
+{
+	struct gpio_led *gpio_led = container_of(led, struct gpio_led, led);
+
+	gpio_direction_output(gpio_led->gpio, !!value ^ gpio_led->active_low);
+}
+
+/**
+ * led_gpio_register - register a gpio controlled LED
+ * @param led	The gpio LED
+ *
+ * This function registers a single gpio as a LED. led->gpio
+ * should be initialized to the gpio to control.
+ */
+int led_gpio_register(struct gpio_led *led)
+{
+	led->led.set = led_gpio_set;
+	led->led.max_value = 1;
+
+	return led_register(&led->led);
+}
+
+/**
+ * led_gpio_unregister - remove a gpio controlled LED from the framework
+ * @param led	The gpio LED
+ */
+void led_gpio_unregister(struct gpio_led *led)
+{
+	led_unregister(&led->led);
+}
+
+static void led_gpio_rgb_set(struct led *led, unsigned int value)
+{
+	struct gpio_rgb_led *rgb = container_of(led, struct gpio_rgb_led, led);
+	int al = rgb->active_low;
+
+	gpio_direction_output(rgb->gpio_r, !!(value & 4) ^ al);
+	gpio_direction_output(rgb->gpio_g, !!(value & 2) ^ al);
+	gpio_direction_output(rgb->gpio_b, !!(value & 1) ^ al);
+}
+
+/**
+ * led_gpio_rgb_register - register three gpios as a rgb LED
+ * @param led	The gpio rg LED
+ *
+ * This function registers three gpios as a rgb LED. led->gpio[rgb]
+ * should be initialized to the gpios to control.
+ */
+int led_gpio_rgb_register(struct gpio_rgb_led *led)
+{
+	led->led.set = led_gpio_rgb_set;
+	led->led.max_value = 7;
+
+	return led_register(&led->led);
+}
+
+/**
+ * led_gpio_rgb_unregister - remove a gpio controlled rgb LED from the framework
+ * @param led	The gpio LED
+ */
+void led_gpio_rgb_unregister(struct gpio_led *led)
+{
+	led_unregister(&led->led);
+}
+
diff --git a/include/led.h b/include/led.h
index 62d0d08..98b8c2e 100644
--- a/include/led.h
+++ b/include/led.h
@@ -22,4 +22,22 @@ int led_register(struct led *led);
 void led_unregister(struct led *led);
 void led_unregister(struct led *led);
 
+/* gpio LED support */
+struct gpio_led {
+	int gpio;
+	bool active_low;
+	struct led led;
+};
+
+struct gpio_rgb_led {
+	int gpio_r, gpio_g, gpio_b;
+	bool active_low;
+	struct led led;
+};
+
+int led_gpio_register(struct gpio_led *led);
+void led_gpio_unregister(struct gpio_led *led);
+int led_gpio_rgb_register(struct gpio_rgb_led *led);
+void led_gpio_rgb_unregister(struct gpio_led *led);
+
 #endif /* __LED_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:15:03 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:03 +0100
Subject: [PATCH 1/7] Add generic poll infrastructure
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-2-git-send-email-s.hauer@pengutronix.de>

From: Marc Kleine-Budde <mkl at pengutronix.de>

Barebox does not have interrupt functionality. Nevertheless it's
sometimes useful to periodically call functions, like for example
a heartbeat LED or watchdog reset. Instead of cluttering the code
with calls to these functions this patch adds a generic polling
infrastructure. Code which might run for longer now can call
poller_call() periodically which in turn will call all registered
pollers.
This patch adds a call to poller_call in two generic pathes. First
of them is getc() which covers waiting for uart input. Second is
ctrlc() which should be called anyway from code which might run
for longer. So instead adding poller_call directly to your code,
consider checking ctrlc instead which also gives additional
convenience to the user.
The poller code is safe against reentrancy which means that it's
safe to call poller_call inside a poller.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/Kconfig   |    3 +++
 common/Makefile  |    1 +
 common/console.c |    5 +++++
 common/poller.c  |   45 +++++++++++++++++++++++++++++++++++++++++++++
 include/poller.h |   31 +++++++++++++++++++++++++++++++
 5 files changed, 85 insertions(+), 0 deletions(-)
 create mode 100644 common/poller.c
 create mode 100644 include/poller.h

diff --git a/common/Kconfig b/common/Kconfig
index 617f640..02bc67e 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -414,6 +414,9 @@ config DEFAULT_ENVIRONMENT_PATH
 	  Relative pathes will be relative to the barebox Toplevel dir, but absolute
 	  pathes are fine aswell.
 
+config POLLER
+	bool "generic polling infrastructure"
+
 endmenu
 
 menu "Debugging                     "
diff --git a/common/Makefile b/common/Makefile
index 753455b..98c9d36 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_OF_FLAT_TREE)	+= ft_build.o
 obj-$(CONFIG_KALLSYMS)		+= kallsyms.o
 obj-$(CONFIG_ENV_HANDLING)	+= environment.o
 obj-$(CONFIG_AUTO_COMPLETE)	+= complete.o
+obj-$(CONFIG_POLLER)		+= poller.o
 
 obj-y += dlmalloc.o
 obj-y += clock.o
diff --git a/common/console.c b/common/console.c
index 82786f2..39ead4b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -34,6 +34,7 @@
 #include <clock.h>
 #include <kfifo.h>
 #include <module.h>
+#include <poller.h>
 #include <linux/list.h>
 
 LIST_HEAD(console_list);
@@ -205,6 +206,8 @@ int getc(void)
 	 */
 	start = get_time_ns();
 	while (1) {
+		poller_call();
+
 		if (tstc()) {
 			kfifo_putc(console_input_buffer, getc_raw());
 
@@ -397,6 +400,8 @@ EXPORT_SYMBOL(vprintf);
 /* test if ctrl-c was pressed */
 int ctrlc (void)
 {
+	poller_call();
+
 	if (tstc() && getc() == 3)
 		return 1;
 	return 0;
diff --git a/common/poller.c b/common/poller.c
new file mode 100644
index 0000000..0583a53
--- /dev/null
+++ b/common/poller.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <module.h>
+#include <param.h>
+#include <poller.h>
+
+static LIST_HEAD(poller_list);
+static int poller_active;
+
+int poller_register(struct poller_struct *poller)
+{
+	list_add_tail(&poller->list, &poller_list);
+
+	return 0;
+}
+
+int poller_unregister(struct poller_struct *poller)
+{
+	list_del(&poller->list);
+
+	return 0;
+}
+
+void poller_call(void)
+{
+	struct poller_struct *poller, *tmp;
+
+	if (poller_active)
+		return;
+
+	poller_active = 1;
+
+	list_for_each_entry_safe(poller, tmp, &poller_list, list)
+		poller->func(poller);
+
+	poller_active = 0;
+}
diff --git a/include/poller.h b/include/poller.h
new file mode 100644
index 0000000..dc98155
--- /dev/null
+++ b/include/poller.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef POLLER_H
+#define POLLER_H
+
+#include <linux/list.h>
+
+struct poller_struct {
+	void (*func)(struct poller_struct *poller);
+
+	struct list_head list;
+};
+
+int poller_register(struct poller_struct *poller);
+int poller_unregister(struct poller_struct *poller);
+
+
+#ifdef CONFIG_POLLER
+void poller_call(void);
+#else
+static inline void poller_call(void)
+{
+}
+#endif	/* CONFIG_POLLER */
+
+#endif	/* !POLLER_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:15:06 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:06 +0100
Subject: [PATCH 4/7] LED: Add LED trigger support
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-5-git-send-email-s.hauer@pengutronix.de>

This patch allows to associate LEDs with certain triggers, such
as heartbeat or network activity.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/led/Kconfig  |    3 +++
 drivers/led/Makefile |    1 +
 include/led.h        |   26 ++++++++++++++++++++++++++
 include/net.h        |    3 +++
 lib/vsprintf.c       |    4 ++++
 net/eth.c            |   20 +++++++++++++++++++-
 net/net.c            |   21 ++++++++++++++++-----
 7 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index b5e2f97..d8540c5 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -7,4 +7,7 @@ config LED_GPIO
 	bool "gpio LED support"
 	depends on GENERIC_GPIO
 
+config LED_TRIGGERS
+	bool "LED triggers support"
+
 endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 29b9fd5..6aafa6d 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_LED) += core.o
 obj-$(CONFIG_LED_GPIO) += led-gpio.o
+obj-$(CONFIG_LED_TRIGGERS) += led-triggers.o
diff --git a/include/led.h b/include/led.h
index 98b8c2e..2dc0f9d 100644
--- a/include/led.h
+++ b/include/led.h
@@ -22,6 +22,32 @@ int led_register(struct led *led);
 void led_unregister(struct led *led);
 void led_unregister(struct led *led);
 
+/* LED trigger support */
+enum led_trigger {
+	led_trigger_panic,
+	led_trigger_heartbeat,
+	led_trigger_net_rx,
+	led_trigger_net_tx,
+	led_trigger_net_txrx,
+	led_trigger_max,
+};
+
+#ifdef CONFIG_LED_TRIGGERS
+int led_set_trigger(enum led_trigger trigger, struct led *led);
+void led_trigger(enum led_trigger trigger, bool enable);
+#else
+static inline int led_set_trigger(enum led_trigger trigger, struct led *led)
+{
+	return 0;
+}
+
+static inline void led_trigger(enum led_trigger trigger, bool enable)
+{
+}
+#endif
+
+int led_get_trigger(enum led_trigger trigger);
+
 /* gpio LED support */
 struct gpio_led {
 	int gpio;
diff --git a/include/net.h b/include/net.h
index c695e5f..71c314e 100644
--- a/include/net.h
+++ b/include/net.h
@@ -18,6 +18,7 @@
 #include <malloc.h>
 #include <stdlib.h>
 #include <clock.h>
+#include <led.h>
 #include <asm/byteorder.h>	/* for nton* / ntoh* stuff */
 
 
@@ -417,4 +418,6 @@ static inline unsigned char *net_udp_get_payload(struct net_connection *con)
 int net_udp_send(struct net_connection *con, int len);
 int net_icmp_send(struct net_connection *con, int len);
 
+void led_trigger_network(enum led_trigger trigger, int active);
+
 #endif /* __NET_H__ */
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e2ea84d..6117337 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -17,6 +17,7 @@
 #include <malloc.h>
 
 #include <common.h>
+#include <led.h>
 #include <reloc.h>
 
 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
@@ -625,6 +626,9 @@ void __noreturn panic(const char *fmt, ...)
 	vprintf(fmt, args);
 	putchar('\n');
 	va_end(args);
+
+	led_trigger(led_trigger_panic, 1);
+
 #if defined (CONFIG_PANIC_HANG)
 	hang();
 #else
diff --git a/net/eth.c b/net/eth.c
index a82a263..6ac4f09 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -77,7 +77,13 @@ int eth_send(void *packet, int length)
 		eth_current->active = 1;
 	}
 
-	return eth_current->send(eth_current, packet, length);
+	led_trigger_network(led_trigger_net_tx, 1);
+
+	ret = eth_current->send(eth_current, packet, length);
+
+	led_trigger_network(led_trigger_net_tx, 0);
+
+	return ret;
 }
 
 int eth_rx(void)
@@ -183,4 +189,16 @@ void eth_unregister(struct eth_device *edev)
 	list_del(&edev->list);
 }
 
+void led_trigger_network(enum led_trigger trigger, int enable)
+{
+	static bool rx_active, tx_active;
 
+	led_trigger(trigger, enable);
+
+	if (trigger == led_trigger_net_tx)
+		tx_active = enable;
+	if (trigger == led_trigger_net_rx)
+		rx_active = enable;
+
+	led_trigger(led_trigger_net_txrx, tx_active || rx_active);
+}
diff --git a/net/net.c b/net/net.c
index a613d1d..afd5964 100644
--- a/net/net.c
+++ b/net/net.c
@@ -628,19 +628,30 @@ int net_receive(unsigned char *pkt, int len)
 {
 	struct ethernet *et = (struct ethernet *)pkt;
 	int et_protlen = ntohs(et->et_protlen);
+	int ret;
 
-	if (len < ETHER_HDR_SIZE)
-		return 0;
+	led_trigger_network(led_trigger_net_rx, 1);
+
+	if (len < ETHER_HDR_SIZE) {
+		ret = 0;
+		goto out;
+	}
 
 	switch (et_protlen) {
 	case PROT_ARP:
-		return net_handle_arp(pkt, len);
+		ret = net_handle_arp(pkt, len);
+		break;
 	case PROT_IP:
-		return net_handle_ip(pkt, len);
+		ret = net_handle_ip(pkt, len);
+		break;
 	default:
 		debug("%s: got unknown protocol type: %d\n", __func__, et_protlen);
-		return 1;
+		ret = 1;
+		break;
 	}
+out:
+	led_trigger_network(led_trigger_net_rx, 0);
+	return ret;
 }
 
 static int net_init(void)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:15:04 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:04 +0100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>

This patch adds core functionality for controlling LEDs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/Kconfig      |    1 +
 drivers/Makefile     |    1 +
 drivers/led/Kconfig  |    6 +++
 drivers/led/Makefile |    1 +
 drivers/led/core.c   |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/led.h        |   25 ++++++++++
 6 files changed, 153 insertions(+), 0 deletions(-)
 create mode 100644 drivers/led/Kconfig
 create mode 100644 drivers/led/Makefile
 create mode 100644 drivers/led/core.c
 create mode 100644 include/led.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index d94017b..86d8fb5 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -12,5 +12,6 @@ source "drivers/video/Kconfig"
 source "drivers/mci/Kconfig"
 source "drivers/clk/Kconfig"
 source "drivers/mfd/Kconfig"
+source "drivers/led/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 242a564..b1b402f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_MCI) += mci/
 obj-$(CONFIG_VIDEO) += video/
 obj-y	+= clk/
 obj-y	+= mfd/
+obj-$(CONFIG_LED) += led/
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
new file mode 100644
index 0000000..964626c
--- /dev/null
+++ b/drivers/led/Kconfig
@@ -0,0 +1,6 @@
+menuconfig LED
+	bool "LED support"
+
+if LED
+
+endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
new file mode 100644
index 0000000..0c1a6b6
--- /dev/null
+++ b/drivers/led/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_LED) += core.o
diff --git a/drivers/led/core.c b/drivers/led/core.c
new file mode 100644
index 0000000..4a0f0a6
--- /dev/null
+++ b/drivers/led/core.c
@@ -0,0 +1,119 @@
+/*
+ * core LED support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <linux/list.h>
+#include <errno.h>
+#include <asm/gpio.h>
+#include <led.h>
+#include <poller.h>
+#include <clock.h>
+
+/**
+ * @file
+ * @brief LED framework
+ *
+ * This file contains the core LED framework for barebox.
+ *
+ * Each LED can be set to a value where 0 means disabled and values
+ * > 0 mean enabled. LEDs can have different enable values where the
+ * exact meaning depends on the LED, for example a gpio controlled rgb
+ * LED can have enable values from 1 to 7 which correspond to different
+ * colors. value could also mean a brightness.
+ * Each LED is assigned a number. numbers start with 0 and are increased
+ * with each registered LED. The number stays the same during lifecycle,
+ * gaps because of unregistered LEDs are not filled up.
+ */
+
+static LIST_HEAD(leds);
+static int num_leds;
+
+/**
+ * led_by_number - get the number of a LED
+ * @param num number of the LED to return
+ */
+struct led *led_by_number(int num)
+{
+	struct led *led;
+
+	list_for_each_entry(led, &leds, list) {
+		if (led->num == num)
+			return led;
+	}
+
+	return NULL;
+}
+
+/**
+ * led_set - set the value of a LED
+ * @param led	the led
+ * @param value	the value of the LED (0 is disabled)
+ */
+int led_set(struct led *led, unsigned int value)
+{
+	if (value > led->max_value)
+		value = led->max_value;
+
+	led->set(led, value);
+
+	return 0;
+}
+
+/**
+ * led_set_num - set the value of a LED
+ * @param num	the number of the LED
+ * @param value	the value of the LED (0 is disabled)
+ */
+int led_set_num(int num, unsigned int value)
+{
+	struct led *led = led_by_number(num);
+
+	if (!led)
+		return -ENODEV;
+
+	return led_set(led, value);
+}
+
+/**
+ * led_register - Register a LED
+ * @param led	the led
+ */
+int led_register(struct led *led)
+{
+	led->num = num_leds++;
+
+	list_add_tail(&led->list, &leds);
+
+	return 0;
+}
+
+/**
+ * led_unregister - Unegister a LED
+ * @param led	the led
+ */
+void led_unregister(struct led *led)
+{
+	list_del(&led->list);
+}
diff --git a/include/led.h b/include/led.h
new file mode 100644
index 0000000..62d0d08
--- /dev/null
+++ b/include/led.h
@@ -0,0 +1,25 @@
+#ifndef __LED_H
+#define __LED_H
+
+struct led {
+	unsigned long triger;
+	void (*set)(struct led *, unsigned int value);
+	int max_value;
+	int num;
+	struct list_head list;
+};
+
+struct led *led_by_number(int no);
+
+static inline int led_get_number(struct led *led)
+{
+	return led->num;
+}
+
+int led_set_num(int num, unsigned int value);
+int led_set(struct led *led, unsigned int value);
+int led_register(struct led *led);
+void led_unregister(struct led *led);
+void led_unregister(struct led *led);
+
+#endif /* __LED_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:15:07 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:15:07 +0100
Subject: [PATCH 5/7] LED: Add led command
In-Reply-To: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292685309-32326-6-git-send-email-s.hauer@pengutronix.de>

This patch allows controlling LEDs via the command line.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/Kconfig  |    7 ++++++
 commands/Makefile |    1 +
 commands/led.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 commands/led.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 5416073..64e08bb 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -372,4 +372,11 @@ config CMD_I2C
 	  include i2c_probe, i2c_read and i2c_write commands to communicate
 	  on i2c bus.
 
+config CMD_LED
+	bool
+	depends on LED
+	prompt "led command"
+	help
+	  include led command to control LEDs
+
 endmenu
diff --git a/commands/Makefile b/commands/Makefile
index ca30b5f..0820483 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_CMD_UBI)		+= ubi.o
 obj-$(CONFIG_CMD_MENU)		+= menu.o
 obj-$(CONFIG_CMD_PASSWD)	+= passwd.o
 obj-$(CONFIG_CMD_LOGIN)		+= login.o
+obj-$(CONFIG_CMD_LED)		+= led.o
diff --git a/commands/led.c b/commands/led.c
new file mode 100644
index 0000000..ef6250f
--- /dev/null
+++ b/commands/led.c
@@ -0,0 +1,60 @@
+/*
+ * LED command support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <led.h>
+#include <command.h>
+#include <getopt.h>
+#include <errno.h>
+
+static int do_led(struct command *cmdtp, int argc, char *argv[])
+{
+	unsigned long led, value;
+	int ret;
+
+	if (argc != 3)
+		return COMMAND_ERROR_USAGE;
+
+	led = simple_strtoul(argv[optind], NULL, 0);
+	value = simple_strtoul(argv[optind + 1], NULL, 0);
+
+	ret = led_set_num(led, value);
+	if (ret < 0) {
+		perror("led");
+		return 1;
+	}
+
+	return 0;
+}
+
+BAREBOX_CMD_HELP_START(led)
+BAREBOX_CMD_HELP_USAGE("led <led> <value>\n")
+BAREBOX_CMD_HELP_SHORT("control the value of a LED. a value of 0 means disabled\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(led)
+	.cmd		= do_led,
+	.usage		= "led <led> <value>",
+	BAREBOX_CMD_HELP(cmd_led_help)
+BAREBOX_CMD_END
-- 
1.7.2.3



From s.hauer at pengutronix.de  Sat Dec 18 10:28:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 16:28:18 +0100
Subject: [PATCH 1/7] Add generic poll infrastructure
In-Reply-To: <1292685309-32326-2-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-2-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101218152818.GI6017@pengutronix.de>

Hi Marc (Kleine-Budde),

I took the version of this patch I had lying around, please let
me know if you have an updated version.

Sascha

On Sat, Dec 18, 2010 at 04:15:03PM +0100, Sascha Hauer wrote:
> From: Marc Kleine-Budde <mkl at pengutronix.de>
> 
> Barebox does not have interrupt functionality. Nevertheless it's
> sometimes useful to periodically call functions, like for example
> a heartbeat LED or watchdog reset. Instead of cluttering the code
> with calls to these functions this patch adds a generic polling
> infrastructure. Code which might run for longer now can call
> poller_call() periodically which in turn will call all registered
> pollers.
> This patch adds a call to poller_call in two generic pathes. First
> of them is getc() which covers waiting for uart input. Second is
> ctrlc() which should be called anyway from code which might run
> for longer. So instead adding poller_call directly to your code,
> consider checking ctrlc instead which also gives additional
> convenience to the user.
> The poller code is safe against reentrancy which means that it's
> safe to call poller_call inside a poller.
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  common/Kconfig   |    3 +++
>  common/Makefile  |    1 +
>  common/console.c |    5 +++++
>  common/poller.c  |   45 +++++++++++++++++++++++++++++++++++++++++++++
>  include/poller.h |   31 +++++++++++++++++++++++++++++++
>  5 files changed, 85 insertions(+), 0 deletions(-)
>  create mode 100644 common/poller.c
>  create mode 100644 include/poller.h
> 
> diff --git a/common/Kconfig b/common/Kconfig
> index 617f640..02bc67e 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -414,6 +414,9 @@ config DEFAULT_ENVIRONMENT_PATH
>  	  Relative pathes will be relative to the barebox Toplevel dir, but absolute
>  	  pathes are fine aswell.
>  
> +config POLLER
> +	bool "generic polling infrastructure"
> +
>  endmenu
>  
>  menu "Debugging                     "
> diff --git a/common/Makefile b/common/Makefile
> index 753455b..98c9d36 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -5,6 +5,7 @@ obj-$(CONFIG_OF_FLAT_TREE)	+= ft_build.o
>  obj-$(CONFIG_KALLSYMS)		+= kallsyms.o
>  obj-$(CONFIG_ENV_HANDLING)	+= environment.o
>  obj-$(CONFIG_AUTO_COMPLETE)	+= complete.o
> +obj-$(CONFIG_POLLER)		+= poller.o
>  
>  obj-y += dlmalloc.o
>  obj-y += clock.o
> diff --git a/common/console.c b/common/console.c
> index 82786f2..39ead4b 100644
> --- a/common/console.c
> +++ b/common/console.c
> @@ -34,6 +34,7 @@
>  #include <clock.h>
>  #include <kfifo.h>
>  #include <module.h>
> +#include <poller.h>
>  #include <linux/list.h>
>  
>  LIST_HEAD(console_list);
> @@ -205,6 +206,8 @@ int getc(void)
>  	 */
>  	start = get_time_ns();
>  	while (1) {
> +		poller_call();
> +
>  		if (tstc()) {
>  			kfifo_putc(console_input_buffer, getc_raw());
>  
> @@ -397,6 +400,8 @@ EXPORT_SYMBOL(vprintf);
>  /* test if ctrl-c was pressed */
>  int ctrlc (void)
>  {
> +	poller_call();
> +
>  	if (tstc() && getc() == 3)
>  		return 1;
>  	return 0;
> diff --git a/common/poller.c b/common/poller.c
> new file mode 100644
> index 0000000..0583a53
> --- /dev/null
> +++ b/common/poller.c
> @@ -0,0 +1,45 @@
> +/*
> + * Copyright (C) 2010 Marc Kleine-Budde <mkl at pengutronix.de>
> + *
> + * This file is released under the GPLv2
> + *
> + */
> +
> +#include <common.h>
> +#include <driver.h>
> +#include <malloc.h>
> +#include <module.h>
> +#include <param.h>
> +#include <poller.h>
> +
> +static LIST_HEAD(poller_list);
> +static int poller_active;
> +
> +int poller_register(struct poller_struct *poller)
> +{
> +	list_add_tail(&poller->list, &poller_list);
> +
> +	return 0;
> +}
> +
> +int poller_unregister(struct poller_struct *poller)
> +{
> +	list_del(&poller->list);
> +
> +	return 0;
> +}
> +
> +void poller_call(void)
> +{
> +	struct poller_struct *poller, *tmp;
> +
> +	if (poller_active)
> +		return;
> +
> +	poller_active = 1;
> +
> +	list_for_each_entry_safe(poller, tmp, &poller_list, list)
> +		poller->func(poller);
> +
> +	poller_active = 0;
> +}
> diff --git a/include/poller.h b/include/poller.h
> new file mode 100644
> index 0000000..dc98155
> --- /dev/null
> +++ b/include/poller.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (C) 2010 Marc Kleine-Budde <mkl at pengutronix.de>
> + *
> + * This file is released under the GPLv2
> + *
> + */
> +
> +#ifndef POLLER_H
> +#define POLLER_H
> +
> +#include <linux/list.h>
> +
> +struct poller_struct {
> +	void (*func)(struct poller_struct *poller);
> +
> +	struct list_head list;
> +};
> +
> +int poller_register(struct poller_struct *poller);
> +int poller_unregister(struct poller_struct *poller);
> +
> +
> +#ifdef CONFIG_POLLER
> +void poller_call(void);
> +#else
> +static inline void poller_call(void)
> +{
> +}
> +#endif	/* CONFIG_POLLER */
> +
> +#endif	/* !POLLER_H */
> -- 
> 1.7.2.3
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From plagnioj at jcrosoft.com  Sat Dec 18 11:38:13 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 18 Dec 2010 17:38:13 +0100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101218163813.GA15695@game.jcrosoft.org>

> +/**
> + * led_set - set the value of a LED
> + * @param led	the led
> + * @param value	the value of the LED (0 is disabled)
> + */
> +int led_set(struct led *led, unsigned int value)
> +{
> +	if (value > led->max_value)
> +		value = led->max_value;
> +
> +	led->set(led, value);
> +
> +	return 0;
why always return 0?
> +}
> +
> +/**
> + * led_set_num - set the value of a LED
> + * @param num	the number of the LED
> + * @param value	the value of the LED (0 is disabled)
> + */
> +int led_set_num(int num, unsigned int value)
> +{
> +	struct led *led = led_by_number(num);
> +
> +	if (!led)
> +		return -ENODEV;
> +
> +	return led_set(led, value);
> +}
> +
> +/**
> + * led_register - Register a LED
> + * @param led	the led
> + */
> +int led_register(struct led *led)
> +{
no safe check?
> +	led->num = num_leds++;
> +
> +	list_add_tail(&led->list, &leds);
> +
> +	return 0;
> +}
> +
> +/**
> + * led_unregister - Unegister a LED
> + * @param led	the led
> + */
> +void led_unregister(struct led *led)
> +{
> +	list_del(&led->list);
> +}
> diff --git a/include/led.h b/include/led.h
> new file mode 100644
> index 0000000..62d0d08
> --- /dev/null
> +++ b/include/led.h
> @@ -0,0 +1,25 @@
> +#ifndef __LED_H
> +#define __LED_H
> +
> +struct led {
> +	unsigned long triger;
> +	void (*set)(struct led *, unsigned int value);
return a int will good to known the result
> +	int max_value;
> +	int num;
> +	struct list_head list;
> +};
> +
> +struct led *led_by_number(int no);
> +
> +static inline int led_get_number(struct led *led)
> +{
> +	return led->num;
> +}
> +
> +int led_set_num(int num, unsigned int value);
> +int led_set(struct led *led, unsigned int value);
> +int led_register(struct led *led);
> +void led_unregister(struct led *led);
> +void led_unregister(struct led *led);
twice

Best Regards,
J.


From plagnioj at jcrosoft.com  Sat Dec 18 11:41:48 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 18 Dec 2010 17:41:48 +0100
Subject: [PATCH 3/7] LED: Add gpio LED support
In-Reply-To: <1292685309-32326-4-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-4-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101218164148.GB15695@game.jcrosoft.org>

> +
> +/**
> + * led_gpio_unregister - remove a gpio controlled LED from the framework
> + * @param led	The gpio LED
> + */
> +void led_gpio_unregister(struct gpio_led *led)
> +{
> +	led_unregister(&led->led);
> +}
> +
how abaout make the rgb support optional?
> +static void led_gpio_rgb_set(struct led *led, unsigned int value)
> +{
> +	struct gpio_rgb_led *rgb = container_of(led, struct gpio_rgb_led, led);
> +	int al = rgb->active_low;
> +
> +	gpio_direction_output(rgb->gpio_r, !!(value & 4) ^ al);
> +	gpio_direction_output(rgb->gpio_g, !!(value & 2) ^ al);
> +	gpio_direction_output(rgb->gpio_b, !!(value & 1) ^ al);
> +}
> +
> +/**
> + * led_gpio_rgb_register - register three gpios as a rgb LED
> + * @param led	The gpio rg LED
> + *
> + * This function registers three gpios as a rgb LED. led->gpio[rgb]
> + * should be initialized to the gpios to control.
> + */
> +int led_gpio_rgb_register(struct gpio_rgb_led *led)
no safe check?
> +{
> +	led->led.set = led_gpio_rgb_set;
> +	led->led.max_value = 7;
> +
> +	return led_register(&led->led);
> +}
> +
> +/**
> + * led_gpio_rgb_unregister - remove a gpio controlled rgb LED from the framework
> + * @param led	The gpio LED
> + */
> +void led_gpio_rgb_unregister(struct gpio_led *led)
> +{
> +	led_unregister(&led->led);
> +}
> +
Best Regards,
J.


From plagnioj at jcrosoft.com  Sat Dec 18 11:45:54 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 18 Dec 2010 17:45:54 +0100
Subject: [PATCH 5/7] LED: Add led command
In-Reply-To: <1292685309-32326-6-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-6-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101218164554.GC15695@game.jcrosoft.org>

On 16:15 Sat 18 Dec     , Sascha Hauer wrote:
> This patch allows controlling LEDs via the command line.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  commands/Kconfig  |    7 ++++++
>  commands/Makefile |    1 +
>  commands/led.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 68 insertions(+), 0 deletions(-)
>  create mode 100644 commands/led.c
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 5416073..64e08bb 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -372,4 +372,11 @@ config CMD_I2C
>  	  include i2c_probe, i2c_read and i2c_write commands to communicate
>  	  on i2c bus.
>  
> +config CMD_LED
> +	bool
> +	depends on LED
> +	prompt "led command"
> +	help
> +	  include led command to control LEDs
> +
>  endmenu
> diff --git a/commands/Makefile b/commands/Makefile
> index ca30b5f..0820483 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -53,3 +53,4 @@ obj-$(CONFIG_CMD_UBI)		+= ubi.o
>  obj-$(CONFIG_CMD_MENU)		+= menu.o
>  obj-$(CONFIG_CMD_PASSWD)	+= passwd.o
>  obj-$(CONFIG_CMD_LOGIN)		+= login.o
> +obj-$(CONFIG_CMD_LED)		+= led.o
> diff --git a/commands/led.c b/commands/led.c
> new file mode 100644
> index 0000000..ef6250f
> --- /dev/null
> +++ b/commands/led.c
> @@ -0,0 +1,60 @@
> +/*
> + * LED command support for barebox
> + *
> + * (C) Copyright 2010 Sascha Hauer, Pengutronix
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <led.h>
> +#include <command.h>
> +#include <getopt.h>
> +#include <errno.h>
> +
> +static int do_led(struct command *cmdtp, int argc, char *argv[])
> +{
> +	unsigned long led, value;
> +	int ret;
> +
> +	if (argc != 3)
> +		return COMMAND_ERROR_USAGE;
> +
> +	led = simple_strtoul(argv[optind], NULL, 0);
> +	value = simple_strtoul(argv[optind + 1], NULL, 0);
> +
> +	ret = led_set_num(led, value);
> +	if (ret < 0) {
> +		perror("led");
> +		return 1;
> +	}
> +
> +	return 0;
> +}
how about list the available led?

Best Regards,
J.


From marek.belisko at gmail.com  Sat Dec 18 11:51:56 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Sat, 18 Dec 2010 17:51:56 +0100
Subject: [PATCH 4/7] LED: Add LED trigger support
In-Reply-To: <1292685309-32326-5-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-5-git-send-email-s.hauer@pengutronix.de>
Message-ID: <AANLkTi=D2uErKO0_HL0poEtcwymgU_E1VfeqUPqe+DW1@mail.gmail.com>

Hi,

On Sat, Dec 18, 2010 at 4:15 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> This patch allows to associate LEDs with certain triggers, such
> as heartbeat or network activity.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
> ?drivers/led/Kconfig ?| ? ?3 +++
> ?drivers/led/Makefile | ? ?1 +
> ?include/led.h ? ? ? ?| ? 26 ++++++++++++++++++++++++++
> ?include/net.h ? ? ? ?| ? ?3 +++
> ?lib/vsprintf.c ? ? ? | ? ?4 ++++
> ?net/eth.c ? ? ? ? ? ?| ? 20 +++++++++++++++++++-
> ?net/net.c ? ? ? ? ? ?| ? 21 ++++++++++++++++-----
> ?7 files changed, 72 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
> index b5e2f97..d8540c5 100644
> --- a/drivers/led/Kconfig
> +++ b/drivers/led/Kconfig
> @@ -7,4 +7,7 @@ config LED_GPIO
> ? ? ? ?bool "gpio LED support"
> ? ? ? ?depends on GENERIC_GPIO
>
> +config LED_TRIGGERS
> + ? ? ? bool "LED triggers support"
> +
> ?endif
> diff --git a/drivers/led/Makefile b/drivers/led/Makefile
> index 29b9fd5..6aafa6d 100644
> --- a/drivers/led/Makefile
> +++ b/drivers/led/Makefile
> @@ -1,2 +1,3 @@
> ?obj-$(CONFIG_LED) += core.o
> ?obj-$(CONFIG_LED_GPIO) += led-gpio.o
> +obj-$(CONFIG_LED_TRIGGERS) += led-triggers.o
> diff --git a/include/led.h b/include/led.h
> index 98b8c2e..2dc0f9d 100644
> --- a/include/led.h
> +++ b/include/led.h
> @@ -22,6 +22,32 @@ int led_register(struct led *led);
> ?void led_unregister(struct led *led);
> ?void led_unregister(struct led *led);
>
> +/* LED trigger support */
> +enum led_trigger {
> + ? ? ? led_trigger_panic,
> + ? ? ? led_trigger_heartbeat,
> + ? ? ? led_trigger_net_rx,
> + ? ? ? led_trigger_net_tx,
> + ? ? ? led_trigger_net_txrx,
> + ? ? ? led_trigger_max,
> +};
shouldn't be enums uppercase?
> +
> +#ifdef CONFIG_LED_TRIGGERS
> +int led_set_trigger(enum led_trigger trigger, struct led *led);
> +void led_trigger(enum led_trigger trigger, bool enable);
> +#else
> +static inline int led_set_trigger(enum led_trigger trigger, struct led *led)
> +{
> + ? ? ? return 0;
> +}
> +
> +static inline void led_trigger(enum led_trigger trigger, bool enable)
> +{
> +}
> +#endif
> +
> +int led_get_trigger(enum led_trigger trigger);
> +
> ?/* gpio LED support */
> ?struct gpio_led {
> ? ? ? ?int gpio;
> diff --git a/include/net.h b/include/net.h
> index c695e5f..71c314e 100644
> --- a/include/net.h
> +++ b/include/net.h
> @@ -18,6 +18,7 @@
> ?#include <malloc.h>
> ?#include <stdlib.h>
> ?#include <clock.h>
> +#include <led.h>
> ?#include <asm/byteorder.h> ? ? /* for nton* / ntoh* stuff */
>
>
> @@ -417,4 +418,6 @@ static inline unsigned char *net_udp_get_payload(struct net_connection *con)
> ?int net_udp_send(struct net_connection *con, int len);
> ?int net_icmp_send(struct net_connection *con, int len);
>
> +void led_trigger_network(enum led_trigger trigger, int active);
> +
> ?#endif /* __NET_H__ */
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index e2ea84d..6117337 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -17,6 +17,7 @@
> ?#include <malloc.h>
>
> ?#include <common.h>
> +#include <led.h>
> ?#include <reloc.h>
>
> ?unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
> @@ -625,6 +626,9 @@ void __noreturn panic(const char *fmt, ...)
> ? ? ? ?vprintf(fmt, args);
> ? ? ? ?putchar('\n');
> ? ? ? ?va_end(args);
> +
> + ? ? ? led_trigger(led_trigger_panic, 1);
> +
> ?#if defined (CONFIG_PANIC_HANG)
> ? ? ? ?hang();
> ?#else
> diff --git a/net/eth.c b/net/eth.c
> index a82a263..6ac4f09 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -77,7 +77,13 @@ int eth_send(void *packet, int length)
> ? ? ? ? ? ? ? ?eth_current->active = 1;
> ? ? ? ?}
>
> - ? ? ? return eth_current->send(eth_current, packet, length);
> + ? ? ? led_trigger_network(led_trigger_net_tx, 1);
> +
> + ? ? ? ret = eth_current->send(eth_current, packet, length);
> +
> + ? ? ? led_trigger_network(led_trigger_net_tx, 0);
> +
> + ? ? ? return ret;
> ?}
>
> ?int eth_rx(void)
> @@ -183,4 +189,16 @@ void eth_unregister(struct eth_device *edev)
> ? ? ? ?list_del(&edev->list);
> ?}
>
> +void led_trigger_network(enum led_trigger trigger, int enable)
> +{
> + ? ? ? static bool rx_active, tx_active;
>
> + ? ? ? led_trigger(trigger, enable);
> +
> + ? ? ? if (trigger == led_trigger_net_tx)
> + ? ? ? ? ? ? ? tx_active = enable;
> + ? ? ? if (trigger == led_trigger_net_rx)
> + ? ? ? ? ? ? ? rx_active = enable;
> +
> + ? ? ? led_trigger(led_trigger_net_txrx, tx_active || rx_active);
> +}
> diff --git a/net/net.c b/net/net.c
> index a613d1d..afd5964 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -628,19 +628,30 @@ int net_receive(unsigned char *pkt, int len)
> ?{
> ? ? ? ?struct ethernet *et = (struct ethernet *)pkt;
> ? ? ? ?int et_protlen = ntohs(et->et_protlen);
> + ? ? ? int ret;
>
> - ? ? ? if (len < ETHER_HDR_SIZE)
> - ? ? ? ? ? ? ? return 0;
> + ? ? ? led_trigger_network(led_trigger_net_rx, 1);
> +
> + ? ? ? if (len < ETHER_HDR_SIZE) {
> + ? ? ? ? ? ? ? ret = 0;
> + ? ? ? ? ? ? ? goto out;
> + ? ? ? }
>
> ? ? ? ?switch (et_protlen) {
> ? ? ? ?case PROT_ARP:
> - ? ? ? ? ? ? ? return net_handle_arp(pkt, len);
> + ? ? ? ? ? ? ? ret = net_handle_arp(pkt, len);
> + ? ? ? ? ? ? ? break;
> ? ? ? ?case PROT_IP:
> - ? ? ? ? ? ? ? return net_handle_ip(pkt, len);
> + ? ? ? ? ? ? ? ret = net_handle_ip(pkt, len);
> + ? ? ? ? ? ? ? break;
> ? ? ? ?default:
> ? ? ? ? ? ? ? ?debug("%s: got unknown protocol type: %d\n", __func__, et_protlen);
> - ? ? ? ? ? ? ? return 1;
> + ? ? ? ? ? ? ? ret = 1;
> + ? ? ? ? ? ? ? break;
> ? ? ? ?}
> +out:
> + ? ? ? led_trigger_network(led_trigger_net_rx, 0);
> + ? ? ? return ret;
> ?}
>
> ?static int net_init(void)
> --
> 1.7.2.3
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From plagnioj at jcrosoft.com  Sat Dec 18 11:48:16 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 18 Dec 2010 17:48:16 +0100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20101218164816.GD15695@game.jcrosoft.org>

Hi,

	how to manage hw led?

	via pwm or hw ip?

Best Regards,
J.


From s.hauer at pengutronix.de  Sat Dec 18 12:18:05 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 18:18:05 +0100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <20101218163813.GA15695@game.jcrosoft.org>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
	<20101218163813.GA15695@game.jcrosoft.org>
Message-ID: <20101218171805.GJ6017@pengutronix.de>

Hi J,

On Sat, Dec 18, 2010 at 05:38:13PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > +/**
> > + * led_set - set the value of a LED
> > + * @param led	the led
> > + * @param value	the value of the LED (0 is disabled)
> > + */
> > +int led_set(struct led *led, unsigned int value)
> > +{
> > +	if (value > led->max_value)
> > +		value = led->max_value;
> > +
> > +	led->set(led, value);
> > +
> > +	return 0;
> why always return 0?

Should make this void, see below.

> > +}
> > +
> > +/**
> > + * led_set_num - set the value of a LED
> > + * @param num	the number of the LED
> > + * @param value	the value of the LED (0 is disabled)
> > + */
> > +int led_set_num(int num, unsigned int value)
> > +{
> > +	struct led *led = led_by_number(num);
> > +
> > +	if (!led)
> > +		return -ENODEV;
> > +
> > +	return led_set(led, value);
> > +}
> > +
> > +/**
> > + * led_register - Register a LED
> > + * @param led	the led
> > + */
> > +int led_register(struct led *led)
> > +{
> no safe check?

What should we check for? NUll pointers? That's not worth it.

> > +	led->num = num_leds++;
> > +
> > +	list_add_tail(&led->list, &leds);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * led_unregister - Unegister a LED
> > + * @param led	the led
> > + */
> > +void led_unregister(struct led *led)
> > +{
> > +	list_del(&led->list);
> > +}
> > diff --git a/include/led.h b/include/led.h
> > new file mode 100644
> > index 0000000..62d0d08
> > --- /dev/null
> > +++ b/include/led.h
> > @@ -0,0 +1,25 @@
> > +#ifndef __LED_H
> > +#define __LED_H
> > +
> > +struct led {
> > +	unsigned long triger;
> > +	void (*set)(struct led *, unsigned int value);
> return a int will good to known the result

I intentionally made this void because setting a LED is not really
supposed to fail. And even if does, I don't know if it's worth anything
to tell the user "setting a LED failed", when this may be even in a loop
and the user is bothered with a hundred of these messages.

> > +	int max_value;
> > +	int num;
> > +	struct list_head list;
> > +};
> > +
> > +struct led *led_by_number(int no);
> > +
> > +static inline int led_get_number(struct led *led)
> > +{
> > +	return led->num;
> > +}
> > +
> > +int led_set_num(int num, unsigned int value);
> > +int led_set(struct led *led, unsigned int value);
> > +int led_register(struct led *led);
> > +void led_unregister(struct led *led);
> > +void led_unregister(struct led *led);
> twice
> 
> Best Regards,
> J.
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Sat Dec 18 12:18:56 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 18:18:56 +0100
Subject: [PATCH 3/7] LED: Add gpio LED support
In-Reply-To: <20101218164148.GB15695@game.jcrosoft.org>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-4-git-send-email-s.hauer@pengutronix.de>
	<20101218164148.GB15695@game.jcrosoft.org>
Message-ID: <20101218171856.GK6017@pengutronix.de>

On Sat, Dec 18, 2010 at 05:41:48PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > +
> > +/**
> > + * led_gpio_unregister - remove a gpio controlled LED from the framework
> > + * @param led	The gpio LED
> > + */
> > +void led_gpio_unregister(struct gpio_led *led)
> > +{
> > +	led_unregister(&led->led);
> > +}
> > +
> how abaout make the rgb support optional?

Good point, most boards do not have this kind of stuff.

> > +static void led_gpio_rgb_set(struct led *led, unsigned int value)
> > +{
> > +	struct gpio_rgb_led *rgb = container_of(led, struct gpio_rgb_led, led);
> > +	int al = rgb->active_low;
> > +
> > +	gpio_direction_output(rgb->gpio_r, !!(value & 4) ^ al);
> > +	gpio_direction_output(rgb->gpio_g, !!(value & 2) ^ al);
> > +	gpio_direction_output(rgb->gpio_b, !!(value & 1) ^ al);
> > +}
> > +
> > +/**
> > + * led_gpio_rgb_register - register three gpios as a rgb LED
> > + * @param led	The gpio rg LED
> > + *
> > + * This function registers three gpios as a rgb LED. led->gpio[rgb]
> > + * should be initialized to the gpios to control.
> > + */
> > +int led_gpio_rgb_register(struct gpio_rgb_led *led)
> no safe check?

no.

> > +{
> > +	led->led.set = led_gpio_rgb_set;
> > +	led->led.max_value = 7;
> > +
> > +	return led_register(&led->led);
> > +}
> > +
> > +/**
> > + * led_gpio_rgb_unregister - remove a gpio controlled rgb LED from the framework
> > + * @param led	The gpio LED
> > + */
> > +void led_gpio_rgb_unregister(struct gpio_led *led)
> > +{
> > +	led_unregister(&led->led);
> > +}
> > +
> Best Regards,
> J.
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Sat Dec 18 12:21:31 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 18:21:31 +0100
Subject: [PATCH 4/7] LED: Add LED trigger support
In-Reply-To: <AANLkTi=D2uErKO0_HL0poEtcwymgU_E1VfeqUPqe+DW1@mail.gmail.com>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-5-git-send-email-s.hauer@pengutronix.de>
	<AANLkTi=D2uErKO0_HL0poEtcwymgU_E1VfeqUPqe+DW1@mail.gmail.com>
Message-ID: <20101218172131.GL6017@pengutronix.de>

Hi Marek,

On Sat, Dec 18, 2010 at 05:51:56PM +0100, Belisko Marek wrote:
> Hi,
> 
> On Sat, Dec 18, 2010 at 4:15 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > This patch allows to associate LEDs with certain triggers, such
> > as heartbeat or network activity.
> >
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> > ?drivers/led/Kconfig ?| ? ?3 +++
> > ?drivers/led/Makefile | ? ?1 +
> > ?include/led.h ? ? ? ?| ? 26 ++++++++++++++++++++++++++
> > ?include/net.h ? ? ? ?| ? ?3 +++
> > ?lib/vsprintf.c ? ? ? | ? ?4 ++++
> > ?net/eth.c ? ? ? ? ? ?| ? 20 +++++++++++++++++++-
> > ?net/net.c ? ? ? ? ? ?| ? 21 ++++++++++++++++-----
> > ?7 files changed, 72 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
> > index b5e2f97..d8540c5 100644
> > --- a/drivers/led/Kconfig
> > +++ b/drivers/led/Kconfig
> > @@ -7,4 +7,7 @@ config LED_GPIO
> > ? ? ? ?bool "gpio LED support"
> > ? ? ? ?depends on GENERIC_GPIO
> >
> > +config LED_TRIGGERS
> > + ? ? ? bool "LED triggers support"
> > +
> > ?endif
> > diff --git a/drivers/led/Makefile b/drivers/led/Makefile
> > index 29b9fd5..6aafa6d 100644
> > --- a/drivers/led/Makefile
> > +++ b/drivers/led/Makefile
> > @@ -1,2 +1,3 @@
> > ?obj-$(CONFIG_LED) += core.o
> > ?obj-$(CONFIG_LED_GPIO) += led-gpio.o
> > +obj-$(CONFIG_LED_TRIGGERS) += led-triggers.o
> > diff --git a/include/led.h b/include/led.h
> > index 98b8c2e..2dc0f9d 100644
> > --- a/include/led.h
> > +++ b/include/led.h
> > @@ -22,6 +22,32 @@ int led_register(struct led *led);
> > ?void led_unregister(struct led *led);
> > ?void led_unregister(struct led *led);
> >
> > +/* LED trigger support */
> > +enum led_trigger {
> > + ? ? ? led_trigger_panic,
> > + ? ? ? led_trigger_heartbeat,
> > + ? ? ? led_trigger_net_rx,
> > + ? ? ? led_trigger_net_tx,
> > + ? ? ? led_trigger_net_txrx,
> > + ? ? ? led_trigger_max,
> > +};
> shouldn't be enums uppercase?

You're right. Will change this.

Sascha

> > +
> > +#ifdef CONFIG_LED_TRIGGERS
> > +int led_set_trigger(enum led_trigger trigger, struct led *led);
> > +void led_trigger(enum led_trigger trigger, bool enable);
> > +#else
> > +static inline int led_set_trigger(enum led_trigger trigger, struct led *led)
> > +{
> > + ? ? ? return 0;
> > +}
> > +
> > +static inline void led_trigger(enum led_trigger trigger, bool enable)
> > +{
> > +}
> > +#endif
> > +
> > +int led_get_trigger(enum led_trigger trigger);
> > +
> > ?/* gpio LED support */
> > ?struct gpio_led {
> > ? ? ? ?int gpio;
> > diff --git a/include/net.h b/include/net.h
> > index c695e5f..71c314e 100644
> > --- a/include/net.h
> > +++ b/include/net.h
> > @@ -18,6 +18,7 @@
> > ?#include <malloc.h>
> > ?#include <stdlib.h>
> > ?#include <clock.h>
> > +#include <led.h>
> > ?#include <asm/byteorder.h> ? ? /* for nton* / ntoh* stuff */
> >
> >
> > @@ -417,4 +418,6 @@ static inline unsigned char *net_udp_get_payload(struct net_connection *con)
> > ?int net_udp_send(struct net_connection *con, int len);
> > ?int net_icmp_send(struct net_connection *con, int len);
> >
> > +void led_trigger_network(enum led_trigger trigger, int active);
> > +
> > ?#endif /* __NET_H__ */
> > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > index e2ea84d..6117337 100644
> > --- a/lib/vsprintf.c
> > +++ b/lib/vsprintf.c
> > @@ -17,6 +17,7 @@
> > ?#include <malloc.h>
> >
> > ?#include <common.h>
> > +#include <led.h>
> > ?#include <reloc.h>
> >
> > ?unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
> > @@ -625,6 +626,9 @@ void __noreturn panic(const char *fmt, ...)
> > ? ? ? ?vprintf(fmt, args);
> > ? ? ? ?putchar('\n');
> > ? ? ? ?va_end(args);
> > +
> > + ? ? ? led_trigger(led_trigger_panic, 1);
> > +
> > ?#if defined (CONFIG_PANIC_HANG)
> > ? ? ? ?hang();
> > ?#else
> > diff --git a/net/eth.c b/net/eth.c
> > index a82a263..6ac4f09 100644
> > --- a/net/eth.c
> > +++ b/net/eth.c
> > @@ -77,7 +77,13 @@ int eth_send(void *packet, int length)
> > ? ? ? ? ? ? ? ?eth_current->active = 1;
> > ? ? ? ?}
> >
> > - ? ? ? return eth_current->send(eth_current, packet, length);
> > + ? ? ? led_trigger_network(led_trigger_net_tx, 1);
> > +
> > + ? ? ? ret = eth_current->send(eth_current, packet, length);
> > +
> > + ? ? ? led_trigger_network(led_trigger_net_tx, 0);
> > +
> > + ? ? ? return ret;
> > ?}
> >
> > ?int eth_rx(void)
> > @@ -183,4 +189,16 @@ void eth_unregister(struct eth_device *edev)
> > ? ? ? ?list_del(&edev->list);
> > ?}
> >
> > +void led_trigger_network(enum led_trigger trigger, int enable)
> > +{
> > + ? ? ? static bool rx_active, tx_active;
> >
> > + ? ? ? led_trigger(trigger, enable);
> > +
> > + ? ? ? if (trigger == led_trigger_net_tx)
> > + ? ? ? ? ? ? ? tx_active = enable;
> > + ? ? ? if (trigger == led_trigger_net_rx)
> > + ? ? ? ? ? ? ? rx_active = enable;
> > +
> > + ? ? ? led_trigger(led_trigger_net_txrx, tx_active || rx_active);
> > +}
> > diff --git a/net/net.c b/net/net.c
> > index a613d1d..afd5964 100644
> > --- a/net/net.c
> > +++ b/net/net.c
> > @@ -628,19 +628,30 @@ int net_receive(unsigned char *pkt, int len)
> > ?{
> > ? ? ? ?struct ethernet *et = (struct ethernet *)pkt;
> > ? ? ? ?int et_protlen = ntohs(et->et_protlen);
> > + ? ? ? int ret;
> >
> > - ? ? ? if (len < ETHER_HDR_SIZE)
> > - ? ? ? ? ? ? ? return 0;
> > + ? ? ? led_trigger_network(led_trigger_net_rx, 1);
> > +
> > + ? ? ? if (len < ETHER_HDR_SIZE) {
> > + ? ? ? ? ? ? ? ret = 0;
> > + ? ? ? ? ? ? ? goto out;
> > + ? ? ? }
> >
> > ? ? ? ?switch (et_protlen) {
> > ? ? ? ?case PROT_ARP:
> > - ? ? ? ? ? ? ? return net_handle_arp(pkt, len);
> > + ? ? ? ? ? ? ? ret = net_handle_arp(pkt, len);
> > + ? ? ? ? ? ? ? break;
> > ? ? ? ?case PROT_IP:
> > - ? ? ? ? ? ? ? return net_handle_ip(pkt, len);
> > + ? ? ? ? ? ? ? ret = net_handle_ip(pkt, len);
> > + ? ? ? ? ? ? ? break;
> > ? ? ? ?default:
> > ? ? ? ? ? ? ? ?debug("%s: got unknown protocol type: %d\n", __func__, et_protlen);
> > - ? ? ? ? ? ? ? return 1;
> > + ? ? ? ? ? ? ? ret = 1;
> > + ? ? ? ? ? ? ? break;
> > ? ? ? ?}
> > +out:
> > + ? ? ? led_trigger_network(led_trigger_net_rx, 0);
> > + ? ? ? return ret;
> > ?}
> >
> > ?static int net_init(void)
> > --
> > 1.7.2.3
> >
> >
> > _______________________________________________
> > barebox mailing list
> > barebox at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/barebox
> >
> 
> thanks,
> 
> marek
> 
> -- 
> as simple and primitive as possible
> -------------------------------------------------
> Marek Belisko - OPEN-NANDRA
> Freelance Developer
> 
> Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
> Tel: +421 915 052 184
> skype: marekwhite
> icq: 290551086
> web: http://open-nandra.com
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Sat Dec 18 12:24:42 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Sat, 18 Dec 2010 18:24:42 +0100
Subject: [PATCH 5/7] LED: Add led command
In-Reply-To: <20101218164554.GC15695@game.jcrosoft.org>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-6-git-send-email-s.hauer@pengutronix.de>
	<20101218164554.GC15695@game.jcrosoft.org>
Message-ID: <20101218172442.GM6017@pengutronix.de>

On Sat, Dec 18, 2010 at 05:45:54PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 16:15 Sat 18 Dec     , Sascha Hauer wrote:
> > This patch allows controlling LEDs via the command line.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  commands/Kconfig  |    7 ++++++
> >  commands/Makefile |    1 +
> >  commands/led.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 68 insertions(+), 0 deletions(-)
> >  create mode 100644 commands/led.c
> > 
> > diff --git a/commands/Kconfig b/commands/Kconfig
> > index 5416073..64e08bb 100644
> > --- a/commands/Kconfig
> > +++ b/commands/Kconfig
> > @@ -372,4 +372,11 @@ config CMD_I2C
> >  	  include i2c_probe, i2c_read and i2c_write commands to communicate
> >  	  on i2c bus.
> >  
> > +config CMD_LED
> > +	bool
> > +	depends on LED
> > +	prompt "led command"
> > +	help
> > +	  include led command to control LEDs
> > +
> >  endmenu
> > diff --git a/commands/Makefile b/commands/Makefile
> > index ca30b5f..0820483 100644
> > --- a/commands/Makefile
> > +++ b/commands/Makefile
> > @@ -53,3 +53,4 @@ obj-$(CONFIG_CMD_UBI)		+= ubi.o
> >  obj-$(CONFIG_CMD_MENU)		+= menu.o
> >  obj-$(CONFIG_CMD_PASSWD)	+= passwd.o
> >  obj-$(CONFIG_CMD_LOGIN)		+= login.o
> > +obj-$(CONFIG_CMD_LED)		+= led.o
> > diff --git a/commands/led.c b/commands/led.c
> > new file mode 100644
> > index 0000000..ef6250f
> > --- /dev/null
> > +++ b/commands/led.c
> > @@ -0,0 +1,60 @@
> > +/*
> > + * LED command support for barebox
> > + *
> > + * (C) Copyright 2010 Sascha Hauer, Pengutronix
> > + *
> > + * See file CREDITS for list of people who contributed to this
> > + * project.
> > + *
> > + * 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, Inc., 59 Temple Place, Suite 330, Boston,
> > + * MA 02111-1307 USA
> > + */
> > +
> > +#include <common.h>
> > +#include <led.h>
> > +#include <command.h>
> > +#include <getopt.h>
> > +#include <errno.h>
> > +
> > +static int do_led(struct command *cmdtp, int argc, char *argv[])
> > +{
> > +	unsigned long led, value;
> > +	int ret;
> > +
> > +	if (argc != 3)
> > +		return COMMAND_ERROR_USAGE;
> > +
> > +	led = simple_strtoul(argv[optind], NULL, 0);
> > +	value = simple_strtoul(argv[optind + 1], NULL, 0);
> > +
> > +	ret = led_set_num(led, value);
> > +	if (ret < 0) {
> > +		perror("led");
> > +		return 1;
> > +	}
> > +
> > +	return 0;
> > +}
> how about list the available led?

What do we want to list here? LEDs do not really have properties other
then the max value (which is probably one for most LEDs). The number of
LEDs would indeed be a good information to have. I also thought about
giving the LEDs names; what do you think?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From marek.belisko at gmail.com  Sat Dec 18 14:06:16 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Sat, 18 Dec 2010 20:06:16 +0100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
Message-ID: <AANLkTimRBbntiw1dQSux6avqMYse+bSxMtYZ=gzQEvc+@mail.gmail.com>

On Sat, Dec 18, 2010 at 4:15 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> This patch adds core functionality for controlling LEDs.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
> ?drivers/Kconfig ? ? ?| ? ?1 +
> ?drivers/Makefile ? ? | ? ?1 +
> ?drivers/led/Kconfig ?| ? ?6 +++
> ?drivers/led/Makefile | ? ?1 +
> ?drivers/led/core.c ? | ?119 ++++++++++++++++++++++++++++++++++++++++++++++++++
> ?include/led.h ? ? ? ?| ? 25 ++++++++++
> ?6 files changed, 153 insertions(+), 0 deletions(-)
> ?create mode 100644 drivers/led/Kconfig
> ?create mode 100644 drivers/led/Makefile
> ?create mode 100644 drivers/led/core.c
> ?create mode 100644 include/led.h
>
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index d94017b..86d8fb5 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -12,5 +12,6 @@ source "drivers/video/Kconfig"
> ?source "drivers/mci/Kconfig"
> ?source "drivers/clk/Kconfig"
> ?source "drivers/mfd/Kconfig"
> +source "drivers/led/Kconfig"
>
> ?endmenu
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 242a564..b1b402f 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_MCI) += mci/
> ?obj-$(CONFIG_VIDEO) += video/
> ?obj-y ?+= clk/
> ?obj-y ?+= mfd/
> +obj-$(CONFIG_LED) += led/
> diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
> new file mode 100644
> index 0000000..964626c
> --- /dev/null
> +++ b/drivers/led/Kconfig
> @@ -0,0 +1,6 @@
> +menuconfig LED
> + ? ? ? bool "LED support"
> +
> +if LED
> +
> +endif
> diff --git a/drivers/led/Makefile b/drivers/led/Makefile
> new file mode 100644
> index 0000000..0c1a6b6
> --- /dev/null
> +++ b/drivers/led/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_LED) += core.o
> diff --git a/drivers/led/core.c b/drivers/led/core.c
> new file mode 100644
> index 0000000..4a0f0a6
> --- /dev/null
> +++ b/drivers/led/core.c
> @@ -0,0 +1,119 @@
> +/*
> + * core LED support for barebox
> + *
> + * (C) Copyright 2010 Sascha Hauer, Pengutronix
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <linux/list.h>
> +#include <errno.h>
> +#include <asm/gpio.h>
> +#include <led.h>
> +#include <poller.h>
Is necessary to include poller.h?
Non of poller function is used there.
> +#include <clock.h>
> +
> +/**
> + * @file
> + * @brief LED framework
> + *
> + * This file contains the core LED framework for barebox.
> + *
> + * Each LED can be set to a value where 0 means disabled and values
> + * > 0 mean enabled. LEDs can have different enable values where the
> + * exact meaning depends on the LED, for example a gpio controlled rgb
> + * LED can have enable values from 1 to 7 which correspond to different
> + * colors. value could also mean a brightness.
> + * Each LED is assigned a number. numbers start with 0 and are increased
> + * with each registered LED. The number stays the same during lifecycle,
> + * gaps because of unregistered LEDs are not filled up.
> + */
> +
> +static LIST_HEAD(leds);
> +static int num_leds;
> +
> +/**
> + * led_by_number - get the number of a LED
> + * @param num number of the LED to return
> + */
> +struct led *led_by_number(int num)
> +{
> + ? ? ? struct led *led;
> +
> + ? ? ? list_for_each_entry(led, &leds, list) {
> + ? ? ? ? ? ? ? if (led->num == num)
> + ? ? ? ? ? ? ? ? ? ? ? return led;
> + ? ? ? }
> +
> + ? ? ? return NULL;
> +}
> +
> +/**
> + * led_set - set the value of a LED
> + * @param led ?the led
> + * @param value ? ? ? ?the value of the LED (0 is disabled)
> + */
> +int led_set(struct led *led, unsigned int value)
> +{
> + ? ? ? if (value > led->max_value)
> + ? ? ? ? ? ? ? value = led->max_value;
> +
> + ? ? ? led->set(led, value);
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * led_set_num - set the value of a LED
> + * @param num ?the number of the LED
> + * @param value ? ? ? ?the value of the LED (0 is disabled)
> + */
> +int led_set_num(int num, unsigned int value)
> +{
> + ? ? ? struct led *led = led_by_number(num);
> +
> + ? ? ? if (!led)
> + ? ? ? ? ? ? ? return -ENODEV;
> +
> + ? ? ? return led_set(led, value);
> +}
> +
> +/**
> + * led_register - Register a LED
> + * @param led ?the led
> + */
> +int led_register(struct led *led)
> +{
> + ? ? ? led->num = num_leds++;
> +
> + ? ? ? list_add_tail(&led->list, &leds);
> +
> + ? ? ? return 0;
> +}
> +
> +/**
> + * led_unregister - Unegister a LED
> + * @param led ?the led
> + */
> +void led_unregister(struct led *led)
> +{
> + ? ? ? list_del(&led->list);
> +}
> diff --git a/include/led.h b/include/led.h
> new file mode 100644
> index 0000000..62d0d08
> --- /dev/null
> +++ b/include/led.h
> @@ -0,0 +1,25 @@
> +#ifndef __LED_H
> +#define __LED_H
> +
> +struct led {
> + ? ? ? unsigned long triger;
> + ? ? ? void (*set)(struct led *, unsigned int value);
> + ? ? ? int max_value;
> + ? ? ? int num;
> + ? ? ? struct list_head list;
> +};
> +
> +struct led *led_by_number(int no);
> +
> +static inline int led_get_number(struct led *led)
> +{
> + ? ? ? return led->num;
> +}
> +
> +int led_set_num(int num, unsigned int value);
> +int led_set(struct led *led, unsigned int value);
> +int led_register(struct led *led);
> +void led_unregister(struct led *led);
> +void led_unregister(struct led *led);
> +
> +#endif /* __LED_H */
> --
> 1.7.2.3
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From marc at cpdesign.com.au  Sun Dec 19 16:31:34 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Mon, 20 Dec 2010 08:31:34 +1100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
Message-ID: <201012200831.34131.marc@cpdesign.com.au>

Hi Sascha,

Thanks, this works well for my board. (tri colour led).

Was drivers/led/led-triggers.c missing from the patch set? 
I haven't been able to compile with trigger support...

> +/**
> + * led_register - Register a LED
> + * @param led	the led
> + */
> +int led_register(struct led *led)
> +{
> +	led->num = num_leds++;
> +
> +	list_add_tail(&led->list, &leds);
> +
> +	return 0;
> +}

How about being able to register a led at a specific number? This means that 
boot/init scripts that want to interact with leds don't rely on the order that 
they are registered.

I also like the suggestion of associating a name to LEDs. This may even be a 
better fit for scripting than reserved numbering.


> +
> +/**
> + * led_unregister - Unegister a LED
> + * @param led	the led
> + */
> +void led_unregister(struct led *led)
> +{
> +	list_del(&led->list);
> +}
> diff --git a/include/led.h b/include/led.h
> new file mode 100644
> index 0000000..62d0d08
> --- /dev/null
> +++ b/include/led.h
> @@ -0,0 +1,25 @@
> +#ifndef __LED_H
> +#define __LED_H
> +
> +struct led {
> +	unsigned long triger;

Spelling typo? (Should this be trigger ?)


> +	void (*set)(struct led *, unsigned int value);
> +	int max_value;
> +	int num;
> +	struct list_head list;
> +};
> +
> +struct led *led_by_number(int no);
> +


Cheers
Marc


From s.hauer at pengutronix.de  Mon Dec 20 03:27:20 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 09:27:20 +0100
Subject: [PATCH 2/7] basic LED support
In-Reply-To: <201012200831.34131.marc@cpdesign.com.au>
References: <1292685309-32326-1-git-send-email-s.hauer@pengutronix.de>
	<1292685309-32326-3-git-send-email-s.hauer@pengutronix.de>
	<201012200831.34131.marc@cpdesign.com.au>
Message-ID: <20101220082720.GN6017@pengutronix.de>

Hi Marc,

On Mon, Dec 20, 2010 at 08:31:34AM +1100, Marc Reilly wrote:
> Hi Sascha,
> 
> Thanks, this works well for my board. (tri colour led).
> 
> Was drivers/led/led-triggers.c missing from the patch set? 
> I haven't been able to compile with trigger support...

Yes, it's missing. I'll send a new series shortly.

> 
> > +/**
> > + * led_register - Register a LED
> > + * @param led	the led
> > + */
> > +int led_register(struct led *led)
> > +{
> > +	led->num = num_leds++;
> > +
> > +	list_add_tail(&led->list, &leds);
> > +
> > +	return 0;
> > +}
> 
> How about being able to register a led at a specific number? This means that 
> boot/init scripts that want to interact with leds don't rely on the order that 
> they are registered.
> 
> I also like the suggestion of associating a name to LEDs. This may even be a 
> better fit for scripting than reserved numbering.

I'll add a name for the LEDs

> 
> 
> > +
> > +/**
> > + * led_unregister - Unegister a LED
> > + * @param led	the led
> > + */
> > +void led_unregister(struct led *led)
> > +{
> > +	list_del(&led->list);
> > +}
> > diff --git a/include/led.h b/include/led.h
> > new file mode 100644
> > index 0000000..62d0d08
> > --- /dev/null
> > +++ b/include/led.h
> > @@ -0,0 +1,25 @@
> > +#ifndef __LED_H
> > +#define __LED_H
> > +
> > +struct led {
> > +	unsigned long triger;
> 
> Spelling typo? (Should this be trigger ?)

Indeed. It turns out I don't need this line add all, so I removed it.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Mon Dec 20 04:53:43 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:43 +0100
Subject: [PATCH v2] LED support
Message-ID: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>

Hi,

This is the second version of the patch series with the comments
integrated I got from the first version.

Sascha



From s.hauer at pengutronix.de  Mon Dec 20 04:53:44 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:44 +0100
Subject: [PATCH 1/8] cfi flash driver: check for ctrl-c during erase
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/nor/cfi_flash.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 2fa2c6b..d190e35 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -498,6 +498,11 @@ static int __cfi_erase(struct cdev *cdev, size_t count, unsigned long offset,
                 if (ret)
                         goto out;
 
+		if (ctrlc()) {
+			ret = -EINTR;
+			goto out;
+		}
+
 		if (verbose)
 			show_progress(i - start);
         }
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:51 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:51 +0100
Subject: [PATCH 8/8] ARM pcm043 board: Add LED support
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-9-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/pcm043/pcm043.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 2191bc8..38f1b8f 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -39,6 +39,7 @@
 #include <mach/imx-nand.h>
 #include <fec.h>
 #include <fb.h>
+#include <led.h>
 #include <asm/mmu.h>
 #include <mach/imx-ipu-fb.h>
 #include <mach/imx-pll.h>
@@ -148,6 +149,10 @@ static int pcm043_mmu_init(void)
 postcore_initcall(pcm043_mmu_init);
 #endif
 
+struct gpio_led led0 = {
+	.gpio = 1 * 32 + 6,
+};
+
 static int imx35_devices_init(void)
 {
 	uint32_t reg;
@@ -157,6 +162,8 @@ static int imx35_devices_init(void)
 	writel(0x10000d03, CSCR_L(0));
 	writel(0x00720900, CSCR_A(0));
 
+	led_gpio_register(&led0);
+
 	reg = readl(IMX_CCM_BASE + CCM_RCSR);
 	/* some fuses provide us vital information about connected hardware */
 	if (reg & 0x20000000)
@@ -226,7 +233,8 @@ static struct pad_desc pcm043_pads[] = {
 	MX35_PAD_RTS1__UART1_RTS,
 	MX35_PAD_CTS1__UART1_CTS,
 	MX35_PAD_I2C1_CLK__I2C1_SCL,
-	MX35_PAD_I2C1_DAT__I2C1_SDA
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+	MX35_PAD_ATA_CS0__GPIO2_6, /* LED */
 };
 
 static int imx35_console_init(void)
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:49 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:49 +0100
Subject: [PATCH 6/8] LED: Add led command
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-7-git-send-email-s.hauer@pengutronix.de>

This patch allows controlling LEDs via the command line.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/Kconfig  |    7 ++++
 commands/Makefile |    1 +
 commands/led.c    |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 0 deletions(-)
 create mode 100644 commands/led.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 5416073..64e08bb 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -372,4 +372,11 @@ config CMD_I2C
 	  include i2c_probe, i2c_read and i2c_write commands to communicate
 	  on i2c bus.
 
+config CMD_LED
+	bool
+	depends on LED
+	prompt "led command"
+	help
+	  include led command to control LEDs
+
 endmenu
diff --git a/commands/Makefile b/commands/Makefile
index ca30b5f..0820483 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_CMD_UBI)		+= ubi.o
 obj-$(CONFIG_CMD_MENU)		+= menu.o
 obj-$(CONFIG_CMD_PASSWD)	+= passwd.o
 obj-$(CONFIG_CMD_LOGIN)		+= login.o
+obj-$(CONFIG_CMD_LED)		+= led.o
diff --git a/commands/led.c b/commands/led.c
new file mode 100644
index 0000000..360ce7c
--- /dev/null
+++ b/commands/led.c
@@ -0,0 +1,90 @@
+/*
+ * LED command support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <led.h>
+#include <command.h>
+#include <getopt.h>
+#include <errno.h>
+
+static int do_led(struct command *cmdtp, int argc, char *argv[])
+{
+	unsigned long value;
+	struct led *led;
+	int ret;
+
+	if (argc == 1) {
+		int i = 0;
+
+		printf("registered LEDs:\n");
+
+		while ((led = led_by_number(i))) {
+			printf("%-2d: name: %-10s max_value: %d\n",
+					i, led->name ? led->name : "none",
+					led->max_value);
+			i++;
+		}
+		return 0;
+	}
+
+	if (argc != 3)
+		return COMMAND_ERROR_USAGE;
+
+	led = led_by_name_or_number(argv[1]);
+	if (!led) {
+		printf("no such LED: %s\n", argv[1]);
+		return 1;
+	}
+
+	value = simple_strtoul(argv[optind + 1], NULL, 0);
+
+	ret = led_set(led, value);
+	if (ret < 0) {
+		perror("led");
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * @page led_command
+
+The exact meaning of <value> is unspecified. It can be a color in case of rgb
+LEDs or a brightness if this is controllable. In most cases only 1 for enabled
+is allowed.
+
+*/
+
+BAREBOX_CMD_HELP_START(led)
+BAREBOX_CMD_HELP_USAGE("led <led> <value>\n")
+BAREBOX_CMD_HELP_SHORT("control the value of a LED. a value of 0 means disabled\n")
+BAREBOX_CMD_HELP_SHORT("without arguments the available LEDs are listed\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(led)
+	.cmd		= do_led,
+	.usage		= "led <led> <value>",
+	BAREBOX_CMD_HELP(cmd_led_help)
+BAREBOX_CMD_END
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:46 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:46 +0100
Subject: [PATCH 3/8] basic LED support
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-4-git-send-email-s.hauer@pengutronix.de>

This patch adds core functionality for controlling LEDs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/Kconfig      |    1 +
 drivers/Makefile     |    1 +
 drivers/led/Kconfig  |    6 ++
 drivers/led/Makefile |    1 +
 drivers/led/core.c   |  157 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/led.h        |   27 +++++++++
 6 files changed, 193 insertions(+), 0 deletions(-)
 create mode 100644 drivers/led/Kconfig
 create mode 100644 drivers/led/Makefile
 create mode 100644 drivers/led/core.c
 create mode 100644 include/led.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index d94017b..86d8fb5 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -12,5 +12,6 @@ source "drivers/video/Kconfig"
 source "drivers/mci/Kconfig"
 source "drivers/clk/Kconfig"
 source "drivers/mfd/Kconfig"
+source "drivers/led/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 242a564..b1b402f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_MCI) += mci/
 obj-$(CONFIG_VIDEO) += video/
 obj-y	+= clk/
 obj-y	+= mfd/
+obj-$(CONFIG_LED) += led/
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
new file mode 100644
index 0000000..964626c
--- /dev/null
+++ b/drivers/led/Kconfig
@@ -0,0 +1,6 @@
+menuconfig LED
+	bool "LED support"
+
+if LED
+
+endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
new file mode 100644
index 0000000..0c1a6b6
--- /dev/null
+++ b/drivers/led/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_LED) += core.o
diff --git a/drivers/led/core.c b/drivers/led/core.c
new file mode 100644
index 0000000..748a978
--- /dev/null
+++ b/drivers/led/core.c
@@ -0,0 +1,157 @@
+/*
+ * core LED support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <linux/list.h>
+#include <errno.h>
+#include <asm/gpio.h>
+#include <led.h>
+#include <poller.h>
+#include <clock.h>
+#include <linux/ctype.h>
+
+/**
+ * @file
+ * @brief LED framework
+ *
+ * This file contains the core LED framework for barebox.
+ *
+ * Each LED can be set to a value where 0 means disabled and values
+ * > 0 mean enabled. LEDs can have different enable values where the
+ * exact meaning depends on the LED, for example a gpio controlled rgb
+ * LED can have enable values from 1 to 7 which correspond to different
+ * colors. value could also mean a brightness.
+ * Each LED is assigned a number. numbers start with 0 and are increased
+ * with each registered LED. The number stays the same during lifecycle,
+ * gaps because of unregistered LEDs are not filled up.
+ */
+
+static LIST_HEAD(leds);
+static int num_leds;
+
+/**
+ * led_by_number - get the number of a LED
+ * @param num number of the LED to return
+ */
+struct led *led_by_number(int num)
+{
+	struct led *led;
+
+	list_for_each_entry(led, &leds, list) {
+		if (led->num == num)
+			return led;
+	}
+
+	return NULL;
+}
+
+/**
+ * led_by_name - get a LED with its name
+ * @param name	name of the LED
+ */
+struct led *led_by_name(const char *name)
+{
+	struct led *led;
+
+	list_for_each_entry(led, &leds, list) {
+		if (led->name && !strcmp(led->name, name))
+			return led;
+	}
+
+	return NULL;
+}
+
+/**
+ * led_by_name_or_number - get a LED with its name or number
+ * @param str	if first character of str is a digit led_by_number
+ *		is returned, led_by_name otherwise.
+ */
+struct led *led_by_name_or_number(const char *str)
+{
+	if (isdigit(*str)) {
+		int l;
+
+		l = simple_strtoul(str, NULL, 0);
+
+		return led_by_number(l);
+	} else {
+		return led_by_name(str);
+	}
+}
+
+/**
+ * led_set - set the value of a LED
+ * @param led	the led
+ * @param value	the value of the LED (0 is disabled)
+ */
+int led_set(struct led *led, unsigned int value)
+{
+	if (value > led->max_value)
+		value = led->max_value;
+
+	led->set(led, value);
+
+	return 0;
+}
+
+/**
+ * led_set_num - set the value of a LED
+ * @param num	the number of the LED
+ * @param value	the value of the LED (0 is disabled)
+ */
+int led_set_num(int num, unsigned int value)
+{
+	struct led *led = led_by_number(num);
+
+	if (!led)
+		return -ENODEV;
+
+	return led_set(led, value);
+}
+
+/**
+ * led_register - Register a LED
+ * @param led	the led
+ */
+int led_register(struct led *led)
+{
+	if (led->name && led_by_name(led->name))
+		return -EBUSY;
+
+	led->num = num_leds++;
+
+	list_add_tail(&led->list, &leds);
+
+	return 0;
+}
+
+/**
+ * led_unregister - Unegister a LED
+ * @param led	the led
+ */
+void led_unregister(struct led *led)
+{
+	list_del(&led->list);
+}
diff --git a/include/led.h b/include/led.h
new file mode 100644
index 0000000..3e7b1d9
--- /dev/null
+++ b/include/led.h
@@ -0,0 +1,27 @@
+#ifndef __LED_H
+#define __LED_H
+
+struct led {
+	void (*set)(struct led *, unsigned int value);
+	int max_value;
+	char *name;
+	int num;
+	struct list_head list;
+};
+
+struct led *led_by_number(int no);
+struct led *led_by_name(const char *name);
+struct led *led_by_name_or_number(const char *str);
+
+static inline int led_get_number(struct led *led)
+{
+	return led->num;
+}
+
+int led_set_num(int num, unsigned int value);
+int led_set(struct led *led, unsigned int value);
+int led_register(struct led *led);
+void led_unregister(struct led *led);
+void led_unregister(struct led *led);
+
+#endif /* __LED_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:47 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:47 +0100
Subject: [PATCH 4/8] LED: Add gpio LED support
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-5-git-send-email-s.hauer@pengutronix.de>

This patch adds support for registering gpios as LEDs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/led/Kconfig    |    8 ++++
 drivers/led/Makefile   |    1 +
 drivers/led/led-gpio.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/led.h          |   43 ++++++++++++++++++++++
 4 files changed, 146 insertions(+), 0 deletions(-)
 create mode 100644 drivers/led/led-gpio.c

diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 964626c..048a0f4 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -3,4 +3,12 @@ menuconfig LED
 
 if LED
 
+config LED_GPIO
+	bool "gpio LED support"
+	depends on GENERIC_GPIO
+
+config LED_GPIO_RGB
+	bool "gpio rgb LED support"
+	depends on LED_GPIO
+
 endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 0c1a6b6..29b9fd5 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_LED) += core.o
+obj-$(CONFIG_LED_GPIO) += led-gpio.o
diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c
new file mode 100644
index 0000000..10c25c6
--- /dev/null
+++ b/drivers/led/led-gpio.c
@@ -0,0 +1,94 @@
+/*
+ * gpio LED support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <led.h>
+#include <asm/gpio.h>
+
+static void led_gpio_set(struct led *led, unsigned int value)
+{
+	struct gpio_led *gpio_led = container_of(led, struct gpio_led, led);
+
+	gpio_direction_output(gpio_led->gpio, !!value ^ gpio_led->active_low);
+}
+
+/**
+ * led_gpio_register - register a gpio controlled LED
+ * @param led	The gpio LED
+ *
+ * This function registers a single gpio as a LED. led->gpio
+ * should be initialized to the gpio to control.
+ */
+int led_gpio_register(struct gpio_led *led)
+{
+	led->led.set = led_gpio_set;
+	led->led.max_value = 1;
+
+	return led_register(&led->led);
+}
+
+/**
+ * led_gpio_unregister - remove a gpio controlled LED from the framework
+ * @param led	The gpio LED
+ */
+void led_gpio_unregister(struct gpio_led *led)
+{
+	led_unregister(&led->led);
+}
+
+#ifdef CONFIG_LED_GPIO_RGB
+
+static void led_gpio_rgb_set(struct led *led, unsigned int value)
+{
+	struct gpio_rgb_led *rgb = container_of(led, struct gpio_rgb_led, led);
+	int al = rgb->active_low;
+
+	gpio_direction_output(rgb->gpio_r, !!(value & 4) ^ al);
+	gpio_direction_output(rgb->gpio_g, !!(value & 2) ^ al);
+	gpio_direction_output(rgb->gpio_b, !!(value & 1) ^ al);
+}
+
+/**
+ * led_gpio_rgb_register - register three gpios as a rgb LED
+ * @param led	The gpio rg LED
+ *
+ * This function registers three gpios as a rgb LED. led->gpio[rgb]
+ * should be initialized to the gpios to control.
+ */
+int led_gpio_rgb_register(struct gpio_rgb_led *led)
+{
+	led->led.set = led_gpio_rgb_set;
+	led->led.max_value = 7;
+
+	return led_register(&led->led);
+}
+
+/**
+ * led_gpio_rgb_unregister - remove a gpio controlled rgb LED from the framework
+ * @param led	The gpio LED
+ */
+void led_gpio_rgb_unregister(struct gpio_led *led)
+{
+	led_unregister(&led->led);
+}
+#endif /* CONFIG_LED_GPIO_RGB */
diff --git a/include/led.h b/include/led.h
index 3e7b1d9..0210897 100644
--- a/include/led.h
+++ b/include/led.h
@@ -1,6 +1,8 @@
 #ifndef __LED_H
 #define __LED_H
 
+#include <errno.h>
+
 struct led {
 	void (*set)(struct led *, unsigned int value);
 	int max_value;
@@ -24,4 +26,45 @@ int led_register(struct led *led);
 void led_unregister(struct led *led);
 void led_unregister(struct led *led);
 
+/* gpio LED support */
+struct gpio_led {
+	int gpio;
+	bool active_low;
+	struct led led;
+};
+
+struct gpio_rgb_led {
+	int gpio_r, gpio_g, gpio_b;
+	bool active_low;
+	struct led led;
+};
+
+#ifdef CONFIG_LED_GPIO
+int led_gpio_register(struct gpio_led *led);
+void led_gpio_unregister(struct gpio_led *led);
+#else
+static inline int led_gpio_register(struct gpio_led *led)
+{
+	return -ENOSYS;
+}
+
+static inline void led_gpio_unregister(struct gpio_led *led)
+{
+}
+#endif
+
+#ifdef CONFIG_LED_GPIO_RGB
+int led_gpio_rgb_register(struct gpio_rgb_led *led);
+void led_gpio_rgb_unregister(struct gpio_led *led);
+#else
+static inline int led_gpio_rgb_register(struct gpio_rgb_led *led)
+{
+	return -ENOSYS;
+}
+
+static inline void led_gpio_rgb_unregister(struct gpio_led *led)
+{
+}
+#endif
+
 #endif /* __LED_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:50 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:50 +0100
Subject: [PATCH 7/8] LED: Add trigger command
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-8-git-send-email-s.hauer@pengutronix.de>

This patch allows controlling LED triggers vie the command line.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/Kconfig   |    8 ++++
 commands/Makefile  |    1 +
 commands/trigger.c |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+), 0 deletions(-)
 create mode 100644 commands/trigger.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 64e08bb..f137f47 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -379,4 +379,12 @@ config CMD_LED
 	help
 	  include led command to control LEDs
 
+config CMD_LED_TRIGGER
+	bool
+	depends on LED_TRIGGERS
+	prompt "trigger command"
+	help
+	  The trigger command allows to control LED triggers from the command
+	  line.
+
 endmenu
diff --git a/commands/Makefile b/commands/Makefile
index 0820483..c89adcf 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_CMD_MENU)		+= menu.o
 obj-$(CONFIG_CMD_PASSWD)	+= passwd.o
 obj-$(CONFIG_CMD_LOGIN)		+= login.o
 obj-$(CONFIG_CMD_LED)		+= led.o
+obj-$(CONFIG_CMD_LED_TRIGGER)	+= trigger.o
diff --git a/commands/trigger.c b/commands/trigger.c
new file mode 100644
index 0000000..162da97
--- /dev/null
+++ b/commands/trigger.c
@@ -0,0 +1,107 @@
+/*
+ * LED trigger command support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <led.h>
+#include <command.h>
+#include <getopt.h>
+#include <errno.h>
+
+#define LED_COMMAND_SET_TRIGGER		1
+#define LED_COMMAND_SHOW_INFO		2
+#define	LED_COMMAND_DISABLE_TRIGGER	3
+
+static char *trigger_names[] = {
+	[LED_TRIGGER_PANIC] = "panic",
+	[LED_TRIGGER_HEARTBEAT] = "heartbeat",
+	[LED_TRIGGER_NET_RX] = "net rx",
+	[LED_TRIGGER_NET_TX] = "net tx",
+	[LED_TRIGGER_NET_TXRX] = "net",
+};
+
+static int do_trigger(struct command *cmdtp, int argc, char *argv[])
+{
+	struct led *led;
+	int i, opt, ret = 0;
+	int cmd = LED_COMMAND_SHOW_INFO;
+	unsigned long trigger = 0;
+
+	while((opt = getopt(argc, argv, "t:d:")) > 0) {
+		switch(opt) {
+		case 't':
+			trigger = simple_strtoul(optarg, NULL, 0);
+			cmd = LED_COMMAND_SET_TRIGGER;
+			break;
+		case 'd':
+			trigger = simple_strtoul(optarg, NULL, 0);
+			cmd = LED_COMMAND_DISABLE_TRIGGER;
+		}
+	}
+
+	switch (cmd) {
+	case LED_COMMAND_SHOW_INFO:
+		for (i = 0; i < LED_TRIGGER_MAX; i++) {
+			int led = led_get_trigger(i);
+			printf("%d: %s", i, trigger_names[i]);
+			if (led >= 0)
+				printf(" (led %d)", led);
+			printf("\n");
+		}
+		break;
+
+	case LED_COMMAND_DISABLE_TRIGGER:
+		led_set_trigger(trigger, NULL);
+		return 0;
+	case LED_COMMAND_SET_TRIGGER:
+		if (argc - optind != 1)
+			return COMMAND_ERROR_USAGE;
+		led = led_by_name_or_number(argv[optind]);
+
+		if (!led) {
+			printf("no such led: %d\n", argv[optind]);
+			return 1;
+		}
+
+		ret = led_set_trigger(trigger, led);
+		break;
+	}
+
+	if (ret)
+		printf("trigger failed: %s\n", strerror(-ret));
+	return ret ? 1 : 0;
+}
+
+BAREBOX_CMD_HELP_START(trigger)
+BAREBOX_CMD_HELP_USAGE("trigger [OPTIONS]\n")
+BAREBOX_CMD_HELP_SHORT("control a LED trigger. Without options the currently assigned triggers are shown.\n")
+BAREBOX_CMD_HELP_OPT  ("-t <trigger> <led>",  "set a trigger for a led\n")
+BAREBOX_CMD_HELP_OPT  ("-d <trigger>",  "disable a trigger\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(trigger)
+	.cmd		= do_trigger,
+	.usage		= "handle LED triggers",
+	BAREBOX_CMD_HELP(cmd_trigger_help)
+BAREBOX_CMD_END
+
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:45 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:45 +0100
Subject: [PATCH 2/8] Add generic poll infrastructure
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-3-git-send-email-s.hauer@pengutronix.de>

From: Marc Kleine-Budde <mkl at pengutronix.de>

Barebox does not have interrupt functionality. Nevertheless it's
sometimes useful to periodically call functions, like for example
a heartbeat LED or watchdog reset. Instead of cluttering the code
with calls to these functions this patch adds a generic polling
infrastructure. Code which might run for longer now can call
poller_call() periodically which in turn will call all registered
pollers.
This patch adds a call to poller_call in two generic pathes. First
of them is getc() which covers waiting for uart input. Second is
ctrlc() which should be called anyway from code which might run
for longer. So instead adding poller_call directly to your code,
consider checking ctrlc instead which also gives additional
convenience to the user.
The poller code is safe against reentrancy which means that it's
safe to call poller_call inside a poller.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/Kconfig   |    3 +++
 common/Makefile  |    1 +
 common/console.c |    5 +++++
 common/poller.c  |   45 +++++++++++++++++++++++++++++++++++++++++++++
 include/poller.h |   31 +++++++++++++++++++++++++++++++
 5 files changed, 85 insertions(+), 0 deletions(-)
 create mode 100644 common/poller.c
 create mode 100644 include/poller.h

diff --git a/common/Kconfig b/common/Kconfig
index 617f640..02bc67e 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -414,6 +414,9 @@ config DEFAULT_ENVIRONMENT_PATH
 	  Relative pathes will be relative to the barebox Toplevel dir, but absolute
 	  pathes are fine aswell.
 
+config POLLER
+	bool "generic polling infrastructure"
+
 endmenu
 
 menu "Debugging                     "
diff --git a/common/Makefile b/common/Makefile
index 753455b..98c9d36 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_OF_FLAT_TREE)	+= ft_build.o
 obj-$(CONFIG_KALLSYMS)		+= kallsyms.o
 obj-$(CONFIG_ENV_HANDLING)	+= environment.o
 obj-$(CONFIG_AUTO_COMPLETE)	+= complete.o
+obj-$(CONFIG_POLLER)		+= poller.o
 
 obj-y += dlmalloc.o
 obj-y += clock.o
diff --git a/common/console.c b/common/console.c
index 82786f2..39ead4b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -34,6 +34,7 @@
 #include <clock.h>
 #include <kfifo.h>
 #include <module.h>
+#include <poller.h>
 #include <linux/list.h>
 
 LIST_HEAD(console_list);
@@ -205,6 +206,8 @@ int getc(void)
 	 */
 	start = get_time_ns();
 	while (1) {
+		poller_call();
+
 		if (tstc()) {
 			kfifo_putc(console_input_buffer, getc_raw());
 
@@ -397,6 +400,8 @@ EXPORT_SYMBOL(vprintf);
 /* test if ctrl-c was pressed */
 int ctrlc (void)
 {
+	poller_call();
+
 	if (tstc() && getc() == 3)
 		return 1;
 	return 0;
diff --git a/common/poller.c b/common/poller.c
new file mode 100644
index 0000000..0583a53
--- /dev/null
+++ b/common/poller.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <module.h>
+#include <param.h>
+#include <poller.h>
+
+static LIST_HEAD(poller_list);
+static int poller_active;
+
+int poller_register(struct poller_struct *poller)
+{
+	list_add_tail(&poller->list, &poller_list);
+
+	return 0;
+}
+
+int poller_unregister(struct poller_struct *poller)
+{
+	list_del(&poller->list);
+
+	return 0;
+}
+
+void poller_call(void)
+{
+	struct poller_struct *poller, *tmp;
+
+	if (poller_active)
+		return;
+
+	poller_active = 1;
+
+	list_for_each_entry_safe(poller, tmp, &poller_list, list)
+		poller->func(poller);
+
+	poller_active = 0;
+}
diff --git a/include/poller.h b/include/poller.h
new file mode 100644
index 0000000..dc98155
--- /dev/null
+++ b/include/poller.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef POLLER_H
+#define POLLER_H
+
+#include <linux/list.h>
+
+struct poller_struct {
+	void (*func)(struct poller_struct *poller);
+
+	struct list_head list;
+};
+
+int poller_register(struct poller_struct *poller);
+int poller_unregister(struct poller_struct *poller);
+
+
+#ifdef CONFIG_POLLER
+void poller_call(void);
+#else
+static inline void poller_call(void)
+{
+}
+#endif	/* CONFIG_POLLER */
+
+#endif	/* !POLLER_H */
-- 
1.7.2.3



From s.hauer at pengutronix.de  Mon Dec 20 04:53:48 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 10:53:48 +0100
Subject: [PATCH 5/8] LED: Add LED trigger support
In-Reply-To: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
References: <1292838831-25038-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1292838831-25038-6-git-send-email-s.hauer@pengutronix.de>

This patch allows to associate LEDs with certain triggers, such
as heartbeat or network activity.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/led/Kconfig        |    7 ++
 drivers/led/Makefile       |    1 +
 drivers/led/led-triggers.c |  153 ++++++++++++++++++++++++++++++++++++++++++++
 include/led.h              |   32 +++++++++
 include/net.h              |    3 +
 lib/vsprintf.c             |    4 +
 net/eth.c                  |    8 ++-
 net/net.c                  |   20 ++++--
 8 files changed, 222 insertions(+), 6 deletions(-)
 create mode 100644 drivers/led/led-triggers.c

diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 048a0f4..106093b 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -11,4 +11,11 @@ config LED_GPIO_RGB
 	bool "gpio rgb LED support"
 	depends on LED_GPIO
 
+config LED_TRIGGERS
+	select POLLER
+	bool "LED triggers support"
+	help
+	  This allows to assign certain triggers like heartbeat or network
+	  activity to LEDs.
+
 endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 29b9fd5..6aafa6d 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_LED) += core.o
 obj-$(CONFIG_LED_GPIO) += led-gpio.o
+obj-$(CONFIG_LED_TRIGGERS) += led-triggers.o
diff --git a/drivers/led/led-triggers.c b/drivers/led/led-triggers.c
new file mode 100644
index 0000000..764b4e7
--- /dev/null
+++ b/drivers/led/led-triggers.c
@@ -0,0 +1,153 @@
+/*
+ * LED trigger support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <poller.h>
+#include <errno.h>
+#include <clock.h>
+#include <led.h>
+#include <init.h>
+
+/**
+ * @file
+ * @brief LED trigger framework
+ *
+ * This file contains triggers which can be associated to LEDs.
+ *
+ * With this framework LEDs can be associated to different events.
+ * An event can be a heartbeat, network activity or panic.
+ * led_trigger() is the central function which is called in the
+ * different barebox frameworks to trigger an event.
+ *
+ * currently there are the following triggers are defined:
+ *
+ * led_trigger_panic:		triggered in panic()
+ * led_trigger_heartbeat:	shows the heartbeat of barebox. Blinks as long
+ *				barebox is up and running.
+ * led_trigger_net_rx:		Triggered during network packet reception
+ * led_trigger_net_tx:		Triggered during network packet transmission
+ * led_trigger_net_txrx:	combination of the two above
+ */
+
+struct led_trigger_struct {
+	struct led *led;
+	uint64_t flash_start;
+};
+
+static struct led_trigger_struct triggers[LED_TRIGGER_MAX];
+
+static void trigger_func(struct poller_struct *poller)
+{
+	int i;
+
+	for (i = 0; i < LED_TRIGGER_MAX; i++) {
+		if (triggers[i].led &&
+		    triggers[i].flash_start &&
+		    is_timeout(triggers[i].flash_start, 200 * MSECOND)) {
+			led_set(triggers[i].led, 0);
+		}
+	}
+
+	if (triggers[LED_TRIGGER_HEARTBEAT].led &&
+			is_timeout(triggers[LED_TRIGGER_HEARTBEAT].flash_start, SECOND))
+		led_trigger(LED_TRIGGER_HEARTBEAT, TRIGGER_FLASH);
+}
+
+static struct poller_struct trigger_poller = {
+	.func = trigger_func,
+};
+
+/**
+ * led_trigger - triggers a trigger
+ * @param trigger	The trigger to enable/disable
+ * @param enable	true if enable
+ *
+ * Enable/disable a LED for a given trigger.
+ */
+void led_trigger(enum led_trigger trigger, enum trigger_type type)
+{
+	if (trigger >= LED_TRIGGER_MAX)
+		return;
+	if (!triggers[trigger].led)
+		return;
+
+	if (type == TRIGGER_FLASH) {
+		if (is_timeout(triggers[trigger].flash_start, 400 * MSECOND)) {
+			led_set(triggers[trigger].led, 1);
+			triggers[trigger].flash_start = get_time_ns();
+		}
+		return;
+	}
+
+	led_set(triggers[trigger].led, type == TRIGGER_ENABLE ? 1 : 0);
+}
+
+/**
+ * led_set_trigger - set the LED for a trigger
+ * @param trigger	The trigger to set a LED for
+ * @param led		The LED
+ *
+ * This function associates a trigger with a LED. Pass led = NULL
+ * to disable a trigger
+ */
+int led_set_trigger(enum led_trigger trigger, struct led *led)
+{
+	int i;
+
+	if (trigger >= LED_TRIGGER_MAX)
+		return -EINVAL;
+
+	if (led)
+		for (i = 0; i < LED_TRIGGER_MAX; i++)
+			if (triggers[i].led == led)
+				return -EBUSY;
+
+	if (triggers[trigger].led && !led)
+		led_set(triggers[trigger].led, 0);
+
+	triggers[trigger].led = led;
+
+	return 0;
+}
+
+/**
+ * led_get_trigger - get the LED for a trigger
+ * @param trigger	The trigger to set a LED for
+ *
+ * return the LED number of a trigger.
+ */
+int led_get_trigger(enum led_trigger trigger)
+{
+	if (trigger >= LED_TRIGGER_MAX)
+		return -EINVAL;
+	if (!triggers[trigger].led)
+		return -ENODEV;
+	return led_get_number(triggers[trigger].led);
+}
+
+int trigger_init(void)
+{
+	return poller_register(&trigger_poller);
+}
+late_initcall(trigger_init);
diff --git a/include/led.h b/include/led.h
index 0210897..9ec1f0d 100644
--- a/include/led.h
+++ b/include/led.h
@@ -26,6 +26,38 @@ int led_register(struct led *led);
 void led_unregister(struct led *led);
 void led_unregister(struct led *led);
 
+/* LED trigger support */
+enum led_trigger {
+	LED_TRIGGER_PANIC,
+	LED_TRIGGER_HEARTBEAT,
+	LED_TRIGGER_NET_RX,
+	LED_TRIGGER_NET_TX,
+	LED_TRIGGER_NET_TXRX,
+	LED_TRIGGER_MAX,
+};
+
+enum trigger_type {
+	TRIGGER_ENABLE,
+	TRIGGER_DISABLE,
+	TRIGGER_FLASH,
+};
+
+#ifdef CONFIG_LED_TRIGGERS
+int led_set_trigger(enum led_trigger trigger, struct led *led);
+void led_trigger(enum led_trigger trigger, enum trigger_type);
+#else
+static inline int led_set_trigger(enum led_trigger trigger, struct led *led)
+{
+	return 0;
+}
+
+static inline void led_trigger(enum led_trigger trigger, enum trigger_type type)
+{
+}
+#endif
+
+int led_get_trigger(enum led_trigger trigger);
+
 /* gpio LED support */
 struct gpio_led {
 	int gpio;
diff --git a/include/net.h b/include/net.h
index c695e5f..ccaab8b 100644
--- a/include/net.h
+++ b/include/net.h
@@ -18,6 +18,7 @@
 #include <malloc.h>
 #include <stdlib.h>
 #include <clock.h>
+#include <led.h>
 #include <asm/byteorder.h>	/* for nton* / ntoh* stuff */
 
 
@@ -417,4 +418,6 @@ static inline unsigned char *net_udp_get_payload(struct net_connection *con)
 int net_udp_send(struct net_connection *con, int len);
 int net_icmp_send(struct net_connection *con, int len);
 
+void led_trigger_network(enum led_trigger trigger);
+
 #endif /* __NET_H__ */
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e2ea84d..fec87ba 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -17,6 +17,7 @@
 #include <malloc.h>
 
 #include <common.h>
+#include <led.h>
 #include <reloc.h>
 
 unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
@@ -625,6 +626,9 @@ void __noreturn panic(const char *fmt, ...)
 	vprintf(fmt, args);
 	putchar('\n');
 	va_end(args);
+
+	led_trigger(LED_TRIGGER_PANIC, TRIGGER_ENABLE);
+
 #if defined (CONFIG_PANIC_HANG)
 	hang();
 #else
diff --git a/net/eth.c b/net/eth.c
index a82a263..7502e98 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -77,6 +77,8 @@ int eth_send(void *packet, int length)
 		eth_current->active = 1;
 	}
 
+	led_trigger_network(LED_TRIGGER_NET_TX);
+
 	return eth_current->send(eth_current, packet, length);
 }
 
@@ -183,4 +185,8 @@ void eth_unregister(struct eth_device *edev)
 	list_del(&edev->list);
 }
 
-
+void led_trigger_network(enum led_trigger trigger)
+{
+	led_trigger(trigger, TRIGGER_FLASH);
+	led_trigger(LED_TRIGGER_NET_TXRX, TRIGGER_FLASH);
+}
diff --git a/net/net.c b/net/net.c
index a613d1d..9b4ab89 100644
--- a/net/net.c
+++ b/net/net.c
@@ -628,19 +628,29 @@ int net_receive(unsigned char *pkt, int len)
 {
 	struct ethernet *et = (struct ethernet *)pkt;
 	int et_protlen = ntohs(et->et_protlen);
+	int ret;
 
-	if (len < ETHER_HDR_SIZE)
-		return 0;
+	led_trigger_network(LED_TRIGGER_NET_RX);
+
+	if (len < ETHER_HDR_SIZE) {
+		ret = 0;
+		goto out;
+	}
 
 	switch (et_protlen) {
 	case PROT_ARP:
-		return net_handle_arp(pkt, len);
+		ret = net_handle_arp(pkt, len);
+		break;
 	case PROT_IP:
-		return net_handle_ip(pkt, len);
+		ret = net_handle_ip(pkt, len);
+		break;
 	default:
 		debug("%s: got unknown protocol type: %d\n", __func__, et_protlen);
-		return 1;
+		ret = 1;
+		break;
 	}
+out:
+	return ret;
 }
 
 static int net_init(void)
-- 
1.7.2.3



From marek.belisko at gmail.com  Mon Dec 20 05:46:44 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Mon, 20 Dec 2010 11:46:44 +0100
Subject: nand_boot_test problem
Message-ID: <AANLkTimRU=-AufgJ0qXBfSSgWiHfaBbnL_e9jdTLVo22@mail.gmail.com>

Hi,

I'm trying to add support for mini2440 to boot from NAND flash.
I overtake boot code from u-boot and re-use a9m2410 lowlevel_init.S.

I could load barebox.bin to NAND flash anyway when try to test command
nand_boot_test 0x31fc0000 262144 512 I get no error just board is reseted.


Any ideas?

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From s.hauer at pengutronix.de  Mon Dec 20 09:06:00 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 20 Dec 2010 15:06:00 +0100
Subject: nand_boot_test problem
In-Reply-To: <AANLkTimRU=-AufgJ0qXBfSSgWiHfaBbnL_e9jdTLVo22@mail.gmail.com>
References: <AANLkTimRU=-AufgJ0qXBfSSgWiHfaBbnL_e9jdTLVo22@mail.gmail.com>
Message-ID: <20101220140600.GQ6017@pengutronix.de>

Hi Marek,

On Mon, Dec 20, 2010 at 11:46:44AM +0100, Belisko Marek wrote:
> Hi,
> 
> I'm trying to add support for mini2440 to boot from NAND flash.
> I overtake boot code from u-boot and re-use a9m2410 lowlevel_init.S.
> 
> I could load barebox.bin to NAND flash anyway when try to test command
> nand_boot_test 0x31fc0000 262144 512 I get no error just board is reseted.

No idea. Can you add some printfs to see how far you get?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From fabio.porcedda at telit.com  Mon Dec 20 09:14:37 2010
From: fabio.porcedda at telit.com (Fabio Porcedda)
Date: Mon, 20 Dec 2010 15:14:37 +0100
Subject: [PATCH v2] xyzModem.c: fix 'dummy' is used uninitialized in this
	function warning
Message-ID: <1292854477-2842-1-git-send-email-fabio.porcedda@telit.com>

fix this gcc 4.4 warning:

xyzModem.c: In function 'xyzModem_stream_open':
xyzModem.c:564: warning: 'dummy' is used uninitialized in this function

Copied from U-Boot

Signed-off-by: Fabio Porcedda <fabio.porcedda at telit.com>
---
 commands/xyzModem.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/xyzModem.c b/commands/xyzModem.c
index 1dd255d..71d7d68 100644
--- a/commands/xyzModem.c
+++ b/commands/xyzModem.c
@@ -492,7 +492,7 @@ int xyzModem_stream_open(connection_info_t *info, int *err)
 			       xyzModem_CHAR_TIMEOUT);
 #else
 /* TODO: CHECK ! */
-	int dummy;
+	int dummy = 0;
 	xyz.__chan = &dummy;
 #endif
 	xyz.len = 0;
-- 
1.7.3.4

Changes for v2:
   - fixed commit log message


From marek.belisko at gmail.com  Mon Dec 20 09:18:56 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Mon, 20 Dec 2010 15:18:56 +0100
Subject: nand_boot_test problem
In-Reply-To: <20101220140600.GQ6017@pengutronix.de>
References: <AANLkTimRU=-AufgJ0qXBfSSgWiHfaBbnL_e9jdTLVo22@mail.gmail.com>
	<20101220140600.GQ6017@pengutronix.de>
Message-ID: <AANLkTimKYgm74zWiDX4LPMM1eyU+xpNxOpswAmWhUO=a@mail.gmail.com>

Hi,

On Mon, Dec 20, 2010 at 3:06 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Marek,
>
> On Mon, Dec 20, 2010 at 11:46:44AM +0100, Belisko Marek wrote:
>> Hi,
>>
>> I'm trying to add support for mini2440 to boot from NAND flash.
>> I overtake boot code from u-boot and re-use a9m2410 lowlevel_init.S.
>>
>> I could load barebox.bin to NAND flash anyway when try to test command
>> nand_boot_test 0x31fc0000 262144 512 I get no error just board is reseted.
>
> No idea. Can you add some printfs to see how far you get?
Well problem disappeared after cleanup and recompile. Sorry for spamming ;)
Anyway is there any work for mini2440 boot from flash in  pengutronix?
>
> Sascha
>
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Mon Dec 20 09:45:14 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 15:45:14 +0100
Subject: nand_boot_test problem
In-Reply-To: <AANLkTimKYgm74zWiDX4LPMM1eyU+xpNxOpswAmWhUO=a@mail.gmail.com>
References: <AANLkTimRU=-AufgJ0qXBfSSgWiHfaBbnL_e9jdTLVo22@mail.gmail.com>
	<20101220140600.GQ6017@pengutronix.de>
	<AANLkTimKYgm74zWiDX4LPMM1eyU+xpNxOpswAmWhUO=a@mail.gmail.com>
Message-ID: <201012201545.14968.jbe@pengutronix.de>

Belisko Marek wrote:
> [...]
> Anyway is there any work for mini2440 boot from flash in pengutronix?

No. I did not had the time yet.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From jbe at pengutronix.de  Mon Dec 20 10:05:01 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:01 +0100
Subject: [PATCH 02/10] ARM Chumby: Fix memory index
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-3-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/chumby_falconwing/falconwing.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index 952a384..e0706f8 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -35,6 +35,7 @@ static struct memory_platform_data ram_pdata = {
 };
 
 static struct device_d sdram_dev = {
+	.id       = -1,
 	.name     = "mem",
 	.map_base = IMX_MEMORY_BASE,
 	.size     = 64 * 1024 * 1024,
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:02 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:02 +0100
Subject: [PATCH 03/10] ARM Chumby: Fix unit of the clocks after the change to
	Hz
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-4-git-send-email-jbe@pengutronix.de>

With the change to Hz as the main clock unit on the STM architecture the
Chumby must also use this unit.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/chumby_falconwing/falconwing.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index e0706f8..10fbba8 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -266,9 +266,9 @@ static int falconwing_devices_init(void)
 		imx_gpio_mode(pad_setup[i]);
 
 	register_device(&sdram_dev);
-	imx_set_ioclk(480U * 1000U);	/* enable IOCLK to run at the PLL frequency */
+	imx_set_ioclk(480000000); /* enable IOCLK to run at the PLL frequency */
 	/* run the SSP unit clock at 100,000 kHz */
-	imx_set_sspclk(0, 100U * 1000U, 1);
+	imx_set_sspclk(0, 100000000, 1);
 	register_device(&mci_dev);
 
 	armlinux_add_dram(&sdram_dev);
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:00 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:00 +0100
Subject: [PATCH 01/10] Add more useful generic macros
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-2-git-send-email-jbe@pengutronix.de>

Stolen from the Linux kernel.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 include/common.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/common.h b/include/common.h
index 1bea10c..35ad7b9 100644
--- a/include/common.h
+++ b/include/common.h
@@ -231,4 +231,14 @@ extern const char version_string[];
 }							\
 )
 
+#define abs(x) ({                               \
+		long __x = (x);                 \
+		(__x < 0) ? -__x : __x;         \
+	})
+
+#define abs64(x) ({                             \
+		s64 __x = (x);                  \
+		(__x < 0) ? -__x : __x;         \
+	})
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:03 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:03 +0100
Subject: [PATCH 04/10] ARM Chumby: Just fix some typos
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-5-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/chumby_falconwing/falconwing.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index 10fbba8..93ce7e2 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -225,8 +225,8 @@ static const uint32_t pad_setup[] = {
  * Try to register an environment storage on the attached MCI card
  * @return 0 on success
  *
- * We relay on the existance of a useable SD card, already attached to
- * our system, to get someting like a persistant memory for our environment.
+ * We rely on the existence of a usable SD card, already attached to
+ * our system, to get something like a persistent memory for our environment.
  * If this SD card is also the boot media, we can use the second partition
  * for our environment purpose (if present!).
  */
@@ -253,7 +253,7 @@ static int register_persistant_environment(void)
 		return -ENODEV;
 	}
 
-	/* use the full partition as our persistant environment storage */
+	/* use the full partition as our persistent environment storage */
 	return devfs_add_partition("disk0.1", 0, cdev->size, DEVFS_PARTITION_FIXED, "env0");
 }
 
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:09 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:09 +0100
Subject: =?UTF-8?q?=5BPATCH=2010/10=5D=20ARM=20Chumby-Falconwing=3A=20Add=20a=20user=20for=20video=20graphics=20support=20on=20i=2EMX23?=
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-11-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/chumby_falconwing/falconwing.c |   88 +++++++++++++++++------
 arch/arm/configs/chumbyone_defconfig           |    3 +
 2 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index 93ce7e2..f5ed133 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -28,6 +28,7 @@
 #include <mach/imx-regs.h>
 #include <mach/clock.h>
 #include <mach/mci.h>
+#include <mach/fb.h>
 
 static struct memory_platform_data ram_pdata = {
 	.name = "ram0",
@@ -53,6 +54,45 @@ static struct device_d mci_dev = {
 	.platform_data = &mci_pdata,
 };
 
+static struct fb_videomode falconwing_vmode = {
+	/*
+	 * Nanovision NMA35QV65-B2-K01 (directly connected)
+	 * Clock: 6.25 MHz
+	 * Syncs: high active, DE low active
+	 * Display area: 70.08 mm x 52.56 mm
+	 */
+	.name = "NMA35",
+	.refresh = 60,
+	.xres = 320,
+	.yres = 240,
+	.pixclock = KHZ2PICOS(6250),    /* max. 10 MHz */
+	/* line lenght should be 64 ?s */
+	.left_margin = 28,
+	.hsync_len = 24,
+	.right_margin = 28,
+	/* frame rate should be 60 Hz */
+	.upper_margin = 8,
+	.vsync_len = 4,
+	.lower_margin = 8,
+	.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode = FB_VMODE_NONINTERLACED,
+	.flag = 0,
+};
+
+static struct imx_fb_videomode fb_mode = {
+	.mode_list = &falconwing_vmode,
+	.mode_cnt = 1,
+	/* the NMA35 is a 24 bit display, but only 18 bits are connected */
+	.ld_intf_width = STMLCDIF_18BIT,
+};
+
+static struct device_d ldcif_dev = {
+	.name = "stmfb",
+	.map_base = IMX_FB_BASE,
+	.size = 4096,
+	.platform_data = &fb_mode,
+};
+
 static const uint32_t pad_setup[] = {
 	/* may be not required as already done by the bootlet code */
 #if 0
@@ -113,33 +153,34 @@ static const uint32_t pad_setup[] = {
 	PWM0_DUART_RX | STRENGTH(S4MA),	/*  strength is TBD */
 
 	/* lcd */
-	LCD_VSYNC,	/* kernel tries with 12 mA for all LCD related pins */
-	LCD_HSYNC,
-	LCD_ENABE,
-	LCD_DOTCLOCK,
-	LCD_D17,
-	LCD_D16,
-	LCD_D15,
-	LCD_D14,
-	LCD_D13,
-	LCD_D12,
-	LCD_D11,
-	LCD_D10,
-	LCD_D9,
-	LCD_D8,
-	LCD_D7,
-	LCD_D6,
-	LCD_D5,
-	LCD_D4,
-	LCD_D3,
-	LCD_D2,
-	LCD_D1,
-	LCD_D0,
+	LCD_VSYNC | STRENGTH(S12MA),
+	LCD_HSYNC | STRENGTH(S12MA),
+	LCD_ENABE | STRENGTH(S12MA),
+	LCD_DOTCLOCK | STRENGTH(S12MA),
+	LCD_D17 | STRENGTH(S12MA),
+	LCD_D16 | STRENGTH(S12MA),
+	LCD_D15 | STRENGTH(S12MA),
+	LCD_D14 | STRENGTH(S12MA),
+	LCD_D13 | STRENGTH(S12MA),
+	LCD_D12 | STRENGTH(S12MA),
+	LCD_D11 | STRENGTH(S12MA),
+	LCD_D10 | STRENGTH(S12MA),
+	LCD_D9 | STRENGTH(S12MA),
+	LCD_D8 | STRENGTH(S12MA),
+	LCD_D7 | STRENGTH(S12MA),
+	LCD_D6 | STRENGTH(S12MA),
+	LCD_D5 | STRENGTH(S12MA),
+	LCD_D4 | STRENGTH(S12MA),
+	LCD_D3 | STRENGTH(S12MA),
+	LCD_D2 | STRENGTH(S12MA),
+	LCD_D1 | STRENGTH(S12MA),
+	LCD_D0 | STRENGTH(S12MA),
 
 	/* LCD usage currently unknown */
 	LCD_CS,	/* used as SPI SS */
 	LCD_RS,	/* used as SPI CLK */
-	LCD_RESET,
+	/* keep the display in reset state */
+	LCD_RESET_GPIO | STRENGTH(S4MA) | GPIO_OUT | GPIO_VALUE(0),
 	LCD_WR,	/* used as SPI MOSI */
 
 	/* I2C to the MMA7455L, KXTE9, AT24C08 (DCID), AT24C128B (ID EEPROM) and QN8005B */
@@ -270,6 +311,7 @@ static int falconwing_devices_init(void)
 	/* run the SSP unit clock at 100,000 kHz */
 	imx_set_sspclk(0, 100000000, 1);
 	register_device(&mci_dev);
+	register_device(&ldcif_dev);
 
 	armlinux_add_dram(&sdram_dev);
 	armlinux_set_bootparams((void*)(sdram_dev.map_base + 0x100));
diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
index 595b6a9..6e6623a 100644
--- a/arch/arm/configs/chumbyone_defconfig
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -23,7 +23,10 @@ CONFIG_CMD_MTEST_ALTERNATIVE=y
 CONFIG_CMD_RESET=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_PARTITION=y
+CONFIG_CMD_BMP=y
 # CONFIG_SPI is not set
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_STM=y
 CONFIG_MCI=y
 CONFIG_MCI_STARTUP=y
 CONFIG_MCI_STM378X=y
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:04 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:04 +0100
Subject: [PATCH 05/10] Fix default framebuffer 'enable' set
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-6-git-send-email-jbe@pengutronix.de>

To setup the default 'enable' setting the "dev_set_param(dev, "enable", "0");"
does not work as expected. After the call the parameter is still "<NULL>".
This is due to any change of the setting is rejected, if the same setting
is already active.
This patch also let the default setting be successfull, but only calls the
graphics backend if a change happens.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 drivers/video/fb.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index ab2c5eb..bef4147 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -39,14 +39,13 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
 
 	enable = simple_strtoul(val, NULL, 0);
 
-	if (info->enabled == !!enable)
-		return 0;
-
 	if (enable) {
-		info->fbops->fb_enable(info);
+		if (!info->enabled)
+			info->fbops->fb_enable(info);
 		new = "1";
 	} else {
-		info->fbops->fb_disable(info);
+		if (info->enabled)
+			info->fbops->fb_disable(info);
 		new = "0";
 	}
 
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:05 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:05 +0100
Subject: [PATCH 06/10] Add the feature to change the video mode at runtime
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-7-git-send-email-jbe@pengutronix.de>

This patch add the possibility to change the video mode at barebox's runtime
if the graphics driver in use supports it.

Signed-off-by: <jbe at pengutronix.de>
---
 drivers/video/fb.c |   35 +++++++++++++++++++++++++++++++++++
 include/fb.h       |    3 +++
 2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index bef4147..aad0e1f 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -56,6 +56,35 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
 	return 0;
 }
 
+static int fb_setup_mode(struct device_d *dev, struct param_d *param,
+		const char *val)
+{
+	struct fb_info *info = dev->priv;
+	int mode, ret;
+
+	if (info->enabled != 0)
+		return -EPERM;
+
+	if (!val)
+		return dev_param_set_generic(dev, param, NULL);
+
+	for (mode = 0; mode < info->num_modes; mode++) {
+		if (!strcmp(info->mode_list[mode].name, val))
+			break;
+	}
+	if (mode >= info->num_modes)
+		return -EINVAL;
+
+	info->mode = &info->mode_list[mode];
+
+	ret = info->fbops->fb_activate_var(info);
+
+	if (ret == 0)
+		dev_param_set_generic(dev, param, val);
+
+	return ret;
+}
+
 static struct file_operations fb_ops = {
 	.read	= mem_read,
 	.write	= mem_write,
@@ -87,6 +116,12 @@ int register_framebuffer(struct fb_info *info)
 	dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
 	dev_set_param(dev, "enable", "0");
 
+	if (info->num_modes && (info->mode_list != NULL) &&
+			(info->fbops->fb_activate_var != NULL)) {
+		dev_add_param(dev, "mode_name", fb_setup_mode, NULL, 0);
+		dev_set_param(dev, "mode_name", info->mode_list[0].name);
+	}
+
 	devfs_create(&info->cdev);
 
 	return 0;
diff --git a/include/fb.h b/include/fb.h
index 379f931..41deb8c 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -73,10 +73,13 @@ struct fb_ops {
 			    unsigned blue, unsigned transp, struct fb_info *info);
 	void (*fb_enable)(struct fb_info *info);
 	void (*fb_disable)(struct fb_info *info);
+	int (*fb_activate_var)(struct fb_info *info);
 };
 
 struct fb_info {
 	struct fb_videomode *mode;
+	struct fb_videomode *mode_list;
+	unsigned num_modes;
 
 	struct fb_ops *fbops;
 	struct device_d dev;		/* This is this fb device */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:08 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:08 +0100
Subject: [PATCH 09/10] ARM KARO-TX28-STK5: Add a user for video graphics
	support on i.MX28
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-10-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/karo-tx28/tx28-stk5.c |  148 +++++++++++++++++++++++++++++++++
 arch/arm/configs/tx28stk5_defconfig   |    4 +
 2 files changed, 152 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
index a032e6a..6de41f7 100644
--- a/arch/arm/boards/karo-tx28/tx28-stk5.c
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -23,6 +23,7 @@
 #include <mach/imx-regs.h>
 #include <mach/clock.h>
 #include <mach/mci.h>
+#include <mach/fb.h>
 
 static struct stm_mci_platform_data mci_pdata = {
 	.caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz,
@@ -48,6 +49,152 @@ static struct device_d fec_dev = {
 	.platform_data = &fec_info,
 };
 
+/*
+ * The TX28 EVK comes with a VGA connector. We can support many video modes
+ *
+ * Note: The VGA connector is driven from the LCD lines via an ADV7125. This
+ * DA converter needs an high active DE signal to show a video signal.
+ */
+static struct fb_videomode tx28evk_vmodes[] = {
+	{
+	/*
+	 * Modeline "640x480" x 59.9 (to be used with the VGA connector)
+	 * Clock: 25.18 MHz
+	 * Line: 640 656 752 800 (31.5 kHz)
+	 * Frame: 480 490 492 525
+	 * Syncs: -hsync -vsync
+	 */
+		.name = "VGA",
+		.refresh = 60,
+		.xres = 640,
+		.yres = 480,
+		.pixclock = KHZ2PICOS(25180),
+		.left_margin = 48,
+		.hsync_len = 96,
+		.right_margin = 16,
+		.upper_margin = 33,
+		.vsync_len = 2,
+		.lower_margin = 10,
+		.sync = FB_SYNC_DE_HIGH_ACT,
+		.vmode = FB_VMODE_NONINTERLACED,
+		.flag = 0,
+	}, {
+	/*
+	 * Emerging ETV570 640 x 480 display (directly connected)
+	 * Clock: 25.175 MHz
+	 * Syncs: low active, DE high active
+	 * Display area: 115.2 mm x 86.4 mm
+	 */
+		.name = "ETV570",
+		.refresh = 60,
+		.xres = 640,
+		.yres = 480,
+		.pixclock = KHZ2PICOS(25175),
+		.left_margin = 114,
+		.hsync_len = 30,
+		.right_margin = 16,
+		.upper_margin = 32,
+		.vsync_len = 3,
+		.lower_margin = 10,
+		.sync = FB_SYNC_DE_HIGH_ACT,
+		.vmode = FB_VMODE_NONINTERLACED,
+		.flag = 0,
+		/*
+		 * This display is connected:
+		 *  display side   -> CPU side
+		 * ----------------------------
+		 * RESET# pin  -> GPIO126 (3/30) LCD_RESET -> L = display reset
+		 * PWRCTRL pin -> GPIO63 (1/31) LCD_ENABLE - > H=on, L=off
+		 * LEDCTRL pin -> GPIO112 (2/16) PWM0 -> 2.5 V = LEDs off
+		 *                                    ->   0 V = LEDs on
+		 *
+		 * Note: Backlight is on, only if PWRCTRL=H _and_ LEDCTRL=0
+		 */
+	}, {
+	/*
+	 * Modeline "800x600" x 60.3
+	 * Clock: 40.00 MHz
+	 * Line: 800 840 968 1056 (37.9 kHz)
+	 * Frame: 600 601 605 628
+	 * Syncs: +hsync +vsync
+	 */
+		.name = "SVGA",
+		.refresh = 60,
+		.xres = 800,
+		.yres = 600,
+		.pixclock = KHZ2PICOS(40000),
+		.left_margin = 88,
+		.hsync_len = 128,
+		.right_margin = 40,
+		.upper_margin = 23,
+		.vsync_len = 4,
+		.lower_margin = 1,
+		.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
+				FB_SYNC_DE_HIGH_ACT,
+		.vmode = FB_VMODE_NONINTERLACED,
+		.flag = 0,
+	}, {
+	/*
+	 * Modeline "1024x768" x 60.0
+	 * Clock: 65.00 MHz
+	 * Line: 1024 1048 1184 1344 (48.4 kHz)
+	 * Frame: 768 771 777 806
+	 * Syncs: -hsync -vsync
+	 */
+		.name = "XGA",
+		.refresh = 60,
+		.xres = 1024,
+		.yres = 768,
+		.pixclock = KHZ2PICOS(65000),
+		.left_margin = 160,
+		.hsync_len = 136,
+		.right_margin = 24,
+		.upper_margin = 29,
+		.vsync_len = 6,
+		.lower_margin = 3,
+		.sync = FB_SYNC_DE_HIGH_ACT,
+		.vmode = FB_VMODE_NONINTERLACED,
+		.flag = 0,
+	}, {
+	/*
+	 * Modeline "1280x1024" x 60.0
+	 * Clock: 108.00 MHz
+	 * Line: 1280 1328 1440 1688 (64.0 kHz)
+	 * Frame: 1024 1025 1028 1066
+	 * Syncs: +hsync +vsync
+	 */
+		.name = "SXGA",
+		.refresh = 60,
+		.xres = 1280,
+		.yres = 1024,
+		.pixclock = KHZ2PICOS(108000),
+		.left_margin = 248,
+		.hsync_len = 112,
+		.right_margin = 48,
+		.upper_margin = 38,
+		.vsync_len = 3,
+		.lower_margin = 1,
+		.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
+				FB_SYNC_DE_HIGH_ACT,
+		.vmode = FB_VMODE_NONINTERLACED,
+		.flag = 0,
+	},
+};
+
+static struct imx_fb_videomode imxfb_mode = {
+	.mode_list = tx28evk_vmodes,
+	.mode_cnt = ARRAY_SIZE(tx28evk_vmodes),
+	.dotclk_delay = 0,	/* no adaption required */
+	.ld_intf_width = STMLCDIF_24BIT,	/* full 24 bit */
+};
+
+static struct device_d ldcif_dev = {
+	.name = "stmfb",
+	.map_base = IMX_FB_BASE,
+	.size = 4096,
+	.platform_data = &imxfb_mode,
+};
+
 static const uint32_t tx28_starterkit_pad_setup[] = {
 	/*
 	 * Part II of phy's initialization
@@ -205,6 +352,7 @@ void base_board_init(void)
 	imx_set_sspclk(0, 100000000, 1);
 
 	register_device(&mci_socket);
+	register_device(&ldcif_dev);
 
 	imx_enable_enetclk();
 	register_device(&fec_dev);
diff --git a/arch/arm/configs/tx28stk5_defconfig b/arch/arm/configs/tx28stk5_defconfig
index 7246553..d6b81c6 100644
--- a/arch/arm/configs/tx28stk5_defconfig
+++ b/arch/arm/configs/tx28stk5_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARCH_STM=y
 CONFIG_ARCH_IMX28=y
 CONFIG_AEABI=y
 CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MALLOC_SIZE=0x800000
 CONFIG_BROKEN=y
 CONFIG_LONGHELP=y
 CONFIG_GLOB=y
@@ -30,12 +31,15 @@ CONFIG_CMD_RESET=y
 CONFIG_CMD_GO=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_PARTITION=y
+CONFIG_CMD_BMP=y
 CONFIG_NET=y
 CONFIG_NET_DHCP=y
 CONFIG_NET_TFTP=y
 CONFIG_NET_RESOLV=y
 CONFIG_DRIVER_NET_FEC_IMX=y
 # CONFIG_SPI is not set
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_STM=y
 CONFIG_MCI=y
 CONFIG_MCI_STARTUP=y
 CONFIG_MCI_STM378X=y
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:07 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:07 +0100
Subject: [PATCH 08/10] ARM STM/i.MX: Add video driver for i.MX23/i.MX28
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-9-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/include/mach/fb.h         |   43 +++
 arch/arm/mach-stm/include/mach/imx23-regs.h |    1 +
 drivers/video/Kconfig                       |    7 +
 drivers/video/Makefile                      |    1 +
 drivers/video/stm.c                         |  540 +++++++++++++++++++++++++++
 5 files changed, 592 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/include/mach/fb.h
 create mode 100644 drivers/video/stm.c

diff --git a/arch/arm/mach-stm/include/mach/fb.h b/arch/arm/mach-stm/include/mach/fb.h
new file mode 100644
index 0000000..65e3be2
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/fb.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#ifndef __MACH_FB_H
+# define __MACH_FB_H
+
+#include <fb.h>
+
+#define STMLCDIF_8BIT 1	/** pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
+
+/** LC display uses active high data enable signal */
+#define FB_SYNC_DE_HIGH_ACT	(1 << 27)
+/** LC display will latch its data at clock's rising edge */
+#define FB_SYNC_CLK_INVERT	(1 << 28)
+/** output RGB digital data inverted */
+#define FB_SYNC_DATA_INVERT	(1 << 29)
+/** Stop clock if no data is sent (required for passive displays) */
+#define FB_SYNC_CLK_IDLE_DIS	(1 << 30)
+/** swap RGB to BGR */
+#define FB_SYNC_SWAP_RGB	(1 << 31)
+
+struct imx_fb_videomode {
+	struct fb_videomode *mode_list;
+	unsigned mode_cnt;
+
+	unsigned dotclk_delay;	/**< refer manual HW_LCDIF_VDCTRL4 register */
+	unsigned ld_intf_width;	/**< refer STMLCDIF_* macros */
+};
+
+#endif /* __MACH_FB_H */
+
diff --git a/arch/arm/mach-stm/include/mach/imx23-regs.h b/arch/arm/mach-stm/include/mach/imx23-regs.h
index 89ca453..caac19b 100644
--- a/arch/arm/mach-stm/include/mach/imx23-regs.h
+++ b/arch/arm/mach-stm/include/mach/imx23-regs.h
@@ -36,6 +36,7 @@
 #define IMX_CCM_BASE		0x80040000
 #define IMX_I2C1_BASE		0x80058000
 #define IMX_SSP1_BASE		0x80010000
+#define IMX_FB_BASE		0x80030000
 #define IMX_SSP2_BASE		0x80034000
 
 #endif /* __ASM_ARCH_MX23_REGS_H */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7a89a3f..c69308e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -20,4 +20,11 @@ config DRIVER_VIDEO_IMX_IPU
 	  Add support for the IPU framebuffer device found on
 	  i.MX31 and i.MX35 CPUs.
 
+config DRIVER_VIDEO_STM
+	bool "i.MX23/28 framebuffer driver"
+	depends on ARCH_STM
+	help
+	  Say 'Y' here to enable framebuffer and splash screen support for
+	  i.MX23 and i.MX28 based systems.
+
 endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 179f0c4..a217a0b 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_VIDEO) += fb.o
 
+obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
 obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
new file mode 100644
index 0000000..f0abe4c
--- /dev/null
+++ b/drivers/video/stm.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe at pengutronix.de>
+ *
+ * This is based on code from:
+ * Author: Vitaly Wool <vital at embeddedalley.com>
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * 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.
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <xfuncs.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/fb.h>
+
+#define HW_LCDIF_CTRL 0x00
+# define CTRL_SFTRST (1 << 31)
+# define CTRL_CLKGATE (1 << 30)
+# define CTRL_BYPASS_COUNT (1 << 19)
+# define CTRL_VSYNC_MODE (1 << 18)
+# define CTRL_DOTCLK_MODE (1 << 17)
+# define CTRL_DATA_SELECT (1 << 16)
+# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
+# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
+# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
+# define CTRL_MASTER (1 << 5)
+# define CTRL_DF16 (1 << 3)
+# define CTRL_DF18 (1 << 2)
+# define CTRL_DF24 (1 << 1)
+# define CTRL_RUN (1 << 0)
+
+#define HW_LCDIF_CTRL1 0x10
+# define CTRL1_FIFO_CLEAR (1 << 21)
+# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
+# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_CTRL2 0x20
+# define HW_LCDIF_TRANSFER_COUNT 0x30
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_TRANSFER_COUNT 0x20
+#endif
+# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
+# define SET_HCOUNT(x) ((x) & 0xffff)
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_CUR_BUF 0x40
+# define HW_LCDIF_NEXT_BUF 0x50
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_CUR_BUF 0x30
+# define HW_LCDIF_NEXT_BUF 0x40
+#endif
+
+#define HW_LCDIF_TIMING 0x60
+# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
+# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
+# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
+# define SET_DATA_SETUP(x) ((x) & 0xff)
+
+#define HW_LCDIF_VDCTRL0 0x70
+# define VDCTRL0_ENABLE_PRESENT (1 << 28)
+# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
+# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
+# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output at falling, capturing at rising edge */
+# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
+# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
+# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
+# define VDCTRL0_HALF_LINE (1 << 19)
+# define VDCTRL0_HALF_LINE_MODE (1 << 18)
+# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL1 0x80
+
+#define HW_LCDIF_VDCTRL2 0x90
+#ifdef CONFIG_ARCH_IMX28
+# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0xff) << 24)
+#endif
+# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL3 0xa0
+# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
+# define VDCTRL3_VSYNC_ONLY (1 << 28)
+# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
+# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
+
+#define HW_LCDIF_VDCTRL4 0xb0
+#ifdef CONFIG_ARCH_IMX28
+# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
+#endif
+# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
+# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_DVICTRL0 0xc0
+#define HW_LCDIF_DVICTRL1 0xd0
+#define HW_LCDIF_DVICTRL2 0xe0
+#define HW_LCDIF_DVICTRL3 0xf0
+#define HW_LCDIF_DVICTRL4 0x100
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_DATA 0x180
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_DATA 0x1b0
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_DEBUG0 0x1d0
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_DEBUG0 0x1f0
+#endif
+# define DEBUG_HSYNC (1 < 26)
+# define DEBUG_VSYNC (1 < 25)
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct imxfb_info {
+	void __iomem *base;
+	unsigned memory_size;
+	struct fb_info info;
+	struct device_d *hw_dev;
+	struct imx_fb_videomode *pdata;
+};
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+	[RED] = {
+		.offset = 11,
+		.length = 5,
+	},
+	[GREEN] = {
+		.offset = 5,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 5,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB666 true colour mode */
+static const struct fb_bitfield def_rgb666[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 6,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 6,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 6,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+	[RED] = {
+		.offset = 16,
+		.length = 8,
+	},
+	[GREEN] = {
+		.offset = 8,
+		.length = 8,
+	},
+	[BLUE] = {
+		.offset = 0,
+		.length = 8,
+	},
+	[TRANSP] = {	/* no support for transparency */
+		.length = 0,
+	}
+};
+
+static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
+{
+	if (bpp == 24)
+		bpp = 32;
+	return (ppl * bpp) >> 3;
+}
+
+static int stmfb_memory_mmgt(struct fb_info *fb_info, unsigned size)
+{
+	struct imxfb_info *fbi = fb_info->priv;
+
+	if (fbi->memory_size != 0) {
+		free(fb_info->screen_base);
+		fb_info->screen_base = NULL;
+		fbi->memory_size = 0;
+	}
+
+	if (fbi->memory_size == 0) {
+		fb_info->screen_base = xzalloc(size);
+		fbi->memory_size = size;
+	}
+
+	return 0;
+}
+
+static void stmfb_enable_controller(struct fb_info *fb_info)
+{
+	struct imxfb_info *fbi = fb_info->priv;
+	uint32_t reg, last_reg;
+	unsigned loop, edges;
+
+	/*
+	 * Sometimes some data is still present in the FIFO. This leads into
+	 * a correct but shifted picture. Clearing the FIFO helps
+	 */
+	writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_SET);
+
+	/* if it was disabled, re-enable the mode again */
+	reg = readl(fbi->base + HW_LCDIF_CTRL);
+	reg |= CTRL_DOTCLK_MODE;
+	writel(reg, fbi->base + HW_LCDIF_CTRL);
+
+	/* enable the SYNC signals first, then the DMA engine */
+	reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
+	reg |= VDCTRL4_SYNC_SIGNALS_ON;
+	writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
+
+	/*
+	 * Give the attached LC display or monitor a chance to sync into
+	 * our signals.
+	 * Wait for at least 2 VSYNCs = four VSYNC edges
+	 */
+	edges = 4;
+
+	while (edges != 0) {
+		loop = 800;
+		last_reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+		do {
+			reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+			if (reg != last_reg)
+				break;
+			last_reg = reg;
+			loop--;
+		} while (loop != 0);
+		edges--;
+	}
+
+	/* stop FIFO reset */
+	writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_CLR);
+	/* start the engine right now */
+	writel(CTRL_RUN, fbi->base + HW_LCDIF_CTRL + BIT_SET);
+}
+
+static void stmfb_disable_controller(struct fb_info *fb_info)
+{
+	struct imxfb_info *fbi = fb_info->priv;
+	unsigned loop;
+	uint32_t reg;
+
+	/*
+	 * Even if we disable the controller here, it will still continue
+	 * until its FIFOs are running out of data
+	 */
+	reg = readl(fbi->base + HW_LCDIF_CTRL);
+	reg &= ~CTRL_DOTCLK_MODE;
+	writel(reg, fbi->base + HW_LCDIF_CTRL);
+
+	loop = 1000;
+	while (loop) {
+		reg = readl(fbi->base + HW_LCDIF_CTRL);
+		if (!(reg & CTRL_RUN))
+			break;
+		loop--;
+	}
+
+	reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
+	reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
+	writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
+}
+
+static int stmfb_activate_var(struct fb_info *fb_info)
+{
+	struct imxfb_info *fbi = fb_info->priv;
+	struct imx_fb_videomode *pdata = fbi->pdata;
+	struct fb_videomode *mode = fb_info->mode;
+	uint32_t reg;
+	int ret;
+	unsigned size;
+
+	/*
+	 * we need at least this amount of memory for the framebuffer
+	 */
+	size = calc_line_length(mode->xres, fb_info->bits_per_pixel) *
+		mode->yres;
+
+	ret = stmfb_memory_mmgt(fb_info, size);
+	if (ret != 0) {
+		dev_err(fbi->hw_dev, "Cannot allocate framebuffer memory\n");
+		return ret;
+	}
+
+	/** @todo ensure HCLK is active at this point of time! */
+
+	size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock) * 1000);
+	if (size == 0) {
+		dev_dbg(fbi->hw_dev, "Unable to set a valid pixel clock\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * bring the controller out of reset and
+	 * configure it into DOTCLOCK mode
+	 */
+	reg = CTRL_BYPASS_COUNT |	/* always in DOTCLOCK mode */
+		CTRL_DOTCLK_MODE;
+	writel(reg, fbi->base + HW_LCDIF_CTRL);
+
+	/* master mode only */
+	reg |= CTRL_MASTER;
+
+	/*
+	 * Configure videomode and interface mode
+	 */
+	reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
+	switch (fb_info->bits_per_pixel) {
+	case 8:
+		reg |= SET_WORD_LENGTH(1);
+		/** @todo refer manual page 2046 for 8 bpp modes */
+		dev_dbg(fbi->hw_dev, "8 bpp mode not supported yet\n");
+		break;
+	case 16:
+		pr_debug("Setting up an RGB565 mode\n");
+		reg |= SET_WORD_LENGTH(0);
+		reg &= ~CTRL_DF16; /* we assume RGB565 */
+		writel(SET_BYTE_PACKAGING(0xf), fbi->base + HW_LCDIF_CTRL1);
+		fb_info->red = def_rgb565[RED];
+		fb_info->green = def_rgb565[GREEN];
+		fb_info->blue = def_rgb565[BLUE];
+		fb_info->transp =  def_rgb565[TRANSP];
+		break;
+	case 24:
+	case 32:
+		pr_debug("Setting up an RGB888/666 mode\n");
+		reg |= SET_WORD_LENGTH(3);
+		switch (pdata->ld_intf_width) {
+		case STMLCDIF_8BIT:
+			dev_dbg(fbi->hw_dev,
+				"Unsupported LCD bus width mapping\n");
+			break;
+		case STMLCDIF_16BIT:
+		case STMLCDIF_18BIT:
+			/* 24 bit to 18 bit mapping
+			 * which means: ignore the upper 2 bits in
+			 * each colour component
+			 */
+			reg |= CTRL_DF24;
+			fb_info->red = def_rgb666[RED];
+			fb_info->green = def_rgb666[GREEN];
+			fb_info->blue = def_rgb666[BLUE];
+			fb_info->transp =  def_rgb666[TRANSP];
+			break;
+		case STMLCDIF_24BIT:
+			/* real 24 bit */
+			fb_info->red = def_rgb888[RED];
+			fb_info->green = def_rgb888[GREEN];
+			fb_info->blue = def_rgb888[BLUE];
+			fb_info->transp =  def_rgb888[TRANSP];
+			break;
+		}
+		/* do not use packed pixels = one pixel per word instead */
+		writel(SET_BYTE_PACKAGING(0x7), fbi->base + HW_LCDIF_CTRL1);
+		break;
+	default:
+		dev_dbg(fbi->hw_dev, "Unhandled colour depth of %u\n",
+			fb_info->bits_per_pixel);
+		return -EINVAL;
+	}
+	writel(reg, fbi->base + HW_LCDIF_CTRL);
+	pr_debug("Setting up CTRL to %08X\n", reg);
+
+	writel(SET_VCOUNT(mode->yres) |
+		SET_HCOUNT(mode->xres), fbi->base + HW_LCDIF_TRANSFER_COUNT);
+
+	reg = VDCTRL0_ENABLE_PRESENT |	/* always in DOTCLOCK mode */
+		VDCTRL0_VSYNC_PERIOD_UNIT |
+		VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
+	if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+		reg |= VDCTRL0_HSYNC_POL;
+	if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+		reg |= VDCTRL0_VSYNC_POL;
+	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
+		reg |= VDCTRL0_ENABLE_POL;
+	if (mode->sync & FB_SYNC_CLK_INVERT)
+		reg |= VDCTRL0_DOTCLK_POL;
+
+	reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
+	writel(reg, fbi->base + HW_LCDIF_VDCTRL0);
+	pr_debug("Setting up VDCTRL0 to %08X\n", reg);
+
+	/* frame length in lines */
+	writel(mode->upper_margin + mode->vsync_len + mode->lower_margin +
+			mode->yres,
+		fbi->base + HW_LCDIF_VDCTRL1);
+
+	/* line length in units of clocks or pixels */
+	writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
+		SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len +
+			mode->right_margin + mode->xres),
+		fbi->base + HW_LCDIF_VDCTRL2);
+
+	writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
+		SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
+		fbi->base + HW_LCDIF_VDCTRL3);
+
+	writel(
+#ifdef CONFIG_ARCH_IMX28
+		SET_DOTCLK_DLY(pdata->dotclk_delay) |
+#endif
+		SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
+		fbi->base + HW_LCDIF_VDCTRL4);
+
+	writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_CUR_BUF);
+	writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_NEXT_BUF);
+
+	return 0;
+}
+
+static void stmfb_info(struct device_d *hw_dev)
+{
+	struct imx_fb_videomode *pdata = hw_dev->platform_data;
+	unsigned u;
+
+	printf(" Supported video modes:\n");
+	for (u = 0; u < pdata->mode_cnt; u++)
+		printf("  - '%s': %u x %u\n", pdata->mode_list[u].name,
+			pdata->mode_list[u].xres, pdata->mode_list[u].yres);
+}
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct fb_ops imxfb_ops = {
+	.fb_activate_var = stmfb_activate_var,
+	.fb_enable = stmfb_enable_controller,
+	.fb_disable = stmfb_disable_controller,
+};
+
+static struct imxfb_info fbi = {
+	.info = {
+		.fbops = &imxfb_ops,
+	},
+};
+
+static int stmfb_probe(struct device_d *hw_dev)
+{
+	struct imx_fb_videomode *pdata = hw_dev->platform_data;
+	int ret;
+
+	/* just init */
+	fbi.info.priv = &fbi;
+
+	/* add runtime hardware info */
+	fbi.hw_dev = hw_dev;
+	fbi.base = (void *)hw_dev->map_base;
+	fbi.pdata = pdata;
+
+	/* add runtime video info */
+	fbi.info.mode_list = pdata->mode_list;
+	fbi.info.num_modes = pdata->mode_cnt;
+	fbi.info.mode = &fbi.info.mode_list[0];
+	fbi.info.xres = fbi.info.mode->xres;
+	fbi.info.yres = fbi.info.mode->yres;
+	fbi.info.bits_per_pixel = 16;
+
+	ret = register_framebuffer(&fbi.info);
+	if (ret != 0) {
+		dev_err(hw_dev, "Failed to register framebuffer\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct driver_d stmfb_driver = {
+	.name	= "stmfb",
+	.probe	= stmfb_probe,
+	.info	= stmfb_info,
+};
+
+static int stmfb_init(void)
+{
+	return register_driver(&stmfb_driver);
+}
+
+device_initcall(stmfb_init);
+
+/**
+ * @file
+ * @brief LCDIF driver for i.MX23 and i.MX28
+ *
+ * The LCDIF support four modes of operation
+ * - MPU interface (to drive smart displays) -> not supported yet
+ * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
+ * - Dotclock interface (to drive LC displays with RGB data and sync signals)
+ * - DVI (to drive ITU-R BT656)  -> not supported yet
+ *
+ * This driver depends on a correct setup of the pins used for this purpose
+ * (platform specific).
+ *
+ * For the developer: Don't forget to set the data bus width to the display
+ * in the imx_fb_videomode structure. You will else end up with ugly colours.
+ * If you fight against jitter you can vary the clock delay. This is a feature
+ * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
+ * the required value in the imx_fb_videomode structure.
+ */
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:05:06 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:05:06 +0100
Subject: [PATCH 07/10] ARM STM/i.MX: Add a pixel clock calculation routine for
	i.MX23/i.MX28
In-Reply-To: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292857509-13881-8-git-send-email-jbe@pengutronix.de>

In order to support video graphics output on i.MX23/i.MX28 based platforms,
a calculation routine for the pixel clock is required.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/Makefile                   |    1 +
 arch/arm/mach-stm/imx_lcd_clk.c              |  149 ++++++++++++++++++++++++++
 arch/arm/mach-stm/include/mach/clock-imx23.h |    2 +
 arch/arm/mach-stm/include/mach/clock-imx28.h |    2 +
 4 files changed, 154 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-stm/imx_lcd_clk.c

diff --git a/arch/arm/mach-stm/Makefile b/arch/arm/mach-stm/Makefile
index 3c7ce09..0ff8fd1 100644
--- a/arch/arm/mach-stm/Makefile
+++ b/arch/arm/mach-stm/Makefile
@@ -1,3 +1,4 @@
 obj-y += imx.o iomux-imx.o reset-imx.o
+obj-$(CONFIG_DRIVER_VIDEO_STM) += imx_lcd_clk.o
 obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o
 obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o
diff --git a/arch/arm/mach-stm/imx_lcd_clk.c b/arch/arm/mach-stm/imx_lcd_clk.c
new file mode 100644
index 0000000..8938664
--- /dev/null
+++ b/arch/arm/mach-stm/imx_lcd_clk.c
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel at pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_ARCH_IMX23
+
+# define HW_CLKCTRL_DIS_LCDIF 0x060
+#  define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+#  define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+#  define MASK_DIS_LCDIF_DIV 0xfff
+#  define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+#  define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+
+# define HW_CLKCTRL_FRAC 0xf0
+#  define MASK_PIXFRAC 0x3f
+#  define GET_PIXFRAC(x) (((x) >> 16) & MASK_PIXFRAC)
+#  define SET_PIXFRAC(x) (((x) & MASK_PIXFRAC) << 16)
+#  define CLKCTRL_FRAC_CLKGATEPIX (1 << 23)
+
+# define HW_CLKCTRL_CLKSEQ 0x110
+#  define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 1)
+
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+
+# define HW_CLKCTRL_DIS_LCDIF 0x120
+#  define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+#  define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+#  define MASK_DIS_LCDIF_DIV 0x1fff
+#  define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+#  define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+
+/* note: On i.MX28 this is called 'FRAC1' */
+# define HW_CLKCTRL_FRAC 0x1c0
+#  define MASK_PIXFRAC 0x3f
+#  define GET_PIXFRAC(x) ((x) & MASK_PIXFRAC)
+#  define SET_PIXFRAC(x) ((x) & MASK_PIXFRAC)
+#  define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
+
+# define HW_CLKCTRL_CLKSEQ 0x1d0
+#  define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
+
+#endif
+
+unsigned imx_get_lcdifclk(void)
+{
+	unsigned rate = (imx_get_mpllclk() / 1000) * 18U;
+	unsigned div;
+
+	div = GET_PIXFRAC(readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC));
+	if (div != 0U) {
+		rate /= div;
+		div = GET_DIS_LCDIF_DIV(readl(IMX_CCM_BASE +
+							HW_CLKCTRL_DIS_LCDIF));
+		if (div != 0U)
+			rate /= div;
+		else
+			pr_debug("LCDIF clock has divisor 0!\n");
+	} else
+		pr_debug("LCDIF clock has frac divisor 0!\n");
+
+	return rate * 1000;
+}
+
+/*
+ * The source of the pixel clock can be the external 24 MHz crystal or the
+ * internal PLL running at 480 MHz. In order to support at least VGA sized
+ * displays/resolutions this routine forces the PLL as the clock source.
+ */
+unsigned imx_set_lcdifclk(unsigned nc)
+{
+	unsigned frac, best_frac = 0, div, best_div = 0, result;
+	int delta, best_delta = 0xffffff;
+	unsigned i, parent_rate = imx_get_mpllclk() / 1000;
+	uint32_t reg;
+
+#define SH_DIV(NOM, DEN, LSH) ((((NOM) / (DEN)) << (LSH)) + \
+			DIV_ROUND_CLOSEST(((NOM) % (DEN)) << (LSH), DEN))
+#define SHIFT 4
+
+	nc /= 1000;
+	nc <<= SHIFT;
+
+	for (frac = 18; frac <= 35; ++frac) {
+		for (div = 1; div <= 255; ++div) {
+			result = DIV_ROUND_CLOSEST(parent_rate *
+						SH_DIV(18U, frac, SHIFT), div);
+			delta = nc - result;
+			if (abs(delta) < abs(best_delta)) {
+				best_delta = delta;
+				best_frac = frac;
+				best_div = div;
+			}
+		}
+	}
+
+	if (best_delta == 0xffffff) {
+		pr_debug("Unable to match the pixelclock\n");
+		return 0;
+	}
+
+	pr_debug("Programming PFD=%u,DIV=%u ref_pix=%u MHz PIXCLK=%u kHz\n",
+			best_frac, best_div, 480 * 18 / best_frac,
+			480000 * 18 / best_frac / best_div);
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC) & ~MASK_PIXFRAC;
+	reg |= SET_PIXFRAC(best_frac);
+	writel(reg, IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+	writel(reg & ~CLKCTRL_FRAC_CLKGATEPIX, IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) & ~MASK_DIS_LCDIF_DIV;
+	reg &= ~CLKCTRL_DIS_LCDIF_GATE;
+	reg |= SET_DIS_LCDIF_DIV(best_div);
+	writel(reg, IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF);
+
+	/* Wait for divider update */
+	for (i = 0; i < 10000; i++) {
+		if (!(readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) &
+						CLKCTRL_DIS_LCDIF_BUSY))
+			break;
+	}
+
+	if (i >= 10000) {
+		pr_debug("Setting LCD clock failed\n");
+		return 0;
+	}
+
+	writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF,
+		IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
+
+	return imx_get_lcdifclk();
+}
diff --git a/arch/arm/mach-stm/include/mach/clock-imx23.h b/arch/arm/mach-stm/include/mach/clock-imx23.h
index bb499f2..723f343 100644
--- a/arch/arm/mach-stm/include/mach/clock-imx23.h
+++ b/arch/arm/mach-stm/include/mach/clock-imx23.h
@@ -22,5 +22,7 @@ unsigned imx_get_xclk(void);
 unsigned imx_get_sspclk(unsigned);
 unsigned imx_set_sspclk(unsigned, unsigned, int);
 unsigned imx_set_ioclk(unsigned);
+unsigned imx_set_lcdifclk(unsigned);
+unsigned imx_get_lcdifclk(void);
 
 #endif /* MACH_CLOCK_IMX23_H */
diff --git a/arch/arm/mach-stm/include/mach/clock-imx28.h b/arch/arm/mach-stm/include/mach/clock-imx28.h
index afc9fb6..45fb043 100644
--- a/arch/arm/mach-stm/include/mach/clock-imx28.h
+++ b/arch/arm/mach-stm/include/mach/clock-imx28.h
@@ -22,6 +22,8 @@ unsigned imx_get_xclk(void);
 unsigned imx_get_sspclk(unsigned);
 unsigned imx_set_sspclk(unsigned, unsigned, int);
 unsigned imx_set_ioclk(unsigned, unsigned);
+unsigned imx_set_lcdifclk(unsigned);
+unsigned imx_get_lcdifclk(void);
 unsigned imx_get_fecclk(void);
 void imx_enable_enetclk(void);
 
-- 
1.7.2.3



From jbe at pengutronix.de  Mon Dec 20 10:04:59 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Mon, 20 Dec 2010 16:04:59 +0100
Subject: [PATCH] Add support for runtime selection of video mode in barebox
Message-ID: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>

Currently barebox uses a fixed video mode setup. Everything is compiled in.
This change set adds the possibility to select a video mode according to a
connected display at runtime (but only for adapted graphic drivers). If more
than one video mode is supported by the platform, running the 'devinfo'
command on the graphic device shows the supported list of video modes.
After selecting the video mode, the output can be enabled.

Always the first listed video mode is selected by default, but graphic output
is still disabled. So, an init script can still change the mode.

My system comes with a VGA connector that supports more than one video mode.

At system start, the first video mode is selected, but no output happens:

barebox:/  devinfo fb0
 base  : 0x00000000
 size  : 0x00096000
 driver: none

 Parameters:
           enable = 0
        mode_name = VGA

To get the list of supported video modes, just 'ask' the driver:

barebox:/ devinfo stmfb0
base  : 0x80030000
size  : 0x00001000
driver: stmfb

 Supported video modes:
   - 'VGA': 640 x 480
   - 'ETV570': 640 x 480
   - 'SVGA': 800 x 600
   - 'XGA': 1024 x 768
   - 'SXGA': 1280 x 1024
no parameters available

To set a new mode, disable the output first (if already enabled) and change
the framebuffer's 'mode_name' parameter:

barebox:/ fb0.mode_name=SVGA

Then (re-)enable it:

barebox:/ fb0.enable=1

barebox:/ devinfo fb0
base  : 0x00000000
size  : 0x00096000
driver: none

Parameters:
          enable = 1
       mode_name = SVGA

Already existing graphic drivers are not touched.

The following changes since commit 97d6b6aac3f0f267afc2e0d8abe55b6e82860d6a:

  ARM tx28stk5_defconfig: update config (2010-12-14 15:22:55 +0100)

are available in the git repository at:
  http://git.pengutronix.de/git/jbe/for_barebox_next/ next_seperate_videomode

Juergen Beisert (10):
      Add more useful generic macros
      ARM Chumby: Fix memory index
      ARM Chumby: Fix unit of the clocks after the change to Hz
      ARM Chumby: Just fix some typos
      Fix default framebuffer 'enable' set
      Add the feature to change the video mode at runtime
      ARM STM/i.MX: Add a pixel clock calculation routine for i.MX23/i.MX28
      ARM STM/i.MX: Add video driver for i.MX23/i.MX28
      ARM KARO-TX28-STK5: Add a user for video graphics support on i.MX28
      ARM Chumby-Falconwing: Add a user for video graphics support on i.MX23

 arch/arm/boards/chumby_falconwing/falconwing.c |   99 +++--
 arch/arm/boards/karo-tx28/tx28-stk5.c          |  148 +++++++
 arch/arm/configs/chumbyone_defconfig           |    3 +
 arch/arm/configs/tx28stk5_defconfig            |    4 +
 arch/arm/mach-stm/Makefile                     |    1 +
 arch/arm/mach-stm/imx_lcd_clk.c                |  149 +++++++
 arch/arm/mach-stm/include/mach/clock-imx23.h   |    2 +
 arch/arm/mach-stm/include/mach/clock-imx28.h   |    2 +
 arch/arm/mach-stm/include/mach/fb.h            |   43 ++
 arch/arm/mach-stm/include/mach/imx23-regs.h    |    1 +
 drivers/video/Kconfig                          |    7 +
 drivers/video/Makefile                         |    1 +
 drivers/video/fb.c                             |   44 ++-
 drivers/video/stm.c                            |  540 ++++++++++++++++++++++++
 include/common.h                               |   10 +
 include/fb.h                                   |    3 +
 16 files changed, 1024 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm/mach-stm/imx_lcd_clk.c
 create mode 100644 arch/arm/mach-stm/include/mach/fb.h
 create mode 100644 drivers/video/stm.c


From khc at pm.waw.pl  Mon Dec 20 17:30:03 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:30:03 +0100
Subject: my IXP4xx-related and other patches
Message-ID: <m362uodqms.fsf@intrepid.localdomain>

Hello,

I've been working a bit on IXP4xx support lately and it seems I'm at the
point I can now boot Barebox on a Goramo Multilink routers
(IXP425-based). It requires several patches (will post them shortly) and
NPE microcode files from Intel (or from elsewhere, the regular non-VLAN
microcode v. 2.4 is needed, i.e., same as with Linux).

The binary microcode must be appended to Barebox at correct offsets for
the NPE driver to find it, details are in board support file
(arch/arm/boards/multilink/multilink.c):

#define BAREBOX_START        0x00000
#define BAREBOX_LENGTH       0x34000
#define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
#define NPE_A_LENGTH         0x05000
#define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
#define NPE_B_LENGTH         0x03000
#define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
#define NPE_C_LENGTH         0x04000
#define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
#define NPE_ENV0_LENGTH      0x20000

when passed to Linux:
Creating XXX MTD partitions on "IXP4XX-Flash.0":
0x000000000000-0x000000034000 : "barebox"
0x000000034000-0x000000039000 : "NPE-A"
0x000000039000-0x00000003c000 : "NPE-B"
0x00000003c000-0x000000040000 : "NPE-C"
0x000000040000-0x000000060000 : "env0"

User-available flash area starts at 0x60000.

All this IXP4xx code is big-endian only. Too much work with LE (NPE
coprocessors would need buffer byte swapping, flash (EXP bus) would need
16-bit word swapping etc). Big-endian Barebox can load both LE and BE
Linux anyway ("bootz" only at the moment).

It should be easily applicable to other IXP42x-based platforms.
-- 
Krzysztof Halasa


From khc at pm.waw.pl  Mon Dec 20 17:42:17 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:42:17 +0100
Subject: [PATCH 2] Remove unused eth_get_name() prototype.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3zks0cbhy.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/include/net.h b/include/net.h
index c695e5f..75088b8 100644
--- a/include/net.h
+++ b/include/net.h
@@ -55,7 +55,6 @@ int eth_open(void);			/* open the device		*/
 int eth_send(void *packet, int length);	   /* Send a packet		*/
 int eth_rx(void);			/* Check for received packets	*/
 void eth_halt(void);			/* stop SCC			*/
-char *eth_get_name(void);		/* get name of current device	*/
 
 /*
  *	Ethernet header


From khc at pm.waw.pl  Mon Dec 20 17:44:00 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:44:00 +0100
Subject: [PATCH 3] Flash CFI: removed unused 'size' variable.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3y67kcbf3.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 2fa2c6b..4af0370 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -995,7 +995,6 @@ static void cfi_init_mtd(struct flash_info *info)
 
 static int cfi_probe (struct device_d *dev)
 {
-	unsigned long size = 0;
 	struct flash_info *info = xzalloc(sizeof(*info));
 
 	dev->priv = (void *)info;
@@ -1004,7 +1003,7 @@ static int cfi_probe (struct device_d *dev)
 
 	/* Init: no FLASHes known */
 	info->flash_id = FLASH_UNKNOWN;
-	size += info->size = flash_get_size(info, dev->map_base);
+	info->size = flash_get_size(info, dev->map_base);
 	info->base = (void __iomem *)dev->map_base;
 
 	if (dev->size == 0) {


From khc at pm.waw.pl  Mon Dec 20 17:45:17 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:45:17 +0100
Subject: [PATCH 4] Fix help text for "loadb" and "loady" commands.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3wrn4cbcy.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/commands/loadb.c b/commands/loadb.c
index faf4a97..dc0e517 100644
--- a/commands/loadb.c
+++ b/commands/loadb.c
@@ -802,7 +802,7 @@ static const __maybe_unused char cmd_loadb_help[] =
     "  -f file   - where to download to - defaults to " DEF_FILE "\n"
     "  -o offset - what offset to download - defaults to 0\n"
     "  -b baud   - baudrate at which to download - defaults to "
-    "console baudrate"
+    "console baudrate\n"
     "  -c        - Create file if it is not present - default disabled";
 #ifdef CONFIG_CMD_LOADB
 BAREBOX_CMD_START(loadb)


From khc at pm.waw.pl  Mon Dec 20 17:54:49 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:54:49 +0100
Subject: [PATCH 5] Fix error handling with malloc,
	memalign etc. Memalign() can't fail now.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3vd2ocax2.fsf@intrepid.localdomain>

Fix error handling with malloc, memalign etc. Memalign() can't fail now.

The idea is to panic() when there is no memory available for normal
operation. Exception: code which can consume arbitrary amount of RAM
(example: files allocated in ramfs) must report error instead of
panic().

This patch also fixes code which didn't check for NULL from malloc()
etc.

Usage: malloc() returns NULL when out of RAM.
xmalloc(), memalign() always return non-NULL or panic().

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 08a57ce..fbaf627 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -95,13 +95,7 @@ void setup_dma_coherent(unsigned long offset)
 
 void *dma_alloc_coherent(size_t size)
 {
-	void *mem;
-
-	mem = memalign(4096, size);
-	if (mem)
-		return mem + dma_coherent_offset;
-
-	return NULL;
+	return memalign(4096, size) + dma_coherent_offset;
 }
 
 unsigned long virt_to_phys(void *virt)
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index fdd23b5..7789cc9 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -28,7 +28,7 @@ void *phys_to_virt(unsigned long phys);
 #else
 static inline void *dma_alloc_coherent(size_t size)
 {
-	return malloc(size);
+	return xmalloc(size);
 }
 
 static inline void dma_free_coherent(void *mem)
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index 287be0d..8409ca8 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -223,10 +223,7 @@ static int add_image(char *str, char *name)
 	struct stat s;
 	char *opt;
 	int fd, ret;
-	struct hf_platform_data *hf = malloc(sizeof(struct hf_platform_data));
-
-	if (!hf)
-		return -1;
+	struct hf_platform_data *hf = xmalloc(sizeof(struct hf_platform_data));
 
 	file = strtok(str, ",");
 	while ((opt = strtok(NULL, ","))) {
@@ -285,11 +282,7 @@ int main(int argc, char *argv[])
 	char str[6];
 	int fdno = 0, envno = 0;
 
-	ram = malloc(malloc_size);
-	if (!ram) {
-		printf("unable to get malloc space\n");
-		exit(1);
-	}
+	ram = xmalloc(malloc_size);
 	mem_malloc_init(ram, ram + malloc_size);
 
 	while (1) {
diff --git a/commands/edit.c b/commands/edit.c
index ca40d59..3519b09 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -184,10 +184,8 @@ static struct line *line_realloc(int len, struct line *line)
 {
 	int size = 32;
 
-	if (!line) {
+	if (!line)
 		line = xzalloc(sizeof(struct line));
-		line->data = malloc(32);
-	}
 
 	while (size < len)
 		size <<= 1;
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index ff63fbe..383c1d8 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -1,9 +1,9 @@
-
+#include <common.h>
 #include <config.h>
 #include <malloc.h>
 #include <string.h>
 #include <mem_malloc.h>
-
+#include <xfuncs.h>
 #include <stdio.h>
 #include <module.h>
 
@@ -1696,12 +1696,12 @@ void *memalign(size_t alignment, size_t bytes)
 	long remainder_size;	/* its size */
 
 	if ((long) bytes < 0)
-		return NULL;
+		panic("memalign: requested %i bytes\n", bytes);
 
 	/* If need less alignment than we give anyway, just relay to malloc */
 
 	if (alignment <= MALLOC_ALIGNMENT)
-		return malloc(bytes);
+		return xmalloc(bytes);
 
 	/* Otherwise, ensure that it is at least a minimum chunk size */
 
@@ -1711,10 +1711,7 @@ void *memalign(size_t alignment, size_t bytes)
 	/* Call malloc with worst case padding to hit alignment. */
 
 	nb = request2size(bytes);
-	m = (char*)(malloc (nb + alignment + MINSIZE));
-
-	if (!m)
-		return NULL;	/* propagate failure */
+	m = (char*)(xmalloc(nb + alignment + MINSIZE));
 
 	p = mem2chunk(m);
 
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 717fea5..9d52beb 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -116,9 +116,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
 {
 	struct clk_lookup_alloc *cla;
 
-	cla = kzalloc(sizeof(*cla), GFP_KERNEL);
-	if (!cla)
-		return NULL;
+	cla = xzalloc(sizeof(*cla), GFP_KERNEL);
 
 	cla->cl.clk = clk;
 	if (con_id) {
@@ -150,8 +148,6 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
 
 	l = clkdev_alloc(r, alias, alias_dev_name);
 	clk_put(r);
-	if (!l)
-		return -ENODEV;
 	clkdev_add(l);
 	return 0;
 }
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 04a1e4c..f1bfba7 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1334,9 +1334,6 @@ static struct driver_d mci_driver = {
 static int mci_init(void)
 {
 	sector_buf = memalign(32, 512);
-	if (!sector_buf)
-		return -ENOMEM;
-
 	return register_driver(&mci_driver);
 }
 
diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c
index 4563ff3..d5e26a1 100644
--- a/drivers/net/at91_ether.c
+++ b/drivers/net/at91_ether.c
@@ -263,7 +263,7 @@ static int at91rm9200_eth_init (struct device_d *dev)
 	struct eth_device *edev;
 	int i;
 
-	edev = malloc(sizeof(struct eth_device));
+	edev = xmalloc(sizeof(struct eth_device));
 	dev->priv = edev;
 
 	edev->open = at91rm9200_eth_open;
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index 8120877..187c0fb 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -440,14 +440,14 @@ static int cs8900_probe(struct device_d *dev)
 
 	debug("cs8900_init()\n");
 
-	priv = (struct cs8900_priv *)malloc(sizeof(*priv));
+	priv = (struct cs8900_priv *)xmalloc(sizeof(*priv));
 	priv->regs = (u16 *)dev->map_base;
 	if (cs8900_check_id(priv)) {
 		free(priv);
 		return -1;
 	}
 
-	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
 	dev->type_data = edev;
 	edev->priv = priv;
 
diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c
index 8b2cb4d..7528316 100644
--- a/drivers/net/fec_mpc5200.c
+++ b/drivers/net/fec_mpc5200.c
@@ -661,9 +661,9 @@ int mpc5xxx_fec_probe(struct device_d *dev)
         struct eth_device *edev;
 	mpc5xxx_fec_priv *fec;
 
-        edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+        edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
         dev->type_data = edev;
-	fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
+	fec = (mpc5xxx_fec_priv *)xmalloc(sizeof(*fec));
         edev->priv = fec;
 	edev->open = mpc5xxx_fec_open,
 	edev->init = mpc5xxx_fec_init,
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 522a9f1..a30a9c8 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -79,7 +79,7 @@ int tap_probe(struct device_d *dev)
 	struct tap_priv *priv;
 	int ret = 0;
 
-	priv = malloc(sizeof(struct tap_priv));
+	priv = xmalloc(sizeof(struct tap_priv));
 	priv->name = "barebox";
 
 	priv->fd = tap_alloc(priv->name);
@@ -88,7 +88,7 @@ int tap_probe(struct device_d *dev)
 		goto out;
 	}
 
-	edev = malloc(sizeof(struct eth_device));
+	edev = xmalloc(sizeof(struct eth_device));
 	dev->type_data = edev;
 	edev->priv = priv;
 
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 4af0370..f7eeb2a 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -326,7 +326,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 #endif
 
 	/* first only malloc space for the first sector */
-	info->start = malloc(sizeof(ulong));
+	info->start = xmalloc(sizeof(ulong));
 
 	info->start[0] = base;
 	info->protect = 0;
@@ -415,8 +415,8 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 			cur_offset += erase_region_size * erase_region_count;
 
 			/* increase the space malloced for the sector start addresses */
-			info->start = realloc(info->start, sizeof(ulong) * (erase_region_count + sect_cnt));
-			info->protect = realloc(info->protect, sizeof(uchar) * (erase_region_count + sect_cnt));
+			info->start = xrealloc(info->start, sizeof(ulong) * (erase_region_count + sect_cnt));
+			info->protect = xrealloc(info->protect, sizeof(uchar) * (erase_region_count + sect_cnt));
 
 			for (j = 0; j < erase_region_count; j++) {
 				info->start[sect_cnt] = sector;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index bc9b0de..442dbc4 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -157,8 +157,7 @@ static int pl011_probe(struct device_d *dev)
 	struct amba_uart_port *uart;
 	struct console_device *cdev;
 
-	uart = malloc(sizeof(struct amba_uart_port));
-
+	uart = xmalloc(sizeof(struct amba_uart_port));
 	uart->clk = clk_get(dev, NULL);
 
 	if (IS_ERR(uart->clk))
diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c
index b99ec4d..1098952 100644
--- a/drivers/serial/atmel.c
+++ b/drivers/serial/atmel.c
@@ -398,8 +398,7 @@ static int atmel_serial_probe(struct device_d *dev)
 	struct atmel_uart_port *uart;
 	struct console_device *cdev;
 
-	uart = malloc(sizeof(struct atmel_uart_port));
-
+	uart = xmalloc(sizeof(struct atmel_uart_port));
 	cdev = &uart->uart;
 	dev->type_data = cdev;
 	cdev->dev = dev;
diff --git a/drivers/serial/serial_blackfin.c b/drivers/serial/serial_blackfin.c
index 2101b7e..59b2fbb 100644
--- a/drivers/serial/serial_blackfin.c
+++ b/drivers/serial/serial_blackfin.c
@@ -115,7 +115,7 @@ static int blackfin_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index a7562f9..984d7f2 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -319,7 +319,7 @@ static int imx_serial_probe(struct device_d *dev)
 	struct imx_serial_priv *priv;
 	uint32_t val;
 
-	priv = malloc(sizeof(*priv));
+	priv = xmalloc(sizeof(*priv));
 	cdev = &priv->cdev;
 
 	priv->regs = (void __force __iomem *)dev->map_base;
diff --git a/drivers/serial/serial_netx.c b/drivers/serial/serial_netx.c
index 7c09519..9d4b29e 100644
--- a/drivers/serial/serial_netx.c
+++ b/drivers/serial/serial_netx.c
@@ -140,7 +140,7 @@ static int netx_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c
index 1a6366f..7923ebb 100644
--- a/drivers/serial/serial_pl010.c
+++ b/drivers/serial/serial_pl010.c
@@ -141,7 +141,7 @@ static int pl010_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index d7eac8f..0a17967 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -121,8 +121,7 @@ static int s3c24x0_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
-
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 978fdd1..fd70e62 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -903,9 +903,6 @@ static int __init composite_bind(struct usb_gadget *gadget)
 	int				status = -ENOMEM;
 
 	cdev = xzalloc(sizeof *cdev);
-	if (!cdev)
-		return status;
-
 	cdev->gadget = gadget;
 	set_gadget_data(gadget, cdev);
 	INIT_LIST_HEAD(&cdev->configs);
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 48fd0b5..20a5064 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -1016,8 +1016,6 @@ fsl_alloc_request(struct usb_ep *_ep)
 	struct fsl_req *req;
 
 	req = xzalloc(sizeof *req);
-	if (!req)
-		return NULL;
 
 	INIT_LIST_HEAD(&req->queue);
 
@@ -2095,7 +2093,7 @@ static int struct_udc_setup(struct fsl_udc *udc,
 	udc->status_req = container_of(fsl_alloc_request(NULL),
 			struct fsl_req, req);
 	/* allocate a small amount of memory to get valid address */
-	udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
+	udc->status_req->req.buf = xmalloc(8);
 	udc->resume_state = USB_STATE_NOTATTACHED;
 	udc->usb_state = USB_STATE_POWERED;
 	udc->ep0_dir = 0;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index cb65b19..edcb3f2 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -206,10 +206,6 @@ gs_alloc_req(struct usb_ep *ep, unsigned len)
 	if (req != NULL) {
 		req->length = len;
 		req->buf = memalign(32, len);
-		if (req->buf == NULL) {
-			usb_ep_free_request(ep, req);
-			return NULL;
-		}
 	}
 
 	return req;
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 0d4f5e7..9f6535d 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -122,8 +122,11 @@ int symfilecnt = 0;
 
 void add_new_symbol(struct symfile *sym, char * symname)
 {
-	sym->symbollist =
-          realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	sym->symbollist = realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	if (!sym->symbollist) {
+		fprintf(stderr, "docproc: out of memory\n");
+		exit(1);
+	}
 	sym->symbollist[sym->symbolcnt++].name = strdup(symname);
 }
 
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4075c35..08b75b6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1317,7 +1317,7 @@ void buf_write(struct buffer *buf, const char *s, int len)
 {
 	if (buf->size - buf->pos < len) {
 		buf->size += len + SZ;
-		buf->p = realloc(buf->p, buf->size);
+		buf->p = NOFAIL(realloc(buf->p, buf->size));
 	}
 	strncpy(buf->p + buf->pos, s, len);
 	buf->pos += len;


From khc at pm.waw.pl  Mon Dec 20 17:58:11 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:58:11 +0100
Subject: [PATCH 6] ARM: support big/little endian switching in "bootz".
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3tyi8carg.fsf@intrepid.localdomain>

ARM: support big/little endian switching in "bootz".
Perhaps one should make this conditional? Mostly for big-endian
Barebox loading little-endian (e.g. armel Debian) Linux.

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index f826da6..4d1c757 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -41,6 +41,7 @@
 #include <asm/setup.h>
 #include <asm/barebox-arm.h>
 #include <asm/armlinux.h>
+#include <asm/system.h>
 
 static struct tag *params;
 static int armlinux_architecture = 0;
@@ -85,9 +86,10 @@ static void setup_memory_tags(void)
 	}
 }
 
-static void setup_commandline_tag(const char *commandline)
+static void setup_commandline_tag(const char *commandline, int swap)
 {
 	const char *p;
+	size_t words;
 
 	if (!commandline)
 		return;
@@ -102,12 +104,18 @@ static void setup_commandline_tag(const char *commandline)
 	if (*p == '\0')
 		return;
 
+	words = (strlen(p) + 1 /* NUL */ + 3 /* round up */) >> 2;
 	params->hdr.tag = ATAG_CMDLINE;
-	params->hdr.size =
-	    (sizeof (struct tag_header) + strlen(p) + 1 + 4) >> 2;
+	params->hdr.size = (sizeof(struct tag_header) >> 2) + words;
 
 	strcpy(params->u.cmdline.cmdline, p);
 
+	if (swap) {
+		u32 *cmd = (u32 *)params->u.cmdline.cmdline;
+		while (words--)
+			cmd[words] = swab32(cmd[words]);
+	}
+
 	params = tag_next(params);
 }
 
@@ -156,13 +164,13 @@ static void setup_end_tag (void)
 	params->hdr.size = 0;
 }
 
-static void setup_tags(struct image_data *data)
+static void setup_tags(struct image_data *data, int swap)
 {
 	const char *commandline = getenv("bootargs");
 
 	setup_start_tag();
 	setup_memory_tags();
-	setup_commandline_tag(commandline);
+	setup_commandline_tag(commandline, swap);
 
 	if (data && data->initrd)
 		setup_initrd_tag (&data->initrd->header);
@@ -231,7 +239,7 @@ static int do_bootm_linux(struct image_data *data)
 	debug("## Transferring control to Linux (at address 0x%p) ...\n",
 	       theKernel);
 
-	setup_tags(data);
+	setup_tags(data, 0);
 
 	if (relocate_image(data->os, (void *)image_get_load(os_header)))
 		return -1;
@@ -290,18 +298,21 @@ late_initcall(armlinux_register_image_handler);
 
 #ifdef CONFIG_CMD_BOOTZ
 struct zimage_header {
-	u32	unsused[9];
+	u32	unused[9];
 	u32	magic;
 	u32	start;
 	u32	end;
 };
 
+#define ZIMAGE_MAGIC 0x016F2818
+
 static int do_bootz(struct command *cmdtp, int argc, char *argv[])
 {
 	void (*theKernel)(int zero, int arch, void *params);
-	int fd, ret;
+	int fd, ret, swap = 0;
 	struct zimage_header header;
 	void *zimage;
+	u32 end;
 
 	if (argc != 2) {
 		barebox_cmd_usage(cmdtp);
@@ -320,27 +331,51 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
 		goto err_out;
 	}
 
-	if (header.magic != 0x016f2818) {
+	switch (header.magic) {
+	case swab32(ZIMAGE_MAGIC):
+		swap = 1;
+		/* fall through */
+	case ZIMAGE_MAGIC:
+		break;
+	default:
 		printf("invalid magic 0x%08x\n", header.magic);
 		goto err_out;
 	}
 
-	zimage = xmalloc(header.end);
+	end = header.end;
+
+	if (swap)
+		end = swab32(end);
+
+	zimage = xmalloc(end);
 	memcpy(zimage, &header, sizeof(header));
 
-	ret = read(fd, zimage + sizeof(header), header.end - sizeof(header));
-	if (ret < header.end - sizeof(header)) {
+	ret = read(fd, zimage + sizeof(header), end - sizeof(header));
+	if (ret < end - sizeof(header)) {
 		printf("could not read %s\n", argv[1]);
 		goto err_out1;
 	}
 
+	if (swap) {
+		void *ptr;
+		for (ptr = zimage; ptr < zimage + end; ptr += 4)
+			*(u32 *)ptr = swab32(*(u32 *)ptr);
+	}
+
 	theKernel = zimage;
 
-	printf("loaded zImage from %s with size %d\n", argv[1], header.end);
+	printf("loaded zImage from %s with size %d\n", argv[1], end);
 
-	setup_tags(NULL);
+	setup_tags(NULL, swap);
 
 	shutdown_barebox();
+	if (swap) {
+		u32 reg;
+		__asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));
+		reg ^= CR_B; /* swap big-endian flag */
+		__asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
+	}
+
 	theKernel(0, armlinux_architecture, armlinux_bootparams);
 
 	return 0;


From khc at pm.waw.pl  Mon Dec 20 18:01:05 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:01:05 +0100
Subject: [PATCH 7] Fix top-level Makefile to work with GNU make 3.82.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3sjxscamm.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/Makefile b/Makefile
index e0a7ed0..4e207cd 100644
--- a/Makefile
+++ b/Makefile
@@ -389,7 +389,11 @@ ifeq ($(config-targets),1)
 include $(srctree)/arch/$(ARCH)/Makefile
 export KBUILD_DEFCONFIG
 
-config %config: scripts_basic outputmakefile FORCE
+config: scripts_basic outputmakefile FORCE
+	$(Q)mkdir -p include/linux include/config
+	$(Q)$(MAKE) $(build)=scripts/kconfig $@
+
+%config: scripts_basic outputmakefile FORCE
 	$(Q)mkdir -p include/linux include/config
 	$(Q)$(MAKE) $(build)=scripts/kconfig $@
 
@@ -1251,7 +1255,7 @@ target-dir = $(dir $@)
 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
 
 # Modules
-/ %/: prepare scripts FORCE
+%/: prepare scripts FORCE
 	$(Q)$(MAKE) $(build)=$(build-dir)
 %.ko: prepare scripts FORCE
 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \


From khc at pm.waw.pl  Mon Dec 20 18:02:02 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:02:02 +0100
Subject: [PATCH 8] Cosmetic fixes,
	including format attributes for printf() and friends.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3r5dccal1.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/commands/crc.c b/commands/crc.c
index 0873a1c..993074c 100644
--- a/commands/crc.c
+++ b/commands/crc.c
@@ -134,7 +134,7 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
 #endif
 
 	if (verify && crc != vcrc) {
-		printf(" != 0x%08x ** ERROR **", vcrc);
+		printf(" != 0x%08lx ** ERROR **", vcrc);
 		err = 1;
 	}
 
diff --git a/commands/flash.c b/commands/flash.c
index 9a0eb50..a3f3508 100644
--- a/commands/flash.c
+++ b/commands/flash.c
@@ -63,7 +63,7 @@ static int do_flerase(struct command *cmdtp, int argc, char *argv[])
 
 	fd = open(filename, O_WRONLY);
 	if (fd < 0) {
-		printf("open %s:", filename, errno_str());
+		printf("open %s: %s", filename, errno_str());
 		return 1;
 	}
 
@@ -139,7 +139,7 @@ static int do_protect(struct command *cmdtp, int argc, char *argv[])
 
 	fd = open(filename, O_WRONLY);
 	if (fd < 0) {
-		printf("open %s:", filename, errno_str());
+		printf("open %s: %s", filename, errno_str());
 		return 1;
 	}
 
diff --git a/commands/go.c b/commands/go.c
index 0262940..6082fe5 100644
--- a/commands/go.c
+++ b/commands/go.c
@@ -55,7 +55,7 @@ static int do_go(struct command *cmdtp, int argc, char *argv[])
 	} else
 		addr = (void *)simple_strtoul(argv[1], NULL, 16);
 
-	printf("## Starting application at 0x%08lX ...\n", addr);
+	printf("## Starting application at 0x%p ...\n", addr);
 
 	console_flush();
 
diff --git a/commands/loadb.c b/commands/loadb.c
index dc0e517..439a83a 100644
--- a/commands/loadb.c
+++ b/commands/loadb.c
@@ -625,7 +625,6 @@ static ulong load_serial_ymodem(void)
 	int res, wr;
 	connection_info_t info;
 	char ymodemBuf[1024];
-	ulong store_addr = ~0;
 	ulong addr = 0;
 
 	size = 0;
diff --git a/commands/ls.c b/commands/ls.c
index 4f9c408..278a8bc 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -32,10 +32,10 @@
 static void ls_one(const char *path, struct stat *s)
 {
 	char modestr[11];
-	unsigned long namelen = strlen(path);
+	unsigned int namelen = strlen(path);
 
 	mkmodestr(s->st_mode, modestr);
-	printf("%s %10u %*.*s\n", modestr, s->st_size, namelen, namelen, path);
+	printf("%s %10lu %*.*s\n", modestr, s->st_size, namelen, namelen, path);
 }
 
 int ls(const char *path, ulong flags)
diff --git a/commands/menu.c b/commands/menu.c
index b9d6699..c3e0901 100644
--- a/commands/menu.c
+++ b/commands/menu.c
@@ -119,7 +119,7 @@ static int do_menu_entry_remove(struct cmd_menu *cm)
 	me = menu_entry_get_by_num(m, cm->num);
 
 	if (!me) {
-		eprintf("Entry '%s' not found\n", cm->num);
+		eprintf("Entry '%i' not found\n", cm->num);
 		return -EINVAL;
 	}
 
diff --git a/drivers/net/netx_eth.c b/drivers/net/netx_eth.c
index 7d55a61..fd40f62 100644
--- a/drivers/net/netx_eth.c
+++ b/drivers/net/netx_eth.c
@@ -7,7 +7,6 @@
 #include <mach/netx-eth.h>
 #include <mach/netx-regs.h>
 #include <xfuncs.h>
-#include <miidev.h>
 #include <init.h>
 #include <driver.h>
 
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index f7eeb2a..677a59d 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -485,7 +485,7 @@ static int __cfi_erase(struct cdev *cdev, size_t count, unsigned long offset,
         unsigned long start, end;
         int i, ret = 0;
 
-	debug("%s: erase 0x%08x (size %d)\n", __func__, offset, count);
+	debug("%s: erase 0x%08lx (size %d)\n", __func__, offset, count);
 
         start = find_sector(finfo, cdev->dev->map_base + offset);
         end   = find_sector(finfo, cdev->dev->map_base + offset + count - 1);
@@ -651,8 +651,8 @@ static int cfi_protect(struct cdev *cdev, size_t count, unsigned long offset, in
 	int i, ret = 0;
 	const char *action = (prot? "protect" : "unprotect");
 
-	printf("%s: %s 0x%08x (size %d)\n", __FUNCTION__,
-		action, cdev->dev->map_base + offset, count);
+	printf("%s: %s 0x%08lx (size %d)\n", __FUNCTION__,
+	       action, cdev->dev->map_base + offset, count);
 
 	start = find_sector(finfo, cdev->dev->map_base + offset);
 	end   = find_sector(finfo, cdev->dev->map_base + offset + count - 1);
@@ -1007,7 +1007,7 @@ static int cfi_probe (struct device_d *dev)
 	info->base = (void __iomem *)dev->map_base;
 
 	if (dev->size == 0) {
-		printf("cfi_probe: size : 0x%08x\n", info->size);
+		printf("cfi_probe: size : 0x%08lx\n", info->size);
 		dev->size = info->size;
 	}
 
diff --git a/include/stdio.h b/include/stdio.h
index 8bc45fa..c824764 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -9,7 +9,7 @@
  */
 
 /* serial stuff */
-void	serial_printf (const char *fmt, ...);
+void	serial_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
 
 /* stdin */
 int	tstc(void);
@@ -20,20 +20,22 @@ int	getc(void);
 void	console_puts(unsigned int ch, const char *s);
 void	console_flush(void);
 
-static inline void puts(const char *s) {
+static inline void puts(const char *s)
+{
 	console_puts(CONSOLE_STDOUT, s);
 }
 
-static inline void putchar(char c) {
+static inline void putchar(char c)
+{
 	console_putc(CONSOLE_STDOUT, c);
 }
 
-int	printf(const char *fmt, ...);
+int	printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
 int	vprintf(const char *fmt, va_list args);
-int	sprintf(char * buf, const char *fmt, ...);
-int	snprintf(char *buf, size_t size, const char *fmt, ...);
+int	sprintf(char *buf, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
+int	snprintf(char *buf, size_t size, const char *fmt, ...) __attribute__ ((format(printf, 3, 4)));
 int	vsprintf(char *buf, const char *fmt, va_list args);
-char	*asprintf(const char *fmt, ...);
+char	*asprintf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
 char	*vasprintf(const char *fmt, va_list ap);
 int	vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
 int	vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
@@ -52,7 +54,7 @@ int	vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
 #define stderr		2
 #define MAX_FILES	128
 
-void	fprintf(int file, const char *fmt, ...);
+void	fprintf(int file, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
 int	fputs(int file, const char *s);
 int	fputc(int file, const char c);
 int	ftstc(int file);
diff --git a/net/tftp.c b/net/tftp.c
index 6be8b8f..0f38b6b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -218,7 +218,7 @@ static void tftp_handler(char *packet, unsigned len)
 			tftp_last_block = 0;
 
 			if (tftp_block != 1) {	/* Assertion */
-				printf("error: First block is not block 1 (%ld)\n",
+				printf("error: First block is not block 1 (%d)\n",
 					tftp_block);
 				tftp_err = -EINVAL;
 				tftp_state = STATE_DONE;


From khc at pm.waw.pl  Mon Dec 20 18:04:20 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:04:20 +0100
Subject: [PATCH 9] ARM: support big-endian processors.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3pqswcah7.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 7e17f9d..3572a1f 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -61,6 +61,9 @@ config CPU_32v7
 
 comment "processor features"
 
+config ARCH_SUPPORTS_BIG_ENDIAN
+	bool
+
 config CPU_BIG_ENDIAN
 	bool "Build big-endian kernel"
 	depends on ARCH_SUPPORTS_BIG_ENDIAN
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 53d7ac1..b55df5d 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -70,6 +70,9 @@ void __naked __bare_init reset(void)
 	r = get_cr();
 	r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
 	r |= CR_A | CR_I;
+#ifdef __ARMEB__
+	r |= CR_B;
+#endif
 	set_cr(r);
 
 #ifdef CONFIG_MACH_DO_LOWLEVEL_INIT


From khc at pm.waw.pl  Mon Dec 20 18:06:12 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:06:12 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo Multilink
	router platform.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3oc8gcae3.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8cb86cb..56b5a0d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -39,6 +39,13 @@ config ARCH_IMX
 	bool "Freescale iMX-based"
 	select GENERIC_GPIO
 
+config ARCH_IXP4XX
+	bool "Intel IXP4xx-based"
+	select CPU_32v5
+	select ARCH_SUPPORTS_BIG_ENDIAN
+	select CPU_BIG_ENDIAN
+	select ARCH_HAS_LOWLEVEL_INIT
+
 config ARCH_STM
 	bool "SigmaTel/FSL iMX-based"
 	select GENERIC_GPIO
@@ -67,6 +74,7 @@ source arch/arm/cpu/Kconfig
 source arch/arm/mach-at91/Kconfig
 source arch/arm/mach-ep93xx/Kconfig
 source arch/arm/mach-imx/Kconfig
+source arch/arm/mach-ixp4xx/Kconfig
 source arch/arm/mach-stm/Kconfig
 source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9729c23..2e9f99d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
 machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_IMX)		:= imx
+machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_STM)		:= stm
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
@@ -73,6 +74,7 @@ board-$(CONFIG_MACH_FREESCALE_MX35_3STACK)	:= freescale-mx35-3-stack
 board-$(CONFIG_MACH_IMX21ADS)			:= imx21ads
 board-$(CONFIG_MACH_IMX27ADS)			:= imx27ads
 board-$(CONFIG_MACH_MMCCPU)			:= mmccpu
+board-$(CONFIG_MACH_MULTILINK)			:= multilink
 board-$(CONFIG_MACH_MX1ADS)			:= mx1ads
 board-$(CONFIG_MACH_NOMADIK_8815NHK)		:= nhk8815
 board-$(CONFIG_MACH_NXDB500)			:= netx
diff --git a/arch/arm/boards/multilink/Makefile b/arch/arm/boards/multilink/Makefile
new file mode 100644
index 0000000..d5a8bbc
--- /dev/null
+++ b/arch/arm/boards/multilink/Makefile
@@ -0,0 +1 @@
+obj-y += lowlevel_init.o multilink.o
diff --git a/arch/arm/boards/multilink/config.h b/arch/arm/boards/multilink/config.h
new file mode 100644
index 0000000..e69de29
diff --git a/arch/arm/boards/multilink/lowlevel_init.S b/arch/arm/boards/multilink/lowlevel_init.S
new file mode 100644
index 0000000..970ef72
--- /dev/null
+++ b/arch/arm/boards/multilink/lowlevel_init.S
@@ -0,0 +1,64 @@
+#include <mach/ixp4xx-regs.h>
+
+	.section ".text_bare_init", "ax"
+	.balign 0x40
+	.space 0x40 /* configuration block at 0x40 */
+
+	.macro DELAY_FOR cycles, reg0
+	ldr \reg0, =\cycles
+	subs \reg0, \reg0, #1
+	subne pc, pc, #0xc
+	.endm
+
+#define CFG_SDRAM_SIZE    0x50 /* u32 */
+#define CFG_SDRAM_CONF    0x54 /* u32 */
+#define CFG_SDRAM_MODE    0x58 /* u32 */
+#define CFG_SDRAM_REFRESH 0x5C /* u32 */
+
+.globl board_init_lowlevel
+board_init_lowlevel:
+	mov r8, #IXP4XX_EXP_BASE(0)
+	ldr r1, [r8, #CFG_SDRAM_CONF]
+	ldr r2, =IXP4XX_SDRAM_CONFIG
+	str r1, [r2]
+
+	/* disable refresh cycles */
+	mov r1, #0
+	add r2, r2, #4 /* r2 = IXP4XX_SDRAM_REFRESH */
+	str r1, [r2]
+
+	/* send NOP command */
+	mov r1, #3
+	add r3, r2, #4 /* r3 = IXP4XX_SDRAM_IR */
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	/* set SDRAM internal refresh */
+	ldr r1, [r8, #CFG_SDRAM_REFRESH]
+	str r1, [r2]
+	DELAY_FOR 0x4000, r0
+
+	/* send precharge-all command to close all open banks */
+	mov r1, #2
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	/* provide 8 auto-refresh cycles */
+	mov r1, #4
+	mov r4, #8
+1:	str r1, [r3]
+	DELAY_FOR 0x100, r0
+	subs r4, r4, #1
+	bne 1b
+
+	/* set mode register in SDRAM */
+	ldr r1, [r8, #CFG_SDRAM_MODE]
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	/* send normal operation command */
+	mov r1, #6
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	mov pc, lr
diff --git a/arch/arm/boards/multilink/multilink.c b/arch/arm/boards/multilink/multilink.c
new file mode 100644
index 0000000..f2fb8f4
--- /dev/null
+++ b/arch/arm/boards/multilink/multilink.c
@@ -0,0 +1,144 @@
+//#define DEBUG
+#include <common.h>
+#include <errno.h>
+#include <init.h>
+#include <linux/types.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/ixp4xx-regs.h>
+#include <mach/platform.h>
+
+/* offsets from start of flash ROM = 0x50000000 */
+#define CFG_ETH0_ADDRESS     0x40 /* 6 bytes */
+#define CFG_ETH1_ADDRESS     0x46 /* 6 bytes */
+#define CFG_REV              0x4C /* u32 */
+#define CFG_SDRAM_SIZE       0x50 /* u32 */
+#define CFG_SDRAM_CONF       0x54 /* u32 */
+#define CFG_SDRAM_MODE       0x58 /* u32 */
+#define CFG_SDRAM_REFRESH    0x5C /* u32 */
+
+#define CFG_HW_BITS          0x60 /* u32 */
+#define  CFG_HW_USB_PORTS    0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
+#define  CFG_HW_HAS_PCI_SLOT 0x00000008
+#define  CFG_HW_HAS_ETH0     0x00000010
+#define  CFG_HW_HAS_ETH1     0x00000020
+#define  CFG_HW_HAS_HSS0     0x00000040
+#define  CFG_HW_HAS_HSS1     0x00000080
+#define  CFG_HW_HAS_UART0    0x00000100
+#define  CFG_HW_HAS_UART1    0x00000200
+#define  CFG_HW_HAS_EEPROM   0x00000400
+
+#define ETH_ALEN             6
+
+#define BAREBOX_START        0x00000
+#define BAREBOX_LENGTH       0x34000
+#define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
+#define NPE_A_LENGTH         0x05000
+#define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
+#define NPE_B_LENGTH         0x03000
+#define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
+#define NPE_C_LENGTH         0x04000
+#define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
+#define NPE_ENV0_LENGTH      0x20000
+
+static struct device_d cfi_dev = {
+	.name     = "cfi_flash",
+	.map_base = IXP4XX_EXP_BASE(0),
+	.size     = 16 * 1024 * 1024,
+};
+
+static struct eth_plat_info eth_pinfo[2] = {
+	{
+		.regs     = IXP4XX_EthB_BASE,
+		.npe      = 1,
+		.phy      = 0,
+		.rxq      = 20,
+		.txreadyq = 29,
+	}, {
+		.regs     = IXP4XX_EthC_BASE,
+		.npe      = 2,
+		.phy      = 1,
+		.rxq      = 21,
+		.txreadyq = 30,
+	}
+};
+
+static struct device_d eth_dev[2] = {
+	{
+		.name           = "ixp4xx_eth",
+		.platform_data  = &eth_pinfo[0],
+	}, {
+		.id             = 1,
+		.name           = "ixp4xx_eth",
+		.platform_data  = &eth_pinfo[1],
+	}
+};
+
+static struct memory_platform_data ram_pdata = {
+	.name           = "ram0",
+	.flags          = DEVFS_RDWR,
+};
+
+struct device_d sdram_dev = {
+	.id             = -1,
+	.name           = "mem",
+	.map_base       = 0x00000000,
+	.size           = 32 * 1024 * 1024,
+	.platform_data  = &ram_pdata,
+};
+
+static inline u8 __init flash_readb(u32 addr)
+{
+	return __raw_readb(IXP4XX_EXP_BASE(0) + addr);
+}
+
+static int __init gml_devices_init(void)
+{
+	u32 hw_bits;
+	int i;
+
+	IXP4XX_EXP_CS0 = IXP4XX_EXP_EN | IXP4XX_EXP_INTEL |
+		IXP4XX_EXP_BITS(24) | IXP4XX_EXP_WR_EN | IXP4XX_EXP_BYTE_RD16;
+	i = register_device(&cfi_dev);
+	if (i)
+		goto out;
+
+	devfs_add_partition("nor0", BAREBOX_START, BAREBOX_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "barebox");
+	devfs_add_partition("nor0", NPE_A_START, NPE_A_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-A");
+	devfs_add_partition("nor0", NPE_B_START, NPE_B_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-B");
+	devfs_add_partition("nor0", NPE_C_START, NPE_C_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-C");
+	devfs_add_partition("nor0", NPE_ENV0_START, NPE_ENV0_LENGTH,
+			    DEVFS_PARTITION_FIXED, "env0");
+
+	hw_bits = __raw_readl(IXP4XX_EXP_BASE(0) + CFG_HW_BITS);
+
+	if (hw_bits & CFG_HW_HAS_ETH0) {
+		for (i = 0; i < ETH_ALEN; i++)
+			eth_pinfo[0].hwaddr[i] = flash_readb(CFG_ETH0_ADDRESS + i);
+		register_device(&eth_dev[0]);
+	}
+
+	if (hw_bits & CFG_HW_HAS_ETH1) {
+		for (i = 0; i < ETH_ALEN; i++)
+			eth_pinfo[1].hwaddr[i] = flash_readb(CFG_ETH1_ADDRESS + i);
+		register_device(&eth_dev[1]);
+	}
+
+	sdram_dev.size = __raw_readl(IXP4XX_EXP_BASE(0) + CFG_SDRAM_SIZE);
+	i = register_device(&sdram_dev);
+	if (i)
+		goto out;
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void *)(0x00000100));
+	armlinux_set_architecture(MACH_TYPE_GORAMO_MLR);
+
+out:
+	return i;
+}
+device_initcall(gml_devices_init);
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
new file mode 100644
index 0000000..f5e4b41
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -0,0 +1,26 @@
+if ARCH_IXP4XX
+
+choice
+	prompt "IXP4xx Board Type"
+
+config MACH_MULTILINK
+	bool "Goramo MultiLink"
+	select MACH_HAS_LOWLEVEL_INIT
+endchoice
+
+config BOARDINFO
+	default "Goramo MultiLink" if MACH_MULTILINK
+
+config IXP4XX_QMGR
+	tristate "IXP4xx Queue Manager support"
+	help
+	  This driver supports IXP4xx built-in hardware queue manager
+	  and is required by the Ethernet driver.
+
+config IXP4XX_NPE
+	tristate "IXP4xx Network Processor Engine support"
+	help
+	  This driver supports IXP4xx built-in network coprocessors
+	  and is required by the Ethernet driver.
+
+endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
new file mode 100644
index 0000000..aa38991
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -0,0 +1,3 @@
+obj-y += lowlevel_init.o generic.o
+obj-$(CONFIG_IXP4XX_QMGR) += qmgr.o
+obj-$(CONFIG_IXP4XX_NPE) += npe.o
diff --git a/arch/arm/mach-ixp4xx/generic.c b/arch/arm/mach-ixp4xx/generic.c
new file mode 100644
index 0000000..02394a4
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/generic.c
@@ -0,0 +1,120 @@
+#include <common.h>
+#include <init.h>
+#include <ns16550.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+
+#define OSTS_FREQUENCY 66666000
+
+void reset_cpu(ulong addr)
+{
+	/* Use on-chip reset capability */
+	/* This may not work on IXP425 rev. A0 */
+
+	IXP4XX_OSWK = IXP4XX_WDT_KEY;
+	IXP4XX_OSWT = 0; /* request immediate reset */
+	IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
+	while (1)
+		;
+}
+
+#include <clock.h>
+
+/**
+ * @brief Provide a simple clock read
+ *
+ * Nothing is simpler.. read direct from clock and provide it
+ * to the caller.
+ *
+ * @return clock counter
+ */
+static uint64_t ixp4xx_clocksource_read(void)
+{
+	return IXP4XX_OSTS;
+}
+
+static struct clocksource cs = {
+	.read = ixp4xx_clocksource_read,
+	.mask = 0xffffffff,
+	.shift = 10,
+};
+
+/**
+ * @brief Initialize the Clock
+ *
+ * We use the Time-Stamp Timer
+ *
+ * @return result of @ref init_clock
+ */
+static int ixp4xx_clocksource_init(void)
+{
+	cs.mult = clocksource_hz2mult(OSTS_FREQUENCY, cs.shift);
+
+	return init_clock(&cs);
+}
+
+/* Run me at boot time */
+core_initcall(ixp4xx_clocksource_init);
+
+
+#ifdef CONFIG_DRIVER_SERIAL_NS16550
+
+/**
+ * @brief UART port register read function for IXP4XX
+ *
+ * @param base base address of UART
+ * @param reg_idx register index
+ *
+ * @return character read from register
+ */
+unsigned int ixp4xx_uart_read(unsigned long base, unsigned char reg_idx)
+{
+	return readb(4 * reg_idx + 3 /* big-endian */ + (uint8_t *)base);
+}
+EXPORT_SYMBOL(ixp4xx_uart_read);
+
+/**
+ * @brief UART port register write function for IXP4XX
+ *
+ * @param val value to write
+ * @param base base address of UART
+ * @param reg_idx register index
+ *
+ * @return void
+ */
+void ixp4xx_uart_write(unsigned int val, unsigned long base, unsigned char reg_idx)
+{
+	writeb(val, 4 * reg_idx + 3 /* big-endian */ + (uint8_t *)base);
+}
+EXPORT_SYMBOL(ixp4xx_uart_write);
+
+
+static struct NS16550_plat serial_plat = {
+	.clock = 14745600,
+	.f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
+	.reg_read = ixp4xx_uart_read,
+	.reg_write = ixp4xx_uart_write,
+};
+
+static struct device_d ixp4xx_serial_device = {
+	.name = "serial_ns16550",
+	.map_base = (u32)IXP4XX_UART1_BASE,
+	.size = 1024,
+	.platform_data = (void *)&serial_plat,
+};
+
+/**
+ * @brief UART serial port initialization
+ *
+ * @return result of device registration
+ */
+static int ixp4xx_console_init(void)
+{
+	/* Register the serial port */
+	return register_device(&ixp4xx_serial_device);
+}
+
+console_initcall(ixp4xx_console_init);
+
+#endif /* CONFIG_DRIVER_SERIAL_NS16550 */
diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
new file mode 100644
index 0000000..3de021e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/cpu.h
+ *
+ * IXP4XX cpu type detection
+ *
+ * Copyright (C) 2007 MontaVista Software, 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+#include <linux/types.h>
+
+/* Processor id value in CP15 Register 0 */
+#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
+#define IXP42X_PROCESSOR_ID_MASK  0xffffffc0
+
+#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
+#define IXP43X_PROCESSOR_ID_MASK  0xfffffff0
+
+#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
+#define IXP46X_PROCESSOR_ID_MASK  0xfffffff0
+
+#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
+				IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
+			 IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
+			 IXP43X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
+			 IXP46X_PROCESSOR_ID_VALUE)
+
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant.  Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline u32 __attribute_const__ read_cpuid_id(void)
+{
+	u32 val;
+	asm("mrc p15, 0, %0, c0, c0, 0" : "=r" (val) : : "cc");
+
+	return val;
+}
+
+static inline u32 ixp4xx_read_feature_bits(void)
+{
+	u32 val = ~IXP4XX_EXP_CFG2;
+
+	if (cpu_is_ixp42x_rev_a0())
+		return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
+					       IXP4XX_FEATURE_AES);
+	if (cpu_is_ixp42x())
+		return val & IXP42X_FEATURE_MASK;
+	if (cpu_is_ixp43x())
+		return val & IXP43X_FEATURE_MASK;
+	return val & IXP46X_FEATURE_MASK;
+}
+
+static inline void ixp4xx_write_feature_bits(u32 value)
+{
+	IXP4XX_EXP_CFG2 = ~value;
+}
+
+#endif  /* _ASM_ARCH_CPU_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
new file mode 100644
index 0000000..da4dc8a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -0,0 +1,365 @@
+/*
+ * Register definitions for IXP4xx chipset.
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, 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.
+ *
+ */
+
+#ifndef _ASM_ARM_IXP4XX_H_
+#define _ASM_ARM_IXP4XX_H_
+
+#ifdef __ASSEMBLER__
+#define IXP4XX_REG(reg)  (reg)
+#else
+#define IXP4XX_REG(reg)  (*(volatile u32 *)(reg))
+#define IXP4XX_BASE(reg) ((u32*)(reg))
+#endif
+
+/* Expansion Bus region */
+
+/* Queue Manager */
+#define IXP4XX_QMGR_BASE              (0x60000000)
+#define IXP4XX_QMGR_REGION_SIZE       (0x00004000)
+
+
+/* PCI Config registers */
+#define IXP4XX_PCI_CFG_BASE           (0xC0000000)
+#define IXP4XX_PCI_CFG_REGION_SIZE    (0x00001000)
+
+/* Peripheral space */
+#define IXP4XX_PERIPHERAL_BASE        (0xC8000000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
+
+/*
+ * Debug UART
+ *
+ * This is basically a remap of UART1 into a region that is section
+ * aligned so that it can be used with the low-level debug code.
+ */
+#define IXP4XX_DEBUG_UART_BASE        (0xC8000000)
+#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
+
+/* Expansion Bus Controller registers. */
+#define IXP4XX_EXP_CS0       IXP4XX_REG(0xC4000000)
+#define IXP4XX_EXP_CS1       IXP4XX_REG(0xC4000004)
+#define IXP4XX_EXP_CS2       IXP4XX_REG(0xC4000008)
+#define IXP4XX_EXP_CS3       IXP4XX_REG(0xC400000C)
+#define IXP4XX_EXP_CS4       IXP4XX_REG(0xC4000010)
+#define IXP4XX_EXP_CS5       IXP4XX_REG(0xC4000014)
+#define IXP4XX_EXP_CS6       IXP4XX_REG(0xC4000018)
+#define IXP4XX_EXP_CS7       IXP4XX_REG(0xC400001C)
+
+#define IXP4XX_EXP_BASE(n)  (0x50000000 + (n) * 1000000)
+
+#define IXP4XX_EXP_EN        0x80000000
+#define IXP4XX_EXP_T1(n)    (0x10000000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T2(n)    (0x04000000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T3(n)    (0x00400000 * (n)) /* valid: 0 - 15 */
+#define IXP4XX_EXP_T4(n)    (0x00100000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T5(n)    (0x00010000 * (n)) /* valid: 0 - 15 */
+#define IXP4XX_EXP_INTEL     0x00000000
+#define IXP4XX_EXP_MOTO      0x00004000
+#define IXP4XX_EXP_HPI       0x00008000
+#define IXP4XX_EXP_BITS(n)  (0x00000400 * ((n) - 9)) /* valid: 9 - 24 */
+#define IXP4XX_EXP_BYTE_RD16 0x00000040
+#define IXP4XX_EXP_HRDY_POL  0x00000020
+#define IXP4XX_EXP_MUX_EN    0x00000010
+#define IXP4XX_EXP_SPLT_EN   0x00000008
+#define IXP4XX_EXP_WR_EN     0x00000002
+#define IXP4XX_EXP_BYTE_EN   0x00000001
+
+#define IXP4XX_EXP_CFG0      IXP4XX_REG(0xC4000020)
+#define IXP4XX_EXP_CFG1      IXP4XX_REG(0xC4000024)
+#define IXP4XX_EXP_CFG2      IXP4XX_REG(0xC4000028)
+#define IXP4XX_EXP_CFG3      IXP4XX_REG(0xC400002C)
+
+
+/* Peripheral Space Register Region Base Addresses */
+#define IXP4XX_UART1_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x0000)
+#define IXP4XX_UART2_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x1000)
+#define IXP4XX_PMU_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x2000)
+#define IXP4XX_INTC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x3000)
+#define IXP4XX_GPIO_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x4000)
+#define IXP4XX_NPEA_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x6000)
+#define IXP4XX_NPEB_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x7000)
+#define IXP4XX_NPEC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x8000)
+#define IXP4XX_EthB_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x9000)
+#define IXP4XX_EthC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xA000)
+#define IXP4XX_USB_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xB000)
+/* IXP46x only */
+#define IXP4XX_EthA_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xC000)
+#define IXP4XX_EthB1_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xD000)
+#define IXP4XX_EthB2_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xE000)
+#define IXP4XX_EthB3_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xF000)
+#define IXP4XX_TIMESYNC_BASE IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x10000)
+#define IXP4XX_I2C_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x11000)
+#define IXP4XX_SSP_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x12000)
+
+/*
+  Constants to make it easy to access Interrupt Controller registers
+ */
+#define IXP4XX_ICPR_OFFSET   0x00 /* Interrupt Status */
+#define IXP4XX_ICMR_OFFSET   0x04 /* Interrupt Enable */
+#define IXP4XX_ICLR_OFFSET   0x08 /* Interrupt IRQ/FIQ Select */
+#define IXP4XX_ICIP_OFFSET   0x0C /* IRQ Status */
+#define IXP4XX_ICFP_OFFSET   0x10 /* FIQ Status */
+#define IXP4XX_ICHR_OFFSET   0x14 /* Interrupt Priority */
+#define IXP4XX_ICIH_OFFSET   0x18 /* IRQ Highest Pri Int */
+#define IXP4XX_ICFH_OFFSET   0x1C /* FIQ Highest Pri Int */
+
+/* IXP465-only */
+#define IXP4XX_ICPR2_OFFSET  0x20 /* Interrupt Status 2 */
+#define IXP4XX_ICMR2_OFFSET  0x24 /* Interrupt Enable 2 */
+#define IXP4XX_ICLR2_OFFSET  0x28 /* Interrupt IRQ/FIQ Select 2 */
+#define IXP4XX_ICIP2_OFFSET  0x2C /* IRQ Status */
+#define IXP4XX_ICFP2_OFFSET  0x30 /* FIQ Status */
+#define IXP4XX_ICEEN_OFFSET  0x34 /* Error High Pri Enable */
+
+
+/* Interrupt Controller Register Definitions. */
+#define IXP4XX_INTC_REG(x)   ((volatile u32 *)(IXP4XX_INTC_BASE + (x)))
+
+#define IXP4XX_ICPR          IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
+#define IXP4XX_ICMR          IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
+#define IXP4XX_ICLR          IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
+#define IXP4XX_ICIP          IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
+#define IXP4XX_ICFP          IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
+#define IXP4XX_ICHR          IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
+#define IXP4XX_ICIH          IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET)
+#define IXP4XX_ICFH          IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
+#define IXP4XX_ICPR2         IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
+#define IXP4XX_ICMR2         IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
+#define IXP4XX_ICLR2         IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
+#define IXP4XX_ICIP2         IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
+#define IXP4XX_ICFP2         IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
+#define IXP4XX_ICEEN         IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
+
+/* Constants to make it easy to access GPIO registers */
+#define IXP4XX_GPIO_GPOUTR_OFFSET   0x00
+#define IXP4XX_GPIO_GPOER_OFFSET    0x04
+#define IXP4XX_GPIO_GPINR_OFFSET    0x08
+#define IXP4XX_GPIO_GPISR_OFFSET    0x0C
+#define IXP4XX_GPIO_GPIT1R_OFFSET   0x10
+#define IXP4XX_GPIO_GPIT2R_OFFSET   0x14
+#define IXP4XX_GPIO_GPCLKR_OFFSET   0x18
+#define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C
+
+/* GPIO Register Definitions - perform only 32-bit reads/writes */
+#define IXP4XX_GPIO_REG(x)   ((volatile u32 *)(IXP4XX_GPIO_BASE + (x)))
+
+#define IXP4XX_GPIO_GPOUTR   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
+#define IXP4XX_GPIO_GPOER    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
+#define IXP4XX_GPIO_GPINR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
+#define IXP4XX_GPIO_GPISR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
+#define IXP4XX_GPIO_GPIT1R   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
+#define IXP4XX_GPIO_GPIT2R   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
+#define IXP4XX_GPIO_GPCLKR   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
+#define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
+
+/* GPIO register bit definitions */
+
+/* Interrupt styles */
+#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH  0x0
+#define IXP4XX_GPIO_STYLE_ACTIVE_LOW   0x1
+#define IXP4XX_GPIO_STYLE_RISING_EDGE  0x2
+#define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3
+#define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4
+
+/* Mask used to clear interrupt styles */
+#define IXP4XX_GPIO_STYLE_CLEAR        0x7
+#define IXP4XX_GPIO_STYLE_SIZE         3
+
+/* Operating System Timer Register Definitions. */
+#define IXP4XX_OSTS          IXP4XX_REG(0xC8005000) /* Continious TimeStamp */
+#define IXP4XX_OST1          IXP4XX_REG(0xC8005004) /* Timer 1 Timestamp */
+#define IXP4XX_OSRT1         IXP4XX_REG(0xC8005008) /* Timer 1 Reload */
+#define IXP4XX_OST2          IXP4XX_REG(0xC800500C) /* Timer 2 Timestamp */
+#define IXP4XX_OSRT2         IXP4XX_REG(0xC8005010) /* Timer 2 Reload */
+#define IXP4XX_OSWT          IXP4XX_REG(0xC8005014) /* Watchdog Timer */
+#define IXP4XX_OSWE          IXP4XX_REG(0xC8005018) /* Watchdog Enable */
+#define IXP4XX_OSWK          IXP4XX_REG(0xC800501C) /* Watchdog Key */
+#define IXP4XX_OSST          IXP4XX_REG(0xC8005020) /* Timer Status */
+
+/* Timer register values and bit definitions */
+#define IXP4XX_OST_ENABLE            0x00000001
+#define IXP4XX_OST_ONE_SHOT          0x00000002
+/* Low order bits of reload value ignored */
+#define IXP4XX_OST_RELOAD_MASK       0x00000003
+#define IXP4XX_OST_DISABLED          0x00000000
+#define IXP4XX_OSST_TIMER_1_PEND     0x00000001
+#define IXP4XX_OSST_TIMER_2_PEND     0x00000002
+#define IXP4XX_OSST_TIMER_TS_PEND    0x00000004
+#define IXP4XX_OSST_TIMER_WDOG_PEND  0x00000008
+#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
+
+#define IXP4XX_WDT_KEY               0x0000482E
+
+#define IXP4XX_WDT_RESET_ENABLE      0x00000001
+#define IXP4XX_WDT_IRQ_ENABLE        0x00000002
+#define IXP4XX_WDT_COUNT_ENABLE      0x00000004
+
+
+/* Constants to make it easy to access PCI Control/Status registers */
+#define PCI_NP_AD_OFFSET           0x00
+#define PCI_NP_CBE_OFFSET          0x04
+#define PCI_NP_WDATA_OFFSET        0x08
+#define PCI_NP_RDATA_OFFSET        0x0c
+#define PCI_CRP_AD_CBE_OFFSET      0x10
+#define PCI_CRP_WDATA_OFFSET       0x14
+#define PCI_CRP_RDATA_OFFSET       0x18
+#define PCI_CSR_OFFSET             0x1c
+#define PCI_ISR_OFFSET             0x20
+#define PCI_INTEN_OFFSET           0x24
+#define PCI_DMACTRL_OFFSET         0x28
+#define PCI_AHBMEMBASE_OFFSET      0x2c
+#define PCI_AHBIOBASE_OFFSET       0x30
+#define PCI_PCIMEMBASE_OFFSET      0x34
+#define PCI_AHBDOORBELL_OFFSET     0x38
+#define PCI_PCIDOORBELL_OFFSET     0x3C
+#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
+#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
+#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
+#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
+#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
+#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
+
+/* PCI Control/Status Registers */
+#define IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE + (x)))
+
+#define PCI_NP_AD            IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
+#define PCI_NP_CBE           IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
+#define PCI_NP_WDATA         IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
+#define PCI_NP_RDATA         IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
+#define PCI_CRP_AD_CBE       IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
+#define PCI_CRP_WDATA        IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
+#define PCI_CRP_RDATA        IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
+#define PCI_CSR              IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
+#define PCI_ISR              IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
+#define PCI_INTEN            IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
+#define PCI_DMACTRL          IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
+#define PCI_AHBMEMBASE       IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
+#define PCI_AHBIOBASE        IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
+#define PCI_PCIMEMBASE       IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
+#define PCI_AHBDOORBELL      IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
+#define PCI_PCIDOORBELL      IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
+#define PCI_ATPDMA0_AHBADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
+#define PCI_ATPDMA0_PCIADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
+#define PCI_ATPDMA0_LENADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
+#define PCI_ATPDMA1_AHBADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
+#define PCI_ATPDMA1_PCIADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
+#define PCI_ATPDMA1_LENADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
+
+/* PCI register values and bit definitions */
+
+/* CSR bit definitions */
+#define PCI_CSR_HOST         0x00000001
+#define PCI_CSR_ARBEN        0x00000002
+#define PCI_CSR_ADS          0x00000004
+#define PCI_CSR_PDS          0x00000008
+#define PCI_CSR_ABE          0x00000010
+#define PCI_CSR_DBT          0x00000020
+#define PCI_CSR_ASE          0x00000100
+#define PCI_CSR_IC           0x00008000
+
+/* ISR (Interrupt status) Register bit definitions */
+#define PCI_ISR_PSE          0x00000001
+#define PCI_ISR_PFE          0x00000002
+#define PCI_ISR_PPE          0x00000004
+#define PCI_ISR_AHBE         0x00000008
+#define PCI_ISR_APDC         0x00000010
+#define PCI_ISR_PADC         0x00000020
+#define PCI_ISR_ADB          0x00000040
+#define PCI_ISR_PDB          0x00000080
+
+/* INTEN (Interrupt Enable) Register bit definitions */
+#define PCI_INTEN_PSE        0x00000001
+#define PCI_INTEN_PFE        0x00000002
+#define PCI_INTEN_PPE        0x00000004
+#define PCI_INTEN_AHBE       0x00000008
+#define PCI_INTEN_APDC       0x00000010
+#define PCI_INTEN_PADC       0x00000020
+#define PCI_INTEN_ADB        0x00000040
+#define PCI_INTEN_PDB        0x00000080
+
+/* Shift value for byte enable on NP cmd/byte enable register */
+#define IXP4XX_PCI_NP_CBE_BESL 4
+
+/* PCI commands supported by NP access unit */
+#define NP_CMD_IOREAD        0x2
+#define NP_CMD_IOWRITE       0x3
+#define NP_CMD_CONFIGREAD    0xA
+#define NP_CMD_CONFIGWRITE   0xB
+#define NP_CMD_MEMREAD       0x6
+#define NP_CMD_MEMWRITE      0x7
+
+/* Constants for CRP access into local config space */
+#define CRP_AD_CBE_BESL      20
+#define CRP_AD_CBE_WRITE     0x00010000
+
+/* USB Device Controller */
+# define IXP4XX_USB_REG(x)   (*((volatile u32 *)(x)))
+
+/* SDRAM Controller registers. */
+#define IXP4XX_SDRAM_CONFIG  IXP4XX_REG(0xCC000000)
+#define IXP4XX_SDRAM_REFRESH IXP4XX_REG(0xCC000004)
+#define IXP4XX_SDRAM_IR      IXP4XX_REG(0xCC000008)
+
+/* "fuse" bits of IXP_EXP_CFG2 */
+/* All IXP4xx CPUs */
+#define IXP4XX_FEATURE_RCOMP            (1 << 0)
+#define IXP4XX_FEATURE_USB_DEVICE       (1 << 1)
+#define IXP4XX_FEATURE_HASH             (1 << 2)
+#define IXP4XX_FEATURE_AES              (1 << 3)
+#define IXP4XX_FEATURE_DES              (1 << 4)
+#define IXP4XX_FEATURE_HDLC             (1 << 5)
+#define IXP4XX_FEATURE_AAL              (1 << 6)
+#define IXP4XX_FEATURE_HSS              (1 << 7)
+#define IXP4XX_FEATURE_UTOPIA           (1 << 8)
+#define IXP4XX_FEATURE_NPEB_ETH0        (1 << 9)
+#define IXP4XX_FEATURE_NPEC_ETH         (1 << 10)
+#define IXP4XX_FEATURE_RESET_NPEA       (1 << 11)
+#define IXP4XX_FEATURE_RESET_NPEB       (1 << 12)
+#define IXP4XX_FEATURE_RESET_NPEC       (1 << 13)
+#define IXP4XX_FEATURE_PCI              (1 << 14)
+#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
+#define IXP4XX_FEATURE_XSCALE_MAX_FREQ  (3 << 22)
+#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP            | \
+			     IXP4XX_FEATURE_USB_DEVICE       | \
+			     IXP4XX_FEATURE_HASH             | \
+			     IXP4XX_FEATURE_AES              | \
+			     IXP4XX_FEATURE_DES              | \
+			     IXP4XX_FEATURE_HDLC             | \
+			     IXP4XX_FEATURE_AAL              | \
+			     IXP4XX_FEATURE_HSS              | \
+			     IXP4XX_FEATURE_UTOPIA           | \
+			     IXP4XX_FEATURE_NPEB_ETH0        | \
+			     IXP4XX_FEATURE_NPEC_ETH         | \
+			     IXP4XX_FEATURE_RESET_NPEA       | \
+			     IXP4XX_FEATURE_RESET_NPEB       | \
+			     IXP4XX_FEATURE_RESET_NPEC       | \
+			     IXP4XX_FEATURE_PCI              | \
+			     IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
+			     IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
+/* IXP43x/46x CPUs */
+#define IXP4XX_FEATURE_ECC_TIMESYNC     (1 << 15)
+#define IXP4XX_FEATURE_USB_HOST         (1 << 18)
+#define IXP4XX_FEATURE_NPEA_ETH         (1 << 19)
+#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK             | \
+			     IXP4XX_FEATURE_ECC_TIMESYNC     | \
+			     IXP4XX_FEATURE_USB_HOST         | \
+			     IXP4XX_FEATURE_NPEA_ETH)
+
+/* IXP46x CPU (including IXP455) only */
+#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3  (1 << 20)
+#define IXP4XX_FEATURE_RSA              (1 << 21)
+#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK             | \
+			     IXP4XX_FEATURE_NPEB_ETH_1_TO_3  | \
+			     IXP4XX_FEATURE_RSA)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/npe.h b/arch/arm/mach-ixp4xx/include/mach/npe.h
new file mode 100644
index 0000000..18bd01b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/npe.h
@@ -0,0 +1,30 @@
+#ifndef __IXP4XX_NPE_H
+#define __IXP4XX_NPE_H
+
+#include <common.h>
+
+#define NPE_NAME_LENGTH 5
+
+struct npe_regs {
+	u32 exec_addr, exec_data, exec_status_cmd, exec_count;
+	u32 action_points[4];
+	u32 watchpoint_fifo, watch_count;
+	u32 profile_count;
+	u32 messaging_status, messaging_control;
+	u32 mailbox_status, /*messaging_*/ in_out_fifo;
+};
+
+struct npe {
+	struct npe_regs *regs;
+	int id, valid;
+	const char name[NPE_NAME_LENGTH + 1];
+};
+
+int npe_running(struct npe *npe);
+int npe_send_message(struct npe *npe, const void *msg, const char *what);
+int npe_recv_message(struct npe *npe, void *msg, const char *what);
+int npe_send_recv_message(struct npe *npe, void *msg, const char *what);
+int npe_load_firmware(struct npe *npe);
+struct npe *npe_request(int id);
+
+#endif /* __IXP4XX_NPE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
new file mode 100644
index 0000000..1df4aa4
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -0,0 +1,15 @@
+#include <asm/types.h>
+
+#define IXP4XX_ETH_NPEA 0x00
+#define IXP4XX_ETH_NPEB 0x10
+#define IXP4XX_ETH_NPEC 0x20
+
+/* Information about built-in Ethernet MAC interfaces */
+struct eth_plat_info {
+	void *regs;
+	u8 npe;
+	u8 phy; /* MII PHY ID, 0 - 31 */
+	u8 rxq; /* configurable, currently 0 - 31 only */
+	u8 txreadyq;
+	u8 hwaddr[6];
+};
diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
new file mode 100644
index 0000000..4e9b8d4
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef IXP4XX_QMGR_H
+#define IXP4XX_QMGR_H
+
+#include <common.h>
+#include <mach/ixp4xx-regs.h>
+#include <asm/io.h>
+
+#define DEBUG_QMGR       0
+
+#define HALF_QUEUES     32
+#define QUEUES          64
+#define MAX_QUEUE_LENGTH 4 /* in dwords */
+
+#define QUEUE_STAT1_EMPTY               1 /* queue status bits */
+#define QUEUE_STAT1_NEARLY_EMPTY        2
+#define QUEUE_STAT1_NEARLY_FULL         4
+#define QUEUE_STAT1_FULL                8
+#define QUEUE_STAT2_UNDERFLOW           1
+#define QUEUE_STAT2_OVERFLOW            2
+
+#define QUEUE_WATERMARK_0_ENTRIES       0
+#define QUEUE_WATERMARK_1_ENTRY         1
+#define QUEUE_WATERMARK_2_ENTRIES       2
+#define QUEUE_WATERMARK_4_ENTRIES       3
+#define QUEUE_WATERMARK_8_ENTRIES       4
+#define QUEUE_WATERMARK_16_ENTRIES      5
+#define QUEUE_WATERMARK_32_ENTRIES      6
+#define QUEUE_WATERMARK_64_ENTRIES      7
+
+/* queue interrupt request conditions */
+#define QUEUE_IRQ_SRC_EMPTY             0
+#define QUEUE_IRQ_SRC_NEARLY_EMPTY      1
+#define QUEUE_IRQ_SRC_NEARLY_FULL       2
+#define QUEUE_IRQ_SRC_FULL              3
+#define QUEUE_IRQ_SRC_NOT_EMPTY         4
+#define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY  5
+#define QUEUE_IRQ_SRC_NOT_NEARLY_FULL   6
+#define QUEUE_IRQ_SRC_NOT_FULL          7
+
+struct qmgr_regs {
+	u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */
+	u32 stat1[4];         /* 0x400 - 0x40F */
+	u32 stat2[2];         /* 0x410 - 0x417 */
+	u32 statne_h;         /* 0x418 - queue nearly empty */
+	u32 statf_h;          /* 0x41C - queue full */
+	u32 irqsrc[4];        /* 0x420 - 0x42F IRC source */
+	u32 irqen[2];         /* 0x430 - 0x437 IRQ enabled */
+	u32 irqstat[2];       /* 0x438 - 0x43F - IRQ access only */
+	u32 reserved[1776];
+	u32 sram[2048];       /* 0x2000 - 0x3FFF - config and buffer */
+};
+
+static const struct qmgr_regs *qmgr_regs = (struct qmgr_regs *)IXP4XX_QMGR_BASE;
+
+void qmgr_set_irq(unsigned int queue, int src,
+		  void (*handler)(void *pdev), void *pdev);
+void qmgr_enable_irq(unsigned int queue);
+void qmgr_disable_irq(unsigned int queue);
+
+/* request_ and release_queue() must be called from non-IRQ context */
+
+#if DEBUG_QMGR
+extern char qmgr_queue_descs[HALF_QUEUES][32];
+
+void qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			unsigned int nearly_empty_watermark,
+			unsigned int nearly_full_watermark,
+			const char *desc_format, const char* name);
+#else
+void __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			  unsigned int nearly_empty_watermark,
+			  unsigned int nearly_full_watermark);
+#define qmgr_request_queue(queue, len, nearly_empty_watermark,       \
+			   nearly_full_watermark, desc_format, name) \
+	__qmgr_request_queue(queue, len, nearly_empty_watermark,     \
+			     nearly_full_watermark)
+#endif
+
+void qmgr_release_queue(unsigned int queue);
+
+
+static inline void qmgr_put_entry(unsigned int queue, u32 val)
+{
+#if DEBUG_QMGR
+	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+	fprintf(stderr, "Queue %s(%i) put %X\n",
+		qmgr_queue_descs[queue], queue, val);
+#endif
+	__raw_writel(val, &qmgr_regs->acc[queue][0]);
+}
+
+static inline u32 qmgr_get_entry(unsigned int queue)
+{
+	u32 val;
+	val = __raw_readl(&qmgr_regs->acc[queue][0]);
+#if DEBUG_QMGR
+	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+	fprintf(stderr, "Queue %s(%i) get %X\n",
+		qmgr_queue_descs[queue], queue, val);
+#endif
+	return val;
+}
+
+static inline int __qmgr_get_stat1(unsigned int queue)
+{
+	return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
+		>> ((queue & 7) << 2)) & 0xF;
+}
+
+/**
+ * qmgr_stat_empty() - checks if a hardware queue is empty
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is empty.
+ */
+static inline int qmgr_stat_empty(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
+}
+
+/**
+ * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is below low watermark.
+ */
+static inline int qmgr_stat_below_low_watermark(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
+}
+
+/**
+ * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is above high watermark
+ */
+static inline int qmgr_stat_above_high_watermark(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
+}
+
+/**
+ * qmgr_stat_full() - checks if a hardware queue is full
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is full.
+ */
+static inline int qmgr_stat_full(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
+}
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/lowlevel_init.S b/arch/arm/mach-ixp4xx/lowlevel_init.S
new file mode 100644
index 0000000..a4e93ef
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/lowlevel_init.S
@@ -0,0 +1,17 @@
+#include <mach/ixp4xx-regs.h>
+
+	.section ".text_bare_init", "ax"
+
+	.globl arch_init_lowlevel
+arch_init_lowlevel:
+	ldr r0, cfg
+	ldr r1, [r0]
+	and r1, r1, #~0x80000000 /* unmap EXP bus from 0x0 */
+	str r1, [r0]
+
+	/* return to ROM */
+	orr lr, #0x50000000
+	mov pc, lr
+
+cfg:
+	.word IXP4XX_EXP_CFG0
diff --git a/arch/arm/mach-ixp4xx/npe.c b/arch/arm/mach-ixp4xx/npe.c
new file mode 100644
index 0000000..a8ddd5a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/npe.c
@@ -0,0 +1,668 @@
+/*
+ * Intel IXP4xx Network Processor Engine driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fs.h>
+#include <init.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+#include <mach/cpu.h>
+#include <mach/npe.h>
+
+#define DEBUG_MSG                      0
+#define DEBUG_FW                       0
+
+#define NPE_COUNT                      3
+#define MAX_RETRIES                    1000  /* microseconds */
+#define NPE_42X_DATA_SIZE              0x800 /* in dwords */
+#define NPE_46X_DATA_SIZE              0x1000
+#define NPE_A_42X_INSTR_SIZE           0x1000
+#define NPE_B_AND_C_42X_INSTR_SIZE     0x800
+#define NPE_46X_INSTR_SIZE             0x1000
+#define REGS_SIZE                      0x1000
+
+#define NPE_PHYS_REG                   32
+
+#define FW_MAGIC                       0xFEEDF00D
+#define FW_BLOCK_TYPE_INSTR            0x0
+#define FW_BLOCK_TYPE_DATA             0x1
+#define FW_BLOCK_TYPE_EOF              0xF
+
+/* NPE exec status (read) and command (write) */
+#define CMD_NPE_STEP                   0x01
+#define CMD_NPE_START                  0x02
+#define CMD_NPE_STOP                   0x03
+#define CMD_NPE_CLR_PIPE               0x04
+#define CMD_CLR_PROFILE_CNT            0x0C
+#define CMD_RD_INS_MEM                 0x10 /* instruction memory */
+#define CMD_WR_INS_MEM                 0x11
+#define CMD_RD_DATA_MEM                0x12 /* data memory */
+#define CMD_WR_DATA_MEM                0x13
+#define CMD_RD_ECS_REG                 0x14 /* exec access register */
+#define CMD_WR_ECS_REG                 0x15
+
+#define STAT_RUN                       0x80000000
+#define STAT_STOP                      0x40000000
+#define STAT_CLEAR                     0x20000000
+#define STAT_ECS_K                     0x00800000 /* pipeline clean */
+
+#define NPE_STEVT                      0x1B
+#define NPE_STARTPC                    0x1C
+#define NPE_REGMAP                     0x1E
+#define NPE_CINDEX                     0x1F
+
+#define INSTR_WR_REG_SHORT             0x0000C000
+#define INSTR_WR_REG_BYTE              0x00004000
+#define INSTR_RD_FIFO                  0x0F888220
+#define INSTR_RESET_MBOX               0x0FAC8210
+
+#define ECS_BG_CTXT_REG_0              0x00 /* Background Executing Context */
+#define ECS_BG_CTXT_REG_1              0x01 /* Stack level */
+#define ECS_BG_CTXT_REG_2              0x02
+#define ECS_PRI_1_CTXT_REG_0           0x04 /* Priority 1 Executing Context */
+#define ECS_PRI_1_CTXT_REG_1           0x05 /* Stack level */
+#define ECS_PRI_1_CTXT_REG_2           0x06
+#define ECS_PRI_2_CTXT_REG_0           0x08 /* Priority 2 Executing Context */
+#define ECS_PRI_2_CTXT_REG_1           0x09 /* Stack level */
+#define ECS_PRI_2_CTXT_REG_2           0x0A
+#define ECS_DBG_CTXT_REG_0             0x0C /* Debug Executing Context */
+#define ECS_DBG_CTXT_REG_1             0x0D /* Stack level */
+#define ECS_DBG_CTXT_REG_2             0x0E
+#define ECS_INSTRUCT_REG               0x11 /* NPE Instruction Register */
+
+#define ECS_REG_0_ACTIVE               0x80000000 /* all levels */
+#define ECS_REG_0_NEXTPC_MASK          0x1FFF0000 /* BG/PRI1/PRI2 levels */
+#define ECS_REG_0_LDUR_BITS            8
+#define ECS_REG_0_LDUR_MASK            0x00000700 /* all levels */
+#define ECS_REG_1_CCTXT_BITS           16
+#define ECS_REG_1_CCTXT_MASK           0x000F0000 /* all levels */
+#define ECS_REG_1_SELCTXT_BITS         0
+#define ECS_REG_1_SELCTXT_MASK         0x0000000F /* all levels */
+#define ECS_DBG_REG_2_IF               0x00100000 /* debug level */
+#define ECS_DBG_REG_2_IE               0x00080000 /* debug level */
+
+/* NPE watchpoint_fifo register bit */
+#define WFIFO_VALID                    0x80000000
+
+/* NPE messaging_status register bit definitions */
+#define MSGSTAT_OFNE  0x00010000 /* OutFifoNotEmpty */
+#define MSGSTAT_IFNF  0x00020000 /* InFifoNotFull */
+#define MSGSTAT_OFNF  0x00040000 /* OutFifoNotFull */
+#define MSGSTAT_IFNE  0x00080000 /* InFifoNotEmpty */
+#define MSGSTAT_MBINT 0x00100000 /* Mailbox interrupt */
+#define MSGSTAT_IFINT 0x00200000 /* InFifo interrupt */
+#define MSGSTAT_OFINT 0x00400000 /* OutFifo interrupt */
+#define MSGSTAT_WFINT 0x00800000 /* WatchFifo interrupt */
+
+/* NPE messaging_control register bit definitions */
+#define MSGCTL_OUT_FIFO       0x00010000 /* enable output FIFO */
+#define MSGCTL_IN_FIFO        0x00020000 /* enable input FIFO */
+#define MSGCTL_OUT_FIFO_WRITE 0x01000000 /* enable FIFO + WRITE */
+#define MSGCTL_IN_FIFO_WRITE  0x02000000
+
+/* NPE mailbox_status value for reset */
+#define RESET_MBOX_STAT          0x0000F0F0
+
+#define print_npe(npe, fmt, ...) fprintf(stderr, "%s: " fmt, npe->name, ## __VA_ARGS__)
+
+#if DEBUG_MSG
+#define debug_msg(npe, fmt, ...) print_npe(npe, fmt, ## __VA_ARGS__)
+#else
+#define debug_msg(npe, fmt, ...)
+#endif
+
+static struct {
+	u32 reg, val;
+} ecs_reset[] = {
+	{ECS_BG_CTXT_REG_0,    0xA0000000},
+	{ECS_BG_CTXT_REG_1,    0x01000000},
+	{ECS_BG_CTXT_REG_2,    0x00008000},
+	{ECS_PRI_1_CTXT_REG_0, 0x20000080},
+	{ECS_PRI_1_CTXT_REG_1, 0x01000000},
+	{ECS_PRI_1_CTXT_REG_2, 0x00008000},
+	{ECS_PRI_2_CTXT_REG_0, 0x20000080},
+	{ECS_PRI_2_CTXT_REG_1, 0x01000000},
+	{ECS_PRI_2_CTXT_REG_2, 0x00008000},
+	{ECS_DBG_CTXT_REG_0,   0x20000000},
+	{ECS_DBG_CTXT_REG_1,   0x00000000},
+	{ECS_DBG_CTXT_REG_2,   0x001E0000},
+	{ECS_INSTRUCT_REG,     0x1003C00F},
+};
+
+static struct npe npe_tab[NPE_COUNT] = {
+	{
+		.regs = (struct npe_regs *)IXP4XX_NPEA_BASE,
+		.id = 0,
+		.name = "NPE-A",
+	}, {
+		.regs = (struct npe_regs *)IXP4XX_NPEB_BASE,
+		.id = 1,
+		.name = "NPE-B",
+	}, {
+		.regs = (struct npe_regs *)IXP4XX_NPEC_BASE,
+		.id = 2,
+		.name = "NPE-C",
+	}
+};
+
+int npe_running(struct npe *npe)
+{
+	return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
+}
+
+static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
+{
+	__raw_writel(data, &npe->regs->exec_data);
+	__raw_writel(addr, &npe->regs->exec_addr);
+	__raw_writel(cmd, &npe->regs->exec_status_cmd);
+}
+
+static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
+{
+	__raw_writel(addr, &npe->regs->exec_addr);
+	__raw_writel(cmd, &npe->regs->exec_status_cmd);
+	/* Iintroduce extra read cycles after issuing read command to NPE
+	   so that we read the register after the NPE has updated it.
+	   This is to overcome race condition between XScale and NPE */
+	__raw_readl(&npe->regs->exec_data);
+	__raw_readl(&npe->regs->exec_data);
+	return __raw_readl(&npe->regs->exec_data);
+}
+
+static void npe_clear_active(struct npe *npe, u32 reg)
+{
+	u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
+	npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
+}
+
+static void npe_start(struct npe *npe)
+{
+	/* ensure only Background Context Stack Level is active */
+	npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
+	npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
+	npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
+
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+	__raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
+}
+
+static void npe_stop(struct npe *npe)
+{
+	__raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
+}
+
+static int npe_debug_instr(struct npe *npe, u32 instr, u32 ctx, u32 ldur)
+{
+	u32 wc;
+	int i;
+
+	/* set the Active bit, and the LDUR, in the debug level */
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
+		      ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
+
+	/* set CCTXT at ECS DEBUG L3 to specify in which context to execute
+	   the instruction, and set SELCTXT at ECS DEBUG Level to specify
+	   which context store to access.
+	   Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
+	*/
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
+		      (ctx << ECS_REG_1_CCTXT_BITS) |
+		      (ctx << ECS_REG_1_SELCTXT_BITS));
+
+	/* clear the pipeline */
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+
+	/* load NPE instruction into the instruction register */
+	npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
+
+	/* we need this value later to wait for completion of NPE execution
+	   step */
+	wc = __raw_readl(&npe->regs->watch_count);
+
+	/* issue a Step One command via the Execution Control register */
+	__raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
+
+	/* Watch Count register increments when NPE completes an instruction */
+	for (i = 0; i < MAX_RETRIES; i++) {
+		if (wc != __raw_readl(&npe->regs->watch_count))
+			return 0;
+		udelay(1);
+	}
+
+	print_npe(npe, "reset: npe_debug_instr(): timeout\n");
+	return -ETIMEDOUT;
+}
+
+static int npe_logical_reg_write8(struct npe *npe, u32 addr, u8 val, u32 ctx)
+{
+	/* here we build the NPE assembler instruction: mov8 d0, #0 */
+	u32 instr = INSTR_WR_REG_BYTE | /* OpCode */
+		addr << 9 |             /* base Operand */
+		(val & 0x1F) << 4 |     /* lower 5 bits to immediate data */
+		(val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
+	return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
+}
+
+static int npe_logical_reg_write16(struct npe *npe, u32 addr, u16 val, u32 ctx)
+{
+	/* here we build the NPE assembler instruction: mov16 d0, #0 */
+	u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
+		addr << 9 |             /* base Operand */
+		(val & 0x1F) << 4 |     /* lower 5 bits to immediate data */
+		(val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
+	return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
+}
+
+static int npe_logical_reg_write32(struct npe *npe, u32 addr, u32 val, u32 ctx)
+{
+	/* write in 16 bit steps first the high and then the low value */
+	if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
+		return -ETIMEDOUT;
+	return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
+}
+
+static int npe_reset(struct npe *npe)
+{
+	u32 val, ctl, exec_count, ctx_reg2;
+	int i;
+
+	ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
+		0x3F3FFFFF;
+
+	/* disable parity interrupt */
+	__raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
+
+	/* pre exec - debug instruction */
+	/* turn off the halt bit by clearing Execution Count register. */
+	exec_count = __raw_readl(&npe->regs->exec_count);
+	__raw_writel(0, &npe->regs->exec_count);
+	/* ensure that IF and IE are on (temporarily), so that we don't end up
+	   stepping forever */
+	ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
+		      ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
+
+	/* clear the FIFOs */
+	while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
+		;
+	while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
+		/* read from the outFIFO until empty */
+		print_npe(npe, "npe_reset: read FIFO = 0x%X\n",
+			  __raw_readl(&npe->regs->in_out_fifo));
+
+	while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
+		/* step execution of the NPE intruction to read inFIFO using
+		   the Debug Executing Context stack */
+		if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
+			return -ETIMEDOUT;
+
+	/* reset the mailbox reg from the XScale side */
+	__raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
+	/* from NPE side */
+	if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
+		return -ETIMEDOUT;
+
+	/* Reset the physical registers in the NPE register file */
+	for (val = 0; val < NPE_PHYS_REG; val++) {
+		if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
+			return -ETIMEDOUT;
+		/* address is either 0 or 4 */
+		if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
+			return -ETIMEDOUT;
+	}
+
+	/* Reset the context store = each context's Context Store registers */
+
+	/* Context 0 has no STARTPC. Instead, this value is used to set NextPC
+	   for Background ECS, to set where NPE starts executing code */
+	val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
+	val &= ~ECS_REG_0_NEXTPC_MASK;
+	val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
+	npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
+
+	for (i = 0; i < 16; i++) {
+		if (i) { /* Context 0 has no STEVT nor STARTPC */
+			/* STEVT = off, 0x80 */
+			if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
+				return -ETIMEDOUT;
+			if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
+				return -ETIMEDOUT;
+		}
+		/* REGMAP = d0->p0, d8->p2, d16->p4 */
+		if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
+			return -ETIMEDOUT;
+		if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
+			return -ETIMEDOUT;
+	}
+
+	/* post exec */
+	/* clear active bit in debug level */
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
+	/* clear the pipeline */
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+	/* restore previous values */
+	__raw_writel(exec_count, &npe->regs->exec_count);
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
+
+	/* write reset values to Execution Context Stack registers */
+	for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
+		npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
+			      ecs_reset[val].val);
+
+	/* clear the profile counter */
+	__raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
+
+	__raw_writel(0, &npe->regs->exec_count);
+	__raw_writel(0, &npe->regs->action_points[0]);
+	__raw_writel(0, &npe->regs->action_points[1]);
+	__raw_writel(0, &npe->regs->action_points[2]);
+	__raw_writel(0, &npe->regs->action_points[3]);
+	__raw_writel(0, &npe->regs->watch_count);
+
+	val = ixp4xx_read_feature_bits();
+	/* reset the NPE */
+	ixp4xx_write_feature_bits(val &
+				  ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
+	/* deassert reset */
+	ixp4xx_write_feature_bits(val |
+				  (IXP4XX_FEATURE_RESET_NPEA << npe->id));
+	for (i = 0; i < MAX_RETRIES; i++) {
+		if (ixp4xx_read_feature_bits() &
+		    (IXP4XX_FEATURE_RESET_NPEA << npe->id))
+			break; /* NPE is back alive */
+		udelay(1);
+	}
+	if (i == MAX_RETRIES)
+		return -ETIMEDOUT;
+
+	npe_stop(npe);
+
+	/* restore NPE configuration bus Control Register - parity settings */
+	__raw_writel(ctl, &npe->regs->messaging_control);
+	return 0;
+}
+
+
+int npe_send_message(struct npe *npe, const void *msg, const char *what)
+{
+	const u32 *send = msg;
+	int cycles = 0;
+
+	debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
+		  what, send[0], send[1]);
+
+	if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
+		debug_msg(npe, "NPE input FIFO not empty\n");
+		return -EIO;
+	}
+
+	__raw_writel(send[0], &npe->regs->in_out_fifo);
+
+	if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
+		debug_msg(npe, "NPE input FIFO full\n");
+		return -EIO;
+	}
+
+	__raw_writel(send[1], &npe->regs->in_out_fifo);
+
+	while ((cycles < MAX_RETRIES) &&
+	       (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
+		udelay(1);
+		cycles++;
+	}
+
+	if (cycles == MAX_RETRIES) {
+		debug_msg(npe, "Timeout sending message\n");
+		return -ETIMEDOUT;
+	}
+
+#if DEBUG_MSG > 1
+	debug_msg(npe, "Sending a message took %i cycles\n", cycles);
+#endif
+	return 0;
+}
+
+int npe_recv_message(struct npe *npe, void *msg, const char *what)
+{
+	u32 *recv = msg;
+	int cycles = 0, cnt = 0;
+
+	debug_msg(npe, "Trying to receive message %s\n", what);
+
+	while (cycles < MAX_RETRIES) {
+		if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
+			recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
+			if (cnt == 2)
+				break;
+		} else {
+			udelay(1);
+			cycles++;
+		}
+	}
+
+	switch(cnt) {
+	case 1:
+		debug_msg(npe, "Received [%08X]\n", recv[0]);
+		break;
+	case 2:
+		debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
+		break;
+	}
+
+	if (cycles == MAX_RETRIES) {
+		debug_msg(npe, "Timeout waiting for message\n");
+		return -ETIMEDOUT;
+	}
+
+#if DEBUG_MSG > 1
+	debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
+#endif
+	return 0;
+}
+
+int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
+{
+	int result;
+	u32 *send = msg, recv[2];
+
+	if ((result = npe_send_message(npe, msg, what)) != 0)
+		return result;
+	if ((result = npe_recv_message(npe, recv, what)) != 0)
+		return result;
+
+	if ((recv[0] != send[0]) || (recv[1] != send[1])) {
+		debug_msg(npe, "Message %s: unexpected message received\n",
+			  what);
+		return -EIO;
+	}
+	return 0;
+}
+
+
+int npe_load_firmware(struct npe *npe)
+{
+	struct dl_block {
+		u32 type;
+		u32 offset;
+	} *blk;
+
+	struct dl_image {
+		u32 magic;
+		u32 id;
+		u32 size;
+		union {
+			u32 data[0];
+			struct dl_block blocks[0];
+		};
+	} *image;
+
+	struct dl_codeblock {
+		u32 npe_addr;
+		u32 size;
+		u32 data[0];
+	} *cb;
+
+	int i, j, err, data_size, instr_size, blocks, table_end;
+	u32 cmd;
+	char name[5 /* "/dev/" */ + NPE_NAME_LENGTH + 1 /* NUL */];
+	size_t image_size;
+
+	sprintf(name, "/dev/%s", npe->name);
+	if (!(image = read_file(name, &image_size))) {
+		print_npe(npe, "bad or missing microcode file %s", name);
+		return -EIO;
+	}
+
+	err = -EINVAL;
+	if (image_size < sizeof(struct dl_image)) {
+		print_npe(npe, "incomplete microcode file %s\n", name);
+		goto err;
+	}
+
+#if DEBUG_FW
+	print_npe(npe, "microcode: %08X %08X %08X (0x%X bytes)\n",
+		  image->magic, image->id, image->size, image->size * 4);
+#endif
+
+	if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
+		image->id = swab32(image->id);
+		image->size = swab32(image->size);
+	} else if (image->magic != FW_MAGIC) {
+		print_npe(npe, "bad microcode file %s magic: 0x%X\n", name, image->magic);
+		goto err;
+	}
+	if ((image->size * 4 + sizeof(struct dl_image)) > image_size) {
+		print_npe(npe, "incomplete microcode file %s\n", name);
+		goto err;
+	}
+	if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
+		print_npe(npe, "NPE ID mismatch in microcode file %s\n", name);
+		goto err;
+	}
+	if (image->magic == swab32(FW_MAGIC))
+		for (i = 0; i < image->size; i++)
+			image->data[i] = swab32(image->data[i]);
+
+	if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
+		print_npe(npe, "IXP43x/IXP46x microcode ignored on IXP42x\n");
+		goto err;
+	}
+
+	if (npe_running(npe)) {
+		print_npe(npe, "unable to load microcode file %s, NPE is already running\n", name);
+		err = -EBUSY;
+		goto err;
+	}
+
+	if (cpu_is_ixp42x()) {
+		if (!npe->id)
+			instr_size = NPE_A_42X_INSTR_SIZE;
+		else
+			instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
+		data_size = NPE_42X_DATA_SIZE;
+	} else {
+		instr_size = NPE_46X_INSTR_SIZE;
+		data_size = NPE_46X_DATA_SIZE;
+	}
+
+	for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
+	     blocks++)
+		if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
+			break;
+	if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
+		print_npe(npe, "microcode EOF block marker not found\n");
+		goto err;
+	}
+
+#if DEBUG_FW
+	print_npe(npe, "%i microcode blocks found\n", blocks);
+#endif
+
+	table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
+	for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
+		if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
+		    || blk->offset < table_end) {
+			print_npe(npe, "invalid offset 0x%X of "
+				  "microcode block #%i\n", blk->offset, i);
+			goto err;
+		}
+
+		cb = (struct dl_codeblock*)&image->data[blk->offset];
+		if (blk->type == FW_BLOCK_TYPE_INSTR) {
+			if (cb->npe_addr + cb->size > instr_size)
+				goto too_big;
+			cmd = CMD_WR_INS_MEM;
+		} else if (blk->type == FW_BLOCK_TYPE_DATA) {
+			if (cb->npe_addr + cb->size > data_size)
+				goto too_big;
+			cmd = CMD_WR_DATA_MEM;
+		} else {
+			print_npe(npe, "invalid microcode block #%i type 0x%X\n",
+				  i, blk->type);
+			goto err;
+		}
+		if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
+			print_npe(npe, "microcode block #%i doesn't "
+				  "fit in microcode image: type %c, start 0x%X,"
+				  " length 0x%X\n", i,
+				  blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
+				  cb->npe_addr, cb->size);
+			goto err;
+		}
+
+		for (j = 0; j < cb->size; j++)
+			npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
+	}
+
+	npe_start(npe);
+	if (!npe_running(npe))
+		print_npe(npe, "unable to start\n");
+	free(image);
+	return 0;
+
+too_big:
+	print_npe(npe, "microcode block #%i doesn't fit in NPE "
+		  "memory: type %c, start 0x%X, length 0x%X\n", i,
+		  blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
+		  cb->npe_addr, cb->size);
+err:
+	free(image);
+	return err;
+}
+
+
+struct npe *npe_request(int id)
+{
+	if (id < NPE_COUNT)
+		if (npe_tab[id].valid)
+			return &npe_tab[id];
+	return NULL;
+}
+
+static int __init npe_init(void)
+{
+	int i;
+
+	for (i = 0; i < NPE_COUNT; i++) {
+		struct npe *npe = &npe_tab[i];
+		if (!(ixp4xx_read_feature_bits() & (IXP4XX_FEATURE_RESET_NPEA << i)))
+			continue; /* NPE already disabled or not present */
+		if (npe_reset(npe))
+			continue;
+		npe->valid = 1;
+	}
+	return 0;
+}
+
+coredevice_initcall(npe_init);
diff --git a/arch/arm/mach-ixp4xx/qmgr.c b/arch/arm/mach-ixp4xx/qmgr.c
new file mode 100644
index 0000000..49cba60
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/qmgr.c
@@ -0,0 +1,269 @@
+/*
+ * Intel IXP4xx Queue Manager driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#include <init.h>
+#include <errno.h>
+#include <mach/qmgr.h>
+
+static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
+
+#if DEBUG_QMGR
+char qmgr_queue_descs[HALF_QUEUES][32];
+#endif
+
+#ifdef CONFIG_USE_IRQ
+
+static void (*irq_handlers[HALF_QUEUES])(void *pdev);
+static void *irq_pdevs[HALF_QUEUES];
+
+#undef fls
+static inline int fls(int x)
+{
+	int ret;
+	asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
+	ret = 32 - ret;
+	return ret;
+}
+
+
+void qmgr_set_irq(unsigned int queue, int src,
+		  void (*handler)(void *pdev), void *pdev)
+{
+	const u32 *reg;
+	int bit;
+	BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL);
+	reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */
+	bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
+	__raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit), reg);
+
+	irq_handlers[queue] = handler;
+	irq_pdevs[queue] = pdev;
+}
+
+
+static void qmgr_irq1_a0(void *data)
+{
+	int i;
+	u32 en_bitmap, src, stat;
+
+	/* ACK - it may clear any bits so don't rely on it */
+	__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]);
+
+	en_bitmap = qmgr_regs->irqen[0];
+	while (en_bitmap) {
+		i = fls(en_bitmap) - 1; /* number of the last "low" queue */
+		en_bitmap &= ~BIT(i);
+		src = qmgr_regs->irqsrc[i >> 3];
+		stat = qmgr_regs->stat1[i >> 3];
+		if (src & 4) /* the IRQ condition is inverted */
+			stat = ~stat;
+		if (stat & BIT(src & 3))
+			irq_handlers[i](irq_pdevs[i]);
+	}
+}
+
+
+static void qmgr_irq1(void *data)
+{
+	int i;
+	u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[0]);
+
+	if (!req_bitmap)
+		return;
+	__raw_writel(req_bitmap, &qmgr_regs->irqstat[0]); /* ACK */
+
+	while (req_bitmap) {
+		i = fls(req_bitmap) - 1; /* number of the last queue */
+		req_bitmap &= ~BIT(i);
+		irq_handlers[i](irq_pdevs[i]);
+	}
+}
+
+
+void qmgr_enable_irq(unsigned int queue)
+{
+	u32 mask = 1 << queue;
+
+	__raw_writel(__raw_readl(&qmgr_regs->irqen[0]) | mask,
+		     &qmgr_regs->irqen[0]);
+}
+
+void qmgr_disable_irq(unsigned int queue)
+{
+	u32 mask = 1 << queue;
+
+	__raw_writel(__raw_readl(&qmgr_regs->irqen[0]) & ~mask,
+		     &qmgr_regs->irqen[0]);
+	__raw_writel(mask, &qmgr_regs->irqstat[0]); /* clear */
+}
+
+#endif /* CONFIG_USE_IRQ */
+
+static inline void shift_mask(u32 *mask)
+{
+	mask[3] = mask[3] << 1 | mask[2] >> 31;
+	mask[2] = mask[2] << 1 | mask[1] >> 31;
+	mask[1] = mask[1] << 1 | mask[0] >> 31;
+	mask[0] <<= 1;
+}
+
+#if DEBUG_QMGR
+void qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			unsigned int nearly_empty_watermark,
+			unsigned int nearly_full_watermark,
+			const char *desc_format, const char* name)
+#else
+void __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			  unsigned int nearly_empty_watermark,
+			  unsigned int nearly_full_watermark)
+#endif
+{
+	u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
+
+	BUG_ON(queue >= HALF_QUEUES);
+	BUG_ON((nearly_empty_watermark | nearly_full_watermark) & ~7);
+
+	switch (len) {
+	case  16:
+		cfg = 0 << 24;
+		mask[0] = 0x1;
+		break;
+	case  32:
+		cfg = 1 << 24;
+		mask[0] = 0x3;
+		break;
+	case  64:
+		cfg = 2 << 24;
+		mask[0] = 0xF;
+		break;
+	case 128:
+		cfg = 3 << 24;
+		mask[0] = 0xFF;
+		break;
+	default:
+		BUG();
+	}
+
+	cfg |= nearly_empty_watermark << 26;
+	cfg |= nearly_full_watermark << 29;
+	len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */
+	mask[1] = mask[2] = mask[3] = 0;
+
+	BUG_ON(__raw_readl(&qmgr_regs->sram[queue]));
+
+	while (1) {
+		if (!(used_sram_bitmap[0] & mask[0]) &&
+		    !(used_sram_bitmap[1] & mask[1]) &&
+		    !(used_sram_bitmap[2] & mask[2]) &&
+		    !(used_sram_bitmap[3] & mask[3]))
+			break; /* found free space */
+
+		addr++;
+		shift_mask(mask);
+		if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
+			fprintf(stderr, "qmgr: no free SRAM space for"
+				" queue %i\n", queue);
+			BUG();
+		}
+	}
+
+	used_sram_bitmap[0] |= mask[0];
+	used_sram_bitmap[1] |= mask[1];
+	used_sram_bitmap[2] |= mask[2];
+	used_sram_bitmap[3] |= mask[3];
+	__raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
+#if DEBUG_QMGR
+	/* no snprintf() */
+	sprintf(qmgr_queue_descs[queue], desc_format, name);
+	fprintf(stderr, "qmgr: requested queue %s(%i) addr = 0x%02X\n",
+		qmgr_queue_descs[queue], queue, addr);
+#endif
+}
+
+void qmgr_release_queue(unsigned int queue)
+{
+	u32 cfg, addr, mask[4];
+
+	BUG_ON(queue >= HALF_QUEUES); /* not in valid range */
+
+	cfg = __raw_readl(&qmgr_regs->sram[queue]);
+	addr = (cfg >> 14) & 0xFF;
+
+	BUG_ON(!addr); /* not requested */
+
+	switch ((cfg >> 24) & 3) {
+	case 0: mask[0] = 0x1; break;
+	case 1: mask[0] = 0x3; break;
+	case 2: mask[0] = 0xF; break;
+	case 3: mask[0] = 0xFF; break;
+	}
+
+	mask[1] = mask[2] = mask[3] = 0;
+
+	while (addr--)
+		shift_mask(mask);
+
+#if DEBUG_QMGR
+	fprintf(stderr, "qmgr: releasing queue %s(%i)\n",
+		qmgr_queue_descs[queue], queue);
+	qmgr_queue_descs[queue][0] = '\x0';
+#endif
+	__raw_writel(0, &qmgr_regs->sram[queue]);
+
+	used_sram_bitmap[0] &= ~mask[0];
+	used_sram_bitmap[1] &= ~mask[1];
+	used_sram_bitmap[2] &= ~mask[2];
+	used_sram_bitmap[3] &= ~mask[3];
+#ifdef CONFIG_USE_IRQ
+	irq_handlers[queue] = NULL; /* catch IRQ bugs */
+#endif
+
+	while ((addr = qmgr_get_entry(queue)))
+		fprintf(stderr, "qmgr: released queue %i not empty: 0x%08X\n",
+			queue, addr);
+}
+
+static int __init qmgr_init(void)
+{
+	int i;
+#ifdef CONFIG_USE_IRQ
+	interrupt_handler_t *handler;
+#endif
+
+	/* reset qmgr registers */
+	for (i = 0; i < 4; i++) {
+		__raw_writel(0x33333333, &qmgr_regs->stat1[i]);
+		__raw_writel(0, &qmgr_regs->irqsrc[i]);
+	}
+	for (i = 0; i < 2; i++) {
+		__raw_writel(0, &qmgr_regs->stat2[i]);
+		__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
+		__raw_writel(0, &qmgr_regs->irqen[i]);
+	}
+
+	__raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h);
+	__raw_writel(0, &qmgr_regs->statf_h);
+
+	for (i = 0; i < QUEUES; i++)
+		__raw_writel(0, &qmgr_regs->sram[i]);
+
+#ifdef CONFIG_USE_IRQ
+	if (cpu_is_ixp42x_rev_a0())
+		handler = qmgr_irq1_a0;
+	else
+		handler = qmgr_irq1;
+
+	irq_install_handler(IXP425_QM1_IRQ, handler, NULL);
+#endif
+	used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
+	return 0;
+}
+
+coredevice_initcall(qmgr_init);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 69f3352..df6e42c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -77,6 +77,14 @@ config DRIVER_NET_MACB
 	depends on HAS_MACB
 	select MIIDEV
 
+config DRIVER_NET_IXP4XX_ETH
+	tristate "Intel IXP4xx Ethernet support"
+	depends on ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
+	select MIIDEV
+	help
+	  Say Y here if you want to use built-in Ethernet ports
+	  on IXP4xx processor.
+
 config DRIVER_NET_TAP
 	bool "tap Ethernet driver"
 	depends on LINUX
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 96d3d32..97cb44b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_DRIVER_NET_MACB)		+= macb.o
 obj-$(CONFIG_DRIVER_NET_TAP)		+= tap.o
 obj-$(CONFIG_MIIDEV)			+= miidev.o
 obj-$(CONFIG_NET_USB)			+= usb/
+obj-$(CONFIG_DRIVER_NET_IXP4XX_ETH)	+= ixp4xx_eth.o
diff --git a/drivers/net/ixp4xx_eth.c b/drivers/net/ixp4xx_eth.c
new file mode 100644
index 0000000..71e6d92
--- /dev/null
+++ b/drivers/net/ixp4xx_eth.c
@@ -0,0 +1,763 @@
+/*
+ * Intel IXP4xx Ethernet driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * Ethernet port config (0x00 is not present on IXP42X):
+ *
+ * logical port		0x00		0x10		0x20
+ * NPE			0 (NPE-A)	1 (NPE-B)	2 (NPE-C)
+ * physical port	2		0		1
+ * RX queue (variable)	20		21		22
+ * TX queue		23		24		25
+ * RX-free queue	26		27		28
+ * TX-done queue is always 31, per-port RX queue is configurable
+ *
+ *
+ * Queue entries:
+ * bits 0 -> 1  - NPE ID (RX and TX-done)
+ * bits 0 -> 2  - priority (TX, per 802.1D)
+ * bits 3 -> 4  - port ID (user-set?)
+ * bits 5 -> 31 - physical descriptor address
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <miidev.h>
+#include <net.h>
+#include <errno.h>
+#include <mach/ixp4xx-regs.h>
+#include <mach/platform.h>
+#include <mach/cpu.h>
+#include <mach/npe.h>
+#include <mach/qmgr.h>
+
+#define DEBUG_DESC		0
+#define DEBUG_RX		0
+#define DEBUG_TX		0
+#define DEBUG_PKT_BYTES		0
+#define DEBUG_MDIO		0
+#define DEBUG_OPEN		0
+#define DEBUG_CLOSE		0
+
+#define RX_DESCS		16 /* also length of all RX queues */
+#define TX_DESCS		16 /* also length of all TX queues */
+#define TXDONE_QUEUE_LEN	16 /* dwords */
+
+#define MAX_MRU			1536 /* 0x600 */
+#define RX_BUFF_SIZE		MAX_MRU
+
+#define MAX_MDIO_RETRIES	100 /* microseconds, typically 30 cycles */
+#define MAX_CLOSE_WAIT		1000 /* microseconds, typically 2-3 cycles */
+#define ETH_ALEN		6
+
+#define PHYSICAL_ID(port)	(((port)->npe->id + 2) % 3)
+#define LOGICAL_ID(port)	((port)->npe->id << 4)
+#define RX_QUEUE(port)		((port)->npe->id + 20) /* can be changed */
+#define TX_QUEUE(port)		((port)->npe->id + 23)
+#define RXFREE_QUEUE(port)	((port)->npe->id + 26)
+#define TXDONE_QUEUE		31
+
+/* TX Control Registers */
+#define TX_CNTRL0_TX_EN		0x01
+#define TX_CNTRL0_HALFDUPLEX	0x02
+#define TX_CNTRL0_RETRY		0x04
+#define TX_CNTRL0_PAD_EN	0x08
+#define TX_CNTRL0_APPEND_FCS	0x10
+#define TX_CNTRL0_2DEFER	0x20
+#define TX_CNTRL0_RMII		0x40 /* reduced MII */
+#define TX_CNTRL1_RETRIES	0x0F /* 4 bits */
+
+/* RX Control Registers */
+#define RX_CNTRL0_RX_EN		0x01
+#define RX_CNTRL0_PADSTRIP_EN	0x02
+#define RX_CNTRL0_SEND_FCS	0x04
+#define RX_CNTRL0_PAUSE_EN	0x08
+#define RX_CNTRL0_LOOP_EN	0x10
+#define RX_CNTRL0_ADDR_FLTR_EN	0x20
+#define RX_CNTRL0_RX_RUNT_EN	0x40
+#define RX_CNTRL0_BCAST_DIS	0x80
+#define RX_CNTRL1_DEFER_EN	0x01
+
+/* Core Control Register */
+#define CORE_RESET		0x01
+#define CORE_RX_FIFO_FLUSH	0x02
+#define CORE_TX_FIFO_FLUSH	0x04
+#define CORE_SEND_JAM		0x08
+#define CORE_MDC_EN		0x10 /* MDIO using NPE-B ETH-0 only */
+
+#define DEFAULT_TX_CNTRL0	(TX_CNTRL0_TX_EN | TX_CNTRL0_RETRY |       \
+				 TX_CNTRL0_PAD_EN | TX_CNTRL0_APPEND_FCS | \
+				 TX_CNTRL0_2DEFER)
+#define DEFAULT_RX_CNTRL0	RX_CNTRL0_RX_EN
+#define DEFAULT_CORE_CNTRL	CORE_MDC_EN
+
+
+/* NPE message codes */
+#define NPE_GETSTATUS			 0x00
+#define NPE_EDB_SETPORTADDRESS		 0x01
+#define NPE_EDB_GETMACADDRESSDATABASE	 0x02
+#define NPE_EDB_SETMACADDRESSSDATABASE	 0x03
+#define NPE_GETSTATS			 0x04
+#define NPE_RESETSTATS			 0x05
+#define NPE_SETMAXFRAMELENGTHS		 0x06
+#define NPE_VLAN_SETRXTAGMODE		 0x07
+#define NPE_VLAN_SETDEFAULTRXVID	 0x08
+#define NPE_VLAN_SETPORTVLANTABLEENTRY	 0x09
+#define NPE_VLAN_SETPORTVLANTABLERANGE	 0x0A
+#define NPE_VLAN_SETRXQOSENTRY		 0x0B
+#define NPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C
+#define NPE_STP_SETBLOCKINGSTATE	 0x0D
+#define NPE_FW_SETFIREWALLMODE		 0x0E
+#define NPE_PC_SETFRAMECONTROLDURATIONID 0x0F
+#define NPE_PC_SETAPMACTABLE		 0x11
+#define NPE_SETLOOPBACK_MODE		 0x12
+#define NPE_PC_SETBSSIDTABLE		 0x13
+#define NPE_ADDRESS_FILTER_CONFIG	 0x14
+#define NPE_APPENDFCSCONFIG		 0x15
+#define NPE_NOTIFY_MAC_RECOVERY_DONE	 0x16
+#define NPE_MAC_RECOVERY_START		 0x17
+
+struct eth_regs {
+	u32 tx_control[2], __res1[2];		 /* 000 */
+	u32 rx_control[2], __res2[2];		 /* 010 */
+	u32 random_seed, __res3[3];		 /* 020 */
+	u32 partial_empty_threshold, __res4;	 /* 030 */
+	u32 partial_full_threshold, __res5;	 /* 038 */
+	u32 tx_start_bytes, __res6[3];		 /* 040 */
+	u32 tx_deferral, rx_deferral, __res7[2]; /* 050 */
+	u32 tx_2part_deferral[2], __res8[2];	 /* 060 */
+	u32 slot_time, __res9[3];		 /* 070 */
+	u32 mdio_command[4];			 /* 080 */
+	u32 mdio_status[4];			 /* 090 */
+	u32 mcast_mask[6], __res10[2];		 /* 0A0 */
+	u32 mcast_addr[6], __res11[2];		 /* 0C0 */
+	u32 int_clock_threshold, __res12[3];	 /* 0E0 */
+	u32 hw_addr[6], __res13[61];		 /* 0F0 */
+	u32 core_control;			 /* 1FC */
+};
+
+/* NPE message structure */
+struct msg {
+	u8 cmd, eth_id, params[6];
+};
+
+/* Ethernet packet descriptor, 32 bytes */
+struct desc {
+	u8 *next;    /* pointer to next buffer, unused */
+
+	u16 buf_len; /* buffer length */
+	u16 pkt_len; /* packet length */
+	u8 *data;    /* pointer to data buffer in RAM */
+	u8 dest_id;
+	u8 src_id;
+	u16 flags;
+	u8 qos;
+	u8 padlen;
+	u16 vlan_tci;
+
+	u8 dst_mac[ETH_ALEN], src_mac[ETH_ALEN];
+};
+
+struct port {
+	struct desc rx_desc_tab[RX_DESCS]; /* alignment: 0x10 */
+	struct desc tx_desc_tab[TX_DESCS];
+	u8 *buff_tab;
+	struct eth_regs *regs;
+	struct npe *npe;
+	u8 firmware[4];
+	struct eth_plat_info *pinfo;
+	struct mii_device miidev;
+	struct eth_device eth;
+};
+
+#define rx_buff(port, n) ((port)->buff_tab + MAX_MRU * (n))
+#define tx_buff(port, n) ((port)->buff_tab + MAX_MRU * (RX_DESCS + (n)))
+
+static struct eth_regs *mdio_regs; /* mdio command and status only */
+
+static int ixp4xx_mdio_cmd(int write, const struct device_d *dev, unsigned char phy_id,
+			   unsigned char location, unsigned short value)
+{
+	int cycles = 0;
+
+	if (__raw_readl(&mdio_regs->mdio_command[3]) & 0x80) {
+		fprintf(stderr, "%s%d: MII not ready to transmit\n", dev->name, dev->id);
+		return -1;
+	}
+
+	if (write) {
+		__raw_writel(value & 0xFF, &mdio_regs->mdio_command[0]);
+		__raw_writel(value >> 8, &mdio_regs->mdio_command[1]);
+	}
+	__raw_writel(((phy_id << 5) | location) & 0xFF,
+		     &mdio_regs->mdio_command[2]);
+	__raw_writel((phy_id >> 3) | (write << 2) | 0x80 /* GO */,
+		     &mdio_regs->mdio_command[3]);
+
+	while ((cycles < MAX_MDIO_RETRIES) &&
+	       (__raw_readl(&mdio_regs->mdio_command[3]) & 0x80)) {
+		udelay(1);
+		cycles++;
+	}
+
+	if (cycles == MAX_MDIO_RETRIES) {
+		fprintf(stderr, "%s%d: MII write failed\n", dev->name, dev->id);
+		return -1;
+	}
+
+#if DEBUG_MDIO
+	fprintf(stderr, "%s%d: mdio_%s() took %i cycles\n", dev->name, dev->id,
+		write ? "write" : "read", cycles);
+#endif
+
+	if (write)
+		return 0;
+
+	if (__raw_readl(&mdio_regs->mdio_status[3]) & 0x80) {
+#if DEBUG_MDIO
+		fprintf(stderr, "%s%d: MII read failed\n", dev->name, dev->id);
+#endif
+		return -1;
+	}
+
+	value = (__raw_readl(&mdio_regs->mdio_status[0]) & 0xFF) |
+		((__raw_readl(&mdio_regs->mdio_status[1]) & 0xFF) << 8);
+#if DEBUG_MDIO
+	fprintf(stderr, "%s%d: MII read [%i] -> 0x%X\n", dev->name, dev->id, location, value);
+#endif
+
+	return value;
+}
+
+static int ixp4xx_mdio_read(struct mii_device *mii, int phy_id, int location)
+{
+	int ret = ixp4xx_mdio_cmd(0, &mii->dev, phy_id, location, 0);
+	return ret;
+}
+
+static int ixp4xx_mdio_write(struct mii_device *mii, int phy_id, int location, int value)
+{
+	int ret = ixp4xx_mdio_cmd(1, &mii->dev, phy_id, location, value);
+#if DEBUG_MDIO
+	fprintf(stderr, "%s%d: MII write [%i] <- 0x%X, err = %i\n",
+		mii->dev.name, mii->dev.id, location, value, ret);
+#endif
+	return ret;
+}
+
+static int ixp4xx_adjust_link(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	int reg, speed, duplex;
+
+	miidev_wait_aneg(&port->miidev);
+
+	reg = mii_read(&port->miidev, port->miidev.address, MII_BMSR);
+	if (reg < 0)
+		goto err_out;
+	if (!(reg & BMSR_LSTATUS)) {
+		printf("%s%d: Link is down", dev->dev.name, dev->dev.id);
+		return -1;
+	}
+
+	reg = mii_read(&port->miidev, port->miidev.address, MII_BMCR);
+	if (reg < 0)
+		goto err_out;
+
+	if (reg & BMCR_ANENABLE) {
+		reg = mii_read(&port->miidev, port->miidev.address, MII_LPA);
+		if (reg < 0)
+			goto err_out;
+		duplex = reg & LPA_DUPLEX;
+		speed = reg & LPA_100 ? 100 : 10;
+	} else {
+		duplex = reg & BMCR_FULLDPLX;
+		speed = reg & BMCR_SPEED100 ? 100 : 10;
+	}
+
+	if (duplex)
+		__raw_writel(DEFAULT_TX_CNTRL0 & ~TX_CNTRL0_HALFDUPLEX,
+			     &port->regs->tx_control[0]);
+	else
+		__raw_writel(DEFAULT_TX_CNTRL0 | TX_CNTRL0_HALFDUPLEX,
+			     &port->regs->tx_control[0]);
+
+	fprintf(stderr, "%s%d: link up, speed %u Mb/s, %s duplex\n",
+		dev->dev.name, dev->dev.id, speed, duplex ? "full" : "half");
+	return 0;
+
+err_out:
+	printf("%s%d: failed to read MII data\n", dev->dev.name, dev->dev.id);
+	return -EIO;
+}
+
+static inline void debug_pkt(struct eth_device *dev, const char *func,
+			     u8 *data, int len)
+{
+#if DEBUG_PKT_BYTES
+	int i;
+
+	fprintf(stderr, "%s%d: %s(%4i) ", dev->dev.name, dev->dev.id, func, len);
+	for (i = 0; i < len; i++) {
+		if (i >= DEBUG_PKT_BYTES)
+			break;
+		fprintf(stderr, "%s%02X",
+			((i == 6) || (i == 12) || (i >= 14)) ? " " : "",
+			data[i]);
+	}
+	fprintf(stderr, "\n");
+#endif
+}
+
+
+static inline void debug_desc(struct desc *desc)
+{
+#if DEBUG_DESC
+	fprintf(stderr, "%07X: %X %3X %3X %07X %2X < %2X %4X %X"
+		" %X %X %02X%02X%02X%02X%02X%02X < %02X%02X%02X%02X%02X%02X\n",
+		(u32)desc, (u32)desc->next, desc->buf_len, desc->pkt_len,
+		(u32)desc->data, desc->dest_id, desc->src_id, desc->flags,
+		desc->qos, desc->padlen, desc->vlan_tci,
+		desc->dst_mac[0], desc->dst_mac[1], desc->dst_mac[2],
+		desc->dst_mac[3], desc->dst_mac[4], desc->dst_mac[5],
+		desc->src_mac[0], desc->src_mac[1], desc->src_mac[2],
+		desc->src_mac[3], desc->src_mac[4], desc->src_mac[5]);
+#endif
+}
+
+static inline int queue_get_desc(unsigned int queue, struct port *port,
+				 int is_tx)
+{
+	u32 addr, n;
+	struct desc *tab;
+
+	if (!(addr = qmgr_get_entry(queue)))
+		return -1;
+
+	addr &= ~0x1F; /* mask out non-address bits */
+	tab = is_tx ? port->tx_desc_tab : port->rx_desc_tab;
+	n = (addr - (u32)tab) / sizeof(struct desc);
+	BUG_ON(n >= (is_tx ? TX_DESCS : RX_DESCS));
+	debug_desc((struct desc*)addr);
+	BUG_ON(tab[n].next);
+	return n;
+}
+
+static inline void queue_put_desc(unsigned int queue, struct desc *desc)
+{
+	debug_desc(desc);
+	BUG_ON(((u32)desc) & 0x1F);
+	qmgr_put_entry(queue, (u32)desc);
+	/* Don't check for queue overflow here, we've allocated sufficient
+	   length and queues >= 32 don't support this check anyway. */
+}
+
+
+static int ixp4xx_eth_poll(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	struct desc *desc;
+	u8 *buff;
+	int n, len;
+
+#if DEBUG_RX
+	fprintf(stderr, "%s%d: eth_poll\n", dev->dev.name, dev->dev.id);
+#endif
+
+	if ((n = queue_get_desc(RX_QUEUE(port), port, 0)) < 0) {
+#if DEBUG_RX
+		fprintf(stderr, "%s%d: eth_poll = no packet received\n", dev->dev.name, dev->dev.id);
+#endif
+		return 0;
+	}
+
+	barrier();
+	desc = &port->rx_desc_tab[n];
+	buff = rx_buff(port, n);
+	len = desc->pkt_len;
+	/* process received frame */
+	memcpy((void *)NetRxPackets[0], buff, len);
+	debug_pkt(dev, "RX", desc->data, len);
+
+	/* put the new buffer on RX-free queue */
+	desc->buf_len = MAX_MRU;
+	desc->pkt_len = 0;
+	queue_put_desc(RXFREE_QUEUE(port), desc);
+
+	net_receive(NetRxPackets[0], len);
+
+#if DEBUG_RX
+	fprintf(stderr, "%s%d: eth_poll end\n", dev->dev.name, dev->dev.id);
+#endif
+	return 0;
+}
+
+
+static int ixp4xx_eth_xmit(struct eth_device *dev, void *data, int len)
+{
+	struct port *port = dev->priv;
+	int n;
+	struct desc *desc;
+
+#if DEBUG_TX
+	fprintf(stderr, "%s%d: eth_xmit\n", dev->dev.name, dev->dev.id);
+#endif
+
+	if (unlikely(len > 1500))
+		return -1;
+
+	debug_pkt(dev, "TX", data, len);
+
+	if ((n = queue_get_desc(TXDONE_QUEUE, port, 1)) < 0)
+		return -1; /* no free buffers */
+	desc = &port->tx_desc_tab[n];
+	desc->data = tx_buff(port, n);
+	desc->buf_len = desc->pkt_len = len;
+	memcpy(desc->data, data, len);
+
+	/* NPE firmware pads short frames with zeros internally */
+	// wmb();
+	barrier();
+	queue_put_desc(TX_QUEUE(port), desc);
+
+#if DEBUG_TX
+	fprintf(stderr, "%s%d: eth_xmit end\n", dev->dev.name, dev->dev.id);
+#endif
+	return 0;
+}
+
+static void request_queues(struct port *port, struct eth_device *dev)
+{
+	qmgr_request_queue(RXFREE_QUEUE(port), RX_DESCS, 0, 0, "%s:RX-free", dev->dev.name);
+	qmgr_request_queue(RX_QUEUE(port), RX_DESCS, 0, 0, "%s:RX", dev->dev.name);
+	qmgr_request_queue(TX_QUEUE(port), TX_DESCS, 0, 0, "%s:TX", dev->dev.name);
+
+	/* Common TX-done queue handles buffers sent out by the NPEs */
+	qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0,
+			   "%s:TX-done", dev->dev.name);
+}
+
+static void release_queues(struct port *port)
+{
+	qmgr_release_queue(RXFREE_QUEUE(port));
+	qmgr_release_queue(RX_QUEUE(port));
+	qmgr_release_queue(TX_QUEUE(port));
+	qmgr_release_queue(TXDONE_QUEUE);
+}
+
+static void init_queues(struct port *port)
+{
+	int i;
+
+	memset(port->tx_desc_tab, 0, sizeof(port->tx_desc_tab)); /* descs */
+	memset(port->rx_desc_tab, 0, sizeof(port->rx_desc_tab));
+
+	/* Setup RX buffers */
+	for (i = 0; i < RX_DESCS; i++) {
+		struct desc *desc = &port->rx_desc_tab[i];
+		desc->buf_len = MAX_MRU;
+		desc->data = rx_buff(port, i);
+	}
+}
+
+static int ixp4xx_eth_open(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	struct npe *npe = port->npe;
+	struct msg msg;
+	int i, err;
+
+#if DEBUG_OPEN
+	fprintf(stderr, "%s%d: opening %p\n", dev->dev.name, dev->dev.id, dev);
+#endif
+
+	if (!npe_running(npe)) {
+		err = npe_load_firmware(npe);
+		if (err)
+			return err;
+
+		if (npe_recv_message(npe, &msg, "ETH_GET_STATUS")) {
+			fprintf(stderr, "%s%d: %s not responding\n", dev->dev.name, dev->dev.id, npe->name);
+			return -EIO;
+		}
+		memcpy(port->firmware, msg.params + 2, 4);
+	}
+
+	if (ixp4xx_adjust_link(dev))
+		return -ENOLINK;
+
+	port->buff_tab = xmalloc((RX_DESCS + TX_DESCS) * MAX_MRU);
+
+	memset(&msg, 0, sizeof(msg));
+	msg.cmd = NPE_VLAN_SETRXQOSENTRY;
+	msg.eth_id = LOGICAL_ID(port);
+	msg.params[3] = RX_QUEUE(port) | 0x80;
+	msg.params[4] = RX_QUEUE(port) >> 4; /* MSB of offset */
+	msg.params[5] = RX_QUEUE(port) << 4; /* LSB of offset */
+	for (i = 0; i < 8; i++) {
+		msg.params[1] = i;
+		if (npe_send_recv_message(port->npe, &msg, "ETH_SET_RXQ")) {
+			err = -EIO;
+			goto out;
+		}
+	}
+
+	msg.cmd = NPE_EDB_SETPORTADDRESS;
+	msg.eth_id = PHYSICAL_ID(port);
+	memcpy(msg.params, port->pinfo->hwaddr, ETH_ALEN);
+	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAC")) {
+		err = -EIO;
+		goto out;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.cmd = NPE_FW_SETFIREWALLMODE;
+	msg.eth_id = LOGICAL_ID(port);
+	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE")) {
+		err = -EIO;
+		goto out;
+	}
+
+	request_queues(port, dev);
+	init_queues(port);
+
+	for (i = 0; i < ETH_ALEN; i++)
+		__raw_writel(port->pinfo->hwaddr[i], &port->regs->hw_addr[i]);
+	__raw_writel(0x08, &port->regs->random_seed);
+	__raw_writel(0x12, &port->regs->partial_empty_threshold);
+	__raw_writel(0x30, &port->regs->partial_full_threshold);
+	__raw_writel(0x08, &port->regs->tx_start_bytes);
+	__raw_writel(0x15, &port->regs->tx_deferral);
+	__raw_writel(0x08, &port->regs->tx_2part_deferral[0]);
+	__raw_writel(0x07, &port->regs->tx_2part_deferral[1]);
+	__raw_writel(0x80, &port->regs->slot_time);
+	__raw_writel(0x01, &port->regs->int_clock_threshold);
+
+	/* Populate queues with buffers, no failure after this point */
+	for (i = 0; i < TX_DESCS; i++)
+		queue_put_desc(TXDONE_QUEUE, &port->tx_desc_tab[i]);
+
+	for (i = 0; i < RX_DESCS; i++)
+		queue_put_desc(RXFREE_QUEUE(port), &port->rx_desc_tab[i]);
+
+	__raw_writel(TX_CNTRL1_RETRIES, &port->regs->tx_control[1]);
+	__raw_writel(DEFAULT_TX_CNTRL0, &port->regs->tx_control[0]);
+	__raw_writel(0, &port->regs->rx_control[1]);
+	__raw_writel(DEFAULT_RX_CNTRL0, &port->regs->rx_control[0]);
+
+#if 0
+	qmgr_set_irq(RX_QUEUE(port), QUEUE_IRQ_SRC_NOT_EMPTY,
+		     eth_rx_irq, dev);
+	qmgr_set_irq(TXDONE_QUEUE, QUEUE_IRQ_SRC_NOT_EMPTY,
+		     eth_txdone_irq, NULL);
+	qmgr_enable_irq(TXDONE_QUEUE);
+#endif
+	memset(&msg, 0, sizeof(msg));
+#if DEBUG_OPEN
+	fprintf(stderr, "%s%d opened\n", dev->dev.name, dev->dev.id);
+#endif
+	return 0;
+out:
+	free(port->buff_tab);
+	port->buff_tab = NULL;
+#if DEBUG_OPEN
+	fprintf(stderr, "%s%d open failed (%i)\n", dev->dev.name, dev->dev.id, err);
+#endif
+	return err;
+}
+
+static void ixp4xx_eth_close(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	struct msg msg;
+	int buffs = RX_DESCS; /* allocated RX buffers */
+	int i;
+
+#if DEBUG_CLOSE
+	fprintf(stderr, "%s%d: closing\n", dev->dev.name, dev->dev.id);
+#endif
+#if 0
+	qmgr_disable_irq(RX_QUEUE(port));
+#endif
+
+	if (!port->buff_tab)
+		return; /* already closed */
+
+	while (queue_get_desc(RXFREE_QUEUE(port), port, 0) >= 0)
+		buffs--;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.cmd = NPE_SETLOOPBACK_MODE;
+	msg.eth_id = LOGICAL_ID(port);
+	msg.params[1] = 1;
+	if (npe_send_recv_message(port->npe, &msg, "ETH_ENABLE_LOOPBACK"))
+		fprintf(stderr, "%s%d: unable to enable loopback\n", dev->dev.name, dev->dev.id);
+
+#if DEBUG_CLOSE
+	fprintf(stderr, "%s%d: draining RX queue\n", dev->dev.name, dev->dev.id);
+#endif
+	i = 0;
+	do { /* drain RX buffers */
+		while (queue_get_desc(RX_QUEUE(port), port, 0) >= 0)
+			buffs--;
+		if (!buffs)
+			break;
+		if (qmgr_stat_full(TXDONE_QUEUE) && !(i % 10)) {
+			/* we have to inject some packet */
+			struct desc *desc;
+			int n = queue_get_desc(TXDONE_QUEUE, port, 1);
+			BUG_ON(n < 0);
+			desc = &port->tx_desc_tab[n];
+			desc->buf_len = desc->pkt_len = 1;
+			//wmb();
+			barrier();
+			queue_put_desc(TX_QUEUE(port), desc);
+		}
+		udelay(1);
+	} while (++i < MAX_CLOSE_WAIT);
+
+	if (buffs)
+		fprintf(stderr, "%s%d: unable to drain RX queue, %i buffer(s) left in NPE\n",
+			dev->dev.name, dev->dev.id, buffs);
+#if DEBUG_CLOSE
+	if (!buffs)
+		fprintf(stderr, "%s%d: draining RX queue took %i cycles\n", dev->dev.name, dev->dev.id, i);
+#endif
+
+	buffs = TX_DESCS;
+	while (queue_get_desc(TX_QUEUE(port), port, 1) >= 0)
+		buffs--; /* cancel TX */
+
+	i = 0;
+	do {
+		while (queue_get_desc(TXDONE_QUEUE, port, 1) >= 0)
+			buffs--;
+		if (!buffs)
+			break;
+	} while (++i < MAX_CLOSE_WAIT);
+
+	if (buffs)
+		fprintf(stderr, "%s%d: unable to drain TX queue, %i buffer(s) left in NPE\n",
+			dev->dev.name, dev->dev.id, buffs);
+#if DEBUG_CLOSE
+	if (!buffs)
+		fprintf(stderr, "%s%d: draining TX queues took %i cycles\n", dev->dev.name, dev->dev.id, i);
+#endif
+
+	msg.params[1] = 0;
+	if (npe_send_recv_message(port->npe, &msg, "ETH_DISABLE_LOOPBACK"))
+		fprintf(stderr, "%s%d: unable to disable loopback\n", dev->dev.name, dev->dev.id);
+
+#if 0
+	qmgr_disable_irq(TXDONE_QUEUE);
+#endif
+	release_queues(port);
+	free(port->buff_tab);
+	port->buff_tab = NULL;
+#if DEBUG_CLOSE
+	fprintf(stderr, "%s%d: closed\n", dev->dev.name, dev->dev.id);
+#endif
+}
+
+static int ixp4xx_eth_get_hwaddr(struct eth_device *eth, unsigned char *addr)
+{
+	struct port *port = eth->priv;
+	memcpy(addr, port->pinfo->hwaddr, 6);
+	return 0;
+}
+
+static int ixp4xx_eth_set_hwaddr(struct eth_device *eth, unsigned char *addr)
+{
+	struct port *port = eth->priv;
+	memcpy(port->pinfo->hwaddr, addr, 6);
+	return 0;
+}
+
+static int ixp4xx_eth_init(struct eth_device *eth)
+{
+	struct port *port = eth->priv;
+
+	__raw_writel(DEFAULT_CORE_CNTRL | CORE_RESET,
+		     &port->regs->core_control);
+	udelay(50);
+	__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
+	udelay(50);
+
+	miidev_restart_aneg(&port->miidev);
+	return 0;
+}
+
+static int ixp4xx_eth_probe(struct device_d *dev)
+{
+	struct npe *npe;
+	struct port *port;
+	struct eth_plat_info *pinfo = dev->platform_data;
+
+	if (!pinfo) {
+		fprintf(stderr, "ixp4xx_eth: no platform information\n");
+		return -ENODEV;
+	}
+
+	if (!(npe = npe_request(pinfo->npe))) {
+		fprintf(stderr, "ixp4xx_eth: unable to acquire NPE\n");
+		return -ENODEV;
+	}
+
+	port = memalign(0x20, sizeof(*port));
+	memset(port, 0, sizeof(*port));
+
+	port->regs = pinfo->regs;
+	port->npe = npe;
+	port->pinfo = pinfo;
+	port->eth.dev.id = -1;
+	port->eth.priv = port;
+	port->eth.init = ixp4xx_eth_init;
+	port->eth.open = ixp4xx_eth_open;
+	port->eth.halt = ixp4xx_eth_close;
+	port->eth.send = ixp4xx_eth_xmit;
+	port->eth.recv = ixp4xx_eth_poll;
+	port->eth.get_ethaddr = ixp4xx_eth_get_hwaddr;
+	port->eth.set_ethaddr = ixp4xx_eth_set_hwaddr;
+
+	port->miidev.dev.id = -1;
+	port->miidev.read = ixp4xx_mdio_read;
+	port->miidev.write = ixp4xx_mdio_write;
+	port->miidev.address = pinfo->phy;
+	port->miidev.edev = &port->eth;
+	mii_register(&port->miidev);
+	eth_register(&port->eth);
+	return 0;
+}
+
+static struct driver_d ixp4xx_eth_driver = {
+	.name  = "ixp4xx_eth",
+	.probe = ixp4xx_eth_probe,
+};
+
+static int __init ixp4xx_eth_module_init(void)
+{
+	if (cpu_is_ixp43x()) {
+		/* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
+		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
+			return -ENOSYS;
+		mdio_regs = (struct eth_regs *)IXP4XX_EthC_BASE;
+	} else {
+		/* All MII PHY accesses use NPE-B Ethernet registers */
+		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
+			return -ENOSYS;
+		mdio_regs = (struct eth_regs *)IXP4XX_EthB_BASE;
+	}
+
+	__raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+
+	register_driver(&ixp4xx_eth_driver);
+	return 0;
+}
+
+device_initcall(ixp4xx_eth_module_init);
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 290619f..0f25ceb 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -102,7 +102,11 @@ static void ns16550_serial_init_port(struct console_device *cdev)
 	baud_divisor = ns16550_calc_divisor(cdev, CONFIG_BAUDRATE);
 
 	/* initializing the device for the first time */
+#ifdef CONFIG_ARCH_IXP4XX
+	plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
+#else
 	plat->reg_write(0x00, base, ier);
+#endif
 #ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
 	plat->reg_write(0x07, base, mdr1);	/* Disable */
 #endif
@@ -181,7 +185,11 @@ static int ns16550_setbaudrate(struct console_device *cdev, int baud_rate)
 	    cdev->dev->platform_data;
 	unsigned long base = cdev->dev->map_base;
 	unsigned int baud_divisor = ns16550_calc_divisor(cdev, baud_rate);
+#ifdef CONFIG_ARCH_IXP4XX
+	plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
+#else
 	plat->reg_write(0x00, base, ier);
+#endif
 	plat->reg_write(LCR_BKSE, base, lcr);
 	plat->reg_write(baud_divisor & 0xff, base, dll);
 	plat->reg_write((baud_divisor >> 8) & 0xff, base, dlm);
diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
index eb2fd10..ba20a6f 100644
--- a/drivers/serial/serial_ns16550.h
+++ b/drivers/serial/serial_ns16550.h
@@ -50,6 +50,8 @@
 #define dll		rbr
 #define dlm		ier
 
+#define IER_UUE		0x40	/* UART Unit Enable (XScale) */
+
 #define FCR_FIFO_EN     0x01	/* Fifo enable */
 #define FCR_RXSR        0x02	/* Receiver soft reset */
 #define FCR_TXSR        0x04	/* Transmitter soft reset */


From khc at pm.waw.pl  Mon Dec 20 18:08:03 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:08:03 +0100
Subject: [PATCH 11] Silence few warnings.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3mxo0cab0.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/common/startup.c b/common/startup.c
index e8c0e7a..be70245 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -56,7 +56,7 @@ static void display_meminfo(void)
 	printf("Malloc space: 0x%08lx -> 0x%08lx (size %s)\n",
 		mstart, mend, size_human_readable(msize));
 #ifdef CONFIG_ARM
-	printf("Stack space : 0x%08lx -> 0x%08lx (size %s)\n",
+	printf("Stack space : 0x%08x -> 0x%08x (size %s)\n",
 		STACK_BASE, STACK_BASE + STACK_SIZE,
 		size_human_readable(STACK_SIZE));
 #endif
diff --git a/lib/readline.c b/lib/readline.c
index b90de77..a3e1de9 100644
--- a/lib/readline.c
+++ b/lib/readline.c
@@ -140,7 +140,7 @@ static char* hist_next(void)
 static void cread_add_char(char ichar, int insert, unsigned long *num,
 	       unsigned long *eol_num, char *buf, unsigned long len)
 {
-	unsigned long wlen;
+	unsigned wlen;
 
 	/* room ??? */
 	if (insert || *num == *eol_num) {
@@ -177,7 +177,7 @@ int readline(const char *prompt, char *buf, int len)
 	unsigned long num = 0;
 	unsigned long eol_num = 0;
 	unsigned long rlen;
-	unsigned long wlen;
+	unsigned wlen;
 	int ichar;
 	int insert = 1;
 	int rc = 0;


From khc at pm.waw.pl  Mon Dec 20 18:10:41 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:10:41 +0100
Subject: [PATCH 12] Fix NOR CFI flash driver to work on big endian systems.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3lj3kca6m.fsf@intrepid.localdomain>

Fix NOR CFI flash driver to work on big endian systems.
Basically this transforms the u8/u16/u32/u64 union into
a single u64 value.

Not tested on LE platform. Apply with caution.

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 90307d2..34031b0 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -77,59 +77,40 @@ static uint flash_offset_cfi[2]={FLASH_OFFSET_CFI,FLASH_OFFSET_CFI_ALT};
 
 static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
 {
-#if defined(__LITTLE_ENDIAN)
-	unsigned short	w;
-	unsigned int	l;
-	unsigned long long ll;
-#endif
-
 	if (bankwidth_is_1(info)) {
-		cword->c = c;
-	} else if (bankwidth_is_2(info)) {
-#if defined(__LITTLE_ENDIAN)
-		w = c;
-		w <<= 8;
-		cword->w = (cword->w >> 8) | w;
-#else
-		cword->w = (cword->w << 8) | c;
-#endif
-	} else if (bankwidth_is_4(info)) {
-#if defined(__LITTLE_ENDIAN)
-		l = c;
-		l <<= 24;
-		cword->l = (cword->l >> 8) | l;
-#else
-		cword->l = (cword->l << 8) | c;
-#endif
-	} else if (bankwidth_is_8(info)) {
-#if defined(__LITTLE_ENDIAN)
-		ll = c;
-		ll <<= 56;
-		cword->ll = (cword->ll >> 8) | ll;
+		*cword = c;
+		return;
+	}
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+	*cword = (*cword << 8) | c;
 #else
-		cword->ll = (cword->ll << 8) | c;
+
+	if (bankwidth_is_2(info))
+		*cword = (*cword >> 8) | (u16)c << 8;
+	else if (bankwidth_is_4(info))
+		*cword = (*cword >> 8) | (u32)c << 24;
+	else if (bankwidth_is_8(info))
+		*cword = (*cword >> 8) | (u64)c << 56;
 #endif
-	}
 }
 
 static int flash_write_cfiword (struct flash_info *info, ulong dest,
 				cfiword_t cword)
 {
-	void *dstaddr;
+	void *dstaddr = (void *)dest;
 	int flag;
 
-	dstaddr = (uchar *) dest;
-
 	/* Check if Flash is (sufficiently) erased */
-	if (bankwidth_is_1(info)) {
-		flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
-	} else if (bankwidth_is_2(info)) {
-		flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
-	} else if (bankwidth_is_4(info)) {
-		flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
-	} else if (bankwidth_is_8(info)) {
-		flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
-	} else
+	if (bankwidth_is_1(info))
+		flag = ((flash_read8(dstaddr) & cword) == cword);
+	else if (bankwidth_is_2(info))
+		flag = ((flash_read16(dstaddr) & cword) == cword);
+	else if (bankwidth_is_4(info))
+		flag = ((flash_read32(dstaddr) & cword) == cword);
+	else if (bankwidth_is_8(info))
+		flag = ((flash_read64(dstaddr) & cword) == cword);
+	else
 		return 2;
 
 	if (!flag)
@@ -185,10 +166,8 @@ static void flash_printqry (struct cfi_qry *qry)
  */
 uchar flash_read_uchar (struct flash_info *info, uint offset)
 {
-	uchar *cp;
-
-	cp = flash_make_addr (info, 0, offset);
-#if defined(__LITTLE_ENDIAN)
+	uchar *cp = flash_make_addr(info, 0, offset);
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	return flash_read8(cp);
 #else
 	return flash_read8(cp + info->portwidth - 1);
@@ -216,7 +195,7 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
 		debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
 	}
 #endif
-#if defined(__LITTLE_ENDIAN)
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	retval = ((flash_read8(addr) << 16) |
 		  (flash_read8(addr + info->portwidth) << 24) |
 		  (flash_read8(addr + 2 * info->portwidth)) |
@@ -534,7 +513,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 
 	/* handle unaligned start */
 	if ((aln = addr - wp) != 0) {
-		cword.l = 0;
+		cword = 0;
 		p = (uchar*)wp;
 		for (i = 0; i < aln; ++i)
 			flash_add_byte (info, &cword, flash_read8(p + i));
@@ -560,7 +539,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 	while (cnt >= info->portwidth) {
 		/* prohibit buffer write when buffer_size is 1 */
 		if (info->buffer_size == 1) {
-			cword.l = 0;
+			cword = 0;
 			for (i = 0; i < info->portwidth; i++)
 				flash_add_byte (info, &cword, *src++);
 			if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
@@ -583,7 +562,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 	}
 #else
 	while (cnt >= info->portwidth) {
-		cword.l = 0;
+		cword = 0;
 		for (i = 0; i < info->portwidth; i++) {
 			flash_add_byte (info, &cword, *src++);
 		}
@@ -600,7 +579,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 	/*
 	 * handle unaligned tail bytes
 	 */
-	cword.l = 0;
+	cword = 0;
 	p = (uchar*)wp;
 	for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
 		flash_add_byte (info, &cword, *src++);
@@ -672,7 +651,7 @@ static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, unsig
         struct flash_info *finfo = (struct flash_info *)cdev->priv;
         int ret;
 
-	debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf, cdev->dev->map_base + offset, count);
+	debug("cfi_write: buf=0x%p addr=0x%08lx count=0x%08x\n",buf, cdev->dev->map_base + offset, count);
 
         ret = write_buff (finfo, buf, cdev->dev->map_base + offset, count);
         return ret == 0 ? count : -1;
@@ -836,17 +815,14 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
 /*
  * make a proper sized command based on the port and chip widths
  */
-void flash_make_cmd (struct flash_info *info, uchar cmd, void *cmdbuf)
+void flash_make_cmd(struct flash_info *info, u8 cmd, cfiword_t *cmdbuf)
 {
-	int i;
-	uchar *cp = (uchar *) cmdbuf;
+	cfiword_t result = 0;
+	int i = info->portwidth / info->chipwidth;
 
-#if defined(__LITTLE_ENDIAN)
-	for (i = info->portwidth; i > 0; i--)
-#else
-	for (i = 1; i <= info->portwidth; i++)
-#endif
-		*cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
+	while (i--)
+		result = (result << (8 * info->chipwidth)) | cmd;
+	*cmdbuf = result;
 }
 
 /*
@@ -860,6 +836,7 @@ void flash_write_cmd (struct flash_info *info, flash_sect_t sect, uint offset, u
 
 	addr = flash_make_addr (info, sect, offset);
 	flash_make_cmd (info, cmd, &cword);
+	debug("%s: %p %lX %X => %p %llX\n", __FUNCTION__, info, sect, offset, addr, cword);
 	flash_write_word(info, cword, addr);
 }
 
@@ -874,14 +851,14 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
 
 	debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
 	if (bankwidth_is_1(info)) {
-		debug ("is= %x %x\n", flash_read8(addr), cword.c);
-		retval = (flash_read8(addr) == cword.c);
+		debug ("is= %x %x\n", flash_read8(addr), (u8)cword);
+		retval = (flash_read8(addr) == cword);
 	} else if (bankwidth_is_2(info)) {
-		debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
-		retval = (flash_read16(addr) == cword.w);
+		debug ("is= %4.4x %4.4x\n", flash_read16(addr), (u16)cword);
+		retval = (flash_read16(addr) == cword);
 	} else if (bankwidth_is_4(info)) {
-		debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), cword.l);
-		retval = (flash_read32(addr) == cword.l);
+		debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), (u32)cword);
+		retval = (flash_read32(addr) == cword);
 	} else if (bankwidth_is_8(info)) {
 #ifdef DEBUG
 		{
@@ -889,11 +866,11 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
 			char str2[20];
 
 			print_longlong (str1, flash_read32(addr));
-			print_longlong (str2, cword.ll);
+			print_longlong (str2, cword);
 			debug ("is= %s %s\n", str1, str2);
 		}
 #endif
-		retval = (flash_read32(addr) == cword.ll);
+		retval = (flash_read64(addr) == cword);
 	} else
 		retval = 0;
 
@@ -902,20 +879,19 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
 
 int flash_isset (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd)
 {
-	void *addr;
+	void *addr = flash_make_addr (info, sect, offset);
 	cfiword_t cword;
 	int retval;
 
-	addr = flash_make_addr (info, sect, offset);
 	flash_make_cmd (info, cmd, &cword);
 	if (bankwidth_is_1(info)) {
-		retval = ((flash_read8(addr) & cword.c) == cword.c);
+		retval = ((flash_read8(addr) & cword) == cword);
 	} else if (bankwidth_is_2(info)) {
-		retval = ((flash_read16(addr) & cword.w) == cword.w);
+		retval = ((flash_read16(addr) & cword) == cword);
 	} else if (bankwidth_is_4(info)) {
-		retval = ((flash_read32(addr) & cword.l) == cword.l);
+		retval = ((flash_read32(addr) & cword) == cword);
 	} else if (bankwidth_is_8(info)) {
-		retval = ((flash_read64(addr) & cword.ll) == cword.ll);
+		retval = ((flash_read64(addr) & cword) == cword);
 	} else
 		retval = 0;
 
@@ -1001,6 +977,7 @@ static int cfi_probe (struct device_d *dev)
 
 	/* Init: no FLASHes known */
 	info->flash_id = FLASH_UNKNOWN;
+	info->cmd_reset = FLASH_CMD_RESET;
 	info->size = flash_get_size(info, dev->map_base);
 	info->base = (void __iomem *)dev->map_base;
 
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index f9023dc..9098021 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -25,10 +25,12 @@
  */
 
 #include <driver.h>
+#include <asm/byteorder.h>
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 
 typedef unsigned long flash_sect_t;
+typedef u64 cfiword_t;
 struct cfi_cmd_set;
 
 /*-----------------------------------------------------------------------
@@ -238,7 +240,7 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
 			       uint64_t tout, char *prompt);
 
 int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd);
-void flash_make_cmd (struct flash_info *info, uchar cmd, void *cmdbuf);
+void flash_make_cmd(struct flash_info *info, uchar cmd, cfiword_t *cmdbuf);
 
 static inline void flash_write8(u8 value, void *addr)
 {
@@ -316,26 +318,19 @@ u32 jedec_read_mfr(struct flash_info *info);
 #define bankwidth_is_8(info) 0
 #endif
 
-typedef union {
-	unsigned char c;
-	unsigned short w;
-	unsigned long l;
-	unsigned long long ll;
-} cfiword_t;
-
 static inline void flash_write_word(struct flash_info *info, cfiword_t datum, void *addr)
 {
 	if (bankwidth_is_1(info)) {
-		debug("fw addr %p val %02x\n", addr, datum.c);
-		flash_write8(datum.c, addr);
+		debug("fw addr %p val %02x\n", addr, (u8)datum);
+		flash_write8(datum, addr);
 	} else if (bankwidth_is_2(info)) {
-		debug("fw addr %p val %04x\n", addr, datum.w);
-		flash_write16(datum.w, addr);
+		debug("fw addr %p val %04x\n", addr, (u16)datum);
+		flash_write16(datum, addr);
 	} else if (bankwidth_is_4(info)) {
-		debug("fw addr %p val %08x\n", addr, datum.l);
-		flash_write32(datum.l, addr);
+		debug("fw addr %p val %08x\n", addr, (u32)datum);
+		flash_write32(datum, addr);
 	} else if (bankwidth_is_8(info)) {
-		flash_write64(datum.ll, addr);
+		flash_write64(datum, addr);
 	}
 }
 


From khc at pm.waw.pl  Mon Dec 20 18:14:12 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Tue, 21 Dec 2010 00:14:12 +0100
Subject: [PATCH 13] Fix usage of __LITTLE_ENDIAN macro.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
Message-ID: <m3k4j4ca0r.fsf@intrepid.localdomain>

Fix usage of __LITTLE_ENDIAN macro.
Both __LITTLE_ENDIAN and __BIG_ENDIAN are always defined by
include/linux/byteorder/generic.h, checking for their existence is
pointless.

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/include/cramfs/cramfs_fs.h b/include/cramfs/cramfs_fs.h
index 5bf72c3..3d3c56f 100644
--- a/include/cramfs/cramfs_fs.h
+++ b/include/cramfs/cramfs_fs.h
@@ -88,7 +88,7 @@ struct cramfs_super {
 #error "No byte order defined in __BYTE_ORDER"
 #endif
 
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 #define CRAMFS_16(x)	(x)
 #define CRAMFS_24(x)	(x)
 #define CRAMFS_32(x)	(x)
@@ -96,7 +96,7 @@ struct cramfs_super {
 #define CRAMFS_GET_OFFSET(x)	((x)->offset)
 #define CRAMFS_SET_OFFSET(x,y)	((x)->offset = (y))
 #define CRAMFS_SET_NAMELEN(x,y) ((x)->namelen = (y))
-#elif defined __BIG_ENDIAN
+#elif __BYTE_ORDER ==__BIG_ENDIAN
 #ifdef __KERNEL__
 #define CRAMFS_16(x)	swab16(x)
 #define CRAMFS_24(x)	((swab32(x)) >> 8)
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 790d64d..1b936ec 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -267,7 +267,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 		((x_ & 0xFF000000UL) >> 24)); \
 	})
 
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 # define swap_16(x) (x)
 # define swap_32(x) (x)
 #else


From s.hauer at pengutronix.de  Tue Dec 21 02:41:55 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Dec 2010 08:41:55 +0100
Subject: [PATCH 6] ARM: support big/little endian switching in "bootz".
In-Reply-To: <m3tyi8carg.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3tyi8carg.fsf@intrepid.localdomain>
Message-ID: <20101221074155.GU6017@pengutronix.de>

Hi Krzysztof,

On Mon, Dec 20, 2010 at 11:58:11PM +0100, Krzysztof Halasa wrote:
> ARM: support big/little endian switching in "bootz".
> Perhaps one should make this conditional? Mostly for big-endian
> Barebox loading little-endian (e.g. armel Debian) Linux.

Making it conditional could require a lot of ifdefs, maybe you could
just do...

> 
> Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
> 
> diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
> index f826da6..4d1c757 100644
> --- a/arch/arm/lib/armlinux.c
> +++ b/arch/arm/lib/armlinux.c
> @@ -41,6 +41,7 @@
>  #include <asm/setup.h>
>  #include <asm/barebox-arm.h>
>  #include <asm/armlinux.h>
> +#include <asm/system.h>
>  
>  static struct tag *params;
>  static int armlinux_architecture = 0;
> @@ -85,9 +86,10 @@ static void setup_memory_tags(void)
>  	}
>  }
>  
> -static void setup_commandline_tag(const char *commandline)
> +static void setup_commandline_tag(const char *commandline, int swap)
>  {
>  	const char *p;
> +	size_t words;
>  
>  	if (!commandline)
>  		return;
> @@ -102,12 +104,18 @@ static void setup_commandline_tag(const char *commandline)
>  	if (*p == '\0')
>  		return;
>  
> +	words = (strlen(p) + 1 /* NUL */ + 3 /* round up */) >> 2;
>  	params->hdr.tag = ATAG_CMDLINE;
> -	params->hdr.size =
> -	    (sizeof (struct tag_header) + strlen(p) + 1 + 4) >> 2;
> +	params->hdr.size = (sizeof(struct tag_header) >> 2) + words;
>  
>  	strcpy(params->u.cmdline.cmdline, p);
>  
> +	if (swap) {
> +		u32 *cmd = (u32 *)params->u.cmdline.cmdline;
> +		while (words--)
> +			cmd[words] = swab32(cmd[words]);
> +	}
> +
>  	params = tag_next(params);
>  }
>  
> @@ -156,13 +164,13 @@ static void setup_end_tag (void)
>  	params->hdr.size = 0;
>  }
>  
> -static void setup_tags(struct image_data *data)
> +static void setup_tags(struct image_data *data, int swap)
>  {
>  	const char *commandline = getenv("bootargs");
>  
>  	setup_start_tag();
>  	setup_memory_tags();
> -	setup_commandline_tag(commandline);
> +	setup_commandline_tag(commandline, swap);
>  
>  	if (data && data->initrd)
>  		setup_initrd_tag (&data->initrd->header);
> @@ -231,7 +239,7 @@ static int do_bootm_linux(struct image_data *data)
>  	debug("## Transferring control to Linux (at address 0x%p) ...\n",
>  	       theKernel);
>  
> -	setup_tags(data);
> +	setup_tags(data, 0);
>  
>  	if (relocate_image(data->os, (void *)image_get_load(os_header)))
>  		return -1;
> @@ -290,18 +298,21 @@ late_initcall(armlinux_register_image_handler);
>  
>  #ifdef CONFIG_CMD_BOOTZ
>  struct zimage_header {
> -	u32	unsused[9];
> +	u32	unused[9];
>  	u32	magic;
>  	u32	start;
>  	u32	end;
>  };
>  
> +#define ZIMAGE_MAGIC 0x016F2818
> +
>  static int do_bootz(struct command *cmdtp, int argc, char *argv[])
>  {
>  	void (*theKernel)(int zero, int arch, void *params);
> -	int fd, ret;
> +	int fd, ret, swap = 0;
>  	struct zimage_header header;
>  	void *zimage;
> +	u32 end;

#ifdef CONFIG_BOOTZ_ENDIANESS_SWAP
	int enable_swap = 1;
#else
	int enable_swap = 0;
#endif

>  
>  	if (argc != 2) {
>  		barebox_cmd_usage(cmdtp);
> @@ -320,27 +331,51 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
>  		goto err_out;
>  	}
>  
> -	if (header.magic != 0x016f2818) {
> +	switch (header.magic) {
> +	case swab32(ZIMAGE_MAGIC):
> +		swap = 1;

		swap = enable_swap;

This should be enough for the compiler to throw away most overhead.

> +		/* fall through */
> +	case ZIMAGE_MAGIC:
> +		break;
> +	default:
>  		printf("invalid magic 0x%08x\n", header.magic);
>  		goto err_out;
>  	}
>  
> -	zimage = xmalloc(header.end);
> +	end = header.end;
> +
> +	if (swap)
> +		end = swab32(end);
> +
> +	zimage = xmalloc(end);
>  	memcpy(zimage, &header, sizeof(header));
>  
> -	ret = read(fd, zimage + sizeof(header), header.end - sizeof(header));
> -	if (ret < header.end - sizeof(header)) {
> +	ret = read(fd, zimage + sizeof(header), end - sizeof(header));
> +	if (ret < end - sizeof(header)) {
>  		printf("could not read %s\n", argv[1]);
>  		goto err_out1;
>  	}
>  
> +	if (swap) {
> +		void *ptr;
> +		for (ptr = zimage; ptr < zimage + end; ptr += 4)
> +			*(u32 *)ptr = swab32(*(u32 *)ptr);
> +	}
> +
>  	theKernel = zimage;
>  
> -	printf("loaded zImage from %s with size %d\n", argv[1], header.end);
> +	printf("loaded zImage from %s with size %d\n", argv[1], end);
>  
> -	setup_tags(NULL);
> +	setup_tags(NULL, swap);
>  
>  	shutdown_barebox();
> +	if (swap) {
> +		u32 reg;
> +		__asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));
> +		reg ^= CR_B; /* swap big-endian flag */
> +		__asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
> +	}
> +
>  	theKernel(0, armlinux_architecture, armlinux_bootparams);
>  
>  	return 0;
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Tue Dec 21 03:35:40 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Dec 2010 09:35:40 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <m3oc8gcae3.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
Message-ID: <20101221083540.GV6017@pengutronix.de>

Hi Krzysztof,

Nice series! I haven't got much to add.

On Tue, Dec 21, 2010 at 12:06:12AM +0100, Krzysztof Halasa wrote:
> +
> +	devfs_add_partition("nor0", BAREBOX_START, BAREBOX_LENGTH,
> +			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "barebox");
> +	devfs_add_partition("nor0", NPE_A_START, NPE_A_LENGTH,
> +			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-A");
> +	devfs_add_partition("nor0", NPE_B_START, NPE_B_LENGTH,
> +			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-B");
> +	devfs_add_partition("nor0", NPE_C_START, NPE_C_LENGTH,
> +			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-C");
> +	devfs_add_partition("nor0", NPE_ENV0_START, NPE_ENV0_LENGTH,
> +			    DEVFS_PARTITION_FIXED, "env0");

These partitions are not on eraseblock boundaries, so I assume you use
some script to combine barebox and firmware into a single image. Can we
integrate this into the make system or at least add some instructions
how to generate this image?

> +
> +#ifdef CONFIG_USE_IRQ
> +
> +static void (*irq_handlers[HALF_QUEUES])(void *pdev);
> +static void *irq_pdevs[HALF_QUEUES];
> +
> +#undef fls
> +static inline int fls(int x)
> +{
> +	int ret;
> +	asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
> +	ret = 32 - ret;
> +	return ret;
> +}

fls is defined in a similar way in arch/arm/include/asm/bitops.h:

#define fls(x) \
	(__builtin_constant_p(x) ? constant_fls(x) : \
	({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }))

Or am I missing something?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Tue Dec 21 03:58:53 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Dec 2010 09:58:53 +0100
Subject: [PATCH 5] Fix error handling with malloc, memalign etc.
	Memalign() can't fail now.
In-Reply-To: <m3vd2ocax2.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3vd2ocax2.fsf@intrepid.localdomain>
Message-ID: <20101221085853.GW6017@pengutronix.de>

On Mon, Dec 20, 2010 at 11:54:49PM +0100, Krzysztof Halasa wrote:
> Fix error handling with malloc, memalign etc. Memalign() can't fail now.
> 
> The idea is to panic() when there is no memory available for normal
> operation. Exception: code which can consume arbitrary amount of RAM
> (example: files allocated in ramfs) must report error instead of
> panic().
> 
> This patch also fixes code which didn't check for NULL from malloc()
> etc.
> 
> Usage: malloc() returns NULL when out of RAM.
> xmalloc(), memalign() always return non-NULL or panic().
> 
> Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
> 
> diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
> index 287be0d..8409ca8 100644
> --- a/arch/sandbox/os/common.c
> +++ b/arch/sandbox/os/common.c
> @@ -223,10 +223,7 @@ static int add_image(char *str, char *name)
>  	struct stat s;
>  	char *opt;
>  	int fd, ret;
> -	struct hf_platform_data *hf = malloc(sizeof(struct hf_platform_data));
> -
> -	if (!hf)
> -		return -1;
> +	struct hf_platform_data *hf = xmalloc(sizeof(struct hf_platform_data));
>  
>  	file = strtok(str, ",");
>  	while ((opt = strtok(NULL, ","))) {
> @@ -285,11 +282,7 @@ int main(int argc, char *argv[])
>  	char str[6];
>  	int fdno = 0, envno = 0;
>  
> -	ram = malloc(malloc_size);
> -	if (!ram) {
> -		printf("unable to get malloc space\n");
> -		exit(1);
> -	}
> +	ram = xmalloc(malloc_size);
>  	mem_malloc_init(ram, ram + malloc_size);
>  
>  	while (1) {

Don't change these. This is the file which connects barebox to the host
on sandbox. This is not the barebox malloc but the glibc malloc which is
called here.

> --- a/common/dlmalloc.c
> +++ b/common/dlmalloc.c
> @@ -1,9 +1,9 @@
> -
> +#include <common.h>
>  #include <config.h>
>  #include <malloc.h>
>  #include <string.h>
>  #include <mem_malloc.h>
> -
> +#include <xfuncs.h>
>  #include <stdio.h>
>  #include <module.h>
>  
> @@ -1696,12 +1696,12 @@ void *memalign(size_t alignment, size_t bytes)
>  	long remainder_size;	/* its size */
>  
>  	if ((long) bytes < 0)
> -		return NULL;
> +		panic("memalign: requested %i bytes\n", bytes);
>  
>  	/* If need less alignment than we give anyway, just relay to malloc */
>  
>  	if (alignment <= MALLOC_ALIGNMENT)
> -		return malloc(bytes);
> +		return xmalloc(bytes);
>  
>  	/* Otherwise, ensure that it is at least a minimum chunk size */
>  
> @@ -1711,10 +1711,7 @@ void *memalign(size_t alignment, size_t bytes)
>  	/* Call malloc with worst case padding to hit alignment. */
>  
>  	nb = request2size(bytes);
> -	m = (char*)(malloc (nb + alignment + MINSIZE));
> -
> -	if (!m)
> -		return NULL;	/* propagate failure */
> +	m = (char*)(xmalloc(nb + alignment + MINSIZE));
>  
>  	p = mem2chunk(m);
>  

I think we shouldn't touch memalign but introduce a xmemalign function
instead. The x in the name stresses that the return value doesn't have
to be checked. Also it gives the user a chance explicitely call memalign
if he wishes to.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Tue Dec 21 04:17:15 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Dec 2010 10:17:15 +0100
Subject: my IXP4xx-related and other patches
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
Message-ID: <20101221091715.GX6017@pengutronix.de>

Hi Krzysztof,

On Mon, Dec 20, 2010 at 11:30:03PM +0100, Krzysztof Halasa wrote:
> Hello,
> 
> I've been working a bit on IXP4xx support lately and it seems I'm at the
> point I can now boot Barebox on a Goramo Multilink routers
> (IXP425-based). It requires several patches (will post them shortly) and
> NPE microcode files from Intel (or from elsewhere, the regular non-VLAN
> microcode v. 2.4 is needed, i.e., same as with Linux).

Nice ;)

I applied all patches except the malloc patch and the ixp4xx core patch
which need minor fixups.

> 
> The binary microcode must be appended to Barebox at correct offsets for
> the NPE driver to find it, details are in board support file
> (arch/arm/boards/multilink/multilink.c):
> 
> #define BAREBOX_START        0x00000
> #define BAREBOX_LENGTH       0x34000
> #define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
> #define NPE_A_LENGTH         0x05000
> #define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
> #define NPE_B_LENGTH         0x03000
> #define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
> #define NPE_C_LENGTH         0x04000
> #define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
> #define NPE_ENV0_LENGTH      0x20000
> 
> when passed to Linux:
> Creating XXX MTD partitions on "IXP4XX-Flash.0":
> 0x000000000000-0x000000034000 : "barebox"
> 0x000000034000-0x000000039000 : "NPE-A"
> 0x000000039000-0x00000003c000 : "NPE-B"
> 0x00000003c000-0x000000040000 : "NPE-C"
> 0x000000040000-0x000000060000 : "env0"

As said in the comment to patch, we need to at least document this.

> 
> User-available flash area starts at 0x60000.
> 
> All this IXP4xx code is big-endian only. Too much work with LE (NPE
> coprocessors would need buffer byte swapping, flash (EXP bus) would need
> 16-bit word swapping etc). Big-endian Barebox can load both LE and BE
> Linux anyway ("bootz" only at the moment).

Yes, big endian is enough for now. It's good to have a big endian ARM
machine in the tree.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From khc at pm.waw.pl  Mon Dec 20 17:40:44 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Mon, 20 Dec 2010 23:40:44 +0100
Subject: [PATCH 1] Delete unused file common/dlmalloc.src.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
Message-ID: <m31v5cdq4z.fsf@intrepid.localdomain>

Delete unused file common/dlmalloc.src.
Or is there any reason to have it here?

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/common/dlmalloc.src b/common/dlmalloc.src
deleted file mode 100644
index 32a38bc..0000000
--- a/common/dlmalloc.src
+++ /dev/null
@@ -1,3265 +0,0 @@
-/* ---------- To make a malloc.h, start cutting here ------------ */
-
-/*
-  A version of malloc/free/realloc written by Doug Lea and released to the
-  public domain.  Send questions/comments/complaints/performance data
-  to dl at cs.oswego.edu
-
-* VERSION 2.6.6  Sun Mar  5 19:10:03 2000  Doug Lea  (dl at gee)
-
-   Note: There may be an updated version of this malloc obtainable at
-	   ftp://g.oswego.edu/pub/misc/malloc.c
-	 Check before installing!
-
-* Why use this malloc?
-
-  This is not the fastest, most space-conserving, most portable, or
-  most tunable malloc ever written. However it is among the fastest
-  while also being among the most space-conserving, portable and tunable.
-  Consistent balance across these factors results in a good general-purpose
-  allocator. For a high-level description, see
-     http://g.oswego.edu/dl/html/malloc.html
-
-* Synopsis of public routines
-
-  (Much fuller descriptions are contained in the program documentation below.)
-
-  malloc(size_t n);
-     Return a pointer to a newly allocated chunk of at least n bytes, or null
-     if no space is available.
-  free(Void_t* p);
-     Release the chunk of memory pointed to by p, or no effect if p is null.
-  realloc(Void_t* p, size_t n);
-     Return a pointer to a chunk of size n that contains the same data
-     as does chunk p up to the minimum of (n, p's size) bytes, or null
-     if no space is available. The returned pointer may or may not be
-     the same as p. If p is null, equivalent to malloc.  Unless the
-     #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
-     size argument of zero (re)allocates a minimum-sized chunk.
-  memalign(size_t alignment, size_t n);
-     Return a pointer to a newly allocated chunk of n bytes, aligned
-     in accord with the alignment argument, which must be a power of
-     two.
-  valloc(size_t n);
-     Equivalent to memalign(pagesize, n), where pagesize is the page
-     size of the system (or as near to this as can be figured out from
-     all the includes/defines below.)
-  pvalloc(size_t n);
-     Equivalent to valloc(minimum-page-that-holds(n)), that is,
-     round up n to nearest pagesize.
-  calloc(size_t unit, size_t quantity);
-     Returns a pointer to quantity * unit bytes, with all locations
-     set to zero.
-  cfree(Void_t* p);
-     Equivalent to free(p).
-  malloc_trim(size_t pad);
-     Release all but pad bytes of freed top-most memory back
-     to the system. Return 1 if successful, else 0.
-  malloc_usable_size(Void_t* p);
-     Report the number usable allocated bytes associated with allocated
-     chunk p. This may or may not report more bytes than were requested,
-     due to alignment and minimum size constraints.
-  malloc_stats();
-     Prints brief summary statistics on stderr.
-  mallinfo()
-     Returns (by copy) a struct containing various summary statistics.
-  mallopt(int parameter_number, int parameter_value)
-     Changes one of the tunable parameters described below. Returns
-     1 if successful in changing the parameter, else 0.
-
-* Vital statistics:
-
-  Alignment:                            8-byte
-       8 byte alignment is currently hardwired into the design.  This
-       seems to suffice for all current machines and C compilers.
-
-  Assumed pointer representation:       4 or 8 bytes
-       Code for 8-byte pointers is untested by me but has worked
-       reliably by Wolfram Gloger, who contributed most of the
-       changes supporting this.
-
-  Assumed size_t  representation:       4 or 8 bytes
-       Note that size_t is allowed to be 4 bytes even if pointers are 8.
-
-  Minimum overhead per allocated chunk: 4 or 8 bytes
-       Each malloced chunk has a hidden overhead of 4 bytes holding size
-       and status information.
-
-  Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
-			  8-byte ptrs:  24/32 bytes (including, 4/8 overhead)
-
-       When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
-       ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
-       needed; 4 (8) for a trailing size field
-       and 8 (16) bytes for free list pointers. Thus, the minimum
-       allocatable size is 16/24/32 bytes.
-
-       Even a request for zero bytes (i.e., malloc(0)) returns a
-       pointer to something of the minimum allocatable size.
-
-  Maximum allocated size: 4-byte size_t: 2^31 -  8 bytes
-			  8-byte size_t: 2^63 - 16 bytes
-
-       It is assumed that (possibly signed) size_t bit values suffice to
-       represent chunk sizes. `Possibly signed' is due to the fact
-       that `size_t' may be defined on a system as either a signed or
-       an unsigned type. To be conservative, values that would appear
-       as negative numbers are avoided.
-       Requests for sizes with a negative sign bit when the request
-       size is treaded as a long will return null.
-
-  Maximum overhead wastage per allocated chunk: normally 15 bytes
-
-       Alignnment demands, plus the minimum allocatable size restriction
-       make the normal worst-case wastage 15 bytes (i.e., up to 15
-       more bytes will be allocated than were requested in malloc), with
-       two exceptions:
-	 1. Because requests for zero bytes allocate non-zero space,
-	    the worst case wastage for a request of zero bytes is 24 bytes.
-	 2. For requests >= mmap_threshold that are serviced via
-	    mmap(), the worst case wastage is 8 bytes plus the remainder
-	    from a system page (the minimal mmap unit); typically 4096 bytes.
-
-* Limitations
-
-    Here are some features that are NOT currently supported
-
-    * No user-definable hooks for callbacks and the like.
-    * No automated mechanism for fully checking that all accesses
-      to malloced memory stay within their bounds.
-    * No support for compaction.
-
-* Synopsis of compile-time options:
-
-    People have reported using previous versions of this malloc on all
-    versions of Unix, sometimes by tweaking some of the defines
-    below. It has been tested most extensively on Solaris and
-    Linux. It is also reported to work on WIN32 platforms.
-    People have also reported adapting this malloc for use in
-    stand-alone embedded systems.
-
-    The implementation is in straight, hand-tuned ANSI C.  Among other
-    consequences, it uses a lot of macros.  Because of this, to be at
-    all usable, this code should be compiled using an optimizing compiler
-    (for example gcc -O2) that can simplify expressions and control
-    paths.
-
-  __STD_C                  (default: derived from C compiler defines)
-     Nonzero if using ANSI-standard C compiler, a C++ compiler, or
-     a C compiler sufficiently close to ANSI to get away with it.
-  DEBUG                    (default: NOT defined)
-     Define to enable debugging. Adds fairly extensive assertion-based
-     checking to help track down memory errors, but noticeably slows down
-     execution.
-  REALLOC_ZERO_BYTES_FREES (default: NOT defined)
-     Define this if you think that realloc(p, 0) should be equivalent
-     to free(p). Otherwise, since malloc returns a unique pointer for
-     malloc(0), so does realloc(p, 0).
-  HAVE_MEMCPY               (default: defined)
-     Define if you are not otherwise using ANSI STD C, but still
-     have memcpy and memset in your C library and want to use them.
-     Otherwise, simple internal versions are supplied.
-  USE_MEMCPY               (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
-     Define as 1 if you want the C library versions of memset and
-     memcpy called in realloc and calloc (otherwise macro versions are used).
-     At least on some platforms, the simple macro versions usually
-     outperform libc versions.
-  HAVE_MMAP                 (default: defined as 1)
-     Define to non-zero to optionally make malloc() use mmap() to
-     allocate very large blocks.
-  HAVE_MREMAP                 (default: defined as 0 unless Linux libc set)
-     Define to non-zero to optionally make realloc() use mremap() to
-     reallocate very large blocks.
-  malloc_getpagesize        (default: derived from system #includes)
-     Either a constant or routine call returning the system page size.
-  HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
-     Optionally define if you are on a system with a /usr/include/malloc.h
-     that declares struct mallinfo. It is not at all necessary to
-     define this even if you do, but will ensure consistency.
-  INTERNAL_SIZE_T           (default: size_t)
-     Define to a 32-bit type (probably `unsigned int') if you are on a
-     64-bit machine, yet do not want or need to allow malloc requests of
-     greater than 2^31 to be handled. This saves space, especially for
-     very small chunks.
-  INTERNAL_LINUX_C_LIB      (default: NOT defined)
-     Defined only when compiled as part of Linux libc.
-     Also note that there is some odd internal name-mangling via defines
-     (for example, internally, `malloc' is named `mALLOc') needed
-     when compiling in this case. These look funny but don't otherwise
-     affect anything.
-  WIN32                     (default: undefined)
-     Define this on MS win (95, nt) platforms to compile in sbrk emulation.
-  LACKS_UNISTD_H            (default: undefined if not WIN32)
-     Define this if your system does not have a <unistd.h>.
-  LACKS_SYS_PARAM_H         (default: undefined if not WIN32)
-     Define this if your system does not have a <sys/param.h>.
-  MORECORE                  (default: sbrk)
-     The name of the routine to call to obtain more memory from the system.
-  MORECORE_FAILURE          (default: -1)
-     The value returned upon failure of MORECORE.
-  MORECORE_CLEARS           (default 1)
-     True (1) if the routine mapped to MORECORE zeroes out memory (which
-     holds for sbrk).
-  DEFAULT_TRIM_THRESHOLD
-  DEFAULT_TOP_PAD
-  DEFAULT_MMAP_THRESHOLD
-  DEFAULT_MMAP_MAX
-     Default values of tunable parameters (described in detail below)
-     controlling interaction with host system routines (sbrk, mmap, etc).
-     These values may also be changed dynamically via mallopt(). The
-     preset defaults are those that give best performance for typical
-     programs/systems.
-  USE_DL_PREFIX             (default: undefined)
-     Prefix all public routines with the string 'dl'.  Useful to
-     quickly avoid procedure declaration conflicts and linker symbol
-     conflicts with existing memory allocation routines.
-
-
-*/
-
-
-
-
-/* Preliminaries */
-
-#ifndef __STD_C
-#ifdef __STDC__
-#define __STD_C     1
-#else
-#if __cplusplus
-#define __STD_C     1
-#else
-#define __STD_C     0
-#endif /*__cplusplus*/
-#endif /*__STDC__*/
-#endif /*__STD_C*/
-
-#ifndef Void_t
-#if (__STD_C || defined(WIN32))
-#define Void_t      void
-#else
-#define Void_t      char
-#endif
-#endif /*Void_t*/
-
-#if __STD_C
-#include <stddef.h>   /* for size_t */
-#else
-#include <sys/types.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>    /* needed for malloc_stats */
-
-
-/*
-  Compile-time options
-*/
-
-
-/*
-    Debugging:
-
-    Because freed chunks may be overwritten with link fields, this
-    malloc will often die when freed memory is overwritten by user
-    programs.  This can be very effective (albeit in an annoying way)
-    in helping track down dangling pointers.
-
-    If you compile with -DDEBUG, a number of assertion checks are
-    enabled that will catch more memory errors. You probably won't be
-    able to make much sense of the actual assertion errors, but they
-    should help you locate incorrectly overwritten memory.  The
-    checking is fairly extensive, and will slow down execution
-    noticeably. Calling malloc_stats or mallinfo with DEBUG set will
-    attempt to check every non-mmapped allocated and free chunk in the
-    course of computing the summmaries. (By nature, mmapped regions
-    cannot be checked very much automatically.)
-
-    Setting DEBUG may also be helpful if you are trying to modify
-    this code. The assertions in the check routines spell out in more
-    detail the assumptions and invariants underlying the algorithms.
-
-*/
-
-#if DEBUG
-#include <assert.h>
-#else
-#define assert(x) ((void)0)
-#endif
-
-
-/*
-  INTERNAL_SIZE_T is the word-size used for internal bookkeeping
-  of chunk sizes. On a 64-bit machine, you can reduce malloc
-  overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
-  at the expense of not being able to handle requests greater than
-  2^31. This limitation is hardly ever a concern; you are encouraged
-  to set this. However, the default version is the same as size_t.
-*/
-
-#ifndef INTERNAL_SIZE_T
-#define INTERNAL_SIZE_T size_t
-#endif
-
-/*
-  REALLOC_ZERO_BYTES_FREES should be set if a call to
-  realloc with zero bytes should be the same as a call to free.
-  Some people think it should. Otherwise, since this malloc
-  returns a unique pointer for malloc(0), so does realloc(p, 0).
-*/
-
-
-/*   #define REALLOC_ZERO_BYTES_FREES */
-
-
-/*
-  WIN32 causes an emulation of sbrk to be compiled in
-  mmap-based options are not currently supported in WIN32.
-*/
-
-/* #define WIN32 */
-#ifdef WIN32
-#define MORECORE wsbrk
-#define HAVE_MMAP 0
-
-#define LACKS_UNISTD_H
-#define LACKS_SYS_PARAM_H
-
-/*
-  Include 'windows.h' to get the necessary declarations for the
-  Microsoft Visual C++ data structures and routines used in the 'sbrk'
-  emulation.
-
-  Define WIN32_LEAN_AND_MEAN so that only the essential Microsoft
-  Visual C++ header files are included.
-*/
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-
-/*
-  HAVE_MEMCPY should be defined if you are not otherwise using
-  ANSI STD C, but still have memcpy and memset in your C library
-  and want to use them in calloc and realloc. Otherwise simple
-  macro versions are defined here.
-
-  USE_MEMCPY should be defined as 1 if you actually want to
-  have memset and memcpy called. People report that the macro
-  versions are often enough faster than libc versions on many
-  systems that it is better to use them.
-
-*/
-
-#define HAVE_MEMCPY
-
-#ifndef USE_MEMCPY
-#ifdef HAVE_MEMCPY
-#define USE_MEMCPY 1
-#else
-#define USE_MEMCPY 0
-#endif
-#endif
-
-#if (__STD_C || defined(HAVE_MEMCPY))
-
-#if __STD_C
-void* memset(void*, int, size_t);
-void* memcpy(void*, const void*, size_t);
-#else
-#ifdef WIN32
-/* On Win32 platforms, 'memset()' and 'memcpy()' are already declared in */
-/* 'windows.h' */
-#else
-Void_t* memset();
-Void_t* memcpy();
-#endif
-#endif
-#endif
-
-#if USE_MEMCPY
-
-/* The following macros are only invoked with (2n+1)-multiples of
-   INTERNAL_SIZE_T units, with a positive integer n. This is exploited
-   for fast inline execution when n is small. */
-
-#define MALLOC_ZERO(charp, nbytes)                                            \
-do {                                                                          \
-  INTERNAL_SIZE_T mzsz = (nbytes);                                            \
-  if(mzsz <= 9*sizeof(mzsz)) {                                                \
-    INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp);                         \
-    if(mzsz >= 5*sizeof(mzsz)) {     *mz++ = 0;                               \
-				     *mz++ = 0;                               \
-      if(mzsz >= 7*sizeof(mzsz)) {   *mz++ = 0;                               \
-				     *mz++ = 0;                               \
-	if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0;                               \
-				     *mz++ = 0; }}}                           \
-				     *mz++ = 0;                               \
-				     *mz++ = 0;                               \
-				     *mz   = 0;                               \
-  } else memset((charp), 0, mzsz);                                            \
-} while(0)
-
-#define MALLOC_COPY(dest,src,nbytes)                                          \
-do {                                                                          \
-  INTERNAL_SIZE_T mcsz = (nbytes);                                            \
-  if(mcsz <= 9*sizeof(mcsz)) {                                                \
-    INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src);                        \
-    INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest);                       \
-    if(mcsz >= 5*sizeof(mcsz)) {     *mcdst++ = *mcsrc++;                     \
-				     *mcdst++ = *mcsrc++;                     \
-      if(mcsz >= 7*sizeof(mcsz)) {   *mcdst++ = *mcsrc++;                     \
-				     *mcdst++ = *mcsrc++;                     \
-	if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++;                     \
-				     *mcdst++ = *mcsrc++; }}}                 \
-				     *mcdst++ = *mcsrc++;                     \
-				     *mcdst++ = *mcsrc++;                     \
-				     *mcdst   = *mcsrc  ;                     \
-  } else memcpy(dest, src, mcsz);                                             \
-} while(0)
-
-#else /* !USE_MEMCPY */
-
-/* Use Duff's device for good zeroing/copying performance. */
-
-#define MALLOC_ZERO(charp, nbytes)                                            \
-do {                                                                          \
-  INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp);                           \
-  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
-  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
-  switch (mctmp) {                                                            \
-    case 0: for(;;) { *mzp++ = 0;                                             \
-    case 7:           *mzp++ = 0;                                             \
-    case 6:           *mzp++ = 0;                                             \
-    case 5:           *mzp++ = 0;                                             \
-    case 4:           *mzp++ = 0;                                             \
-    case 3:           *mzp++ = 0;                                             \
-    case 2:           *mzp++ = 0;                                             \
-    case 1:           *mzp++ = 0; if(mcn <= 0) break; mcn--; }                \
-  }                                                                           \
-} while(0)
-
-#define MALLOC_COPY(dest,src,nbytes)                                          \
-do {                                                                          \
-  INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src;                            \
-  INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest;                           \
-  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
-  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
-  switch (mctmp) {                                                            \
-    case 0: for(;;) { *mcdst++ = *mcsrc++;                                    \
-    case 7:           *mcdst++ = *mcsrc++;                                    \
-    case 6:           *mcdst++ = *mcsrc++;                                    \
-    case 5:           *mcdst++ = *mcsrc++;                                    \
-    case 4:           *mcdst++ = *mcsrc++;                                    \
-    case 3:           *mcdst++ = *mcsrc++;                                    \
-    case 2:           *mcdst++ = *mcsrc++;                                    \
-    case 1:           *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; }       \
-  }                                                                           \
-} while(0)
-
-#endif
-
-
-/*
-  Define HAVE_MMAP to optionally make malloc() use mmap() to
-  allocate very large blocks.  These will be returned to the
-  operating system immediately after a free().
-*/
-
-#ifndef HAVE_MMAP
-#define HAVE_MMAP 1
-#endif
-
-/*
-  Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
-  large blocks.  This is currently only possible on Linux with
-  kernel versions newer than 1.3.77.
-*/
-
-#ifndef HAVE_MREMAP
-#ifdef INTERNAL_LINUX_C_LIB
-#define HAVE_MREMAP 1
-#else
-#define HAVE_MREMAP 0
-#endif
-#endif
-
-#if HAVE_MMAP
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#endif /* HAVE_MMAP */
-
-/*
-  Access to system page size. To the extent possible, this malloc
-  manages memory from the system in page-size units.
-
-  The following mechanics for getpagesize were adapted from
-  bsd/gnu getpagesize.h
-*/
-
-#ifndef LACKS_UNISTD_H
-#  include <unistd.h>
-#endif
-
-#ifndef malloc_getpagesize
-#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
-#    ifndef _SC_PAGE_SIZE
-#      define _SC_PAGE_SIZE _SC_PAGESIZE
-#    endif
-#  endif
-#  ifdef _SC_PAGE_SIZE
-#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
-#  else
-#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
-       extern size_t getpagesize();
-#      define malloc_getpagesize getpagesize()
-#    else
-#      ifdef WIN32
-#        define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */
-#      else
-#        ifndef LACKS_SYS_PARAM_H
-#          include <sys/param.h>
-#        endif
-#        ifdef EXEC_PAGESIZE
-#          define malloc_getpagesize EXEC_PAGESIZE
-#        else
-#          ifdef NBPG
-#            ifndef CLSIZE
-#              define malloc_getpagesize NBPG
-#            else
-#              define malloc_getpagesize (NBPG * CLSIZE)
-#            endif
-#          else
-#            ifdef NBPC
-#              define malloc_getpagesize NBPC
-#            else
-#              ifdef PAGESIZE
-#                define malloc_getpagesize PAGESIZE
-#              else
-#                define malloc_getpagesize (4096) /* just guess */
-#              endif
-#            endif
-#          endif
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-
-/*
-
-  This version of malloc supports the standard SVID/XPG mallinfo
-  routine that returns a struct containing the same kind of
-  information you can get from malloc_stats. It should work on
-  any SVID/XPG compliant system that has a /usr/include/malloc.h
-  defining struct mallinfo. (If you'd like to install such a thing
-  yourself, cut out the preliminary declarations as described above
-  and below and save them in a malloc.h file. But there's no
-  compelling reason to bother to do this.)
-
-  The main declaration needed is the mallinfo struct that is returned
-  (by-copy) by mallinfo().  The SVID/XPG malloinfo struct contains a
-  bunch of fields, most of which are not even meaningful in this
-  version of malloc. Some of these fields are are instead filled by
-  mallinfo() with other numbers that might possibly be of interest.
-
-  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
-  /usr/include/malloc.h file that includes a declaration of struct
-  mallinfo.  If so, it is included; else an SVID2/XPG2 compliant
-  version is declared below.  These must be precisely the same for
-  mallinfo() to work.
-
-*/
-
-/* #define HAVE_USR_INCLUDE_MALLOC_H */
-
-#if HAVE_USR_INCLUDE_MALLOC_H
-#include "/usr/include/malloc.h"
-#else
-
-/* SVID2/XPG mallinfo structure */
-
-struct mallinfo {
-  int arena;    /* total space allocated from system */
-  int ordblks;  /* number of non-inuse chunks */
-  int smblks;   /* unused -- always zero */
-  int hblks;    /* number of mmapped regions */
-  int hblkhd;   /* total space in mmapped regions */
-  int usmblks;  /* unused -- always zero */
-  int fsmblks;  /* unused -- always zero */
-  int uordblks; /* total allocated space */
-  int fordblks; /* total non-inuse space */
-  int keepcost; /* top-most, releasable (via malloc_trim) space */
-};
-
-/* SVID2/XPG mallopt options */
-
-#define M_MXFAST  1    /* UNUSED in this malloc */
-#define M_NLBLKS  2    /* UNUSED in this malloc */
-#define M_GRAIN   3    /* UNUSED in this malloc */
-#define M_KEEP    4    /* UNUSED in this malloc */
-
-#endif
-
-/* mallopt options that actually do something */
-
-#define M_TRIM_THRESHOLD    -1
-#define M_TOP_PAD           -2
-#define M_MMAP_THRESHOLD    -3
-#define M_MMAP_MAX          -4
-
-
-#ifndef DEFAULT_TRIM_THRESHOLD
-#define DEFAULT_TRIM_THRESHOLD (128 * 1024)
-#endif
-
-/*
-    M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
-      to keep before releasing via malloc_trim in free().
-
-      Automatic trimming is mainly useful in long-lived programs.
-      Because trimming via sbrk can be slow on some systems, and can
-      sometimes be wasteful (in cases where programs immediately
-      afterward allocate more large chunks) the value should be high
-      enough so that your overall system performance would improve by
-      releasing.
-
-      The trim threshold and the mmap control parameters (see below)
-      can be traded off with one another. Trimming and mmapping are
-      two different ways of releasing unused memory back to the
-      system. Between these two, it is often possible to keep
-      system-level demands of a long-lived program down to a bare
-      minimum. For example, in one test suite of sessions measuring
-      the XF86 X server on Linux, using a trim threshold of 128K and a
-      mmap threshold of 192K led to near-minimal long term resource
-      consumption.
-
-      If you are using this malloc in a long-lived program, it should
-      pay to experiment with these values.  As a rough guide, you
-      might set to a value close to the average size of a process
-      (program) running on your system.  Releasing this much memory
-      would allow such a process to run in memory.  Generally, it's
-      worth it to tune for trimming rather tham memory mapping when a
-      program undergoes phases where several large chunks are
-      allocated and released in ways that can reuse each other's
-      storage, perhaps mixed with phases where there are no such
-      chunks at all.  And in well-behaved long-lived programs,
-      controlling release of large blocks via trimming versus mapping
-      is usually faster.
-
-      However, in most programs, these parameters serve mainly as
-      protection against the system-level effects of carrying around
-      massive amounts of unneeded memory. Since frequent calls to
-      sbrk, mmap, and munmap otherwise degrade performance, the default
-      parameters are set to relatively high values that serve only as
-      safeguards.
-
-      The default trim value is high enough to cause trimming only in
-      fairly extreme (by current memory consumption standards) cases.
-      It must be greater than page size to have any useful effect.  To
-      disable trimming completely, you can set to (unsigned long)(-1);
-
-
-*/
-
-
-#ifndef DEFAULT_TOP_PAD
-#define DEFAULT_TOP_PAD        (0)
-#endif
-
-/*
-    M_TOP_PAD is the amount of extra `padding' space to allocate or
-      retain whenever sbrk is called. It is used in two ways internally:
-
-      * When sbrk is called to extend the top of the arena to satisfy
-	a new malloc request, this much padding is added to the sbrk
-	request.
-
-      * When malloc_trim is called automatically from free(),
-	it is used as the `pad' argument.
-
-      In both cases, the actual amount of padding is rounded
-      so that the end of the arena is always a system page boundary.
-
-      The main reason for using padding is to avoid calling sbrk so
-      often. Having even a small pad greatly reduces the likelihood
-      that nearly every malloc request during program start-up (or
-      after trimming) will invoke sbrk, which needlessly wastes
-      time.
-
-      Automatic rounding-up to page-size units is normally sufficient
-      to avoid measurable overhead, so the default is 0.  However, in
-      systems where sbrk is relatively slow, it can pay to increase
-      this value, at the expense of carrying around more memory than
-      the program needs.
-
-*/
-
-
-#ifndef DEFAULT_MMAP_THRESHOLD
-#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
-#endif
-
-/*
-
-    M_MMAP_THRESHOLD is the request size threshold for using mmap()
-      to service a request. Requests of at least this size that cannot
-      be allocated using already-existing space will be serviced via mmap.
-      (If enough normal freed space already exists it is used instead.)
-
-      Using mmap segregates relatively large chunks of memory so that
-      they can be individually obtained and released from the host
-      system. A request serviced through mmap is never reused by any
-      other request (at least not directly; the system may just so
-      happen to remap successive requests to the same locations).
-
-      Segregating space in this way has the benefit that mmapped space
-      can ALWAYS be individually released back to the system, which
-      helps keep the system level memory demands of a long-lived
-      program low. Mapped memory can never become `locked' between
-      other chunks, as can happen with normally allocated chunks, which
-      menas that even trimming via malloc_trim would not release them.
-
-      However, it has the disadvantages that:
-
-	 1. The space cannot be reclaimed, consolidated, and then
-	    used to service later requests, as happens with normal chunks.
-	 2. It can lead to more wastage because of mmap page alignment
-	    requirements
-	 3. It causes malloc performance to be more dependent on host
-	    system memory management support routines which may vary in
-	    implementation quality and may impose arbitrary
-	    limitations. Generally, servicing a request via normal
-	    malloc steps is faster than going through a system's mmap.
-
-      All together, these considerations should lead you to use mmap
-      only for relatively large requests.
-
-
-*/
-
-
-#ifndef DEFAULT_MMAP_MAX
-#if HAVE_MMAP
-#define DEFAULT_MMAP_MAX       (64)
-#else
-#define DEFAULT_MMAP_MAX       (0)
-#endif
-#endif
-
-/*
-    M_MMAP_MAX is the maximum number of requests to simultaneously
-      service using mmap. This parameter exists because:
-
-	 1. Some systems have a limited number of internal tables for
-	    use by mmap.
-	 2. In most systems, overreliance on mmap can degrade overall
-	    performance.
-	 3. If a program allocates many large regions, it is probably
-	    better off using normal sbrk-based allocation routines that
-	    can reclaim and reallocate normal heap memory. Using a
-	    small value allows transition into this mode after the
-	    first few allocations.
-
-      Setting to 0 disables all use of mmap.  If HAVE_MMAP is not set,
-      the default value is 0, and attempts to set it to non-zero values
-      in mallopt will fail.
-*/
-
-
-/*
-    USE_DL_PREFIX will prefix all public routines with the string 'dl'.
-      Useful to quickly avoid procedure declaration conflicts and linker
-      symbol conflicts with existing memory allocation routines.
-
-*/
-
-/* #define USE_DL_PREFIX */
-
-
-/*
-
-  Special defines for linux libc
-
-  Except when compiled using these special defines for Linux libc
-  using weak aliases, this malloc is NOT designed to work in
-  multithreaded applications.  No semaphores or other concurrency
-  control are provided to ensure that multiple malloc or free calls
-  don't run at the same time, which could be disasterous. A single
-  semaphore could be used across malloc, realloc, and free (which is
-  essentially the effect of the linux weak alias approach). It would
-  be hard to obtain finer granularity.
-
-*/
-
-
-#ifdef INTERNAL_LINUX_C_LIB
-
-#if __STD_C
-
-Void_t * __default_morecore_init (ptrdiff_t);
-Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
-
-#else
-
-Void_t * __default_morecore_init ();
-Void_t *(*__morecore)() = __default_morecore_init;
-
-#endif
-
-#define MORECORE (*__morecore)
-#define MORECORE_FAILURE 0
-#define MORECORE_CLEARS 1
-
-#else /* INTERNAL_LINUX_C_LIB */
-
-#if __STD_C
-extern Void_t*     sbrk(ptrdiff_t);
-#else
-extern Void_t*     sbrk();
-#endif
-
-#ifndef MORECORE
-#define MORECORE sbrk
-#endif
-
-#ifndef MORECORE_FAILURE
-#define MORECORE_FAILURE -1
-#endif
-
-#ifndef MORECORE_CLEARS
-#define MORECORE_CLEARS 1
-#endif
-
-#endif /* INTERNAL_LINUX_C_LIB */
-
-#if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
-
-#define cALLOc		__libc_calloc
-#define fREe		__libc_free
-#define mALLOc		__libc_malloc
-#define mEMALIGn	__libc_memalign
-#define rEALLOc		__libc_realloc
-#define vALLOc		__libc_valloc
-#define pvALLOc		__libc_pvalloc
-#define mALLINFo	__libc_mallinfo
-#define mALLOPt		__libc_mallopt
-
-#pragma weak calloc = __libc_calloc
-#pragma weak free = __libc_free
-#pragma weak cfree = __libc_free
-#pragma weak malloc = __libc_malloc
-#pragma weak memalign = __libc_memalign
-#pragma weak realloc = __libc_realloc
-#pragma weak valloc = __libc_valloc
-#pragma weak pvalloc = __libc_pvalloc
-#pragma weak mallinfo = __libc_mallinfo
-#pragma weak mallopt = __libc_mallopt
-
-#else
-
-#ifdef USE_DL_PREFIX
-#define cALLOc		dlcalloc
-#define fREe		dlfree
-#define mALLOc		dlmalloc
-#define mEMALIGn	dlmemalign
-#define rEALLOc		dlrealloc
-#define vALLOc		dlvalloc
-#define pvALLOc		dlpvalloc
-#define mALLINFo	dlmallinfo
-#define mALLOPt		dlmallopt
-#else /* USE_DL_PREFIX */
-#define cALLOc		calloc
-#define fREe		free
-#define mALLOc		malloc
-#define mEMALIGn	memalign
-#define rEALLOc		realloc
-#define vALLOc		valloc
-#define pvALLOc		pvalloc
-#define mALLINFo	mallinfo
-#define mALLOPt		mallopt
-#endif /* USE_DL_PREFIX */
-
-#endif
-
-/* Public routines */
-
-#if __STD_C
-
-Void_t* mALLOc(size_t);
-void    fREe(Void_t*);
-Void_t* rEALLOc(Void_t*, size_t);
-Void_t* mEMALIGn(size_t, size_t);
-Void_t* vALLOc(size_t);
-Void_t* pvALLOc(size_t);
-Void_t* cALLOc(size_t, size_t);
-void    cfree(Void_t*);
-int     malloc_trim(size_t);
-size_t  malloc_usable_size(Void_t*);
-void    malloc_stats();
-int     mALLOPt(int, int);
-struct mallinfo mALLINFo(void);
-#else
-Void_t* mALLOc();
-void    fREe();
-Void_t* rEALLOc();
-Void_t* mEMALIGn();
-Void_t* vALLOc();
-Void_t* pvALLOc();
-Void_t* cALLOc();
-void    cfree();
-int     malloc_trim();
-size_t  malloc_usable_size();
-void    malloc_stats();
-int     mALLOPt();
-struct mallinfo mALLINFo();
-#endif
-
-
-#ifdef __cplusplus
-};  /* end of extern "C" */
-#endif
-
-/* ---------- To make a malloc.h, end cutting here ------------ */
-
-
-/*
-  Emulation of sbrk for WIN32
-  All code within the ifdef WIN32 is untested by me.
-
-  Thanks to Martin Fong and others for supplying this.
-*/
-
-
-#ifdef WIN32
-
-#define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
-~(malloc_getpagesize-1))
-#define AlignPage64K(add) (((add) + (0x10000 - 1)) & ~(0x10000 - 1))
-
-/* resrve 64MB to insure large contiguous space */
-#define RESERVED_SIZE (1024*1024*64)
-#define NEXT_SIZE (2048*1024)
-#define TOP_MEMORY ((unsigned long)2*1024*1024*1024)
-
-struct GmListElement;
-typedef struct GmListElement GmListElement;
-
-struct GmListElement
-{
-	GmListElement* next;
-	void* base;
-};
-
-static GmListElement* head = 0;
-static unsigned int gNextAddress = 0;
-static unsigned int gAddressBase = 0;
-static unsigned int gAllocatedSize = 0;
-
-static
-GmListElement* makeGmListElement (void* bas)
-{
-	GmListElement* this;
-	this = (GmListElement*)(void*)LocalAlloc (0, sizeof (GmListElement));
-	assert (this);
-	if (this)
-	{
-		this->base = bas;
-		this->next = head;
-		head = this;
-	}
-	return this;
-}
-
-void gcleanup ()
-{
-	BOOL rval;
-	assert ( (head == NULL) || (head->base == (void*)gAddressBase));
-	if (gAddressBase && (gNextAddress - gAddressBase))
-	{
-		rval = VirtualFree ((void*)gAddressBase,
-							gNextAddress - gAddressBase,
-							MEM_DECOMMIT);
-	assert (rval);
-	}
-	while (head)
-	{
-		GmListElement* next = head->next;
-		rval = VirtualFree (head->base, 0, MEM_RELEASE);
-		assert (rval);
-		LocalFree (head);
-		head = next;
-	}
-}
-
-static
-void* findRegion (void* start_address, unsigned long size)
-{
-	MEMORY_BASIC_INFORMATION info;
-	if (size >= TOP_MEMORY) return NULL;
-
-	while ((unsigned long)start_address + size < TOP_MEMORY)
-	{
-		VirtualQuery (start_address, &info, sizeof (info));
-		if ((info.State == MEM_FREE) && (info.RegionSize >= size))
-			return start_address;
-		else
-		{
-			/* Requested region is not available so see if the */
-			/* next region is available.  Set 'start_address' */
-			/* to the next region and call 'VirtualQuery()' */
-			/* again. */
-
-			start_address = (char*)info.BaseAddress + info.RegionSize;
-
-			/* Make sure we start looking for the next region */
-			/* on the *next* 64K boundary.  Otherwise, even if */
-			/* the new region is free according to */
-			/* 'VirtualQuery()', the subsequent call to */
-			/* 'VirtualAlloc()' (which follows the call to */
-			/* this routine in 'wsbrk()') will round *down* */
-			/* the requested address to a 64K boundary which */
-			/* we already know is an address in the */
-			/* unavailable region.  Thus, the subsequent call */
-			/* to 'VirtualAlloc()' will fail and bring us back */
-			/* here, causing us to go into an infinite loop. */
-
-			start_address =
-				(void *) AlignPage64K((unsigned long) start_address);
-		}
-	}
-	return NULL;
-
-}
-
-
-void* wsbrk (long size)
-{
-	void* tmp;
-	if (size > 0)
-	{
-		if (gAddressBase == 0)
-		{
-			gAllocatedSize = max (RESERVED_SIZE, AlignPage (size));
-			gNextAddress = gAddressBase =
-				(unsigned int)VirtualAlloc (NULL, gAllocatedSize,
-											MEM_RESERVE, PAGE_NOACCESS);
-		} else if (AlignPage (gNextAddress + size) > (gAddressBase +
-gAllocatedSize))
-		{
-			long new_size = max (NEXT_SIZE, AlignPage (size));
-			void* new_address = (void*)(gAddressBase+gAllocatedSize);
-			do
-			{
-				new_address = findRegion (new_address, new_size);
-
-				if (new_address == 0)
-					return (void*)-1;
-
-				gAddressBase = gNextAddress =
-					(unsigned int)VirtualAlloc (new_address, new_size,
-												MEM_RESERVE, PAGE_NOACCESS);
-				/* repeat in case of race condition */
-				/* The region that we found has been snagged */
-				/* by another thread */
-			}
-			while (gAddressBase == 0);
-
-			assert (new_address == (void*)gAddressBase);
-
-			gAllocatedSize = new_size;
-
-			if (!makeGmListElement ((void*)gAddressBase))
-				return (void*)-1;
-		}
-		if ((size + gNextAddress) > AlignPage (gNextAddress))
-		{
-			void* res;
-			res = VirtualAlloc ((void*)AlignPage (gNextAddress),
-								(size + gNextAddress -
-								 AlignPage (gNextAddress)),
-								MEM_COMMIT, PAGE_READWRITE);
-			if (res == 0)
-				return (void*)-1;
-		}
-		tmp = (void*)gNextAddress;
-		gNextAddress = (unsigned int)tmp + size;
-		return tmp;
-	}
-	else if (size < 0)
-	{
-		unsigned int alignedGoal = AlignPage (gNextAddress + size);
-		/* Trim by releasing the virtual memory */
-		if (alignedGoal >= gAddressBase)
-		{
-			VirtualFree ((void*)alignedGoal, gNextAddress - alignedGoal,
-						 MEM_DECOMMIT);
-			gNextAddress = gNextAddress + size;
-			return (void*)gNextAddress;
-		}
-		else
-		{
-			VirtualFree ((void*)gAddressBase, gNextAddress - gAddressBase,
-						 MEM_DECOMMIT);
-			gNextAddress = gAddressBase;
-			return (void*)-1;
-		}
-	}
-	else
-	{
-		return (void*)gNextAddress;
-	}
-}
-
-#endif
-
-
-
-/*
-  Type declarations
-*/
-
-
-struct malloc_chunk
-{
-  INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
-  INTERNAL_SIZE_T size;      /* Size in bytes, including overhead. */
-  struct malloc_chunk* fd;   /* double links -- used only if free. */
-  struct malloc_chunk* bk;
-};
-
-typedef struct malloc_chunk* mchunkptr;
-
-/*
-
-   malloc_chunk details:
-
-    (The following includes lightly edited explanations by Colin Plumb.)
-
-    Chunks of memory are maintained using a `boundary tag' method as
-    described in e.g., Knuth or Standish.  (See the paper by Paul
-    Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
-    survey of such techniques.)  Sizes of free chunks are stored both
-    in the front of each chunk and at the end.  This makes
-    consolidating fragmented chunks into bigger chunks very fast.  The
-    size fields also hold bits representing whether chunks are free or
-    in use.
-
-    An allocated chunk looks like this:
-
-
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Size of previous chunk, if allocated            | |
-	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Size of chunk, in bytes                         |P|
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             User data starts here...                          .
-	    .                                                               .
-	    .             (malloc_usable_space() bytes)                     .
-	    .                                                               |
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Size of chunk                                     |
-	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-
-    Where "chunk" is the front of the chunk for the purpose of most of
-    the malloc code, but "mem" is the pointer that is returned to the
-    user.  "Nextchunk" is the beginning of the next contiguous chunk.
-
-    Chunks always begin on even word boundries, so the mem portion
-    (which is returned to the user) is also on an even word boundary, and
-    thus double-word aligned.
-
-    Free chunks are stored in circular doubly-linked lists, and look like this:
-
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Size of previous chunk                            |
-	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `head:' |             Size of chunk, in bytes                         |P|
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Forward pointer to next chunk in list             |
-	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Back pointer to previous chunk in list            |
-	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	    |             Unused space (may be 0 bytes long)                .
-	    .                                                               .
-	    .                                                               |
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `foot:' |             Size of chunk, in bytes                           |
-	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-    The P (PREV_INUSE) bit, stored in the unused low-order bit of the
-    chunk size (which is always a multiple of two words), is an in-use
-    bit for the *previous* chunk.  If that bit is *clear*, then the
-    word before the current chunk size contains the previous chunk
-    size, and can be used to find the front of the previous chunk.
-    (The very first chunk allocated always has this bit set,
-    preventing access to non-existent (or non-owned) memory.)
-
-    Note that the `foot' of the current chunk is actually represented
-    as the prev_size of the NEXT chunk. (This makes it easier to
-    deal with alignments etc).
-
-    The two exceptions to all this are
-
-     1. The special chunk `top', which doesn't bother using the
-	trailing size field since there is no
-	next contiguous chunk that would have to index off it. (After
-	initialization, `top' is forced to always exist.  If it would
-	become less than MINSIZE bytes long, it is replenished via
-	malloc_extend_top.)
-
-     2. Chunks allocated via mmap, which have the second-lowest-order
-	bit (IS_MMAPPED) set in their size fields.  Because they are
-	never merged or traversed from any other chunk, they have no
-	foot size or inuse information.
-
-    Available chunks are kept in any of several places (all declared below):
-
-    * `av': An array of chunks serving as bin headers for consolidated
-       chunks. Each bin is doubly linked.  The bins are approximately
-       proportionally (log) spaced.  There are a lot of these bins
-       (128). This may look excessive, but works very well in
-       practice.  All procedures maintain the invariant that no
-       consolidated chunk physically borders another one. Chunks in
-       bins are kept in size order, with ties going to the
-       approximately least recently used chunk.
-
-       The chunks in each bin are maintained in decreasing sorted order by
-       size.  This is irrelevant for the small bins, which all contain
-       the same-sized chunks, but facilitates best-fit allocation for
-       larger chunks. (These lists are just sequential. Keeping them in
-       order almost never requires enough traversal to warrant using
-       fancier ordered data structures.)  Chunks of the same size are
-       linked with the most recently freed at the front, and allocations
-       are taken from the back.  This results in LRU or FIFO allocation
-       order, which tends to give each chunk an equal opportunity to be
-       consolidated with adjacent freed chunks, resulting in larger free
-       chunks and less fragmentation.
-
-    * `top': The top-most available chunk (i.e., the one bordering the
-       end of available memory) is treated specially. It is never
-       included in any bin, is used only if no other chunk is
-       available, and is released back to the system if it is very
-       large (see M_TRIM_THRESHOLD).
-
-    * `last_remainder': A bin holding only the remainder of the
-       most recently split (non-top) chunk. This bin is checked
-       before other non-fitting chunks, so as to provide better
-       locality for runs of sequentially allocated chunks.
-
-    *  Implicitly, through the host system's memory mapping tables.
-       If supported, requests greater than a threshold are usually
-       serviced via calls to mmap, and then later released via munmap.
-
-*/
-
-
-
-
-
-/*  sizes, alignments */
-
-#define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))
-#define MALLOC_ALIGNMENT       (SIZE_SZ + SIZE_SZ)
-#define MALLOC_ALIGN_MASK      (MALLOC_ALIGNMENT - 1)
-#define MINSIZE                (sizeof(struct malloc_chunk))
-
-/* conversion from malloc headers to user pointers, and back */
-
-#define chunk2mem(p)   ((Void_t*)((char*)(p) + 2*SIZE_SZ))
-#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
-
-/* pad request bytes into a usable size */
-
-#define request2size(req) \
- (((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
-  (long)(MINSIZE + MALLOC_ALIGN_MASK)) ? MINSIZE : \
-   (((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
-
-/* Check if m has acceptable alignment */
-
-#define aligned_OK(m)    (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
-
-
-
-
-/*
-  Physical chunk operations
-*/
-
-
-/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
-
-#define PREV_INUSE 0x1
-
-/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
-
-#define IS_MMAPPED 0x2
-
-/* Bits to mask off when extracting size */
-
-#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
-
-
-/* Ptr to next physical malloc_chunk. */
-
-#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
-
-/* Ptr to previous physical malloc_chunk */
-
-#define prev_chunk(p)\
-   ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
-
-
-/* Treat space at ptr + offset as a chunk */
-
-#define chunk_at_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
-
-
-
-
-/*
-  Dealing with use bits
-*/
-
-/* extract p's inuse bit */
-
-#define inuse(p)\
-((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
-
-/* extract inuse bit of previous chunk */
-
-#define prev_inuse(p)  ((p)->size & PREV_INUSE)
-
-/* check for mmap()'ed chunk */
-
-#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
-
-/* set/clear chunk as in use without otherwise disturbing */
-
-#define set_inuse(p)\
-((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
-
-#define clear_inuse(p)\
-((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
-
-/* check/set/clear inuse bits in known places */
-
-#define inuse_bit_at_offset(p, s)\
- (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
-
-#define set_inuse_bit_at_offset(p, s)\
- (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
-
-#define clear_inuse_bit_at_offset(p, s)\
- (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
-
-
-
-
-/*
-  Dealing with size fields
-*/
-
-/* Get size, ignoring use bits */
-
-#define chunksize(p)          ((p)->size & ~(SIZE_BITS))
-
-/* Set size at head, without disturbing its use bit */
-
-#define set_head_size(p, s)   ((p)->size = (((p)->size & PREV_INUSE) | (s)))
-
-/* Set size/use ignoring previous bits in header */
-
-#define set_head(p, s)        ((p)->size = (s))
-
-/* Set size at footer (only when chunk is not in use) */
-
-#define set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
-
-
-
-
-
-/*
-   Bins
-
-    The bins, `av_' are an array of pairs of pointers serving as the
-    heads of (initially empty) doubly-linked lists of chunks, laid out
-    in a way so that each pair can be treated as if it were in a
-    malloc_chunk. (This way, the fd/bk offsets for linking bin heads
-    and chunks are the same).
-
-    Bins for sizes < 512 bytes contain chunks of all the same size, spaced
-    8 bytes apart. Larger bins are approximately logarithmically
-    spaced. (See the table below.) The `av_' array is never mentioned
-    directly in the code, but instead via bin access macros.
-
-    Bin layout:
-
-    64 bins of size       8
-    32 bins of size      64
-    16 bins of size     512
-     8 bins of size    4096
-     4 bins of size   32768
-     2 bins of size  262144
-     1 bin  of size what's left
-
-    There is actually a little bit of slop in the numbers in bin_index
-    for the sake of speed. This makes no difference elsewhere.
-
-    The special chunks `top' and `last_remainder' get their own bins,
-    (this is implemented via yet more trickery with the av_ array),
-    although `top' is never properly linked to its bin since it is
-    always handled specially.
-
-*/
-
-#define NAV             128   /* number of bins */
-
-typedef struct malloc_chunk* mbinptr;
-
-/* access macros */
-
-#define bin_at(i)      ((mbinptr)((char*)&(av_[2*(i) + 2]) - 2*SIZE_SZ))
-#define next_bin(b)    ((mbinptr)((char*)(b) + 2 * sizeof(mbinptr)))
-#define prev_bin(b)    ((mbinptr)((char*)(b) - 2 * sizeof(mbinptr)))
-
-/*
-   The first 2 bins are never indexed. The corresponding av_ cells are instead
-   used for bookkeeping. This is not to save space, but to simplify
-   indexing, maintain locality, and avoid some initialization tests.
-*/
-
-#define top            (bin_at(0)->fd)   /* The topmost chunk */
-#define last_remainder (bin_at(1))       /* remainder from last split */
-
-
-/*
-   Because top initially points to its own bin with initial
-   zero size, thus forcing extension on the first malloc request,
-   we avoid having any special code in malloc to check whether
-   it even exists yet. But we still need to in malloc_extend_top.
-*/
-
-#define initial_top    ((mchunkptr)(bin_at(0)))
-
-/* Helper macro to initialize bins */
-
-#define IAV(i)  bin_at(i), bin_at(i)
-
-static mbinptr av_[NAV * 2 + 2] = {
- 0, 0,
- IAV(0),   IAV(1),   IAV(2),   IAV(3),   IAV(4),   IAV(5),   IAV(6),   IAV(7),
- IAV(8),   IAV(9),   IAV(10),  IAV(11),  IAV(12),  IAV(13),  IAV(14),  IAV(15),
- IAV(16),  IAV(17),  IAV(18),  IAV(19),  IAV(20),  IAV(21),  IAV(22),  IAV(23),
- IAV(24),  IAV(25),  IAV(26),  IAV(27),  IAV(28),  IAV(29),  IAV(30),  IAV(31),
- IAV(32),  IAV(33),  IAV(34),  IAV(35),  IAV(36),  IAV(37),  IAV(38),  IAV(39),
- IAV(40),  IAV(41),  IAV(42),  IAV(43),  IAV(44),  IAV(45),  IAV(46),  IAV(47),
- IAV(48),  IAV(49),  IAV(50),  IAV(51),  IAV(52),  IAV(53),  IAV(54),  IAV(55),
- IAV(56),  IAV(57),  IAV(58),  IAV(59),  IAV(60),  IAV(61),  IAV(62),  IAV(63),
- IAV(64),  IAV(65),  IAV(66),  IAV(67),  IAV(68),  IAV(69),  IAV(70),  IAV(71),
- IAV(72),  IAV(73),  IAV(74),  IAV(75),  IAV(76),  IAV(77),  IAV(78),  IAV(79),
- IAV(80),  IAV(81),  IAV(82),  IAV(83),  IAV(84),  IAV(85),  IAV(86),  IAV(87),
- IAV(88),  IAV(89),  IAV(90),  IAV(91),  IAV(92),  IAV(93),  IAV(94),  IAV(95),
- IAV(96),  IAV(97),  IAV(98),  IAV(99),  IAV(100), IAV(101), IAV(102), IAV(103),
- IAV(104), IAV(105), IAV(106), IAV(107), IAV(108), IAV(109), IAV(110), IAV(111),
- IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119),
- IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
-};
-
-
-
-/* field-extraction macros */
-
-#define first(b) ((b)->fd)
-#define last(b)  ((b)->bk)
-
-/*
-  Indexing into bins
-*/
-
-#define bin_index(sz)                                                          \
-(((((unsigned long)(sz)) >> 9) ==    0) ?       (((unsigned long)(sz)) >>  3): \
- ((((unsigned long)(sz)) >> 9) <=    4) ?  56 + (((unsigned long)(sz)) >>  6): \
- ((((unsigned long)(sz)) >> 9) <=   20) ?  91 + (((unsigned long)(sz)) >>  9): \
- ((((unsigned long)(sz)) >> 9) <=   84) ? 110 + (((unsigned long)(sz)) >> 12): \
- ((((unsigned long)(sz)) >> 9) <=  340) ? 119 + (((unsigned long)(sz)) >> 15): \
- ((((unsigned long)(sz)) >> 9) <= 1364) ? 124 + (((unsigned long)(sz)) >> 18): \
-					  126)
-/*
-  bins for chunks < 512 are all spaced 8 bytes apart, and hold
-  identically sized chunks. This is exploited in malloc.
-*/
-
-#define MAX_SMALLBIN         63
-#define MAX_SMALLBIN_SIZE   512
-#define SMALLBIN_WIDTH        8
-
-#define smallbin_index(sz)  (((unsigned long)(sz)) >> 3)
-
-/*
-   Requests are `small' if both the corresponding and the next bin are small
-*/
-
-#define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
-
-
-
-/*
-    To help compensate for the large number of bins, a one-level index
-    structure is used for bin-by-bin searching.  `binblocks' is a
-    one-word bitvector recording whether groups of BINBLOCKWIDTH bins
-    have any (possibly) non-empty bins, so they can be skipped over
-    all at once during during traversals. The bits are NOT always
-    cleared as soon as all bins in a block are empty, but instead only
-    when all are noticed to be empty during traversal in malloc.
-*/
-
-#define BINBLOCKWIDTH     4   /* bins per block */
-
-#define binblocks      (bin_at(0)->size) /* bitvector of nonempty blocks */
-
-/* bin<->block macros */
-
-#define idx2binblock(ix)    ((unsigned)1 << (ix / BINBLOCKWIDTH))
-#define mark_binblock(ii)   (binblocks |= idx2binblock(ii))
-#define clear_binblock(ii)  (binblocks &= ~(idx2binblock(ii)))
-
-
-
-
-
-/*  Other static bookkeeping data */
-
-/* variables holding tunable values */
-
-static unsigned long trim_threshold   = DEFAULT_TRIM_THRESHOLD;
-static unsigned long top_pad          = DEFAULT_TOP_PAD;
-static unsigned int  n_mmaps_max      = DEFAULT_MMAP_MAX;
-static unsigned long mmap_threshold   = DEFAULT_MMAP_THRESHOLD;
-
-/* The first value returned from sbrk */
-static char* sbrk_base = (char*)(-1);
-
-/* The maximum memory obtained from system via sbrk */
-static unsigned long max_sbrked_mem = 0;
-
-/* The maximum via either sbrk or mmap */
-static unsigned long max_total_mem = 0;
-
-/* internal working copy of mallinfo */
-static struct mallinfo current_mallinfo = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/* The total memory obtained from system via sbrk */
-#define sbrked_mem  (current_mallinfo.arena)
-
-/* Tracking mmaps */
-
-static unsigned int n_mmaps = 0;
-static unsigned int max_n_mmaps = 0;
-static unsigned long mmapped_mem = 0;
-static unsigned long max_mmapped_mem = 0;
-
-
-
-/*
-  Debugging support
-*/
-
-#if DEBUG
-
-
-/*
-  These routines make a number of assertions about the states
-  of data structures that should be true at all times. If any
-  are not true, it's very likely that a user program has somehow
-  trashed memory. (It's also possible that there is a coding error
-  in malloc. In which case, please report it!)
-*/
-
-#if __STD_C
-static void do_check_chunk(mchunkptr p)
-#else
-static void do_check_chunk(p) mchunkptr p;
-#endif
-{
-  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
-
-  /* No checkable chunk is mmapped */
-  assert(!chunk_is_mmapped(p));
-
-  /* Check for legal address ... */
-  assert((char*)p >= sbrk_base);
-  if (p != top)
-    assert((char*)p + sz <= (char*)top);
-  else
-    assert((char*)p + sz <= sbrk_base + sbrked_mem);
-
-}
-
-
-#if __STD_C
-static void do_check_free_chunk(mchunkptr p)
-#else
-static void do_check_free_chunk(p) mchunkptr p;
-#endif
-{
-  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
-  mchunkptr next = chunk_at_offset(p, sz);
-
-  do_check_chunk(p);
-
-  /* Check whether it claims to be free ... */
-  assert(!inuse(p));
-
-  /* Unless a special marker, must have OK fields */
-  if ((long)sz >= (long)MINSIZE)
-  {
-    assert((sz & MALLOC_ALIGN_MASK) == 0);
-    assert(aligned_OK(chunk2mem(p)));
-    /* ... matching footer field */
-    assert(next->prev_size == sz);
-    /* ... and is fully consolidated */
-    assert(prev_inuse(p));
-    assert (next == top || inuse(next));
-
-    /* ... and has minimally sane links */
-    assert(p->fd->bk == p);
-    assert(p->bk->fd == p);
-  }
-  else /* markers are always of size SIZE_SZ */
-    assert(sz == SIZE_SZ);
-}
-
-#if __STD_C
-static void do_check_inuse_chunk(mchunkptr p)
-#else
-static void do_check_inuse_chunk(p) mchunkptr p;
-#endif
-{
-  mchunkptr next = next_chunk(p);
-  do_check_chunk(p);
-
-  /* Check whether it claims to be in use ... */
-  assert(inuse(p));
-
-  /* ... and is surrounded by OK chunks.
-    Since more things can be checked with free chunks than inuse ones,
-    if an inuse chunk borders them and debug is on, it's worth doing them.
-  */
-  if (!prev_inuse(p))
-  {
-    mchunkptr prv = prev_chunk(p);
-    assert(next_chunk(prv) == p);
-    do_check_free_chunk(prv);
-  }
-  if (next == top)
-  {
-    assert(prev_inuse(next));
-    assert(chunksize(next) >= MINSIZE);
-  }
-  else if (!inuse(next))
-    do_check_free_chunk(next);
-
-}
-
-#if __STD_C
-static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
-#else
-static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
-#endif
-{
-  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
-  long room = sz - s;
-
-  do_check_inuse_chunk(p);
-
-  /* Legal size ... */
-  assert((long)sz >= (long)MINSIZE);
-  assert((sz & MALLOC_ALIGN_MASK) == 0);
-  assert(room >= 0);
-  assert(room < (long)MINSIZE);
-
-  /* ... and alignment */
-  assert(aligned_OK(chunk2mem(p)));
-
-
-  /* ... and was allocated at front of an available chunk */
-  assert(prev_inuse(p));
-
-}
-
-
-#define check_free_chunk(P)  do_check_free_chunk(P)
-#define check_inuse_chunk(P) do_check_inuse_chunk(P)
-#define check_chunk(P) do_check_chunk(P)
-#define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N)
-#else
-#define check_free_chunk(P)
-#define check_inuse_chunk(P)
-#define check_chunk(P)
-#define check_malloced_chunk(P,N)
-#endif
-
-
-
-/*
-  Macro-based internal utilities
-*/
-
-
-/*
-  Linking chunks in bin lists.
-  Call these only with variables, not arbitrary expressions, as arguments.
-*/
-
-/*
-  Place chunk p of size s in its bin, in size order,
-  putting it ahead of others of same size.
-*/
-
-
-#define frontlink(P, S, IDX, BK, FD)                                          \
-{                                                                             \
-  if (S < MAX_SMALLBIN_SIZE)                                                  \
-  {                                                                           \
-    IDX = smallbin_index(S);                                                  \
-    mark_binblock(IDX);                                                       \
-    BK = bin_at(IDX);                                                         \
-    FD = BK->fd;                                                              \
-    P->bk = BK;                                                               \
-    P->fd = FD;                                                               \
-    FD->bk = BK->fd = P;                                                      \
-  }                                                                           \
-  else                                                                        \
-  {                                                                           \
-    IDX = bin_index(S);                                                       \
-    BK = bin_at(IDX);                                                         \
-    FD = BK->fd;                                                              \
-    if (FD == BK) mark_binblock(IDX);                                         \
-    else                                                                      \
-    {                                                                         \
-      while (FD != BK && S < chunksize(FD)) FD = FD->fd;                      \
-      BK = FD->bk;                                                            \
-    }                                                                         \
-    P->bk = BK;                                                               \
-    P->fd = FD;                                                               \
-    FD->bk = BK->fd = P;                                                      \
-  }                                                                           \
-}
-
-
-/* take a chunk off a list */
-
-#define unlink(P, BK, FD)                                                     \
-{                                                                             \
-  BK = P->bk;                                                                 \
-  FD = P->fd;                                                                 \
-  FD->bk = BK;                                                                \
-  BK->fd = FD;                                                                \
-}                                                                             \
-
-/* Place p as the last remainder */
-
-#define link_last_remainder(P)                                                \
-{                                                                             \
-  last_remainder->fd = last_remainder->bk =  P;                               \
-  P->fd = P->bk = last_remainder;                                             \
-}
-
-/* Clear the last_remainder bin */
-
-#define clear_last_remainder \
-  (last_remainder->fd = last_remainder->bk = last_remainder)
-
-
-
-
-
-/* Routines dealing with mmap(). */
-
-#if HAVE_MMAP
-
-#if __STD_C
-static mchunkptr mmap_chunk(size_t size)
-#else
-static mchunkptr mmap_chunk(size) size_t size;
-#endif
-{
-  size_t page_mask = malloc_getpagesize - 1;
-  mchunkptr p;
-
-#ifndef MAP_ANONYMOUS
-  static int fd = -1;
-#endif
-
-  if(n_mmaps >= n_mmaps_max) return 0; /* too many regions */
-
-  /* For mmapped chunks, the overhead is one SIZE_SZ unit larger, because
-   * there is no following chunk whose prev_size field could be used.
-   */
-  size = (size + SIZE_SZ + page_mask) & ~page_mask;
-
-#ifdef MAP_ANONYMOUS
-  p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE,
-		      MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-#else /* !MAP_ANONYMOUS */
-  if (fd < 0)
-  {
-    fd = open("/dev/zero", O_RDWR);
-    if(fd < 0) return 0;
-  }
-  p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-#endif
-
-  if(p == (mchunkptr)-1) return 0;
-
-  n_mmaps++;
-  if (n_mmaps > max_n_mmaps) max_n_mmaps = n_mmaps;
-
-  /* We demand that eight bytes into a page must be 8-byte aligned. */
-  assert(aligned_OK(chunk2mem(p)));
-
-  /* The offset to the start of the mmapped region is stored
-   * in the prev_size field of the chunk; normally it is zero,
-   * but that can be changed in memalign().
-   */
-  p->prev_size = 0;
-  set_head(p, size|IS_MMAPPED);
-
-  mmapped_mem += size;
-  if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
-    max_mmapped_mem = mmapped_mem;
-  if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
-    max_total_mem = mmapped_mem + sbrked_mem;
-  return p;
-}
-
-#if __STD_C
-static void munmap_chunk(mchunkptr p)
-#else
-static void munmap_chunk(p) mchunkptr p;
-#endif
-{
-  INTERNAL_SIZE_T size = chunksize(p);
-  int ret;
-
-  assert (chunk_is_mmapped(p));
-  assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
-  assert((n_mmaps > 0));
-  assert(((p->prev_size + size) & (malloc_getpagesize-1)) == 0);
-
-  n_mmaps--;
-  mmapped_mem -= (size + p->prev_size);
-
-  ret = munmap((char *)p - p->prev_size, size + p->prev_size);
-
-  /* munmap returns non-zero on failure */
-  assert(ret == 0);
-}
-
-#if HAVE_MREMAP
-
-#if __STD_C
-static mchunkptr mremap_chunk(mchunkptr p, size_t new_size)
-#else
-static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
-#endif
-{
-  size_t page_mask = malloc_getpagesize - 1;
-  INTERNAL_SIZE_T offset = p->prev_size;
-  INTERNAL_SIZE_T size = chunksize(p);
-  char *cp;
-
-  assert (chunk_is_mmapped(p));
-  assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
-  assert((n_mmaps > 0));
-  assert(((size + offset) & (malloc_getpagesize-1)) == 0);
-
-  /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */
-  new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask;
-
-  cp = (char *)mremap((char *)p - offset, size + offset, new_size, 1);
-
-  if (cp == (char *)-1) return 0;
-
-  p = (mchunkptr)(cp + offset);
-
-  assert(aligned_OK(chunk2mem(p)));
-
-  assert((p->prev_size == offset));
-  set_head(p, (new_size - offset)|IS_MMAPPED);
-
-  mmapped_mem -= size + offset;
-  mmapped_mem += new_size;
-  if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
-    max_mmapped_mem = mmapped_mem;
-  if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
-    max_total_mem = mmapped_mem + sbrked_mem;
-  return p;
-}
-
-#endif /* HAVE_MREMAP */
-
-#endif /* HAVE_MMAP */
-
-
-
-
-/*
-  Extend the top-most chunk by obtaining memory from system.
-  Main interface to sbrk (but see also malloc_trim).
-*/
-
-#if __STD_C
-static void malloc_extend_top(INTERNAL_SIZE_T nb)
-#else
-static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
-#endif
-{
-  char*     brk;                  /* return value from sbrk */
-  INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
-  INTERNAL_SIZE_T correction;     /* bytes for 2nd sbrk call */
-  char*     new_brk;              /* return of 2nd sbrk call */
-  INTERNAL_SIZE_T top_size;       /* new size of top chunk */
-
-  mchunkptr old_top     = top;  /* Record state of old top */
-  INTERNAL_SIZE_T old_top_size = chunksize(old_top);
-  char*     old_end      = (char*)(chunk_at_offset(old_top, old_top_size));
-
-  /* Pad request with top_pad plus minimal overhead */
-
-  INTERNAL_SIZE_T    sbrk_size     = nb + top_pad + MINSIZE;
-  unsigned long pagesz    = malloc_getpagesize;
-
-  /* If not the first time through, round to preserve page boundary */
-  /* Otherwise, we need to correct to a page size below anyway. */
-  /* (We also correct below if an intervening foreign sbrk call.) */
-
-  if (sbrk_base != (char*)(-1))
-    sbrk_size = (sbrk_size + (pagesz - 1)) & ~(pagesz - 1);
-
-  brk = (char*)(MORECORE (sbrk_size));
-
-  /* Fail if sbrk failed or if a foreign sbrk call killed our space */
-  if (brk == (char*)(MORECORE_FAILURE) ||
-      (brk < old_end && old_top != initial_top))
-    return;
-
-  sbrked_mem += sbrk_size;
-
-  if (brk == old_end) /* can just add bytes to current top */
-  {
-    top_size = sbrk_size + old_top_size;
-    set_head(top, top_size | PREV_INUSE);
-  }
-  else
-  {
-    if (sbrk_base == (char*)(-1))  /* First time through. Record base */
-      sbrk_base = brk;
-    else  /* Someone else called sbrk().  Count those bytes as sbrked_mem. */
-      sbrked_mem += brk - (char*)old_end;
-
-    /* Guarantee alignment of first new chunk made from this space */
-    front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;
-    if (front_misalign > 0)
-    {
-      correction = (MALLOC_ALIGNMENT) - front_misalign;
-      brk += correction;
-    }
-    else
-      correction = 0;
-
-    /* Guarantee the next brk will be at a page boundary */
-
-    correction += ((((unsigned long)(brk + sbrk_size))+(pagesz-1)) &
-		   ~(pagesz - 1)) - ((unsigned long)(brk + sbrk_size));
-
-    /* Allocate correction */
-    new_brk = (char*)(MORECORE (correction));
-    if (new_brk == (char*)(MORECORE_FAILURE)) return;
-
-    sbrked_mem += correction;
-
-    top = (mchunkptr)brk;
-    top_size = new_brk - brk + correction;
-    set_head(top, top_size | PREV_INUSE);
-
-    if (old_top != initial_top)
-    {
-
-      /* There must have been an intervening foreign sbrk call. */
-      /* A double fencepost is necessary to prevent consolidation */
-
-      /* If not enough space to do this, then user did something very wrong */
-      if (old_top_size < MINSIZE)
-      {
-	set_head(top, PREV_INUSE); /* will force null return from malloc */
-	return;
-      }
-
-      /* Also keep size a multiple of MALLOC_ALIGNMENT */
-      old_top_size = (old_top_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
-      set_head_size(old_top, old_top_size);
-      chunk_at_offset(old_top, old_top_size          )->size =
-	SIZE_SZ|PREV_INUSE;
-      chunk_at_offset(old_top, old_top_size + SIZE_SZ)->size =
-	SIZE_SZ|PREV_INUSE;
-      /* If possible, release the rest. */
-      if (old_top_size >= MINSIZE)
-	fREe(chunk2mem(old_top));
-    }
-  }
-
-  if ((unsigned long)sbrked_mem > (unsigned long)max_sbrked_mem)
-    max_sbrked_mem = sbrked_mem;
-  if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
-    max_total_mem = mmapped_mem + sbrked_mem;
-
-  /* We always land on a page boundary */
-  assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
-}
-
-
-
-
-/* Main public routines */
-
-
-/*
-  Malloc Algorthim:
-
-    The requested size is first converted into a usable form, `nb'.
-    This currently means to add 4 bytes overhead plus possibly more to
-    obtain 8-byte alignment and/or to obtain a size of at least
-    MINSIZE (currently 16 bytes), the smallest allocatable size.
-    (All fits are considered `exact' if they are within MINSIZE bytes.)
-
-    From there, the first successful of the following steps is taken:
-
-      1. The bin corresponding to the request size is scanned, and if
-	 a chunk of exactly the right size is found, it is taken.
-
-      2. The most recently remaindered chunk is used if it is big
-	 enough.  This is a form of (roving) first fit, used only in
-	 the absence of exact fits. Runs of consecutive requests use
-	 the remainder of the chunk used for the previous such request
-	 whenever possible. This limited use of a first-fit style
-	 allocation strategy tends to give contiguous chunks
-	 coextensive lifetimes, which improves locality and can reduce
-	 fragmentation in the long run.
-
-      3. Other bins are scanned in increasing size order, using a
-	 chunk big enough to fulfill the request, and splitting off
-	 any remainder.  This search is strictly by best-fit; i.e.,
-	 the smallest (with ties going to approximately the least
-	 recently used) chunk that fits is selected.
-
-      4. If large enough, the chunk bordering the end of memory
-	 (`top') is split off. (This use of `top' is in accord with
-	 the best-fit search rule.  In effect, `top' is treated as
-	 larger (and thus less well fitting) than any other available
-	 chunk since it can be extended to be as large as necessary
-	 (up to system limitations).
-
-      5. If the request size meets the mmap threshold and the
-	 system supports mmap, and there are few enough currently
-	 allocated mmapped regions, and a call to mmap succeeds,
-	 the request is allocated via direct memory mapping.
-
-      6. Otherwise, the top of memory is extended by
-	 obtaining more space from the system (normally using sbrk,
-	 but definable to anything else via the MORECORE macro).
-	 Memory is gathered from the system (in system page-sized
-	 units) in a way that allows chunks obtained across different
-	 sbrk calls to be consolidated, but does not require
-	 contiguous memory. Thus, it should be safe to intersperse
-	 mallocs with other sbrk calls.
-
-
-      All allocations are made from the the `lowest' part of any found
-      chunk. (The implementation invariant is that prev_inuse is
-      always true of any allocated chunk; i.e., that each allocated
-      chunk borders either a previously allocated and still in-use chunk,
-      or the base of its memory arena.)
-
-*/
-
-#if __STD_C
-Void_t* mALLOc(size_t bytes)
-#else
-Void_t* mALLOc(bytes) size_t bytes;
-#endif
-{
-  mchunkptr victim;                  /* inspected/selected chunk */
-  INTERNAL_SIZE_T victim_size;       /* its size */
-  int       idx;                     /* index for bin traversal */
-  mbinptr   bin;                     /* associated bin */
-  mchunkptr remainder;               /* remainder from a split */
-  long      remainder_size;          /* its size */
-  int       remainder_index;         /* its bin index */
-  unsigned long block;               /* block traverser bit */
-  int       startidx;                /* first bin of a traversed block */
-  mchunkptr fwd;                     /* misc temp for linking */
-  mchunkptr bck;                     /* misc temp for linking */
-  mbinptr q;                         /* misc temp */
-
-  INTERNAL_SIZE_T nb;
-
-  if ((long)bytes < 0) return 0;
-
-  nb = request2size(bytes);  /* padded request size; */
-
-  /* Check for exact match in a bin */
-
-  if (is_small_request(nb))  /* Faster version for small requests */
-  {
-    idx = smallbin_index(nb);
-
-    /* No traversal or size check necessary for small bins.  */
-
-    q = bin_at(idx);
-    victim = last(q);
-
-    /* Also scan the next one, since it would have a remainder < MINSIZE */
-    if (victim == q)
-    {
-      q = next_bin(q);
-      victim = last(q);
-    }
-    if (victim != q)
-    {
-      victim_size = chunksize(victim);
-      unlink(victim, bck, fwd);
-      set_inuse_bit_at_offset(victim, victim_size);
-      check_malloced_chunk(victim, nb);
-      return chunk2mem(victim);
-    }
-
-    idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */
-
-  }
-  else
-  {
-    idx = bin_index(nb);
-    bin = bin_at(idx);
-
-    for (victim = last(bin); victim != bin; victim = victim->bk)
-    {
-      victim_size = chunksize(victim);
-      remainder_size = victim_size - nb;
-
-      if (remainder_size >= (long)MINSIZE) /* too big */
-      {
-	--idx; /* adjust to rescan below after checking last remainder */
-	break;
-      }
-
-      else if (remainder_size >= 0) /* exact fit */
-      {
-	unlink(victim, bck, fwd);
-	set_inuse_bit_at_offset(victim, victim_size);
-	check_malloced_chunk(victim, nb);
-	return chunk2mem(victim);
-      }
-    }
-
-    ++idx;
-
-  }
-
-  /* Try to use the last split-off remainder */
-
-  if ( (victim = last_remainder->fd) != last_remainder)
-  {
-    victim_size = chunksize(victim);
-    remainder_size = victim_size - nb;
-
-    if (remainder_size >= (long)MINSIZE) /* re-split */
-    {
-      remainder = chunk_at_offset(victim, nb);
-      set_head(victim, nb | PREV_INUSE);
-      link_last_remainder(remainder);
-      set_head(remainder, remainder_size | PREV_INUSE);
-      set_foot(remainder, remainder_size);
-      check_malloced_chunk(victim, nb);
-      return chunk2mem(victim);
-    }
-
-    clear_last_remainder;
-
-    if (remainder_size >= 0)  /* exhaust */
-    {
-      set_inuse_bit_at_offset(victim, victim_size);
-      check_malloced_chunk(victim, nb);
-      return chunk2mem(victim);
-    }
-
-    /* Else place in bin */
-
-    frontlink(victim, victim_size, remainder_index, bck, fwd);
-  }
-
-  /*
-     If there are any possibly nonempty big-enough blocks,
-     search for best fitting chunk by scanning bins in blockwidth units.
-  */
-
-  if ( (block = idx2binblock(idx)) <= binblocks)
-  {
-
-    /* Get to the first marked block */
-
-    if ( (block & binblocks) == 0)
-    {
-      /* force to an even block boundary */
-      idx = (idx & ~(BINBLOCKWIDTH - 1)) + BINBLOCKWIDTH;
-      block <<= 1;
-      while ((block & binblocks) == 0)
-      {
-	idx += BINBLOCKWIDTH;
-	block <<= 1;
-      }
-    }
-
-    /* For each possibly nonempty block ... */
-    for (;;)
-    {
-      startidx = idx;          /* (track incomplete blocks) */
-      q = bin = bin_at(idx);
-
-      /* For each bin in this block ... */
-      do
-      {
-	/* Find and use first big enough chunk ... */
-
-	for (victim = last(bin); victim != bin; victim = victim->bk)
-	{
-	  victim_size = chunksize(victim);
-	  remainder_size = victim_size - nb;
-
-	  if (remainder_size >= (long)MINSIZE) /* split */
-	  {
-	    remainder = chunk_at_offset(victim, nb);
-	    set_head(victim, nb | PREV_INUSE);
-	    unlink(victim, bck, fwd);
-	    link_last_remainder(remainder);
-	    set_head(remainder, remainder_size | PREV_INUSE);
-	    set_foot(remainder, remainder_size);
-	    check_malloced_chunk(victim, nb);
-	    return chunk2mem(victim);
-	  }
-
-	  else if (remainder_size >= 0)  /* take */
-	  {
-	    set_inuse_bit_at_offset(victim, victim_size);
-	    unlink(victim, bck, fwd);
-	    check_malloced_chunk(victim, nb);
-	    return chunk2mem(victim);
-	  }
-
-	}
-
-       bin = next_bin(bin);
-
-      } while ((++idx & (BINBLOCKWIDTH - 1)) != 0);
-
-      /* Clear out the block bit. */
-
-      do   /* Possibly backtrack to try to clear a partial block */
-      {
-	if ((startidx & (BINBLOCKWIDTH - 1)) == 0)
-	{
-	  binblocks &= ~block;
-	  break;
-	}
-	--startidx;
-       q = prev_bin(q);
-      } while (first(q) == q);
-
-      /* Get to the next possibly nonempty block */
-
-      if ( (block <<= 1) <= binblocks && (block != 0) )
-      {
-	while ((block & binblocks) == 0)
-	{
-	  idx += BINBLOCKWIDTH;
-	  block <<= 1;
-	}
-      }
-      else
-	break;
-    }
-  }
-
-
-  /* Try to use top chunk */
-
-  /* Require that there be a remainder, ensuring top always exists  */
-  if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
-  {
-
-#if HAVE_MMAP
-    /* If big and would otherwise need to extend, try to use mmap instead */
-    if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
-	(victim = mmap_chunk(nb)) != 0)
-      return chunk2mem(victim);
-#endif
-
-    /* Try to extend */
-    malloc_extend_top(nb);
-    if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
-      return 0; /* propagate failure */
-  }
-
-  victim = top;
-  set_head(victim, nb | PREV_INUSE);
-  top = chunk_at_offset(victim, nb);
-  set_head(top, remainder_size | PREV_INUSE);
-  check_malloced_chunk(victim, nb);
-  return chunk2mem(victim);
-
-}
-
-
-
-
-/*
-
-  free() algorithm :
-
-    cases:
-
-       1. free(0) has no effect.
-
-       2. If the chunk was allocated via mmap, it is release via munmap().
-
-       3. If a returned chunk borders the current high end of memory,
-	  it is consolidated into the top, and if the total unused
-	  topmost memory exceeds the trim threshold, malloc_trim is
-	  called.
-
-       4. Other chunks are consolidated as they arrive, and
-	  placed in corresponding bins. (This includes the case of
-	  consolidating with the current `last_remainder').
-
-*/
-
-
-#if __STD_C
-void fREe(Void_t* mem)
-#else
-void fREe(mem) Void_t* mem;
-#endif
-{
-  mchunkptr p;         /* chunk corresponding to mem */
-  INTERNAL_SIZE_T hd;  /* its head field */
-  INTERNAL_SIZE_T sz;  /* its size */
-  int       idx;       /* its bin index */
-  mchunkptr next;      /* next contiguous chunk */
-  INTERNAL_SIZE_T nextsz; /* its size */
-  INTERNAL_SIZE_T prevsz; /* size of previous contiguous chunk */
-  mchunkptr bck;       /* misc temp for linking */
-  mchunkptr fwd;       /* misc temp for linking */
-  int       islr;      /* track whether merging with last_remainder */
-
-  if (mem == 0)                              /* free(0) has no effect */
-    return;
-
-  p = mem2chunk(mem);
-  hd = p->size;
-
-#if HAVE_MMAP
-  if (hd & IS_MMAPPED)                       /* release mmapped memory. */
-  {
-    munmap_chunk(p);
-    return;
-  }
-#endif
-
-  check_inuse_chunk(p);
-
-  sz = hd & ~PREV_INUSE;
-  next = chunk_at_offset(p, sz);
-  nextsz = chunksize(next);
-
-  if (next == top)                            /* merge with top */
-  {
-    sz += nextsz;
-
-    if (!(hd & PREV_INUSE))                    /* consolidate backward */
-    {
-      prevsz = p->prev_size;
-      p = chunk_at_offset(p, -((long) prevsz));
-      sz += prevsz;
-      unlink(p, bck, fwd);
-    }
-
-    set_head(p, sz | PREV_INUSE);
-    top = p;
-    if ((unsigned long)(sz) >= (unsigned long)trim_threshold)
-      malloc_trim(top_pad);
-    return;
-  }
-
-  set_head(next, nextsz);                    /* clear inuse bit */
-
-  islr = 0;
-
-  if (!(hd & PREV_INUSE))                    /* consolidate backward */
-  {
-    prevsz = p->prev_size;
-    p = chunk_at_offset(p, -((long) prevsz));
-    sz += prevsz;
-
-    if (p->fd == last_remainder)             /* keep as last_remainder */
-      islr = 1;
-    else
-      unlink(p, bck, fwd);
-  }
-
-  if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
-  {
-    sz += nextsz;
-
-    if (!islr && next->fd == last_remainder)  /* re-insert last_remainder */
-    {
-      islr = 1;
-      link_last_remainder(p);
-    }
-    else
-      unlink(next, bck, fwd);
-  }
-
-
-  set_head(p, sz | PREV_INUSE);
-  set_foot(p, sz);
-  if (!islr)
-    frontlink(p, sz, idx, bck, fwd);
-}
-
-
-
-
-
-/*
-
-  Realloc algorithm:
-
-    Chunks that were obtained via mmap cannot be extended or shrunk
-    unless HAVE_MREMAP is defined, in which case mremap is used.
-    Otherwise, if their reallocation is for additional space, they are
-    copied.  If for less, they are just left alone.
-
-    Otherwise, if the reallocation is for additional space, and the
-    chunk can be extended, it is, else a malloc-copy-free sequence is
-    taken.  There are several different ways that a chunk could be
-    extended. All are tried:
-
-       * Extending forward into following adjacent free chunk.
-       * Shifting backwards, joining preceding adjacent space
-       * Both shifting backwards and extending forward.
-       * Extending into newly sbrked space
-
-    Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with a
-    size argument of zero (re)allocates a minimum-sized chunk.
-
-    If the reallocation is for less space, and the new request is for
-    a `small' (<512 bytes) size, then the newly unused space is lopped
-    off and freed.
-
-    The old unix realloc convention of allowing the last-free'd chunk
-    to be used as an argument to realloc is no longer supported.
-    I don't know of any programs still relying on this feature,
-    and allowing it would also allow too many other incorrect
-    usages of realloc to be sensible.
-
-
-*/
-
-
-#if __STD_C
-Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
-#else
-Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
-#endif
-{
-  INTERNAL_SIZE_T    nb;      /* padded request size */
-
-  mchunkptr oldp;             /* chunk corresponding to oldmem */
-  INTERNAL_SIZE_T    oldsize; /* its size */
-
-  mchunkptr newp;             /* chunk to return */
-  INTERNAL_SIZE_T    newsize; /* its size */
-  Void_t*   newmem;           /* corresponding user mem */
-
-  mchunkptr next;             /* next contiguous chunk after oldp */
-  INTERNAL_SIZE_T  nextsize;  /* its size */
-
-  mchunkptr prev;             /* previous contiguous chunk before oldp */
-  INTERNAL_SIZE_T  prevsize;  /* its size */
-
-  mchunkptr remainder;        /* holds split off extra space from newp */
-  INTERNAL_SIZE_T  remainder_size;   /* its size */
-
-  mchunkptr bck;              /* misc temp for linking */
-  mchunkptr fwd;              /* misc temp for linking */
-
-#ifdef REALLOC_ZERO_BYTES_FREES
-  if (bytes == 0) { fREe(oldmem); return 0; }
-#endif
-
-  if ((long)bytes < 0) return 0;
-
-  /* realloc of null is supposed to be same as malloc */
-  if (oldmem == 0) return mALLOc(bytes);
-
-  newp    = oldp    = mem2chunk(oldmem);
-  newsize = oldsize = chunksize(oldp);
-
-
-  nb = request2size(bytes);
-
-#if HAVE_MMAP
-  if (chunk_is_mmapped(oldp))
-  {
-#if HAVE_MREMAP
-    newp = mremap_chunk(oldp, nb);
-    if(newp) return chunk2mem(newp);
-#endif
-    /* Note the extra SIZE_SZ overhead. */
-    if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
-    /* Must alloc, copy, free. */
-    newmem = mALLOc(bytes);
-    if (newmem == 0) return 0; /* propagate failure */
-    MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
-    munmap_chunk(oldp);
-    return newmem;
-  }
-#endif
-
-  check_inuse_chunk(oldp);
-
-  if ((long)(oldsize) < (long)(nb))
-  {
-
-    /* Try expanding forward */
-
-    next = chunk_at_offset(oldp, oldsize);
-    if (next == top || !inuse(next))
-    {
-      nextsize = chunksize(next);
-
-      /* Forward into top only if a remainder */
-      if (next == top)
-      {
-	if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE))
-	{
-	  newsize += nextsize;
-	  top = chunk_at_offset(oldp, nb);
-	  set_head(top, (newsize - nb) | PREV_INUSE);
-	  set_head_size(oldp, nb);
-	  return chunk2mem(oldp);
-	}
-      }
-
-      /* Forward into next chunk */
-      else if (((long)(nextsize + newsize) >= (long)(nb)))
-      {
-	unlink(next, bck, fwd);
-	newsize  += nextsize;
-	goto split;
-      }
-    }
-    else
-    {
-      next = 0;
-      nextsize = 0;
-    }
-
-    /* Try shifting backwards. */
-
-    if (!prev_inuse(oldp))
-    {
-      prev = prev_chunk(oldp);
-      prevsize = chunksize(prev);
-
-      /* try forward + backward first to save a later consolidation */
-
-      if (next != 0)
-      {
-	/* into top */
-	if (next == top)
-	{
-	  if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE))
-	  {
-	    unlink(prev, bck, fwd);
-	    newp = prev;
-	    newsize += prevsize + nextsize;
-	    newmem = chunk2mem(newp);
-	    MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
-	    top = chunk_at_offset(newp, nb);
-	    set_head(top, (newsize - nb) | PREV_INUSE);
-	    set_head_size(newp, nb);
-	    return newmem;
-	  }
-	}
-
-	/* into next chunk */
-	else if (((long)(nextsize + prevsize + newsize) >= (long)(nb)))
-	{
-	  unlink(next, bck, fwd);
-	  unlink(prev, bck, fwd);
-	  newp = prev;
-	  newsize += nextsize + prevsize;
-	  newmem = chunk2mem(newp);
-	  MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
-	  goto split;
-	}
-      }
-
-      /* backward only */
-      if (prev != 0 && (long)(prevsize + newsize) >= (long)nb)
-      {
-	unlink(prev, bck, fwd);
-	newp = prev;
-	newsize += prevsize;
-	newmem = chunk2mem(newp);
-	MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
-	goto split;
-      }
-    }
-
-    /* Must allocate */
-
-    newmem = mALLOc (bytes);
-
-    if (newmem == 0)  /* propagate failure */
-      return 0;
-
-    /* Avoid copy if newp is next chunk after oldp. */
-    /* (This can only happen when new chunk is sbrk'ed.) */
-
-    if ( (newp = mem2chunk(newmem)) == next_chunk(oldp))
-    {
-      newsize += chunksize(newp);
-      newp = oldp;
-      goto split;
-    }
-
-    /* Otherwise copy, free, and exit */
-    MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
-    fREe(oldmem);
-    return newmem;
-  }
-
-
- split:  /* split off extra room in old or expanded chunk */
-
-  if (newsize - nb >= MINSIZE) /* split off remainder */
-  {
-    remainder = chunk_at_offset(newp, nb);
-    remainder_size = newsize - nb;
-    set_head_size(newp, nb);
-    set_head(remainder, remainder_size | PREV_INUSE);
-    set_inuse_bit_at_offset(remainder, remainder_size);
-    fREe(chunk2mem(remainder)); /* let free() deal with it */
-  }
-  else
-  {
-    set_head_size(newp, newsize);
-    set_inuse_bit_at_offset(newp, newsize);
-  }
-
-  check_inuse_chunk(newp);
-  return chunk2mem(newp);
-}
-
-
-
-
-/*
-
-  memalign algorithm:
-
-    memalign requests more than enough space from malloc, finds a spot
-    within that chunk that meets the alignment request, and then
-    possibly frees the leading and trailing space.
-
-    The alignment argument must be a power of two. This property is not
-    checked by memalign, so misuse may result in random runtime errors.
-
-    8-byte alignment is guaranteed by normal malloc calls, so don't
-    bother calling memalign with an argument of 8 or less.
-
-    Overreliance on memalign is a sure way to fragment space.
-
-*/
-
-
-#if __STD_C
-Void_t* mEMALIGn(size_t alignment, size_t bytes)
-#else
-Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
-#endif
-{
-  INTERNAL_SIZE_T    nb;      /* padded  request size */
-  char*     m;                /* memory returned by malloc call */
-  mchunkptr p;                /* corresponding chunk */
-  char*     brk;              /* alignment point within p */
-  mchunkptr newp;             /* chunk to return */
-  INTERNAL_SIZE_T  newsize;   /* its size */
-  INTERNAL_SIZE_T  leadsize;  /* leading space befor alignment point */
-  mchunkptr remainder;        /* spare room at end to split off */
-  long      remainder_size;   /* its size */
-
-  if ((long)bytes < 0) return 0;
-
-  /* If need less alignment than we give anyway, just relay to malloc */
-
-  if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
-
-  /* Otherwise, ensure that it is at least a minimum chunk size */
-
-  if (alignment <  MINSIZE) alignment = MINSIZE;
-
-  /* Call malloc with worst case padding to hit alignment. */
-
-  nb = request2size(bytes);
-  m  = (char*)(mALLOc(nb + alignment + MINSIZE));
-
-  if (m == 0) return 0; /* propagate failure */
-
-  p = mem2chunk(m);
-
-  if ((((unsigned long)(m)) % alignment) == 0) /* aligned */
-  {
-#if HAVE_MMAP
-    if(chunk_is_mmapped(p))
-      return chunk2mem(p); /* nothing more to do */
-#endif
-  }
-  else /* misaligned */
-  {
-    /*
-      Find an aligned spot inside chunk.
-      Since we need to give back leading space in a chunk of at
-      least MINSIZE, if the first calculation places us at
-      a spot with less than MINSIZE leader, we can move to the
-      next aligned spot -- we've allocated enough total room so that
-      this is always possible.
-    */
-
-    brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) & -((signed) alignment));
-    if ((long)(brk - (char*)(p)) < MINSIZE) brk = brk + alignment;
-
-    newp = (mchunkptr)brk;
-    leadsize = brk - (char*)(p);
-    newsize = chunksize(p) - leadsize;
-
-#if HAVE_MMAP
-    if(chunk_is_mmapped(p))
-    {
-      newp->prev_size = p->prev_size + leadsize;
-      set_head(newp, newsize|IS_MMAPPED);
-      return chunk2mem(newp);
-    }
-#endif
-
-    /* give back leader, use the rest */
-
-    set_head(newp, newsize | PREV_INUSE);
-    set_inuse_bit_at_offset(newp, newsize);
-    set_head_size(p, leadsize);
-    fREe(chunk2mem(p));
-    p = newp;
-
-    assert (newsize >= nb && (((unsigned long)(chunk2mem(p))) % alignment) == 0);
-  }
-
-  /* Also give back spare room at the end */
-
-  remainder_size = chunksize(p) - nb;
-
-  if (remainder_size >= (long)MINSIZE)
-  {
-    remainder = chunk_at_offset(p, nb);
-    set_head(remainder, remainder_size | PREV_INUSE);
-    set_head_size(p, nb);
-    fREe(chunk2mem(remainder));
-  }
-
-  check_inuse_chunk(p);
-  return chunk2mem(p);
-
-}
-
-
-
-
-/*
-    valloc just invokes memalign with alignment argument equal
-    to the page size of the system (or as near to this as can
-    be figured out from all the includes/defines above.)
-*/
-
-#if __STD_C
-Void_t* vALLOc(size_t bytes)
-#else
-Void_t* vALLOc(bytes) size_t bytes;
-#endif
-{
-  return mEMALIGn (malloc_getpagesize, bytes);
-}
-
-/*
-  pvalloc just invokes valloc for the nearest pagesize
-  that will accommodate request
-*/
-
-
-#if __STD_C
-Void_t* pvALLOc(size_t bytes)
-#else
-Void_t* pvALLOc(bytes) size_t bytes;
-#endif
-{
-  size_t pagesize = malloc_getpagesize;
-  return mEMALIGn (pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
-}
-
-/*
-
-  calloc calls malloc, then zeroes out the allocated chunk.
-
-*/
-
-#if __STD_C
-Void_t* cALLOc(size_t n, size_t elem_size)
-#else
-Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
-#endif
-{
-  mchunkptr p;
-  INTERNAL_SIZE_T csz;
-
-  INTERNAL_SIZE_T sz = n * elem_size;
-
-
-  /* check if expand_top called, in which case don't need to clear */
-#if MORECORE_CLEARS
-  mchunkptr oldtop = top;
-  INTERNAL_SIZE_T oldtopsize = chunksize(top);
-#endif
-  Void_t* mem = mALLOc (sz);
-
-  if ((long)n < 0) return 0;
-
-  if (mem == 0)
-    return 0;
-  else
-  {
-    p = mem2chunk(mem);
-
-    /* Two optional cases in which clearing not necessary */
-
-
-#if HAVE_MMAP
-    if (chunk_is_mmapped(p)) return mem;
-#endif
-
-    csz = chunksize(p);
-
-#if MORECORE_CLEARS
-    if (p == oldtop && csz > oldtopsize)
-    {
-      /* clear only the bytes from non-freshly-sbrked memory */
-      csz = oldtopsize;
-    }
-#endif
-
-    MALLOC_ZERO(mem, csz - SIZE_SZ);
-    return mem;
-  }
-}
-
-/*
-
-  cfree just calls free. It is needed/defined on some systems
-  that pair it with calloc, presumably for odd historical reasons.
-
-*/
-
-#if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
-#if __STD_C
-void cfree(Void_t *mem)
-#else
-void cfree(mem) Void_t *mem;
-#endif
-{
-  fREe(mem);
-}
-#endif
-
-
-
-/*
-
-    Malloc_trim gives memory back to the system (via negative
-    arguments to sbrk) if there is unused memory at the `high' end of
-    the malloc pool. You can call this after freeing large blocks of
-    memory to potentially reduce the system-level memory requirements
-    of a program. However, it cannot guarantee to reduce memory. Under
-    some allocation patterns, some large free blocks of memory will be
-    locked between two used chunks, so they cannot be given back to
-    the system.
-
-    The `pad' argument to malloc_trim represents the amount of free
-    trailing space to leave untrimmed. If this argument is zero,
-    only the minimum amount of memory to maintain internal data
-    structures will be left (one page or less). Non-zero arguments
-    can be supplied to maintain enough trailing space to service
-    future expected allocations without having to re-obtain memory
-    from the system.
-
-    Malloc_trim returns 1 if it actually released any memory, else 0.
-
-*/
-
-#if __STD_C
-int malloc_trim(size_t pad)
-#else
-int malloc_trim(pad) size_t pad;
-#endif
-{
-  long  top_size;        /* Amount of top-most memory */
-  long  extra;           /* Amount to release */
-  char* current_brk;     /* address returned by pre-check sbrk call */
-  char* new_brk;         /* address returned by negative sbrk call */
-
-  unsigned long pagesz = malloc_getpagesize;
-
-  top_size = chunksize(top);
-  extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
-
-  if (extra < (long)pagesz)  /* Not enough memory to release */
-    return 0;
-
-  else
-  {
-    /* Test to make sure no one else called sbrk */
-    current_brk = (char*)(MORECORE (0));
-    if (current_brk != (char*)(top) + top_size)
-      return 0;     /* Apparently we don't own memory; must fail */
-
-    else
-    {
-      new_brk = (char*)(MORECORE (-extra));
-
-      if (new_brk == (char*)(MORECORE_FAILURE)) /* sbrk failed? */
-      {
-	/* Try to figure out what we have */
-	current_brk = (char*)(MORECORE (0));
-	top_size = current_brk - (char*)top;
-	if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */
-	{
-	  sbrked_mem = current_brk - sbrk_base;
-	  set_head(top, top_size | PREV_INUSE);
-	}
-	check_chunk(top);
-	return 0;
-      }
-
-      else
-      {
-	/* Success. Adjust top accordingly. */
-	set_head(top, (top_size - extra) | PREV_INUSE);
-	sbrked_mem -= extra;
-	check_chunk(top);
-	return 1;
-      }
-    }
-  }
-}
-
-
-
-/*
-  malloc_usable_size:
-
-    This routine tells you how many bytes you can actually use in an
-    allocated chunk, which may be more than you requested (although
-    often not). You can use this many bytes without worrying about
-    overwriting other allocated objects. Not a particularly great
-    programming practice, but still sometimes useful.
-
-*/
-
-#if __STD_C
-size_t malloc_usable_size(Void_t* mem)
-#else
-size_t malloc_usable_size(mem) Void_t* mem;
-#endif
-{
-  mchunkptr p;
-  if (mem == 0)
-    return 0;
-  else
-  {
-    p = mem2chunk(mem);
-    if(!chunk_is_mmapped(p))
-    {
-      if (!inuse(p)) return 0;
-      check_inuse_chunk(p);
-      return chunksize(p) - SIZE_SZ;
-    }
-    return chunksize(p) - 2*SIZE_SZ;
-  }
-}
-
-
-
-
-/* Utility to update current_mallinfo for malloc_stats and mallinfo() */
-
-static void malloc_update_mallinfo()
-{
-  int i;
-  mbinptr b;
-  mchunkptr p;
-#if DEBUG
-  mchunkptr q;
-#endif
-
-  INTERNAL_SIZE_T avail = chunksize(top);
-  int   navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0;
-
-  for (i = 1; i < NAV; ++i)
-  {
-    b = bin_at(i);
-    for (p = last(b); p != b; p = p->bk)
-    {
-#if DEBUG
-      check_free_chunk(p);
-      for (q = next_chunk(p);
-	   q < top && inuse(q) && (long)(chunksize(q)) >= (long)MINSIZE;
-	   q = next_chunk(q))
-	check_inuse_chunk(q);
-#endif
-      avail += chunksize(p);
-      navail++;
-    }
-  }
-
-  current_mallinfo.ordblks = navail;
-  current_mallinfo.uordblks = sbrked_mem - avail;
-  current_mallinfo.fordblks = avail;
-  current_mallinfo.hblks = n_mmaps;
-  current_mallinfo.hblkhd = mmapped_mem;
-  current_mallinfo.keepcost = chunksize(top);
-
-}
-
-
-
-/*
-
-  malloc_stats:
-
-    Prints on stderr the amount of space obtain from the system (both
-    via sbrk and mmap), the maximum amount (which may be more than
-    current if malloc_trim and/or munmap got called), the maximum
-    number of simultaneous mmap regions used, and the current number
-    of bytes allocated via malloc (or realloc, etc) but not yet
-    freed. (Note that this is the number of bytes allocated, not the
-    number requested. It will be larger than the number requested
-    because of alignment and bookkeeping overhead.)
-
-*/
-
-void malloc_stats()
-{
-  malloc_update_mallinfo();
-  fprintf(stderr, "max system bytes = %10u\n",
-	  (unsigned int)(max_total_mem));
-  fprintf(stderr, "system bytes     = %10u\n",
-	  (unsigned int)(sbrked_mem + mmapped_mem));
-  fprintf(stderr, "in use bytes     = %10u\n",
-	  (unsigned int)(current_mallinfo.uordblks + mmapped_mem));
-#if HAVE_MMAP
-  fprintf(stderr, "max mmap regions = %10u\n",
-	  (unsigned int)max_n_mmaps);
-#endif
-}
-
-/*
-  mallinfo returns a copy of updated current mallinfo.
-*/
-
-struct mallinfo mALLINFo()
-{
-  malloc_update_mallinfo();
-  return current_mallinfo;
-}
-
-
-
-
-/*
-  mallopt:
-
-    mallopt is the general SVID/XPG interface to tunable parameters.
-    The format is to provide a (parameter-number, parameter-value) pair.
-    mallopt then sets the corresponding parameter to the argument
-    value if it can (i.e., so long as the value is meaningful),
-    and returns 1 if successful else 0.
-
-    See descriptions of tunable parameters above.
-
-*/
-
-#if __STD_C
-int mALLOPt(int param_number, int value)
-#else
-int mALLOPt(param_number, value) int param_number; int value;
-#endif
-{
-  switch(param_number)
-  {
-    case M_TRIM_THRESHOLD:
-      trim_threshold = value; return 1;
-    case M_TOP_PAD:
-      top_pad = value; return 1;
-    case M_MMAP_THRESHOLD:
-      mmap_threshold = value; return 1;
-    case M_MMAP_MAX:
-#if HAVE_MMAP
-      n_mmaps_max = value; return 1;
-#else
-      if (value != 0) return 0; else  n_mmaps_max = value; return 1;
-#endif
-
-    default:
-      return 0;
-  }
-}
-
-/*
-
-History:
-
-    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
-      * return null for negative arguments
-      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
-	 * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
-	  (e.g. WIN32 platforms)
-	 * Cleanup up header file inclusion for WIN32 platforms
-	 * Cleanup code to avoid Microsoft Visual C++ compiler complaints
-	 * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
-	   memory allocation routines
-	 * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
-	 * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
-	   usage of 'assert' in non-WIN32 code
-	 * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
-	   avoid infinite loop
-      * Always call 'fREe()' rather than 'free()'
-
-    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
-      * Fixed ordering problem with boundary-stamping
-
-    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
-      * Added pvalloc, as recommended by H.J. Liu
-      * Added 64bit pointer support mainly from Wolfram Gloger
-      * Added anonymously donated WIN32 sbrk emulation
-      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
-      * malloc_extend_top: fix mask error that caused wastage after
-	foreign sbrks
-      * Add linux mremap support code from HJ Liu
-
-    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
-      * Integrated most documentation with the code.
-      * Add support for mmap, with help from
-	Wolfram Gloger (Gloger at lrz.uni-muenchen.de).
-      * Use last_remainder in more cases.
-      * Pack bins using idea from  colin at nyx10.cs.du.edu
-      * Use ordered bins instead of best-fit threshhold
-      * Eliminate block-local decls to simplify tracing and debugging.
-      * Support another case of realloc via move into top
-      * Fix error occuring when initial sbrk_base not word-aligned.
-      * Rely on page size for units instead of SBRK_UNIT to
-	avoid surprises about sbrk alignment conventions.
-      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
-	(raymond at es.ele.tue.nl) for the suggestion.
-      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
-      * More precautions for cases where other routines call sbrk,
-	courtesy of Wolfram Gloger (Gloger at lrz.uni-muenchen.de).
-      * Added macros etc., allowing use in linux libc from
-	H.J. Lu (hjl at gnu.ai.mit.edu)
-      * Inverted this history list
-
-    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
-      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
-      * Removed all preallocation code since under current scheme
-	the work required to undo bad preallocations exceeds
-	the work saved in good cases for most test programs.
-      * No longer use return list or unconsolidated bins since
-	no scheme using them consistently outperforms those that don't
-	given above changes.
-      * Use best fit for very large chunks to prevent some worst-cases.
-      * Added some support for debugging
-
-    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
-      * Removed footers when chunks are in use. Thanks to
-	Paul Wilson (wilson at cs.texas.edu) for the suggestion.
-
-    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
-      * Added malloc_trim, with help from Wolfram Gloger
-	(wmglo at Dent.MED.Uni-Muenchen.DE).
-
-    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
-
-    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
-      * realloc: try to expand in both directions
-      * malloc: swap order of clean-bin strategy;
-      * realloc: only conditionally expand backwards
-      * Try not to scavenge used bins
-      * Use bin counts as a guide to preallocation
-      * Occasionally bin return list chunks in first scan
-      * Add a few optimizations from colin at nyx10.cs.du.edu
-
-    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
-      * faster bin computation & slightly different binning
-      * merged all consolidations to one part of malloc proper
-	 (eliminating old malloc_find_space & malloc_clean_bin)
-      * Scan 2 returns chunks (not just 1)
-      * Propagate failure in realloc if malloc returns 0
-      * Add stuff to allow compilation on non-ANSI compilers
-	  from kpv at research.att.com
-
-    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
-      * removed potential for odd address access in prev_chunk
-      * removed dependency on getpagesize.h
-      * misc cosmetics and a bit more internal documentation
-      * anticosmetics: mangled names in macros to evade debugger strangeness
-      * tested on sparc, hp-700, dec-mips, rs6000
-	  with gcc & native cc (hp, dec only) allowing
-	  Detlefs & Zorn comparison study (in SIGPLAN Notices.)
-
-    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
-      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
-	 structure of old version,  but most details differ.)
-
-*/


From marek.belisko at gmail.com  Tue Dec 21 02:42:41 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Tue, 21 Dec 2010 08:42:41 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <m3oc8gcae3.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
Message-ID: <AANLkTi=ptG8Ubx-caJ1Nnv7mxEZtKK5UAtWiPjEGj=H5@mail.gmail.com>

Hi,

On Tue, Dec 21, 2010 at 12:06 AM, Krzysztof Halasa <khc at pm.waw.pl> wrote:
> Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 8cb86cb..56b5a0d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -39,6 +39,13 @@ config ARCH_IMX
> ? ? ? ?bool "Freescale iMX-based"
> ? ? ? ?select GENERIC_GPIO
>
> +config ARCH_IXP4XX
> + ? ? ? bool "Intel IXP4xx-based"
> + ? ? ? select CPU_32v5
> + ? ? ? select ARCH_SUPPORTS_BIG_ENDIAN
> + ? ? ? select CPU_BIG_ENDIAN
> + ? ? ? select ARCH_HAS_LOWLEVEL_INIT
> +
Should go to different Kconfig. This is ARM related and you have
intel cpu which is possibly x86.  Also in other patches you stick to ARM
but your CPU doesn't have ARM core.

> ?config ARCH_STM
> ? ? ? ?bool "SigmaTel/FSL iMX-based"
> ? ? ? ?select GENERIC_GPIO
> @@ -67,6 +74,7 @@ source arch/arm/cpu/Kconfig
> ?source arch/arm/mach-at91/Kconfig
> ?source arch/arm/mach-ep93xx/Kconfig
> ?source arch/arm/mach-imx/Kconfig
> +source arch/arm/mach-ixp4xx/Kconfig
> ?source arch/arm/mach-stm/Kconfig
> ?source arch/arm/mach-netx/Kconfig
> ?source arch/arm/mach-nomadik/Kconfig
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 9729c23..2e9f99d 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
> ?machine-$(CONFIG_ARCH_AT91) ? ? ? ? ? ?:= at91
> ?machine-$(CONFIG_ARCH_EP93XX) ? ? ? ? ?:= ep93xx
> ?machine-$(CONFIG_ARCH_IMX) ? ? ? ? ? ? := imx
> +machine-$(CONFIG_ARCH_IXP4XX) ? ? ? ? ?:= ixp4xx
> ?machine-$(CONFIG_ARCH_STM) ? ? ? ? ? ? := stm
> ?machine-$(CONFIG_ARCH_NOMADIK) ? ? ? ? := nomadik
> ?machine-$(CONFIG_ARCH_NETX) ? ? ? ? ? ?:= netx
> @@ -73,6 +74,7 @@ board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) ? ?:= freescale-mx35-3-stack
> ?board-$(CONFIG_MACH_IMX21ADS) ? ? ? ? ? ? ? ? ?:= imx21ads
> ?board-$(CONFIG_MACH_IMX27ADS) ? ? ? ? ? ? ? ? ?:= imx27ads
> ?board-$(CONFIG_MACH_MMCCPU) ? ? ? ? ? ? ? ? ? ?:= mmccpu
> +board-$(CONFIG_MACH_MULTILINK) ? ? ? ? ? ? ? ? := multilink
> ?board-$(CONFIG_MACH_MX1ADS) ? ? ? ? ? ? ? ? ? ?:= mx1ads
> ?board-$(CONFIG_MACH_NOMADIK_8815NHK) ? ? ? ? ? := nhk8815
> ?board-$(CONFIG_MACH_NXDB500) ? ? ? ? ? ? ? ? ? := netx
> diff --git a/arch/arm/boards/multilink/Makefile b/arch/arm/boards/multilink/Makefile
> new file mode 100644
> index 0000000..d5a8bbc
> --- /dev/null
> +++ b/arch/arm/boards/multilink/Makefile
> @@ -0,0 +1 @@
> +obj-y += lowlevel_init.o multilink.o
> diff --git a/arch/arm/boards/multilink/config.h b/arch/arm/boards/multilink/config.h
> new file mode 100644
> index 0000000..e69de29
> diff --git a/arch/arm/boards/multilink/lowlevel_init.S b/arch/arm/boards/multilink/lowlevel_init.S
> new file mode 100644
> index 0000000..970ef72
> --- /dev/null
> +++ b/arch/arm/boards/multilink/lowlevel_init.S
> @@ -0,0 +1,64 @@
> +#include <mach/ixp4xx-regs.h>
> +
> + ? ? ? .section ".text_bare_init", "ax"
> + ? ? ? .balign 0x40
> + ? ? ? .space 0x40 /* configuration block at 0x40 */
> +
> + ? ? ? .macro DELAY_FOR cycles, reg0
> + ? ? ? ldr \reg0, =\cycles
> + ? ? ? subs \reg0, \reg0, #1
> + ? ? ? subne pc, pc, #0xc
> + ? ? ? .endm
> +
> +#define CFG_SDRAM_SIZE ? ?0x50 /* u32 */
> +#define CFG_SDRAM_CONF ? ?0x54 /* u32 */
> +#define CFG_SDRAM_MODE ? ?0x58 /* u32 */
> +#define CFG_SDRAM_REFRESH 0x5C /* u32 */
> +
> +.globl board_init_lowlevel
> +board_init_lowlevel:
> + ? ? ? mov r8, #IXP4XX_EXP_BASE(0)
> + ? ? ? ldr r1, [r8, #CFG_SDRAM_CONF]
> + ? ? ? ldr r2, =IXP4XX_SDRAM_CONFIG
> + ? ? ? str r1, [r2]
> +
> + ? ? ? /* disable refresh cycles */
> + ? ? ? mov r1, #0
> + ? ? ? add r2, r2, #4 /* r2 = IXP4XX_SDRAM_REFRESH */
> + ? ? ? str r1, [r2]
> +
> + ? ? ? /* send NOP command */
> + ? ? ? mov r1, #3
> + ? ? ? add r3, r2, #4 /* r3 = IXP4XX_SDRAM_IR */
> + ? ? ? str r1, [r3]
> + ? ? ? DELAY_FOR 0x4000, r0
> +
> + ? ? ? /* set SDRAM internal refresh */
> + ? ? ? ldr r1, [r8, #CFG_SDRAM_REFRESH]
> + ? ? ? str r1, [r2]
> + ? ? ? DELAY_FOR 0x4000, r0
> +
> + ? ? ? /* send precharge-all command to close all open banks */
> + ? ? ? mov r1, #2
> + ? ? ? str r1, [r3]
> + ? ? ? DELAY_FOR 0x4000, r0
> +
> + ? ? ? /* provide 8 auto-refresh cycles */
> + ? ? ? mov r1, #4
> + ? ? ? mov r4, #8
> +1: ? ? str r1, [r3]
> + ? ? ? DELAY_FOR 0x100, r0
> + ? ? ? subs r4, r4, #1
> + ? ? ? bne 1b
> +
> + ? ? ? /* set mode register in SDRAM */
> + ? ? ? ldr r1, [r8, #CFG_SDRAM_MODE]
> + ? ? ? str r1, [r3]
> + ? ? ? DELAY_FOR 0x4000, r0
> +
> + ? ? ? /* send normal operation command */
> + ? ? ? mov r1, #6
> + ? ? ? str r1, [r3]
> + ? ? ? DELAY_FOR 0x4000, r0
> +
> + ? ? ? mov pc, lr
> diff --git a/arch/arm/boards/multilink/multilink.c b/arch/arm/boards/multilink/multilink.c
> new file mode 100644
> index 0000000..f2fb8f4
> --- /dev/null
> +++ b/arch/arm/boards/multilink/multilink.c
> @@ -0,0 +1,144 @@
> +//#define DEBUG
> +#include <common.h>
> +#include <errno.h>
> +#include <init.h>
> +#include <linux/types.h>
> +#include <asm/armlinux.h>
> +#include <asm/io.h>
> +#include <generated/mach-types.h>
> +#include <mach/ixp4xx-regs.h>
> +#include <mach/platform.h>
> +
> +/* offsets from start of flash ROM = 0x50000000 */
> +#define CFG_ETH0_ADDRESS ? ? 0x40 /* 6 bytes */
> +#define CFG_ETH1_ADDRESS ? ? 0x46 /* 6 bytes */
> +#define CFG_REV ? ? ? ? ? ? ?0x4C /* u32 */
> +#define CFG_SDRAM_SIZE ? ? ? 0x50 /* u32 */
> +#define CFG_SDRAM_CONF ? ? ? 0x54 /* u32 */
> +#define CFG_SDRAM_MODE ? ? ? 0x58 /* u32 */
> +#define CFG_SDRAM_REFRESH ? ?0x5C /* u32 */
> +
> +#define CFG_HW_BITS ? ? ? ? ?0x60 /* u32 */
> +#define ?CFG_HW_USB_PORTS ? ?0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
> +#define ?CFG_HW_HAS_PCI_SLOT 0x00000008
> +#define ?CFG_HW_HAS_ETH0 ? ? 0x00000010
> +#define ?CFG_HW_HAS_ETH1 ? ? 0x00000020
> +#define ?CFG_HW_HAS_HSS0 ? ? 0x00000040
> +#define ?CFG_HW_HAS_HSS1 ? ? 0x00000080
> +#define ?CFG_HW_HAS_UART0 ? ?0x00000100
> +#define ?CFG_HW_HAS_UART1 ? ?0x00000200
> +#define ?CFG_HW_HAS_EEPROM ? 0x00000400
> +
> +#define ETH_ALEN ? ? ? ? ? ? 6
> +
> +#define BAREBOX_START ? ? ? ?0x00000
> +#define BAREBOX_LENGTH ? ? ? 0x34000
> +#define NPE_A_START ? ? ? ? ?(BAREBOX_START + BAREBOX_LENGTH)
> +#define NPE_A_LENGTH ? ? ? ? 0x05000
> +#define NPE_B_START ? ? ? ? ?(NPE_A_START + NPE_A_LENGTH)
> +#define NPE_B_LENGTH ? ? ? ? 0x03000
> +#define NPE_C_START ? ? ? ? ?(NPE_B_START + NPE_B_LENGTH)
> +#define NPE_C_LENGTH ? ? ? ? 0x04000
> +#define NPE_ENV0_START ? ? ? (NPE_C_START + NPE_C_LENGTH)
> +#define NPE_ENV0_LENGTH ? ? ?0x20000
> +
> +static struct device_d cfi_dev = {
> + ? ? ? .name ? ? = "cfi_flash",
> + ? ? ? .map_base = IXP4XX_EXP_BASE(0),
> + ? ? ? .size ? ? = 16 * 1024 * 1024,
> +};
> +
> +static struct eth_plat_info eth_pinfo[2] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .regs ? ? = IXP4XX_EthB_BASE,
> + ? ? ? ? ? ? ? .npe ? ? ?= 1,
> + ? ? ? ? ? ? ? .phy ? ? ?= 0,
> + ? ? ? ? ? ? ? .rxq ? ? ?= 20,
> + ? ? ? ? ? ? ? .txreadyq = 29,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .regs ? ? = IXP4XX_EthC_BASE,
> + ? ? ? ? ? ? ? .npe ? ? ?= 2,
> + ? ? ? ? ? ? ? .phy ? ? ?= 1,
> + ? ? ? ? ? ? ? .rxq ? ? ?= 21,
> + ? ? ? ? ? ? ? .txreadyq = 30,
> + ? ? ? }
> +};
> +
> +static struct device_d eth_dev[2] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .name ? ? ? ? ? = "ixp4xx_eth",
> + ? ? ? ? ? ? ? .platform_data ?= &eth_pinfo[0],
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .id ? ? ? ? ? ? = 1,
> + ? ? ? ? ? ? ? .name ? ? ? ? ? = "ixp4xx_eth",
> + ? ? ? ? ? ? ? .platform_data ?= &eth_pinfo[1],
> + ? ? ? }
> +};
> +
> +static struct memory_platform_data ram_pdata = {
> + ? ? ? .name ? ? ? ? ? = "ram0",
> + ? ? ? .flags ? ? ? ? ?= DEVFS_RDWR,
> +};
> +
> +struct device_d sdram_dev = {
> + ? ? ? .id ? ? ? ? ? ? = -1,
> + ? ? ? .name ? ? ? ? ? = "mem",
> + ? ? ? .map_base ? ? ? = 0x00000000,
> + ? ? ? .size ? ? ? ? ? = 32 * 1024 * 1024,
> + ? ? ? .platform_data ?= &ram_pdata,
> +};
> +
> +static inline u8 __init flash_readb(u32 addr)
> +{
> + ? ? ? return __raw_readb(IXP4XX_EXP_BASE(0) + addr);
> +}
> +
> +static int __init gml_devices_init(void)
> +{
> + ? ? ? u32 hw_bits;
> + ? ? ? int i;
> +
> + ? ? ? IXP4XX_EXP_CS0 = IXP4XX_EXP_EN | IXP4XX_EXP_INTEL |
> + ? ? ? ? ? ? ? IXP4XX_EXP_BITS(24) | IXP4XX_EXP_WR_EN | IXP4XX_EXP_BYTE_RD16;
> + ? ? ? i = register_device(&cfi_dev);
> + ? ? ? if (i)
> + ? ? ? ? ? ? ? goto out;
> +
> + ? ? ? devfs_add_partition("nor0", BAREBOX_START, BAREBOX_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "barebox");
> + ? ? ? devfs_add_partition("nor0", NPE_A_START, NPE_A_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-A");
> + ? ? ? devfs_add_partition("nor0", NPE_B_START, NPE_B_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-B");
> + ? ? ? devfs_add_partition("nor0", NPE_C_START, NPE_C_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-C");
> + ? ? ? devfs_add_partition("nor0", NPE_ENV0_START, NPE_ENV0_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? DEVFS_PARTITION_FIXED, "env0");
> +
> + ? ? ? hw_bits = __raw_readl(IXP4XX_EXP_BASE(0) + CFG_HW_BITS);
> +
> + ? ? ? if (hw_bits & CFG_HW_HAS_ETH0) {
> + ? ? ? ? ? ? ? for (i = 0; i < ETH_ALEN; i++)
> + ? ? ? ? ? ? ? ? ? ? ? eth_pinfo[0].hwaddr[i] = flash_readb(CFG_ETH0_ADDRESS + i);
> + ? ? ? ? ? ? ? register_device(&eth_dev[0]);
> + ? ? ? }
> +
> + ? ? ? if (hw_bits & CFG_HW_HAS_ETH1) {
> + ? ? ? ? ? ? ? for (i = 0; i < ETH_ALEN; i++)
> + ? ? ? ? ? ? ? ? ? ? ? eth_pinfo[1].hwaddr[i] = flash_readb(CFG_ETH1_ADDRESS + i);
> + ? ? ? ? ? ? ? register_device(&eth_dev[1]);
> + ? ? ? }
> +
> + ? ? ? sdram_dev.size = __raw_readl(IXP4XX_EXP_BASE(0) + CFG_SDRAM_SIZE);
> + ? ? ? i = register_device(&sdram_dev);
> + ? ? ? if (i)
> + ? ? ? ? ? ? ? goto out;
> +
> + ? ? ? armlinux_add_dram(&sdram_dev);
> + ? ? ? armlinux_set_bootparams((void *)(0x00000100));
> + ? ? ? armlinux_set_architecture(MACH_TYPE_GORAMO_MLR);
> +
> +out:
> + ? ? ? return i;
> +}
> +device_initcall(gml_devices_init);
> diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
> new file mode 100644
> index 0000000..f5e4b41
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/Kconfig
> @@ -0,0 +1,26 @@
> +if ARCH_IXP4XX
> +
> +choice
> + ? ? ? prompt "IXP4xx Board Type"
> +
> +config MACH_MULTILINK
> + ? ? ? bool "Goramo MultiLink"
> + ? ? ? select MACH_HAS_LOWLEVEL_INIT
> +endchoice
> +
> +config BOARDINFO
> + ? ? ? default "Goramo MultiLink" if MACH_MULTILINK
> +
> +config IXP4XX_QMGR
> + ? ? ? tristate "IXP4xx Queue Manager support"
> + ? ? ? help
> + ? ? ? ? This driver supports IXP4xx built-in hardware queue manager
> + ? ? ? ? and is required by the Ethernet driver.
> +
> +config IXP4XX_NPE
> + ? ? ? tristate "IXP4xx Network Processor Engine support"
> + ? ? ? help
> + ? ? ? ? This driver supports IXP4xx built-in network coprocessors
> + ? ? ? ? and is required by the Ethernet driver.
> +
> +endif
> diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
> new file mode 100644
> index 0000000..aa38991
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/Makefile
> @@ -0,0 +1,3 @@
> +obj-y += lowlevel_init.o generic.o
> +obj-$(CONFIG_IXP4XX_QMGR) += qmgr.o
> +obj-$(CONFIG_IXP4XX_NPE) += npe.o
> diff --git a/arch/arm/mach-ixp4xx/generic.c b/arch/arm/mach-ixp4xx/generic.c
> new file mode 100644
> index 0000000..02394a4
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/generic.c
> @@ -0,0 +1,120 @@
> +#include <common.h>
> +#include <init.h>
> +#include <ns16550.h>
> +#include <asm/armlinux.h>
> +#include <asm/io.h>
> +#include <mach/ixp4xx-regs.h>
> +
> +#define OSTS_FREQUENCY 66666000
> +
> +void reset_cpu(ulong addr)
> +{
> + ? ? ? /* Use on-chip reset capability */
> + ? ? ? /* This may not work on IXP425 rev. A0 */
> +
> + ? ? ? IXP4XX_OSWK = IXP4XX_WDT_KEY;
> + ? ? ? IXP4XX_OSWT = 0; /* request immediate reset */
> + ? ? ? IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
> + ? ? ? while (1)
> + ? ? ? ? ? ? ? ;
> +}
> +
> +#include <clock.h>
> +
> +/**
> + * @brief Provide a simple clock read
> + *
> + * Nothing is simpler.. read direct from clock and provide it
> + * to the caller.
> + *
> + * @return clock counter
> + */
> +static uint64_t ixp4xx_clocksource_read(void)
> +{
> + ? ? ? return IXP4XX_OSTS;
> +}
> +
> +static struct clocksource cs = {
> + ? ? ? .read = ixp4xx_clocksource_read,
> + ? ? ? .mask = 0xffffffff,
> + ? ? ? .shift = 10,
> +};
> +
> +/**
> + * @brief Initialize the Clock
> + *
> + * We use the Time-Stamp Timer
> + *
> + * @return result of @ref init_clock
> + */
> +static int ixp4xx_clocksource_init(void)
> +{
> + ? ? ? cs.mult = clocksource_hz2mult(OSTS_FREQUENCY, cs.shift);
> +
> + ? ? ? return init_clock(&cs);
> +}
> +
> +/* Run me at boot time */
> +core_initcall(ixp4xx_clocksource_init);
> +
> +
> +#ifdef CONFIG_DRIVER_SERIAL_NS16550
> +
> +/**
> + * @brief UART port register read function for IXP4XX
> + *
> + * @param base base address of UART
> + * @param reg_idx register index
> + *
> + * @return character read from register
> + */
> +unsigned int ixp4xx_uart_read(unsigned long base, unsigned char reg_idx)
> +{
> + ? ? ? return readb(4 * reg_idx + 3 /* big-endian */ + (uint8_t *)base);
> +}
> +EXPORT_SYMBOL(ixp4xx_uart_read);
> +
> +/**
> + * @brief UART port register write function for IXP4XX
> + *
> + * @param val value to write
> + * @param base base address of UART
> + * @param reg_idx register index
> + *
> + * @return void
> + */
> +void ixp4xx_uart_write(unsigned int val, unsigned long base, unsigned char reg_idx)
> +{
> + ? ? ? writeb(val, 4 * reg_idx + 3 /* big-endian */ + (uint8_t *)base);
> +}
> +EXPORT_SYMBOL(ixp4xx_uart_write);
> +
> +
> +static struct NS16550_plat serial_plat = {
> + ? ? ? .clock = 14745600,
> + ? ? ? .f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
> + ? ? ? .reg_read = ixp4xx_uart_read,
> + ? ? ? .reg_write = ixp4xx_uart_write,
> +};
> +
> +static struct device_d ixp4xx_serial_device = {
> + ? ? ? .name = "serial_ns16550",
> + ? ? ? .map_base = (u32)IXP4XX_UART1_BASE,
> + ? ? ? .size = 1024,
> + ? ? ? .platform_data = (void *)&serial_plat,
> +};
> +
> +/**
> + * @brief UART serial port initialization
> + *
> + * @return result of device registration
> + */
> +static int ixp4xx_console_init(void)
> +{
> + ? ? ? /* Register the serial port */
> + ? ? ? return register_device(&ixp4xx_serial_device);
> +}
> +
> +console_initcall(ixp4xx_console_init);
> +
> +#endif /* CONFIG_DRIVER_SERIAL_NS16550 */
> diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
> new file mode 100644
> index 0000000..3de021e
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
> @@ -0,0 +1,70 @@
> +/*
> + * arch/arm/mach-ixp4xx/include/mach/cpu.h
> + *
> + * IXP4XX cpu type detection
> + *
> + * Copyright (C) 2007 MontaVista Software, 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.
> + *
> + */
> +
> +#ifndef __ASM_ARCH_CPU_H__
> +#define __ASM_ARCH_CPU_H__
> +
> +#include <linux/types.h>
> +
> +/* Processor id value in CP15 Register 0 */
> +#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
> +#define IXP42X_PROCESSOR_ID_MASK ?0xffffffc0
> +
> +#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
> +#define IXP43X_PROCESSOR_ID_MASK ?0xfffffff0
> +
> +#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
> +#define IXP46X_PROCESSOR_ID_MASK ?0xfffffff0
> +
> +#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IXP42X_PROCESSOR_ID_VALUE)
> +#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
> + ? ? ? ? ? ? ? ? ? ? ? ?IXP42X_PROCESSOR_ID_VALUE)
> +#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
> + ? ? ? ? ? ? ? ? ? ? ? ?IXP43X_PROCESSOR_ID_VALUE)
> +#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
> + ? ? ? ? ? ? ? ? ? ? ? ?IXP46X_PROCESSOR_ID_VALUE)
> +
> +/*
> + * The CPU ID never changes at run time, so we might as well tell the
> + * compiler that it's constant. ?Use this function to read the CPU ID
> + * rather than directly reading processor_id or read_cpuid() directly.
> + */
> +static inline u32 __attribute_const__ read_cpuid_id(void)
> +{
> + ? ? ? u32 val;
> + ? ? ? asm("mrc p15, 0, %0, c0, c0, 0" : "=r" (val) : : "cc");
> +
> + ? ? ? return val;
> +}
> +
> +static inline u32 ixp4xx_read_feature_bits(void)
> +{
> + ? ? ? u32 val = ~IXP4XX_EXP_CFG2;
> +
> + ? ? ? if (cpu_is_ixp42x_rev_a0())
> + ? ? ? ? ? ? ? return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_AES);
> + ? ? ? if (cpu_is_ixp42x())
> + ? ? ? ? ? ? ? return val & IXP42X_FEATURE_MASK;
> + ? ? ? if (cpu_is_ixp43x())
> + ? ? ? ? ? ? ? return val & IXP43X_FEATURE_MASK;
> + ? ? ? return val & IXP46X_FEATURE_MASK;
> +}
> +
> +static inline void ixp4xx_write_feature_bits(u32 value)
> +{
> + ? ? ? IXP4XX_EXP_CFG2 = ~value;
> +}
> +
> +#endif ?/* _ASM_ARCH_CPU_H */
> diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
> new file mode 100644
> index 0000000..da4dc8a
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
> @@ -0,0 +1,365 @@
> +/*
> + * Register definitions for IXP4xx chipset.
> + *
> + * Copyright (C) 2002 Intel Corporation.
> + * Copyright (C) 2003-2004 MontaVista Software, 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.
> + *
> + */
> +
> +#ifndef _ASM_ARM_IXP4XX_H_
> +#define _ASM_ARM_IXP4XX_H_
> +
> +#ifdef __ASSEMBLER__
> +#define IXP4XX_REG(reg) ?(reg)
> +#else
> +#define IXP4XX_REG(reg) ?(*(volatile u32 *)(reg))
> +#define IXP4XX_BASE(reg) ((u32*)(reg))
> +#endif
> +
> +/* Expansion Bus region */
> +
> +/* Queue Manager */
> +#define IXP4XX_QMGR_BASE ? ? ? ? ? ? ?(0x60000000)
> +#define IXP4XX_QMGR_REGION_SIZE ? ? ? (0x00004000)
> +
> +
> +/* PCI Config registers */
> +#define IXP4XX_PCI_CFG_BASE ? ? ? ? ? (0xC0000000)
> +#define IXP4XX_PCI_CFG_REGION_SIZE ? ?(0x00001000)
> +
> +/* Peripheral space */
> +#define IXP4XX_PERIPHERAL_BASE ? ? ? ?(0xC8000000)
> +#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
> +
> +/*
> + * Debug UART
> + *
> + * This is basically a remap of UART1 into a region that is section
> + * aligned so that it can be used with the low-level debug code.
> + */
> +#define IXP4XX_DEBUG_UART_BASE ? ? ? ?(0xC8000000)
> +#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
> +
> +/* Expansion Bus Controller registers. */
> +#define IXP4XX_EXP_CS0 ? ? ? IXP4XX_REG(0xC4000000)
> +#define IXP4XX_EXP_CS1 ? ? ? IXP4XX_REG(0xC4000004)
> +#define IXP4XX_EXP_CS2 ? ? ? IXP4XX_REG(0xC4000008)
> +#define IXP4XX_EXP_CS3 ? ? ? IXP4XX_REG(0xC400000C)
> +#define IXP4XX_EXP_CS4 ? ? ? IXP4XX_REG(0xC4000010)
> +#define IXP4XX_EXP_CS5 ? ? ? IXP4XX_REG(0xC4000014)
> +#define IXP4XX_EXP_CS6 ? ? ? IXP4XX_REG(0xC4000018)
> +#define IXP4XX_EXP_CS7 ? ? ? IXP4XX_REG(0xC400001C)
> +
> +#define IXP4XX_EXP_BASE(n) ?(0x50000000 + (n) * 1000000)
> +
> +#define IXP4XX_EXP_EN ? ? ? ?0x80000000
> +#define IXP4XX_EXP_T1(n) ? ?(0x10000000 * (n)) /* valid: 0 - 3 */
> +#define IXP4XX_EXP_T2(n) ? ?(0x04000000 * (n)) /* valid: 0 - 3 */
> +#define IXP4XX_EXP_T3(n) ? ?(0x00400000 * (n)) /* valid: 0 - 15 */
> +#define IXP4XX_EXP_T4(n) ? ?(0x00100000 * (n)) /* valid: 0 - 3 */
> +#define IXP4XX_EXP_T5(n) ? ?(0x00010000 * (n)) /* valid: 0 - 15 */
> +#define IXP4XX_EXP_INTEL ? ? 0x00000000
> +#define IXP4XX_EXP_MOTO ? ? ?0x00004000
> +#define IXP4XX_EXP_HPI ? ? ? 0x00008000
> +#define IXP4XX_EXP_BITS(n) ?(0x00000400 * ((n) - 9)) /* valid: 9 - 24 */
> +#define IXP4XX_EXP_BYTE_RD16 0x00000040
> +#define IXP4XX_EXP_HRDY_POL ?0x00000020
> +#define IXP4XX_EXP_MUX_EN ? ?0x00000010
> +#define IXP4XX_EXP_SPLT_EN ? 0x00000008
> +#define IXP4XX_EXP_WR_EN ? ? 0x00000002
> +#define IXP4XX_EXP_BYTE_EN ? 0x00000001
> +
> +#define IXP4XX_EXP_CFG0 ? ? ?IXP4XX_REG(0xC4000020)
> +#define IXP4XX_EXP_CFG1 ? ? ?IXP4XX_REG(0xC4000024)
> +#define IXP4XX_EXP_CFG2 ? ? ?IXP4XX_REG(0xC4000028)
> +#define IXP4XX_EXP_CFG3 ? ? ?IXP4XX_REG(0xC400002C)
> +
> +
> +/* Peripheral Space Register Region Base Addresses */
> +#define IXP4XX_UART1_BASE ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x0000)
> +#define IXP4XX_UART2_BASE ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x1000)
> +#define IXP4XX_PMU_BASE ? ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x2000)
> +#define IXP4XX_INTC_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x3000)
> +#define IXP4XX_GPIO_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x4000)
> +#define IXP4XX_NPEA_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x6000)
> +#define IXP4XX_NPEB_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x7000)
> +#define IXP4XX_NPEC_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x8000)
> +#define IXP4XX_EthB_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x9000)
> +#define IXP4XX_EthC_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xA000)
> +#define IXP4XX_USB_BASE ? ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xB000)
> +/* IXP46x only */
> +#define IXP4XX_EthA_BASE ? ? IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xC000)
> +#define IXP4XX_EthB1_BASE ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xD000)
> +#define IXP4XX_EthB2_BASE ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xE000)
> +#define IXP4XX_EthB3_BASE ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xF000)
> +#define IXP4XX_TIMESYNC_BASE IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x10000)
> +#define IXP4XX_I2C_BASE ? ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x11000)
> +#define IXP4XX_SSP_BASE ? ? ?IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x12000)
> +
> +/*
> + ?Constants to make it easy to access Interrupt Controller registers
> + */
> +#define IXP4XX_ICPR_OFFSET ? 0x00 /* Interrupt Status */
> +#define IXP4XX_ICMR_OFFSET ? 0x04 /* Interrupt Enable */
> +#define IXP4XX_ICLR_OFFSET ? 0x08 /* Interrupt IRQ/FIQ Select */
> +#define IXP4XX_ICIP_OFFSET ? 0x0C /* IRQ Status */
> +#define IXP4XX_ICFP_OFFSET ? 0x10 /* FIQ Status */
> +#define IXP4XX_ICHR_OFFSET ? 0x14 /* Interrupt Priority */
> +#define IXP4XX_ICIH_OFFSET ? 0x18 /* IRQ Highest Pri Int */
> +#define IXP4XX_ICFH_OFFSET ? 0x1C /* FIQ Highest Pri Int */
> +
> +/* IXP465-only */
> +#define IXP4XX_ICPR2_OFFSET ?0x20 /* Interrupt Status 2 */
> +#define IXP4XX_ICMR2_OFFSET ?0x24 /* Interrupt Enable 2 */
> +#define IXP4XX_ICLR2_OFFSET ?0x28 /* Interrupt IRQ/FIQ Select 2 */
> +#define IXP4XX_ICIP2_OFFSET ?0x2C /* IRQ Status */
> +#define IXP4XX_ICFP2_OFFSET ?0x30 /* FIQ Status */
> +#define IXP4XX_ICEEN_OFFSET ?0x34 /* Error High Pri Enable */
> +
> +
> +/* Interrupt Controller Register Definitions. */
> +#define IXP4XX_INTC_REG(x) ? ((volatile u32 *)(IXP4XX_INTC_BASE + (x)))
> +
> +#define IXP4XX_ICPR ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
> +#define IXP4XX_ICMR ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
> +#define IXP4XX_ICLR ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
> +#define IXP4XX_ICIP ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
> +#define IXP4XX_ICFP ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
> +#define IXP4XX_ICHR ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
> +#define IXP4XX_ICIH ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET)
> +#define IXP4XX_ICFH ? ? ? ? ?IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
> +#define IXP4XX_ICPR2 ? ? ? ? IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
> +#define IXP4XX_ICMR2 ? ? ? ? IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
> +#define IXP4XX_ICLR2 ? ? ? ? IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
> +#define IXP4XX_ICIP2 ? ? ? ? IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
> +#define IXP4XX_ICFP2 ? ? ? ? IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
> +#define IXP4XX_ICEEN ? ? ? ? IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
> +
> +/* Constants to make it easy to access GPIO registers */
> +#define IXP4XX_GPIO_GPOUTR_OFFSET ? 0x00
> +#define IXP4XX_GPIO_GPOER_OFFSET ? ?0x04
> +#define IXP4XX_GPIO_GPINR_OFFSET ? ?0x08
> +#define IXP4XX_GPIO_GPISR_OFFSET ? ?0x0C
> +#define IXP4XX_GPIO_GPIT1R_OFFSET ? 0x10
> +#define IXP4XX_GPIO_GPIT2R_OFFSET ? 0x14
> +#define IXP4XX_GPIO_GPCLKR_OFFSET ? 0x18
> +#define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C
> +
> +/* GPIO Register Definitions - perform only 32-bit reads/writes */
> +#define IXP4XX_GPIO_REG(x) ? ((volatile u32 *)(IXP4XX_GPIO_BASE + (x)))
> +
> +#define IXP4XX_GPIO_GPOUTR ? IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
> +#define IXP4XX_GPIO_GPOER ? ?IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
> +#define IXP4XX_GPIO_GPINR ? ?IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
> +#define IXP4XX_GPIO_GPISR ? ?IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
> +#define IXP4XX_GPIO_GPIT1R ? IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
> +#define IXP4XX_GPIO_GPIT2R ? IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
> +#define IXP4XX_GPIO_GPCLKR ? IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
> +#define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
> +
> +/* GPIO register bit definitions */
> +
> +/* Interrupt styles */
> +#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH ?0x0
> +#define IXP4XX_GPIO_STYLE_ACTIVE_LOW ? 0x1
> +#define IXP4XX_GPIO_STYLE_RISING_EDGE ?0x2
> +#define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3
> +#define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4
> +
> +/* Mask used to clear interrupt styles */
> +#define IXP4XX_GPIO_STYLE_CLEAR ? ? ? ?0x7
> +#define IXP4XX_GPIO_STYLE_SIZE ? ? ? ? 3
> +
> +/* Operating System Timer Register Definitions. */
> +#define IXP4XX_OSTS ? ? ? ? ?IXP4XX_REG(0xC8005000) /* Continious TimeStamp */
> +#define IXP4XX_OST1 ? ? ? ? ?IXP4XX_REG(0xC8005004) /* Timer 1 Timestamp */
> +#define IXP4XX_OSRT1 ? ? ? ? IXP4XX_REG(0xC8005008) /* Timer 1 Reload */
> +#define IXP4XX_OST2 ? ? ? ? ?IXP4XX_REG(0xC800500C) /* Timer 2 Timestamp */
> +#define IXP4XX_OSRT2 ? ? ? ? IXP4XX_REG(0xC8005010) /* Timer 2 Reload */
> +#define IXP4XX_OSWT ? ? ? ? ?IXP4XX_REG(0xC8005014) /* Watchdog Timer */
> +#define IXP4XX_OSWE ? ? ? ? ?IXP4XX_REG(0xC8005018) /* Watchdog Enable */
> +#define IXP4XX_OSWK ? ? ? ? ?IXP4XX_REG(0xC800501C) /* Watchdog Key */
> +#define IXP4XX_OSST ? ? ? ? ?IXP4XX_REG(0xC8005020) /* Timer Status */
> +
> +/* Timer register values and bit definitions */
> +#define IXP4XX_OST_ENABLE ? ? ? ? ? ?0x00000001
> +#define IXP4XX_OST_ONE_SHOT ? ? ? ? ?0x00000002
> +/* Low order bits of reload value ignored */
> +#define IXP4XX_OST_RELOAD_MASK ? ? ? 0x00000003
> +#define IXP4XX_OST_DISABLED ? ? ? ? ?0x00000000
> +#define IXP4XX_OSST_TIMER_1_PEND ? ? 0x00000001
> +#define IXP4XX_OSST_TIMER_2_PEND ? ? 0x00000002
> +#define IXP4XX_OSST_TIMER_TS_PEND ? ?0x00000004
> +#define IXP4XX_OSST_TIMER_WDOG_PEND ?0x00000008
> +#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
> +
> +#define IXP4XX_WDT_KEY ? ? ? ? ? ? ? 0x0000482E
> +
> +#define IXP4XX_WDT_RESET_ENABLE ? ? ?0x00000001
> +#define IXP4XX_WDT_IRQ_ENABLE ? ? ? ?0x00000002
> +#define IXP4XX_WDT_COUNT_ENABLE ? ? ?0x00000004
> +
> +
> +/* Constants to make it easy to access PCI Control/Status registers */
> +#define PCI_NP_AD_OFFSET ? ? ? ? ? 0x00
> +#define PCI_NP_CBE_OFFSET ? ? ? ? ?0x04
> +#define PCI_NP_WDATA_OFFSET ? ? ? ?0x08
> +#define PCI_NP_RDATA_OFFSET ? ? ? ?0x0c
> +#define PCI_CRP_AD_CBE_OFFSET ? ? ?0x10
> +#define PCI_CRP_WDATA_OFFSET ? ? ? 0x14
> +#define PCI_CRP_RDATA_OFFSET ? ? ? 0x18
> +#define PCI_CSR_OFFSET ? ? ? ? ? ? 0x1c
> +#define PCI_ISR_OFFSET ? ? ? ? ? ? 0x20
> +#define PCI_INTEN_OFFSET ? ? ? ? ? 0x24
> +#define PCI_DMACTRL_OFFSET ? ? ? ? 0x28
> +#define PCI_AHBMEMBASE_OFFSET ? ? ?0x2c
> +#define PCI_AHBIOBASE_OFFSET ? ? ? 0x30
> +#define PCI_PCIMEMBASE_OFFSET ? ? ?0x34
> +#define PCI_AHBDOORBELL_OFFSET ? ? 0x38
> +#define PCI_PCIDOORBELL_OFFSET ? ? 0x3C
> +#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
> +#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
> +#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
> +#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
> +#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
> +#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
> +
> +/* PCI Control/Status Registers */
> +#define IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE + (x)))
> +
> +#define PCI_NP_AD ? ? ? ? ? ?IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
> +#define PCI_NP_CBE ? ? ? ? ? IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
> +#define PCI_NP_WDATA ? ? ? ? IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
> +#define PCI_NP_RDATA ? ? ? ? IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
> +#define PCI_CRP_AD_CBE ? ? ? IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
> +#define PCI_CRP_WDATA ? ? ? ?IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
> +#define PCI_CRP_RDATA ? ? ? ?IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
> +#define PCI_CSR ? ? ? ? ? ? ?IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
> +#define PCI_ISR ? ? ? ? ? ? ?IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
> +#define PCI_INTEN ? ? ? ? ? ?IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
> +#define PCI_DMACTRL ? ? ? ? ?IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
> +#define PCI_AHBMEMBASE ? ? ? IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
> +#define PCI_AHBIOBASE ? ? ? ?IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
> +#define PCI_PCIMEMBASE ? ? ? IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
> +#define PCI_AHBDOORBELL ? ? ?IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
> +#define PCI_PCIDOORBELL ? ? ?IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
> +#define PCI_ATPDMA0_AHBADDR ?IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
> +#define PCI_ATPDMA0_PCIADDR ?IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
> +#define PCI_ATPDMA0_LENADDR ?IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
> +#define PCI_ATPDMA1_AHBADDR ?IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
> +#define PCI_ATPDMA1_PCIADDR ?IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
> +#define PCI_ATPDMA1_LENADDR ?IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
> +
> +/* PCI register values and bit definitions */
> +
> +/* CSR bit definitions */
> +#define PCI_CSR_HOST ? ? ? ? 0x00000001
> +#define PCI_CSR_ARBEN ? ? ? ?0x00000002
> +#define PCI_CSR_ADS ? ? ? ? ?0x00000004
> +#define PCI_CSR_PDS ? ? ? ? ?0x00000008
> +#define PCI_CSR_ABE ? ? ? ? ?0x00000010
> +#define PCI_CSR_DBT ? ? ? ? ?0x00000020
> +#define PCI_CSR_ASE ? ? ? ? ?0x00000100
> +#define PCI_CSR_IC ? ? ? ? ? 0x00008000
> +
> +/* ISR (Interrupt status) Register bit definitions */
> +#define PCI_ISR_PSE ? ? ? ? ?0x00000001
> +#define PCI_ISR_PFE ? ? ? ? ?0x00000002
> +#define PCI_ISR_PPE ? ? ? ? ?0x00000004
> +#define PCI_ISR_AHBE ? ? ? ? 0x00000008
> +#define PCI_ISR_APDC ? ? ? ? 0x00000010
> +#define PCI_ISR_PADC ? ? ? ? 0x00000020
> +#define PCI_ISR_ADB ? ? ? ? ?0x00000040
> +#define PCI_ISR_PDB ? ? ? ? ?0x00000080
> +
> +/* INTEN (Interrupt Enable) Register bit definitions */
> +#define PCI_INTEN_PSE ? ? ? ?0x00000001
> +#define PCI_INTEN_PFE ? ? ? ?0x00000002
> +#define PCI_INTEN_PPE ? ? ? ?0x00000004
> +#define PCI_INTEN_AHBE ? ? ? 0x00000008
> +#define PCI_INTEN_APDC ? ? ? 0x00000010
> +#define PCI_INTEN_PADC ? ? ? 0x00000020
> +#define PCI_INTEN_ADB ? ? ? ?0x00000040
> +#define PCI_INTEN_PDB ? ? ? ?0x00000080
> +
> +/* Shift value for byte enable on NP cmd/byte enable register */
> +#define IXP4XX_PCI_NP_CBE_BESL 4
> +
> +/* PCI commands supported by NP access unit */
> +#define NP_CMD_IOREAD ? ? ? ?0x2
> +#define NP_CMD_IOWRITE ? ? ? 0x3
> +#define NP_CMD_CONFIGREAD ? ?0xA
> +#define NP_CMD_CONFIGWRITE ? 0xB
> +#define NP_CMD_MEMREAD ? ? ? 0x6
> +#define NP_CMD_MEMWRITE ? ? ?0x7
> +
> +/* Constants for CRP access into local config space */
> +#define CRP_AD_CBE_BESL ? ? ?20
> +#define CRP_AD_CBE_WRITE ? ? 0x00010000
> +
> +/* USB Device Controller */
> +# define IXP4XX_USB_REG(x) ? (*((volatile u32 *)(x)))
> +
> +/* SDRAM Controller registers. */
> +#define IXP4XX_SDRAM_CONFIG ?IXP4XX_REG(0xCC000000)
> +#define IXP4XX_SDRAM_REFRESH IXP4XX_REG(0xCC000004)
> +#define IXP4XX_SDRAM_IR ? ? ?IXP4XX_REG(0xCC000008)
> +
> +/* "fuse" bits of IXP_EXP_CFG2 */
> +/* All IXP4xx CPUs */
> +#define IXP4XX_FEATURE_RCOMP ? ? ? ? ? ?(1 << 0)
> +#define IXP4XX_FEATURE_USB_DEVICE ? ? ? (1 << 1)
> +#define IXP4XX_FEATURE_HASH ? ? ? ? ? ? (1 << 2)
> +#define IXP4XX_FEATURE_AES ? ? ? ? ? ? ?(1 << 3)
> +#define IXP4XX_FEATURE_DES ? ? ? ? ? ? ?(1 << 4)
> +#define IXP4XX_FEATURE_HDLC ? ? ? ? ? ? (1 << 5)
> +#define IXP4XX_FEATURE_AAL ? ? ? ? ? ? ?(1 << 6)
> +#define IXP4XX_FEATURE_HSS ? ? ? ? ? ? ?(1 << 7)
> +#define IXP4XX_FEATURE_UTOPIA ? ? ? ? ? (1 << 8)
> +#define IXP4XX_FEATURE_NPEB_ETH0 ? ? ? ?(1 << 9)
> +#define IXP4XX_FEATURE_NPEC_ETH ? ? ? ? (1 << 10)
> +#define IXP4XX_FEATURE_RESET_NPEA ? ? ? (1 << 11)
> +#define IXP4XX_FEATURE_RESET_NPEB ? ? ? (1 << 12)
> +#define IXP4XX_FEATURE_RESET_NPEC ? ? ? (1 << 13)
> +#define IXP4XX_FEATURE_PCI ? ? ? ? ? ? ?(1 << 14)
> +#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
> +#define IXP4XX_FEATURE_XSCALE_MAX_FREQ ?(3 << 22)
> +#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP ? ? ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_USB_DEVICE ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_HASH ? ? ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_AES ? ? ? ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_DES ? ? ? ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_HDLC ? ? ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_AAL ? ? ? ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_HSS ? ? ? ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_UTOPIA ? ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_NPEB_ETH0 ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_NPEC_ETH ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_RESET_NPEA ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_RESET_NPEB ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_RESET_NPEC ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_PCI ? ? ? ? ? ? ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_XSCALE_MAX_FREQ)
> +
> +/* IXP43x/46x CPUs */
> +#define IXP4XX_FEATURE_ECC_TIMESYNC ? ? (1 << 15)
> +#define IXP4XX_FEATURE_USB_HOST ? ? ? ? (1 << 18)
> +#define IXP4XX_FEATURE_NPEA_ETH ? ? ? ? (1 << 19)
> +#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK ? ? ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_ECC_TIMESYNC ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_USB_HOST ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_NPEA_ETH)
> +
> +/* IXP46x CPU (including IXP455) only */
> +#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3 ?(1 << 20)
> +#define IXP4XX_FEATURE_RSA ? ? ? ? ? ? ?(1 << 21)
> +#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK ? ? ? ? ? ? | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_NPEB_ETH_1_TO_3 ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?IXP4XX_FEATURE_RSA)
> +
> +#endif
> diff --git a/arch/arm/mach-ixp4xx/include/mach/npe.h b/arch/arm/mach-ixp4xx/include/mach/npe.h
> new file mode 100644
> index 0000000..18bd01b
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/include/mach/npe.h
> @@ -0,0 +1,30 @@
> +#ifndef __IXP4XX_NPE_H
> +#define __IXP4XX_NPE_H
> +
> +#include <common.h>
> +
> +#define NPE_NAME_LENGTH 5
> +
> +struct npe_regs {
> + ? ? ? u32 exec_addr, exec_data, exec_status_cmd, exec_count;
> + ? ? ? u32 action_points[4];
> + ? ? ? u32 watchpoint_fifo, watch_count;
> + ? ? ? u32 profile_count;
> + ? ? ? u32 messaging_status, messaging_control;
> + ? ? ? u32 mailbox_status, /*messaging_*/ in_out_fifo;
> +};
> +
> +struct npe {
> + ? ? ? struct npe_regs *regs;
> + ? ? ? int id, valid;
> + ? ? ? const char name[NPE_NAME_LENGTH + 1];
> +};
> +
> +int npe_running(struct npe *npe);
> +int npe_send_message(struct npe *npe, const void *msg, const char *what);
> +int npe_recv_message(struct npe *npe, void *msg, const char *what);
> +int npe_send_recv_message(struct npe *npe, void *msg, const char *what);
> +int npe_load_firmware(struct npe *npe);
> +struct npe *npe_request(int id);
> +
> +#endif /* __IXP4XX_NPE_H */
> diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
> new file mode 100644
> index 0000000..1df4aa4
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
> @@ -0,0 +1,15 @@
> +#include <asm/types.h>
> +
> +#define IXP4XX_ETH_NPEA 0x00
> +#define IXP4XX_ETH_NPEB 0x10
> +#define IXP4XX_ETH_NPEC 0x20
> +
> +/* Information about built-in Ethernet MAC interfaces */
> +struct eth_plat_info {
> + ? ? ? void *regs;
> + ? ? ? u8 npe;
> + ? ? ? u8 phy; /* MII PHY ID, 0 - 31 */
> + ? ? ? u8 rxq; /* configurable, currently 0 - 31 only */
> + ? ? ? u8 txreadyq;
> + ? ? ? u8 hwaddr[6];
> +};
> diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
> new file mode 100644
> index 0000000..4e9b8d4
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
> @@ -0,0 +1,164 @@
> +/*
> + * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License
> + * as published by the Free Software Foundation.
> + */
> +
> +#ifndef IXP4XX_QMGR_H
> +#define IXP4XX_QMGR_H
> +
> +#include <common.h>
> +#include <mach/ixp4xx-regs.h>
> +#include <asm/io.h>
> +
> +#define DEBUG_QMGR ? ? ? 0
> +
> +#define HALF_QUEUES ? ? 32
> +#define QUEUES ? ? ? ? ?64
> +#define MAX_QUEUE_LENGTH 4 /* in dwords */
> +
> +#define QUEUE_STAT1_EMPTY ? ? ? ? ? ? ? 1 /* queue status bits */
> +#define QUEUE_STAT1_NEARLY_EMPTY ? ? ? ?2
> +#define QUEUE_STAT1_NEARLY_FULL ? ? ? ? 4
> +#define QUEUE_STAT1_FULL ? ? ? ? ? ? ? ?8
> +#define QUEUE_STAT2_UNDERFLOW ? ? ? ? ? 1
> +#define QUEUE_STAT2_OVERFLOW ? ? ? ? ? ?2
> +
> +#define QUEUE_WATERMARK_0_ENTRIES ? ? ? 0
> +#define QUEUE_WATERMARK_1_ENTRY ? ? ? ? 1
> +#define QUEUE_WATERMARK_2_ENTRIES ? ? ? 2
> +#define QUEUE_WATERMARK_4_ENTRIES ? ? ? 3
> +#define QUEUE_WATERMARK_8_ENTRIES ? ? ? 4
> +#define QUEUE_WATERMARK_16_ENTRIES ? ? ?5
> +#define QUEUE_WATERMARK_32_ENTRIES ? ? ?6
> +#define QUEUE_WATERMARK_64_ENTRIES ? ? ?7
> +
> +/* queue interrupt request conditions */
> +#define QUEUE_IRQ_SRC_EMPTY ? ? ? ? ? ? 0
> +#define QUEUE_IRQ_SRC_NEARLY_EMPTY ? ? ?1
> +#define QUEUE_IRQ_SRC_NEARLY_FULL ? ? ? 2
> +#define QUEUE_IRQ_SRC_FULL ? ? ? ? ? ? ?3
> +#define QUEUE_IRQ_SRC_NOT_EMPTY ? ? ? ? 4
> +#define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY ?5
> +#define QUEUE_IRQ_SRC_NOT_NEARLY_FULL ? 6
> +#define QUEUE_IRQ_SRC_NOT_FULL ? ? ? ? ?7
> +
> +struct qmgr_regs {
> + ? ? ? u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */
> + ? ? ? u32 stat1[4]; ? ? ? ? /* 0x400 - 0x40F */
> + ? ? ? u32 stat2[2]; ? ? ? ? /* 0x410 - 0x417 */
> + ? ? ? u32 statne_h; ? ? ? ? /* 0x418 - queue nearly empty */
> + ? ? ? u32 statf_h; ? ? ? ? ?/* 0x41C - queue full */
> + ? ? ? u32 irqsrc[4]; ? ? ? ?/* 0x420 - 0x42F IRC source */
> + ? ? ? u32 irqen[2]; ? ? ? ? /* 0x430 - 0x437 IRQ enabled */
> + ? ? ? u32 irqstat[2]; ? ? ? /* 0x438 - 0x43F - IRQ access only */
> + ? ? ? u32 reserved[1776];
> + ? ? ? u32 sram[2048]; ? ? ? /* 0x2000 - 0x3FFF - config and buffer */
> +};
> +
> +static const struct qmgr_regs *qmgr_regs = (struct qmgr_regs *)IXP4XX_QMGR_BASE;
> +
> +void qmgr_set_irq(unsigned int queue, int src,
> + ? ? ? ? ? ? ? ? void (*handler)(void *pdev), void *pdev);
> +void qmgr_enable_irq(unsigned int queue);
> +void qmgr_disable_irq(unsigned int queue);
> +
> +/* request_ and release_queue() must be called from non-IRQ context */
> +
> +#if DEBUG_QMGR
> +extern char qmgr_queue_descs[HALF_QUEUES][32];
> +
> +void qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
> + ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_empty_watermark,
> + ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_full_watermark,
> + ? ? ? ? ? ? ? ? ? ? ? const char *desc_format, const char* name);
> +#else
> +void __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
> + ? ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_empty_watermark,
> + ? ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_full_watermark);
> +#define qmgr_request_queue(queue, len, nearly_empty_watermark, ? ? ? \
> + ? ? ? ? ? ? ? ? ? ? ? ? ?nearly_full_watermark, desc_format, name) \
> + ? ? ? __qmgr_request_queue(queue, len, nearly_empty_watermark, ? ? \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?nearly_full_watermark)
> +#endif
> +
> +void qmgr_release_queue(unsigned int queue);
> +
> +
> +static inline void qmgr_put_entry(unsigned int queue, u32 val)
> +{
> +#if DEBUG_QMGR
> + ? ? ? BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
> +
> + ? ? ? fprintf(stderr, "Queue %s(%i) put %X\n",
> + ? ? ? ? ? ? ? qmgr_queue_descs[queue], queue, val);
> +#endif
> + ? ? ? __raw_writel(val, &qmgr_regs->acc[queue][0]);
> +}
> +
> +static inline u32 qmgr_get_entry(unsigned int queue)
> +{
> + ? ? ? u32 val;
> + ? ? ? val = __raw_readl(&qmgr_regs->acc[queue][0]);
> +#if DEBUG_QMGR
> + ? ? ? BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
> +
> + ? ? ? fprintf(stderr, "Queue %s(%i) get %X\n",
> + ? ? ? ? ? ? ? qmgr_queue_descs[queue], queue, val);
> +#endif
> + ? ? ? return val;
> +}
> +
> +static inline int __qmgr_get_stat1(unsigned int queue)
> +{
> + ? ? ? return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
> + ? ? ? ? ? ? ? >> ((queue & 7) << 2)) & 0xF;
> +}
> +
> +/**
> + * qmgr_stat_empty() - checks if a hardware queue is empty
> + * @queue: queue number
> + *
> + * Returns non-zero value if the queue is empty.
> + */
> +static inline int qmgr_stat_empty(unsigned int queue)
> +{
> + ? ? ? return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
> +}
> +
> +/**
> + * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
> + * @queue: queue number
> + *
> + * Returns non-zero value if the queue is below low watermark.
> + */
> +static inline int qmgr_stat_below_low_watermark(unsigned int queue)
> +{
> + ? ? ? return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
> +}
> +
> +/**
> + * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
> + * @queue: queue number
> + *
> + * Returns non-zero value if the queue is above high watermark
> + */
> +static inline int qmgr_stat_above_high_watermark(unsigned int queue)
> +{
> + ? ? ? return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
> +}
> +
> +/**
> + * qmgr_stat_full() - checks if a hardware queue is full
> + * @queue: queue number
> + *
> + * Returns non-zero value if the queue is full.
> + */
> +static inline int qmgr_stat_full(unsigned int queue)
> +{
> + ? ? ? return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
> +}
> +
> +#endif
> diff --git a/arch/arm/mach-ixp4xx/lowlevel_init.S b/arch/arm/mach-ixp4xx/lowlevel_init.S
> new file mode 100644
> index 0000000..a4e93ef
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/lowlevel_init.S
> @@ -0,0 +1,17 @@
> +#include <mach/ixp4xx-regs.h>
> +
> + ? ? ? .section ".text_bare_init", "ax"
> +
> + ? ? ? .globl arch_init_lowlevel
> +arch_init_lowlevel:
> + ? ? ? ldr r0, cfg
> + ? ? ? ldr r1, [r0]
> + ? ? ? and r1, r1, #~0x80000000 /* unmap EXP bus from 0x0 */
> + ? ? ? str r1, [r0]
> +
> + ? ? ? /* return to ROM */
> + ? ? ? orr lr, #0x50000000
> + ? ? ? mov pc, lr
> +
> +cfg:
> + ? ? ? .word IXP4XX_EXP_CFG0
> diff --git a/arch/arm/mach-ixp4xx/npe.c b/arch/arm/mach-ixp4xx/npe.c
> new file mode 100644
> index 0000000..a8ddd5a
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/npe.c
> @@ -0,0 +1,668 @@
> +/*
> + * Intel IXP4xx Network Processor Engine driver for Linux
> + *
> + * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License
> + * as published by the Free Software Foundation.
> + */
> +
> +#include <common.h>
> +#include <errno.h>
> +#include <fs.h>
> +#include <init.h>
> +#include <malloc.h>
> +#include <asm/byteorder.h>
> +#include <asm/io.h>
> +#include <mach/ixp4xx-regs.h>
> +#include <mach/cpu.h>
> +#include <mach/npe.h>
> +
> +#define DEBUG_MSG ? ? ? ? ? ? ? ? ? ? ?0
> +#define DEBUG_FW ? ? ? ? ? ? ? ? ? ? ? 0
> +
> +#define NPE_COUNT ? ? ? ? ? ? ? ? ? ? ?3
> +#define MAX_RETRIES ? ? ? ? ? ? ? ? ? ?1000 ?/* microseconds */
> +#define NPE_42X_DATA_SIZE ? ? ? ? ? ? ?0x800 /* in dwords */
> +#define NPE_46X_DATA_SIZE ? ? ? ? ? ? ?0x1000
> +#define NPE_A_42X_INSTR_SIZE ? ? ? ? ? 0x1000
> +#define NPE_B_AND_C_42X_INSTR_SIZE ? ? 0x800
> +#define NPE_46X_INSTR_SIZE ? ? ? ? ? ? 0x1000
> +#define REGS_SIZE ? ? ? ? ? ? ? ? ? ? ?0x1000
> +
> +#define NPE_PHYS_REG ? ? ? ? ? ? ? ? ? 32
> +
> +#define FW_MAGIC ? ? ? ? ? ? ? ? ? ? ? 0xFEEDF00D
> +#define FW_BLOCK_TYPE_INSTR ? ? ? ? ? ?0x0
> +#define FW_BLOCK_TYPE_DATA ? ? ? ? ? ? 0x1
> +#define FW_BLOCK_TYPE_EOF ? ? ? ? ? ? ?0xF
> +
> +/* NPE exec status (read) and command (write) */
> +#define CMD_NPE_STEP ? ? ? ? ? ? ? ? ? 0x01
> +#define CMD_NPE_START ? ? ? ? ? ? ? ? ?0x02
> +#define CMD_NPE_STOP ? ? ? ? ? ? ? ? ? 0x03
> +#define CMD_NPE_CLR_PIPE ? ? ? ? ? ? ? 0x04
> +#define CMD_CLR_PROFILE_CNT ? ? ? ? ? ?0x0C
> +#define CMD_RD_INS_MEM ? ? ? ? ? ? ? ? 0x10 /* instruction memory */
> +#define CMD_WR_INS_MEM ? ? ? ? ? ? ? ? 0x11
> +#define CMD_RD_DATA_MEM ? ? ? ? ? ? ? ?0x12 /* data memory */
> +#define CMD_WR_DATA_MEM ? ? ? ? ? ? ? ?0x13
> +#define CMD_RD_ECS_REG ? ? ? ? ? ? ? ? 0x14 /* exec access register */
> +#define CMD_WR_ECS_REG ? ? ? ? ? ? ? ? 0x15
> +
> +#define STAT_RUN ? ? ? ? ? ? ? ? ? ? ? 0x80000000
> +#define STAT_STOP ? ? ? ? ? ? ? ? ? ? ?0x40000000
> +#define STAT_CLEAR ? ? ? ? ? ? ? ? ? ? 0x20000000
> +#define STAT_ECS_K ? ? ? ? ? ? ? ? ? ? 0x00800000 /* pipeline clean */
> +
> +#define NPE_STEVT ? ? ? ? ? ? ? ? ? ? ?0x1B
> +#define NPE_STARTPC ? ? ? ? ? ? ? ? ? ?0x1C
> +#define NPE_REGMAP ? ? ? ? ? ? ? ? ? ? 0x1E
> +#define NPE_CINDEX ? ? ? ? ? ? ? ? ? ? 0x1F
> +
> +#define INSTR_WR_REG_SHORT ? ? ? ? ? ? 0x0000C000
> +#define INSTR_WR_REG_BYTE ? ? ? ? ? ? ?0x00004000
> +#define INSTR_RD_FIFO ? ? ? ? ? ? ? ? ?0x0F888220
> +#define INSTR_RESET_MBOX ? ? ? ? ? ? ? 0x0FAC8210
> +
> +#define ECS_BG_CTXT_REG_0 ? ? ? ? ? ? ?0x00 /* Background Executing Context */
> +#define ECS_BG_CTXT_REG_1 ? ? ? ? ? ? ?0x01 /* Stack level */
> +#define ECS_BG_CTXT_REG_2 ? ? ? ? ? ? ?0x02
> +#define ECS_PRI_1_CTXT_REG_0 ? ? ? ? ? 0x04 /* Priority 1 Executing Context */
> +#define ECS_PRI_1_CTXT_REG_1 ? ? ? ? ? 0x05 /* Stack level */
> +#define ECS_PRI_1_CTXT_REG_2 ? ? ? ? ? 0x06
> +#define ECS_PRI_2_CTXT_REG_0 ? ? ? ? ? 0x08 /* Priority 2 Executing Context */
> +#define ECS_PRI_2_CTXT_REG_1 ? ? ? ? ? 0x09 /* Stack level */
> +#define ECS_PRI_2_CTXT_REG_2 ? ? ? ? ? 0x0A
> +#define ECS_DBG_CTXT_REG_0 ? ? ? ? ? ? 0x0C /* Debug Executing Context */
> +#define ECS_DBG_CTXT_REG_1 ? ? ? ? ? ? 0x0D /* Stack level */
> +#define ECS_DBG_CTXT_REG_2 ? ? ? ? ? ? 0x0E
> +#define ECS_INSTRUCT_REG ? ? ? ? ? ? ? 0x11 /* NPE Instruction Register */
> +
> +#define ECS_REG_0_ACTIVE ? ? ? ? ? ? ? 0x80000000 /* all levels */
> +#define ECS_REG_0_NEXTPC_MASK ? ? ? ? ?0x1FFF0000 /* BG/PRI1/PRI2 levels */
> +#define ECS_REG_0_LDUR_BITS ? ? ? ? ? ?8
> +#define ECS_REG_0_LDUR_MASK ? ? ? ? ? ?0x00000700 /* all levels */
> +#define ECS_REG_1_CCTXT_BITS ? ? ? ? ? 16
> +#define ECS_REG_1_CCTXT_MASK ? ? ? ? ? 0x000F0000 /* all levels */
> +#define ECS_REG_1_SELCTXT_BITS ? ? ? ? 0
> +#define ECS_REG_1_SELCTXT_MASK ? ? ? ? 0x0000000F /* all levels */
> +#define ECS_DBG_REG_2_IF ? ? ? ? ? ? ? 0x00100000 /* debug level */
> +#define ECS_DBG_REG_2_IE ? ? ? ? ? ? ? 0x00080000 /* debug level */
> +
> +/* NPE watchpoint_fifo register bit */
> +#define WFIFO_VALID ? ? ? ? ? ? ? ? ? ?0x80000000
> +
> +/* NPE messaging_status register bit definitions */
> +#define MSGSTAT_OFNE ?0x00010000 /* OutFifoNotEmpty */
> +#define MSGSTAT_IFNF ?0x00020000 /* InFifoNotFull */
> +#define MSGSTAT_OFNF ?0x00040000 /* OutFifoNotFull */
> +#define MSGSTAT_IFNE ?0x00080000 /* InFifoNotEmpty */
> +#define MSGSTAT_MBINT 0x00100000 /* Mailbox interrupt */
> +#define MSGSTAT_IFINT 0x00200000 /* InFifo interrupt */
> +#define MSGSTAT_OFINT 0x00400000 /* OutFifo interrupt */
> +#define MSGSTAT_WFINT 0x00800000 /* WatchFifo interrupt */
> +
> +/* NPE messaging_control register bit definitions */
> +#define MSGCTL_OUT_FIFO ? ? ? 0x00010000 /* enable output FIFO */
> +#define MSGCTL_IN_FIFO ? ? ? ?0x00020000 /* enable input FIFO */
> +#define MSGCTL_OUT_FIFO_WRITE 0x01000000 /* enable FIFO + WRITE */
> +#define MSGCTL_IN_FIFO_WRITE ?0x02000000
> +
> +/* NPE mailbox_status value for reset */
> +#define RESET_MBOX_STAT ? ? ? ? ?0x0000F0F0
> +
> +#define print_npe(npe, fmt, ...) fprintf(stderr, "%s: " fmt, npe->name, ## __VA_ARGS__)
> +
> +#if DEBUG_MSG
> +#define debug_msg(npe, fmt, ...) print_npe(npe, fmt, ## __VA_ARGS__)
> +#else
> +#define debug_msg(npe, fmt, ...)
> +#endif
> +
> +static struct {
> + ? ? ? u32 reg, val;
> +} ecs_reset[] = {
> + ? ? ? {ECS_BG_CTXT_REG_0, ? ?0xA0000000},
> + ? ? ? {ECS_BG_CTXT_REG_1, ? ?0x01000000},
> + ? ? ? {ECS_BG_CTXT_REG_2, ? ?0x00008000},
> + ? ? ? {ECS_PRI_1_CTXT_REG_0, 0x20000080},
> + ? ? ? {ECS_PRI_1_CTXT_REG_1, 0x01000000},
> + ? ? ? {ECS_PRI_1_CTXT_REG_2, 0x00008000},
> + ? ? ? {ECS_PRI_2_CTXT_REG_0, 0x20000080},
> + ? ? ? {ECS_PRI_2_CTXT_REG_1, 0x01000000},
> + ? ? ? {ECS_PRI_2_CTXT_REG_2, 0x00008000},
> + ? ? ? {ECS_DBG_CTXT_REG_0, ? 0x20000000},
> + ? ? ? {ECS_DBG_CTXT_REG_1, ? 0x00000000},
> + ? ? ? {ECS_DBG_CTXT_REG_2, ? 0x001E0000},
> + ? ? ? {ECS_INSTRUCT_REG, ? ? 0x1003C00F},
> +};
> +
> +static struct npe npe_tab[NPE_COUNT] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .regs = (struct npe_regs *)IXP4XX_NPEA_BASE,
> + ? ? ? ? ? ? ? .id = 0,
> + ? ? ? ? ? ? ? .name = "NPE-A",
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .regs = (struct npe_regs *)IXP4XX_NPEB_BASE,
> + ? ? ? ? ? ? ? .id = 1,
> + ? ? ? ? ? ? ? .name = "NPE-B",
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .regs = (struct npe_regs *)IXP4XX_NPEC_BASE,
> + ? ? ? ? ? ? ? .id = 2,
> + ? ? ? ? ? ? ? .name = "NPE-C",
> + ? ? ? }
> +};
> +
> +int npe_running(struct npe *npe)
> +{
> + ? ? ? return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
> +}
> +
> +static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
> +{
> + ? ? ? __raw_writel(data, &npe->regs->exec_data);
> + ? ? ? __raw_writel(addr, &npe->regs->exec_addr);
> + ? ? ? __raw_writel(cmd, &npe->regs->exec_status_cmd);
> +}
> +
> +static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
> +{
> + ? ? ? __raw_writel(addr, &npe->regs->exec_addr);
> + ? ? ? __raw_writel(cmd, &npe->regs->exec_status_cmd);
> + ? ? ? /* Iintroduce extra read cycles after issuing read command to NPE
> + ? ? ? ? ?so that we read the register after the NPE has updated it.
> + ? ? ? ? ?This is to overcome race condition between XScale and NPE */
> + ? ? ? __raw_readl(&npe->regs->exec_data);
> + ? ? ? __raw_readl(&npe->regs->exec_data);
> + ? ? ? return __raw_readl(&npe->regs->exec_data);
> +}
> +
> +static void npe_clear_active(struct npe *npe, u32 reg)
> +{
> + ? ? ? u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
> + ? ? ? npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
> +}
> +
> +static void npe_start(struct npe *npe)
> +{
> + ? ? ? /* ensure only Background Context Stack Level is active */
> + ? ? ? npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
> + ? ? ? npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
> + ? ? ? npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
> +
> + ? ? ? __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
> + ? ? ? __raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
> +}
> +
> +static void npe_stop(struct npe *npe)
> +{
> + ? ? ? __raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
> + ? ? ? __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
> +}
> +
> +static int npe_debug_instr(struct npe *npe, u32 instr, u32 ctx, u32 ldur)
> +{
> + ? ? ? u32 wc;
> + ? ? ? int i;
> +
> + ? ? ? /* set the Active bit, and the LDUR, in the debug level */
> + ? ? ? npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
> + ? ? ? ? ? ? ? ? ? ? ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
> +
> + ? ? ? /* set CCTXT at ECS DEBUG L3 to specify in which context to execute
> + ? ? ? ? ?the instruction, and set SELCTXT at ECS DEBUG Level to specify
> + ? ? ? ? ?which context store to access.
> + ? ? ? ? ?Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
> + ? ? ? */
> + ? ? ? npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
> + ? ? ? ? ? ? ? ? ? ? (ctx << ECS_REG_1_CCTXT_BITS) |
> + ? ? ? ? ? ? ? ? ? ? (ctx << ECS_REG_1_SELCTXT_BITS));
> +
> + ? ? ? /* clear the pipeline */
> + ? ? ? __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
> +
> + ? ? ? /* load NPE instruction into the instruction register */
> + ? ? ? npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
> +
> + ? ? ? /* we need this value later to wait for completion of NPE execution
> + ? ? ? ? ?step */
> + ? ? ? wc = __raw_readl(&npe->regs->watch_count);
> +
> + ? ? ? /* issue a Step One command via the Execution Control register */
> + ? ? ? __raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
> +
> + ? ? ? /* Watch Count register increments when NPE completes an instruction */
> + ? ? ? for (i = 0; i < MAX_RETRIES; i++) {
> + ? ? ? ? ? ? ? if (wc != __raw_readl(&npe->regs->watch_count))
> + ? ? ? ? ? ? ? ? ? ? ? return 0;
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? }
> +
> + ? ? ? print_npe(npe, "reset: npe_debug_instr(): timeout\n");
> + ? ? ? return -ETIMEDOUT;
> +}
> +
> +static int npe_logical_reg_write8(struct npe *npe, u32 addr, u8 val, u32 ctx)
> +{
> + ? ? ? /* here we build the NPE assembler instruction: mov8 d0, #0 */
> + ? ? ? u32 instr = INSTR_WR_REG_BYTE | /* OpCode */
> + ? ? ? ? ? ? ? addr << 9 | ? ? ? ? ? ? /* base Operand */
> + ? ? ? ? ? ? ? (val & 0x1F) << 4 | ? ? /* lower 5 bits to immediate data */
> + ? ? ? ? ? ? ? (val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
> + ? ? ? return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
> +}
> +
> +static int npe_logical_reg_write16(struct npe *npe, u32 addr, u16 val, u32 ctx)
> +{
> + ? ? ? /* here we build the NPE assembler instruction: mov16 d0, #0 */
> + ? ? ? u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
> + ? ? ? ? ? ? ? addr << 9 | ? ? ? ? ? ? /* base Operand */
> + ? ? ? ? ? ? ? (val & 0x1F) << 4 | ? ? /* lower 5 bits to immediate data */
> + ? ? ? ? ? ? ? (val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
> + ? ? ? return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
> +}
> +
> +static int npe_logical_reg_write32(struct npe *npe, u32 addr, u32 val, u32 ctx)
> +{
> + ? ? ? /* write in 16 bit steps first the high and then the low value */
> + ? ? ? if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
> + ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
> +}
> +
> +static int npe_reset(struct npe *npe)
> +{
> + ? ? ? u32 val, ctl, exec_count, ctx_reg2;
> + ? ? ? int i;
> +
> + ? ? ? ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
> + ? ? ? ? ? ? ? 0x3F3FFFFF;
> +
> + ? ? ? /* disable parity interrupt */
> + ? ? ? __raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
> +
> + ? ? ? /* pre exec - debug instruction */
> + ? ? ? /* turn off the halt bit by clearing Execution Count register. */
> + ? ? ? exec_count = __raw_readl(&npe->regs->exec_count);
> + ? ? ? __raw_writel(0, &npe->regs->exec_count);
> + ? ? ? /* ensure that IF and IE are on (temporarily), so that we don't end up
> + ? ? ? ? ?stepping forever */
> + ? ? ? ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
> + ? ? ? npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
> + ? ? ? ? ? ? ? ? ? ? ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
> +
> + ? ? ? /* clear the FIFOs */
> + ? ? ? while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
> + ? ? ? ? ? ? ? ;
> + ? ? ? while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
> + ? ? ? ? ? ? ? /* read from the outFIFO until empty */
> + ? ? ? ? ? ? ? print_npe(npe, "npe_reset: read FIFO = 0x%X\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? __raw_readl(&npe->regs->in_out_fifo));
> +
> + ? ? ? while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
> + ? ? ? ? ? ? ? /* step execution of the NPE intruction to read inFIFO using
> + ? ? ? ? ? ? ? ? ?the Debug Executing Context stack */
> + ? ? ? ? ? ? ? if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
> + ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> +
> + ? ? ? /* reset the mailbox reg from the XScale side */
> + ? ? ? __raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
> + ? ? ? /* from NPE side */
> + ? ? ? if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
> + ? ? ? ? ? ? ? return -ETIMEDOUT;
> +
> + ? ? ? /* Reset the physical registers in the NPE register file */
> + ? ? ? for (val = 0; val < NPE_PHYS_REG; val++) {
> + ? ? ? ? ? ? ? if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
> + ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? ? ? ? ? /* address is either 0 or 4 */
> + ? ? ? ? ? ? ? if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
> + ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? }
> +
> + ? ? ? /* Reset the context store = each context's Context Store registers */
> +
> + ? ? ? /* Context 0 has no STARTPC. Instead, this value is used to set NextPC
> + ? ? ? ? ?for Background ECS, to set where NPE starts executing code */
> + ? ? ? val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
> + ? ? ? val &= ~ECS_REG_0_NEXTPC_MASK;
> + ? ? ? val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
> + ? ? ? npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
> +
> + ? ? ? for (i = 0; i < 16; i++) {
> + ? ? ? ? ? ? ? if (i) { /* Context 0 has no STEVT nor STARTPC */
> + ? ? ? ? ? ? ? ? ? ? ? /* STEVT = off, 0x80 */
> + ? ? ? ? ? ? ? ? ? ? ? if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? ? ? ? ? ? ? ? ? if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? /* REGMAP = d0->p0, d8->p2, d16->p4 */
> + ? ? ? ? ? ? ? if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
> + ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? ? ? ? ? if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
> + ? ? ? ? ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? }
> +
> + ? ? ? /* post exec */
> + ? ? ? /* clear active bit in debug level */
> + ? ? ? npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
> + ? ? ? /* clear the pipeline */
> + ? ? ? __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
> + ? ? ? /* restore previous values */
> + ? ? ? __raw_writel(exec_count, &npe->regs->exec_count);
> + ? ? ? npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
> +
> + ? ? ? /* write reset values to Execution Context Stack registers */
> + ? ? ? for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
> + ? ? ? ? ? ? ? npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ecs_reset[val].val);
> +
> + ? ? ? /* clear the profile counter */
> + ? ? ? __raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
> +
> + ? ? ? __raw_writel(0, &npe->regs->exec_count);
> + ? ? ? __raw_writel(0, &npe->regs->action_points[0]);
> + ? ? ? __raw_writel(0, &npe->regs->action_points[1]);
> + ? ? ? __raw_writel(0, &npe->regs->action_points[2]);
> + ? ? ? __raw_writel(0, &npe->regs->action_points[3]);
> + ? ? ? __raw_writel(0, &npe->regs->watch_count);
> +
> + ? ? ? val = ixp4xx_read_feature_bits();
> + ? ? ? /* reset the NPE */
> + ? ? ? ixp4xx_write_feature_bits(val &
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
> + ? ? ? /* deassert reset */
> + ? ? ? ixp4xx_write_feature_bits(val |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (IXP4XX_FEATURE_RESET_NPEA << npe->id));
> + ? ? ? for (i = 0; i < MAX_RETRIES; i++) {
> + ? ? ? ? ? ? ? if (ixp4xx_read_feature_bits() &
> + ? ? ? ? ? ? ? ? ? (IXP4XX_FEATURE_RESET_NPEA << npe->id))
> + ? ? ? ? ? ? ? ? ? ? ? break; /* NPE is back alive */
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? }
> + ? ? ? if (i == MAX_RETRIES)
> + ? ? ? ? ? ? ? return -ETIMEDOUT;
> +
> + ? ? ? npe_stop(npe);
> +
> + ? ? ? /* restore NPE configuration bus Control Register - parity settings */
> + ? ? ? __raw_writel(ctl, &npe->regs->messaging_control);
> + ? ? ? return 0;
> +}
> +
> +
> +int npe_send_message(struct npe *npe, const void *msg, const char *what)
> +{
> + ? ? ? const u32 *send = msg;
> + ? ? ? int cycles = 0;
> +
> + ? ? ? debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
> + ? ? ? ? ? ? ? ? what, send[0], send[1]);
> +
> + ? ? ? if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
> + ? ? ? ? ? ? ? debug_msg(npe, "NPE input FIFO not empty\n");
> + ? ? ? ? ? ? ? return -EIO;
> + ? ? ? }
> +
> + ? ? ? __raw_writel(send[0], &npe->regs->in_out_fifo);
> +
> + ? ? ? if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
> + ? ? ? ? ? ? ? debug_msg(npe, "NPE input FIFO full\n");
> + ? ? ? ? ? ? ? return -EIO;
> + ? ? ? }
> +
> + ? ? ? __raw_writel(send[1], &npe->regs->in_out_fifo);
> +
> + ? ? ? while ((cycles < MAX_RETRIES) &&
> + ? ? ? ? ? ? ?(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? ? ? ? ? cycles++;
> + ? ? ? }
> +
> + ? ? ? if (cycles == MAX_RETRIES) {
> + ? ? ? ? ? ? ? debug_msg(npe, "Timeout sending message\n");
> + ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? }
> +
> +#if DEBUG_MSG > 1
> + ? ? ? debug_msg(npe, "Sending a message took %i cycles\n", cycles);
> +#endif
> + ? ? ? return 0;
> +}
> +
> +int npe_recv_message(struct npe *npe, void *msg, const char *what)
> +{
> + ? ? ? u32 *recv = msg;
> + ? ? ? int cycles = 0, cnt = 0;
> +
> + ? ? ? debug_msg(npe, "Trying to receive message %s\n", what);
> +
> + ? ? ? while (cycles < MAX_RETRIES) {
> + ? ? ? ? ? ? ? if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
> + ? ? ? ? ? ? ? ? ? ? ? recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
> + ? ? ? ? ? ? ? ? ? ? ? if (cnt == 2)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? } else {
> + ? ? ? ? ? ? ? ? ? ? ? udelay(1);
> + ? ? ? ? ? ? ? ? ? ? ? cycles++;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? switch(cnt) {
> + ? ? ? case 1:
> + ? ? ? ? ? ? ? debug_msg(npe, "Received [%08X]\n", recv[0]);
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 2:
> + ? ? ? ? ? ? ? debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +
> + ? ? ? if (cycles == MAX_RETRIES) {
> + ? ? ? ? ? ? ? debug_msg(npe, "Timeout waiting for message\n");
> + ? ? ? ? ? ? ? return -ETIMEDOUT;
> + ? ? ? }
> +
> +#if DEBUG_MSG > 1
> + ? ? ? debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
> +#endif
> + ? ? ? return 0;
> +}
> +
> +int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
> +{
> + ? ? ? int result;
> + ? ? ? u32 *send = msg, recv[2];
> +
> + ? ? ? if ((result = npe_send_message(npe, msg, what)) != 0)
> + ? ? ? ? ? ? ? return result;
> + ? ? ? if ((result = npe_recv_message(npe, recv, what)) != 0)
> + ? ? ? ? ? ? ? return result;
> +
> + ? ? ? if ((recv[0] != send[0]) || (recv[1] != send[1])) {
> + ? ? ? ? ? ? ? debug_msg(npe, "Message %s: unexpected message received\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? what);
> + ? ? ? ? ? ? ? return -EIO;
> + ? ? ? }
> + ? ? ? return 0;
> +}
> +
> +
> +int npe_load_firmware(struct npe *npe)
> +{
> + ? ? ? struct dl_block {
> + ? ? ? ? ? ? ? u32 type;
> + ? ? ? ? ? ? ? u32 offset;
> + ? ? ? } *blk;
> +
> + ? ? ? struct dl_image {
> + ? ? ? ? ? ? ? u32 magic;
> + ? ? ? ? ? ? ? u32 id;
> + ? ? ? ? ? ? ? u32 size;
> + ? ? ? ? ? ? ? union {
> + ? ? ? ? ? ? ? ? ? ? ? u32 data[0];
> + ? ? ? ? ? ? ? ? ? ? ? struct dl_block blocks[0];
> + ? ? ? ? ? ? ? };
> + ? ? ? } *image;
> +
> + ? ? ? struct dl_codeblock {
> + ? ? ? ? ? ? ? u32 npe_addr;
> + ? ? ? ? ? ? ? u32 size;
> + ? ? ? ? ? ? ? u32 data[0];
> + ? ? ? } *cb;
> +
> + ? ? ? int i, j, err, data_size, instr_size, blocks, table_end;
> + ? ? ? u32 cmd;
> + ? ? ? char name[5 /* "/dev/" */ + NPE_NAME_LENGTH + 1 /* NUL */];
> + ? ? ? size_t image_size;
> +
> + ? ? ? sprintf(name, "/dev/%s", npe->name);
> + ? ? ? if (!(image = read_file(name, &image_size))) {
> + ? ? ? ? ? ? ? print_npe(npe, "bad or missing microcode file %s", name);
> + ? ? ? ? ? ? ? return -EIO;
> + ? ? ? }
> +
> + ? ? ? err = -EINVAL;
> + ? ? ? if (image_size < sizeof(struct dl_image)) {
> + ? ? ? ? ? ? ? print_npe(npe, "incomplete microcode file %s\n", name);
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> +
> +#if DEBUG_FW
> + ? ? ? print_npe(npe, "microcode: %08X %08X %08X (0x%X bytes)\n",
> + ? ? ? ? ? ? ? ? image->magic, image->id, image->size, image->size * 4);
> +#endif
> +
> + ? ? ? if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
> + ? ? ? ? ? ? ? image->id = swab32(image->id);
> + ? ? ? ? ? ? ? image->size = swab32(image->size);
> + ? ? ? } else if (image->magic != FW_MAGIC) {
> + ? ? ? ? ? ? ? print_npe(npe, "bad microcode file %s magic: 0x%X\n", name, image->magic);
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> + ? ? ? if ((image->size * 4 + sizeof(struct dl_image)) > image_size) {
> + ? ? ? ? ? ? ? print_npe(npe, "incomplete microcode file %s\n", name);
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> + ? ? ? if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
> + ? ? ? ? ? ? ? print_npe(npe, "NPE ID mismatch in microcode file %s\n", name);
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> + ? ? ? if (image->magic == swab32(FW_MAGIC))
> + ? ? ? ? ? ? ? for (i = 0; i < image->size; i++)
> + ? ? ? ? ? ? ? ? ? ? ? image->data[i] = swab32(image->data[i]);
> +
> + ? ? ? if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
> + ? ? ? ? ? ? ? print_npe(npe, "IXP43x/IXP46x microcode ignored on IXP42x\n");
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> +
> + ? ? ? if (npe_running(npe)) {
> + ? ? ? ? ? ? ? print_npe(npe, "unable to load microcode file %s, NPE is already running\n", name);
> + ? ? ? ? ? ? ? err = -EBUSY;
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> +
> + ? ? ? if (cpu_is_ixp42x()) {
> + ? ? ? ? ? ? ? if (!npe->id)
> + ? ? ? ? ? ? ? ? ? ? ? instr_size = NPE_A_42X_INSTR_SIZE;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
> + ? ? ? ? ? ? ? data_size = NPE_42X_DATA_SIZE;
> + ? ? ? } else {
> + ? ? ? ? ? ? ? instr_size = NPE_46X_INSTR_SIZE;
> + ? ? ? ? ? ? ? data_size = NPE_46X_DATA_SIZE;
> + ? ? ? }
> +
> + ? ? ? for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
> + ? ? ? ? ? ?blocks++)
> + ? ? ? ? ? ? ? if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
> + ? ? ? ? ? ? ? print_npe(npe, "microcode EOF block marker not found\n");
> + ? ? ? ? ? ? ? goto err;
> + ? ? ? }
> +
> +#if DEBUG_FW
> + ? ? ? print_npe(npe, "%i microcode blocks found\n", blocks);
> +#endif
> +
> + ? ? ? table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
> + ? ? ? for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
> + ? ? ? ? ? ? ? if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
> + ? ? ? ? ? ? ? ? ? || blk->offset < table_end) {
> + ? ? ? ? ? ? ? ? ? ? ? print_npe(npe, "invalid offset 0x%X of "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "microcode block #%i\n", blk->offset, i);
> + ? ? ? ? ? ? ? ? ? ? ? goto err;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? cb = (struct dl_codeblock*)&image->data[blk->offset];
> + ? ? ? ? ? ? ? if (blk->type == FW_BLOCK_TYPE_INSTR) {
> + ? ? ? ? ? ? ? ? ? ? ? if (cb->npe_addr + cb->size > instr_size)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto too_big;
> + ? ? ? ? ? ? ? ? ? ? ? cmd = CMD_WR_INS_MEM;
> + ? ? ? ? ? ? ? } else if (blk->type == FW_BLOCK_TYPE_DATA) {
> + ? ? ? ? ? ? ? ? ? ? ? if (cb->npe_addr + cb->size > data_size)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto too_big;
> + ? ? ? ? ? ? ? ? ? ? ? cmd = CMD_WR_DATA_MEM;
> + ? ? ? ? ? ? ? } else {
> + ? ? ? ? ? ? ? ? ? ? ? print_npe(npe, "invalid microcode block #%i type 0x%X\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i, blk->type);
> + ? ? ? ? ? ? ? ? ? ? ? goto err;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
> + ? ? ? ? ? ? ? ? ? ? ? print_npe(npe, "microcode block #%i doesn't "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "fit in microcode image: type %c, start 0x%X,"
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " length 0x%X\n", i,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cb->npe_addr, cb->size);
> + ? ? ? ? ? ? ? ? ? ? ? goto err;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? for (j = 0; j < cb->size; j++)
> + ? ? ? ? ? ? ? ? ? ? ? npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
> + ? ? ? }
> +
> + ? ? ? npe_start(npe);
> + ? ? ? if (!npe_running(npe))
> + ? ? ? ? ? ? ? print_npe(npe, "unable to start\n");
> + ? ? ? free(image);
> + ? ? ? return 0;
> +
> +too_big:
> + ? ? ? print_npe(npe, "microcode block #%i doesn't fit in NPE "
> + ? ? ? ? ? ? ? ? "memory: type %c, start 0x%X, length 0x%X\n", i,
> + ? ? ? ? ? ? ? ? blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
> + ? ? ? ? ? ? ? ? cb->npe_addr, cb->size);
> +err:
> + ? ? ? free(image);
> + ? ? ? return err;
> +}
> +
> +
> +struct npe *npe_request(int id)
> +{
> + ? ? ? if (id < NPE_COUNT)
> + ? ? ? ? ? ? ? if (npe_tab[id].valid)
> + ? ? ? ? ? ? ? ? ? ? ? return &npe_tab[id];
> + ? ? ? return NULL;
> +}
> +
> +static int __init npe_init(void)
> +{
> + ? ? ? int i;
> +
> + ? ? ? for (i = 0; i < NPE_COUNT; i++) {
> + ? ? ? ? ? ? ? struct npe *npe = &npe_tab[i];
> + ? ? ? ? ? ? ? if (!(ixp4xx_read_feature_bits() & (IXP4XX_FEATURE_RESET_NPEA << i)))
> + ? ? ? ? ? ? ? ? ? ? ? continue; /* NPE already disabled or not present */
> + ? ? ? ? ? ? ? if (npe_reset(npe))
> + ? ? ? ? ? ? ? ? ? ? ? continue;
> + ? ? ? ? ? ? ? npe->valid = 1;
> + ? ? ? }
> + ? ? ? return 0;
> +}
> +
> +coredevice_initcall(npe_init);
> diff --git a/arch/arm/mach-ixp4xx/qmgr.c b/arch/arm/mach-ixp4xx/qmgr.c
> new file mode 100644
> index 0000000..49cba60
> --- /dev/null
> +++ b/arch/arm/mach-ixp4xx/qmgr.c
> @@ -0,0 +1,269 @@
> +/*
> + * Intel IXP4xx Queue Manager driver for Linux
> + *
> + * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License
> + * as published by the Free Software Foundation.
> + */
> +
> +#include <init.h>
> +#include <errno.h>
> +#include <mach/qmgr.h>
> +
> +static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
> +
> +#if DEBUG_QMGR
> +char qmgr_queue_descs[HALF_QUEUES][32];
> +#endif
> +
> +#ifdef CONFIG_USE_IRQ
> +
> +static void (*irq_handlers[HALF_QUEUES])(void *pdev);
> +static void *irq_pdevs[HALF_QUEUES];
> +
> +#undef fls
> +static inline int fls(int x)
> +{
> + ? ? ? int ret;
> + ? ? ? asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
> + ? ? ? ret = 32 - ret;
> + ? ? ? return ret;
> +}
> +
> +
> +void qmgr_set_irq(unsigned int queue, int src,
> + ? ? ? ? ? ? ? ? void (*handler)(void *pdev), void *pdev)
> +{
> + ? ? ? const u32 *reg;
> + ? ? ? int bit;
> + ? ? ? BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL);
> + ? ? ? reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */
> + ? ? ? bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
> + ? ? ? __raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit), reg);
> +
> + ? ? ? irq_handlers[queue] = handler;
> + ? ? ? irq_pdevs[queue] = pdev;
> +}
> +
> +
> +static void qmgr_irq1_a0(void *data)
> +{
> + ? ? ? int i;
> + ? ? ? u32 en_bitmap, src, stat;
> +
> + ? ? ? /* ACK - it may clear any bits so don't rely on it */
> + ? ? ? __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]);
> +
> + ? ? ? en_bitmap = qmgr_regs->irqen[0];
> + ? ? ? while (en_bitmap) {
> + ? ? ? ? ? ? ? i = fls(en_bitmap) - 1; /* number of the last "low" queue */
> + ? ? ? ? ? ? ? en_bitmap &= ~BIT(i);
> + ? ? ? ? ? ? ? src = qmgr_regs->irqsrc[i >> 3];
> + ? ? ? ? ? ? ? stat = qmgr_regs->stat1[i >> 3];
> + ? ? ? ? ? ? ? if (src & 4) /* the IRQ condition is inverted */
> + ? ? ? ? ? ? ? ? ? ? ? stat = ~stat;
> + ? ? ? ? ? ? ? if (stat & BIT(src & 3))
> + ? ? ? ? ? ? ? ? ? ? ? irq_handlers[i](irq_pdevs[i]);
> + ? ? ? }
> +}
> +
> +
> +static void qmgr_irq1(void *data)
> +{
> + ? ? ? int i;
> + ? ? ? u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[0]);
> +
> + ? ? ? if (!req_bitmap)
> + ? ? ? ? ? ? ? return;
> + ? ? ? __raw_writel(req_bitmap, &qmgr_regs->irqstat[0]); /* ACK */
> +
> + ? ? ? while (req_bitmap) {
> + ? ? ? ? ? ? ? i = fls(req_bitmap) - 1; /* number of the last queue */
> + ? ? ? ? ? ? ? req_bitmap &= ~BIT(i);
> + ? ? ? ? ? ? ? irq_handlers[i](irq_pdevs[i]);
> + ? ? ? }
> +}
> +
> +
> +void qmgr_enable_irq(unsigned int queue)
> +{
> + ? ? ? u32 mask = 1 << queue;
> +
> + ? ? ? __raw_writel(__raw_readl(&qmgr_regs->irqen[0]) | mask,
> + ? ? ? ? ? ? ? ? ? ?&qmgr_regs->irqen[0]);
> +}
> +
> +void qmgr_disable_irq(unsigned int queue)
> +{
> + ? ? ? u32 mask = 1 << queue;
> +
> + ? ? ? __raw_writel(__raw_readl(&qmgr_regs->irqen[0]) & ~mask,
> + ? ? ? ? ? ? ? ? ? ?&qmgr_regs->irqen[0]);
> + ? ? ? __raw_writel(mask, &qmgr_regs->irqstat[0]); /* clear */
> +}
> +
> +#endif /* CONFIG_USE_IRQ */
> +
> +static inline void shift_mask(u32 *mask)
> +{
> + ? ? ? mask[3] = mask[3] << 1 | mask[2] >> 31;
> + ? ? ? mask[2] = mask[2] << 1 | mask[1] >> 31;
> + ? ? ? mask[1] = mask[1] << 1 | mask[0] >> 31;
> + ? ? ? mask[0] <<= 1;
> +}
> +
> +#if DEBUG_QMGR
> +void qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
> + ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_empty_watermark,
> + ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_full_watermark,
> + ? ? ? ? ? ? ? ? ? ? ? const char *desc_format, const char* name)
> +#else
> +void __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
> + ? ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_empty_watermark,
> + ? ? ? ? ? ? ? ? ? ? ? ? unsigned int nearly_full_watermark)
> +#endif
> +{
> + ? ? ? u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
> +
> + ? ? ? BUG_ON(queue >= HALF_QUEUES);
> + ? ? ? BUG_ON((nearly_empty_watermark | nearly_full_watermark) & ~7);
> +
> + ? ? ? switch (len) {
> + ? ? ? case ?16:
> + ? ? ? ? ? ? ? cfg = 0 << 24;
> + ? ? ? ? ? ? ? mask[0] = 0x1;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case ?32:
> + ? ? ? ? ? ? ? cfg = 1 << 24;
> + ? ? ? ? ? ? ? mask[0] = 0x3;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case ?64:
> + ? ? ? ? ? ? ? cfg = 2 << 24;
> + ? ? ? ? ? ? ? mask[0] = 0xF;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 128:
> + ? ? ? ? ? ? ? cfg = 3 << 24;
> + ? ? ? ? ? ? ? mask[0] = 0xFF;
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? BUG();
> + ? ? ? }
> +
> + ? ? ? cfg |= nearly_empty_watermark << 26;
> + ? ? ? cfg |= nearly_full_watermark << 29;
> + ? ? ? len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */
> + ? ? ? mask[1] = mask[2] = mask[3] = 0;
> +
> + ? ? ? BUG_ON(__raw_readl(&qmgr_regs->sram[queue]));
> +
> + ? ? ? while (1) {
> + ? ? ? ? ? ? ? if (!(used_sram_bitmap[0] & mask[0]) &&
> + ? ? ? ? ? ? ? ? ? !(used_sram_bitmap[1] & mask[1]) &&
> + ? ? ? ? ? ? ? ? ? !(used_sram_bitmap[2] & mask[2]) &&
> + ? ? ? ? ? ? ? ? ? !(used_sram_bitmap[3] & mask[3]))
> + ? ? ? ? ? ? ? ? ? ? ? break; /* found free space */
> +
> + ? ? ? ? ? ? ? addr++;
> + ? ? ? ? ? ? ? shift_mask(mask);
> + ? ? ? ? ? ? ? if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
> + ? ? ? ? ? ? ? ? ? ? ? fprintf(stderr, "qmgr: no free SRAM space for"
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " queue %i\n", queue);
> + ? ? ? ? ? ? ? ? ? ? ? BUG();
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? used_sram_bitmap[0] |= mask[0];
> + ? ? ? used_sram_bitmap[1] |= mask[1];
> + ? ? ? used_sram_bitmap[2] |= mask[2];
> + ? ? ? used_sram_bitmap[3] |= mask[3];
> + ? ? ? __raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
> +#if DEBUG_QMGR
> + ? ? ? /* no snprintf() */
> + ? ? ? sprintf(qmgr_queue_descs[queue], desc_format, name);
> + ? ? ? fprintf(stderr, "qmgr: requested queue %s(%i) addr = 0x%02X\n",
> + ? ? ? ? ? ? ? qmgr_queue_descs[queue], queue, addr);
> +#endif
> +}
> +
> +void qmgr_release_queue(unsigned int queue)
> +{
> + ? ? ? u32 cfg, addr, mask[4];
> +
> + ? ? ? BUG_ON(queue >= HALF_QUEUES); /* not in valid range */
> +
> + ? ? ? cfg = __raw_readl(&qmgr_regs->sram[queue]);
> + ? ? ? addr = (cfg >> 14) & 0xFF;
> +
> + ? ? ? BUG_ON(!addr); /* not requested */
> +
> + ? ? ? switch ((cfg >> 24) & 3) {
> + ? ? ? case 0: mask[0] = 0x1; break;
> + ? ? ? case 1: mask[0] = 0x3; break;
> + ? ? ? case 2: mask[0] = 0xF; break;
> + ? ? ? case 3: mask[0] = 0xFF; break;
> + ? ? ? }
> +
> + ? ? ? mask[1] = mask[2] = mask[3] = 0;
> +
> + ? ? ? while (addr--)
> + ? ? ? ? ? ? ? shift_mask(mask);
> +
> +#if DEBUG_QMGR
> + ? ? ? fprintf(stderr, "qmgr: releasing queue %s(%i)\n",
> + ? ? ? ? ? ? ? qmgr_queue_descs[queue], queue);
> + ? ? ? qmgr_queue_descs[queue][0] = '\x0';
> +#endif
> + ? ? ? __raw_writel(0, &qmgr_regs->sram[queue]);
> +
> + ? ? ? used_sram_bitmap[0] &= ~mask[0];
> + ? ? ? used_sram_bitmap[1] &= ~mask[1];
> + ? ? ? used_sram_bitmap[2] &= ~mask[2];
> + ? ? ? used_sram_bitmap[3] &= ~mask[3];
> +#ifdef CONFIG_USE_IRQ
> + ? ? ? irq_handlers[queue] = NULL; /* catch IRQ bugs */
> +#endif
> +
> + ? ? ? while ((addr = qmgr_get_entry(queue)))
> + ? ? ? ? ? ? ? fprintf(stderr, "qmgr: released queue %i not empty: 0x%08X\n",
> + ? ? ? ? ? ? ? ? ? ? ? queue, addr);
> +}
> +
> +static int __init qmgr_init(void)
> +{
> + ? ? ? int i;
> +#ifdef CONFIG_USE_IRQ
> + ? ? ? interrupt_handler_t *handler;
> +#endif
> +
> + ? ? ? /* reset qmgr registers */
> + ? ? ? for (i = 0; i < 4; i++) {
> + ? ? ? ? ? ? ? __raw_writel(0x33333333, &qmgr_regs->stat1[i]);
> + ? ? ? ? ? ? ? __raw_writel(0, &qmgr_regs->irqsrc[i]);
> + ? ? ? }
> + ? ? ? for (i = 0; i < 2; i++) {
> + ? ? ? ? ? ? ? __raw_writel(0, &qmgr_regs->stat2[i]);
> + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
> + ? ? ? ? ? ? ? __raw_writel(0, &qmgr_regs->irqen[i]);
> + ? ? ? }
> +
> + ? ? ? __raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h);
> + ? ? ? __raw_writel(0, &qmgr_regs->statf_h);
> +
> + ? ? ? for (i = 0; i < QUEUES; i++)
> + ? ? ? ? ? ? ? __raw_writel(0, &qmgr_regs->sram[i]);
> +
> +#ifdef CONFIG_USE_IRQ
> + ? ? ? if (cpu_is_ixp42x_rev_a0())
> + ? ? ? ? ? ? ? handler = qmgr_irq1_a0;
> + ? ? ? else
> + ? ? ? ? ? ? ? handler = qmgr_irq1;
> +
> + ? ? ? irq_install_handler(IXP425_QM1_IRQ, handler, NULL);
> +#endif
> + ? ? ? used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
> + ? ? ? return 0;
> +}
> +
> +coredevice_initcall(qmgr_init);
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 69f3352..df6e42c 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -77,6 +77,14 @@ config DRIVER_NET_MACB
> ? ? ? ?depends on HAS_MACB
> ? ? ? ?select MIIDEV
>
> +config DRIVER_NET_IXP4XX_ETH
> + ? ? ? tristate "Intel IXP4xx Ethernet support"
> + ? ? ? depends on ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
> + ? ? ? select MIIDEV
> + ? ? ? help
> + ? ? ? ? Say Y here if you want to use built-in Ethernet ports
> + ? ? ? ? on IXP4xx processor.
> +
> ?config DRIVER_NET_TAP
> ? ? ? ?bool "tap Ethernet driver"
> ? ? ? ?depends on LINUX
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 96d3d32..97cb44b 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_DRIVER_NET_MACB) ? ? ? ? += macb.o
> ?obj-$(CONFIG_DRIVER_NET_TAP) ? ? ? ? ? += tap.o
> ?obj-$(CONFIG_MIIDEV) ? ? ? ? ? ? ? ? ? += miidev.o
> ?obj-$(CONFIG_NET_USB) ? ? ? ? ? ? ? ? ?+= usb/
> +obj-$(CONFIG_DRIVER_NET_IXP4XX_ETH) ? ?+= ixp4xx_eth.o
> diff --git a/drivers/net/ixp4xx_eth.c b/drivers/net/ixp4xx_eth.c
> new file mode 100644
> index 0000000..71e6d92
> --- /dev/null
> +++ b/drivers/net/ixp4xx_eth.c
> @@ -0,0 +1,763 @@
> +/*
> + * Intel IXP4xx Ethernet driver for Linux
> + *
> + * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License
> + * as published by the Free Software Foundation.
> + *
> + * Ethernet port config (0x00 is not present on IXP42X):
> + *
> + * logical port ? ? ? ? ? ? ? ?0x00 ? ? ? ? ? ?0x10 ? ? ? ? ? ?0x20
> + * NPE ? ? ? ? ? ? ? ? 0 (NPE-A) ? ? ? 1 (NPE-B) ? ? ? 2 (NPE-C)
> + * physical port ? ? ? 2 ? ? ? ? ? ? ? 0 ? ? ? ? ? ? ? 1
> + * RX queue (variable) 20 ? ? ? ? ? ? ?21 ? ? ? ? ? ? ?22
> + * TX queue ? ? ? ? ? ?23 ? ? ? ? ? ? ?24 ? ? ? ? ? ? ?25
> + * RX-free queue ? ? ? 26 ? ? ? ? ? ? ?27 ? ? ? ? ? ? ?28
> + * TX-done queue is always 31, per-port RX queue is configurable
> + *
> + *
> + * Queue entries:
> + * bits 0 -> 1 ?- NPE ID (RX and TX-done)
> + * bits 0 -> 2 ?- priority (TX, per 802.1D)
> + * bits 3 -> 4 ?- port ID (user-set?)
> + * bits 5 -> 31 - physical descriptor address
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <malloc.h>
> +#include <miidev.h>
> +#include <net.h>
> +#include <errno.h>
> +#include <mach/ixp4xx-regs.h>
> +#include <mach/platform.h>
> +#include <mach/cpu.h>
> +#include <mach/npe.h>
> +#include <mach/qmgr.h>
> +
> +#define DEBUG_DESC ? ? ? ? ? ? 0
> +#define DEBUG_RX ? ? ? ? ? ? ? 0
> +#define DEBUG_TX ? ? ? ? ? ? ? 0
> +#define DEBUG_PKT_BYTES ? ? ? ? ? ? ? ?0
> +#define DEBUG_MDIO ? ? ? ? ? ? 0
> +#define DEBUG_OPEN ? ? ? ? ? ? 0
> +#define DEBUG_CLOSE ? ? ? ? ? ?0
> +
> +#define RX_DESCS ? ? ? ? ? ? ? 16 /* also length of all RX queues */
> +#define TX_DESCS ? ? ? ? ? ? ? 16 /* also length of all TX queues */
> +#define TXDONE_QUEUE_LEN ? ? ? 16 /* dwords */
> +
> +#define MAX_MRU ? ? ? ? ? ? ? ? ? ? ? ?1536 /* 0x600 */
> +#define RX_BUFF_SIZE ? ? ? ? ? MAX_MRU
> +
> +#define MAX_MDIO_RETRIES ? ? ? 100 /* microseconds, typically 30 cycles */
> +#define MAX_CLOSE_WAIT ? ? ? ? 1000 /* microseconds, typically 2-3 cycles */
> +#define ETH_ALEN ? ? ? ? ? ? ? 6
> +
> +#define PHYSICAL_ID(port) ? ? ?(((port)->npe->id + 2) % 3)
> +#define LOGICAL_ID(port) ? ? ? ((port)->npe->id << 4)
> +#define RX_QUEUE(port) ? ? ? ? ((port)->npe->id + 20) /* can be changed */
> +#define TX_QUEUE(port) ? ? ? ? ((port)->npe->id + 23)
> +#define RXFREE_QUEUE(port) ? ? ((port)->npe->id + 26)
> +#define TXDONE_QUEUE ? ? ? ? ? 31
> +
> +/* TX Control Registers */
> +#define TX_CNTRL0_TX_EN ? ? ? ? ? ? ? ?0x01
> +#define TX_CNTRL0_HALFDUPLEX ? 0x02
> +#define TX_CNTRL0_RETRY ? ? ? ? ? ? ? ?0x04
> +#define TX_CNTRL0_PAD_EN ? ? ? 0x08
> +#define TX_CNTRL0_APPEND_FCS ? 0x10
> +#define TX_CNTRL0_2DEFER ? ? ? 0x20
> +#define TX_CNTRL0_RMII ? ? ? ? 0x40 /* reduced MII */
> +#define TX_CNTRL1_RETRIES ? ? ?0x0F /* 4 bits */
> +
> +/* RX Control Registers */
> +#define RX_CNTRL0_RX_EN ? ? ? ? ? ? ? ?0x01
> +#define RX_CNTRL0_PADSTRIP_EN ?0x02
> +#define RX_CNTRL0_SEND_FCS ? ? 0x04
> +#define RX_CNTRL0_PAUSE_EN ? ? 0x08
> +#define RX_CNTRL0_LOOP_EN ? ? ?0x10
> +#define RX_CNTRL0_ADDR_FLTR_EN 0x20
> +#define RX_CNTRL0_RX_RUNT_EN ? 0x40
> +#define RX_CNTRL0_BCAST_DIS ? ?0x80
> +#define RX_CNTRL1_DEFER_EN ? ? 0x01
> +
> +/* Core Control Register */
> +#define CORE_RESET ? ? ? ? ? ? 0x01
> +#define CORE_RX_FIFO_FLUSH ? ? 0x02
> +#define CORE_TX_FIFO_FLUSH ? ? 0x04
> +#define CORE_SEND_JAM ? ? ? ? ?0x08
> +#define CORE_MDC_EN ? ? ? ? ? ?0x10 /* MDIO using NPE-B ETH-0 only */
> +
> +#define DEFAULT_TX_CNTRL0 ? ? ?(TX_CNTRL0_TX_EN | TX_CNTRL0_RETRY | ? ? ? \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TX_CNTRL0_PAD_EN | TX_CNTRL0_APPEND_FCS | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TX_CNTRL0_2DEFER)
> +#define DEFAULT_RX_CNTRL0 ? ? ?RX_CNTRL0_RX_EN
> +#define DEFAULT_CORE_CNTRL ? ? CORE_MDC_EN
> +
> +
> +/* NPE message codes */
> +#define NPE_GETSTATUS ? ? ? ? ? ? ? ? ? 0x00
> +#define NPE_EDB_SETPORTADDRESS ? ? ? ? ?0x01
> +#define NPE_EDB_GETMACADDRESSDATABASE ? 0x02
> +#define NPE_EDB_SETMACADDRESSSDATABASE ?0x03
> +#define NPE_GETSTATS ? ? ? ? ? ? ? ? ? ?0x04
> +#define NPE_RESETSTATS ? ? ? ? ? ? ? ? ?0x05
> +#define NPE_SETMAXFRAMELENGTHS ? ? ? ? ?0x06
> +#define NPE_VLAN_SETRXTAGMODE ? ? ? ? ? 0x07
> +#define NPE_VLAN_SETDEFAULTRXVID ? ? ? ?0x08
> +#define NPE_VLAN_SETPORTVLANTABLEENTRY ?0x09
> +#define NPE_VLAN_SETPORTVLANTABLERANGE ?0x0A
> +#define NPE_VLAN_SETRXQOSENTRY ? ? ? ? ?0x0B
> +#define NPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C
> +#define NPE_STP_SETBLOCKINGSTATE ? ? ? ?0x0D
> +#define NPE_FW_SETFIREWALLMODE ? ? ? ? ?0x0E
> +#define NPE_PC_SETFRAMECONTROLDURATIONID 0x0F
> +#define NPE_PC_SETAPMACTABLE ? ? ? ? ? ?0x11
> +#define NPE_SETLOOPBACK_MODE ? ? ? ? ? ?0x12
> +#define NPE_PC_SETBSSIDTABLE ? ? ? ? ? ?0x13
> +#define NPE_ADDRESS_FILTER_CONFIG ? ? ? 0x14
> +#define NPE_APPENDFCSCONFIG ? ? ? ? ? ? 0x15
> +#define NPE_NOTIFY_MAC_RECOVERY_DONE ? ?0x16
> +#define NPE_MAC_RECOVERY_START ? ? ? ? ?0x17
> +
> +struct eth_regs {
> + ? ? ? u32 tx_control[2], __res1[2]; ? ? ? ? ? ?/* 000 */
> + ? ? ? u32 rx_control[2], __res2[2]; ? ? ? ? ? ?/* 010 */
> + ? ? ? u32 random_seed, __res3[3]; ? ? ? ? ? ? ?/* 020 */
> + ? ? ? u32 partial_empty_threshold, __res4; ? ? /* 030 */
> + ? ? ? u32 partial_full_threshold, __res5; ? ? ?/* 038 */
> + ? ? ? u32 tx_start_bytes, __res6[3]; ? ? ? ? ? /* 040 */
> + ? ? ? u32 tx_deferral, rx_deferral, __res7[2]; /* 050 */
> + ? ? ? u32 tx_2part_deferral[2], __res8[2]; ? ? /* 060 */
> + ? ? ? u32 slot_time, __res9[3]; ? ? ? ? ? ? ? ?/* 070 */
> + ? ? ? u32 mdio_command[4]; ? ? ? ? ? ? ? ? ? ? /* 080 */
> + ? ? ? u32 mdio_status[4]; ? ? ? ? ? ? ? ? ? ? ?/* 090 */
> + ? ? ? u32 mcast_mask[6], __res10[2]; ? ? ? ? ? /* 0A0 */
> + ? ? ? u32 mcast_addr[6], __res11[2]; ? ? ? ? ? /* 0C0 */
> + ? ? ? u32 int_clock_threshold, __res12[3]; ? ? /* 0E0 */
> + ? ? ? u32 hw_addr[6], __res13[61]; ? ? ? ? ? ? /* 0F0 */
> + ? ? ? u32 core_control; ? ? ? ? ? ? ? ? ? ? ? ?/* 1FC */
> +};
> +
> +/* NPE message structure */
> +struct msg {
> + ? ? ? u8 cmd, eth_id, params[6];
> +};
> +
> +/* Ethernet packet descriptor, 32 bytes */
> +struct desc {
> + ? ? ? u8 *next; ? ?/* pointer to next buffer, unused */
> +
> + ? ? ? u16 buf_len; /* buffer length */
> + ? ? ? u16 pkt_len; /* packet length */
> + ? ? ? u8 *data; ? ?/* pointer to data buffer in RAM */
> + ? ? ? u8 dest_id;
> + ? ? ? u8 src_id;
> + ? ? ? u16 flags;
> + ? ? ? u8 qos;
> + ? ? ? u8 padlen;
> + ? ? ? u16 vlan_tci;
> +
> + ? ? ? u8 dst_mac[ETH_ALEN], src_mac[ETH_ALEN];
> +};
> +
> +struct port {
> + ? ? ? struct desc rx_desc_tab[RX_DESCS]; /* alignment: 0x10 */
> + ? ? ? struct desc tx_desc_tab[TX_DESCS];
> + ? ? ? u8 *buff_tab;
> + ? ? ? struct eth_regs *regs;
> + ? ? ? struct npe *npe;
> + ? ? ? u8 firmware[4];
> + ? ? ? struct eth_plat_info *pinfo;
> + ? ? ? struct mii_device miidev;
> + ? ? ? struct eth_device eth;
> +};
> +
> +#define rx_buff(port, n) ((port)->buff_tab + MAX_MRU * (n))
> +#define tx_buff(port, n) ((port)->buff_tab + MAX_MRU * (RX_DESCS + (n)))
> +
> +static struct eth_regs *mdio_regs; /* mdio command and status only */
> +
> +static int ixp4xx_mdio_cmd(int write, const struct device_d *dev, unsigned char phy_id,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned char location, unsigned short value)
> +{
> + ? ? ? int cycles = 0;
> +
> + ? ? ? if (__raw_readl(&mdio_regs->mdio_command[3]) & 0x80) {
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: MII not ready to transmit\n", dev->name, dev->id);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? if (write) {
> + ? ? ? ? ? ? ? __raw_writel(value & 0xFF, &mdio_regs->mdio_command[0]);
> + ? ? ? ? ? ? ? __raw_writel(value >> 8, &mdio_regs->mdio_command[1]);
> + ? ? ? }
> + ? ? ? __raw_writel(((phy_id << 5) | location) & 0xFF,
> + ? ? ? ? ? ? ? ? ? ?&mdio_regs->mdio_command[2]);
> + ? ? ? __raw_writel((phy_id >> 3) | (write << 2) | 0x80 /* GO */,
> + ? ? ? ? ? ? ? ? ? ?&mdio_regs->mdio_command[3]);
> +
> + ? ? ? while ((cycles < MAX_MDIO_RETRIES) &&
> + ? ? ? ? ? ? ?(__raw_readl(&mdio_regs->mdio_command[3]) & 0x80)) {
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? ? ? ? ? cycles++;
> + ? ? ? }
> +
> + ? ? ? if (cycles == MAX_MDIO_RETRIES) {
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: MII write failed\n", dev->name, dev->id);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> +#if DEBUG_MDIO
> + ? ? ? fprintf(stderr, "%s%d: mdio_%s() took %i cycles\n", dev->name, dev->id,
> + ? ? ? ? ? ? ? write ? "write" : "read", cycles);
> +#endif
> +
> + ? ? ? if (write)
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? if (__raw_readl(&mdio_regs->mdio_status[3]) & 0x80) {
> +#if DEBUG_MDIO
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: MII read failed\n", dev->name, dev->id);
> +#endif
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? value = (__raw_readl(&mdio_regs->mdio_status[0]) & 0xFF) |
> + ? ? ? ? ? ? ? ((__raw_readl(&mdio_regs->mdio_status[1]) & 0xFF) << 8);
> +#if DEBUG_MDIO
> + ? ? ? fprintf(stderr, "%s%d: MII read [%i] -> 0x%X\n", dev->name, dev->id, location, value);
> +#endif
> +
> + ? ? ? return value;
> +}
> +
> +static int ixp4xx_mdio_read(struct mii_device *mii, int phy_id, int location)
> +{
> + ? ? ? int ret = ixp4xx_mdio_cmd(0, &mii->dev, phy_id, location, 0);
> + ? ? ? return ret;
> +}
> +
> +static int ixp4xx_mdio_write(struct mii_device *mii, int phy_id, int location, int value)
> +{
> + ? ? ? int ret = ixp4xx_mdio_cmd(1, &mii->dev, phy_id, location, value);
> +#if DEBUG_MDIO
> + ? ? ? fprintf(stderr, "%s%d: MII write [%i] <- 0x%X, err = %i\n",
> + ? ? ? ? ? ? ? mii->dev.name, mii->dev.id, location, value, ret);
> +#endif
> + ? ? ? return ret;
> +}
> +
> +static int ixp4xx_adjust_link(struct eth_device *dev)
> +{
> + ? ? ? struct port *port = dev->priv;
> + ? ? ? int reg, speed, duplex;
> +
> + ? ? ? miidev_wait_aneg(&port->miidev);
> +
> + ? ? ? reg = mii_read(&port->miidev, port->miidev.address, MII_BMSR);
> + ? ? ? if (reg < 0)
> + ? ? ? ? ? ? ? goto err_out;
> + ? ? ? if (!(reg & BMSR_LSTATUS)) {
> + ? ? ? ? ? ? ? printf("%s%d: Link is down", dev->dev.name, dev->dev.id);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? reg = mii_read(&port->miidev, port->miidev.address, MII_BMCR);
> + ? ? ? if (reg < 0)
> + ? ? ? ? ? ? ? goto err_out;
> +
> + ? ? ? if (reg & BMCR_ANENABLE) {
> + ? ? ? ? ? ? ? reg = mii_read(&port->miidev, port->miidev.address, MII_LPA);
> + ? ? ? ? ? ? ? if (reg < 0)
> + ? ? ? ? ? ? ? ? ? ? ? goto err_out;
> + ? ? ? ? ? ? ? duplex = reg & LPA_DUPLEX;
> + ? ? ? ? ? ? ? speed = reg & LPA_100 ? 100 : 10;
> + ? ? ? } else {
> + ? ? ? ? ? ? ? duplex = reg & BMCR_FULLDPLX;
> + ? ? ? ? ? ? ? speed = reg & BMCR_SPEED100 ? 100 : 10;
> + ? ? ? }
> +
> + ? ? ? if (duplex)
> + ? ? ? ? ? ? ? __raw_writel(DEFAULT_TX_CNTRL0 & ~TX_CNTRL0_HALFDUPLEX,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?&port->regs->tx_control[0]);
> + ? ? ? else
> + ? ? ? ? ? ? ? __raw_writel(DEFAULT_TX_CNTRL0 | TX_CNTRL0_HALFDUPLEX,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?&port->regs->tx_control[0]);
> +
> + ? ? ? fprintf(stderr, "%s%d: link up, speed %u Mb/s, %s duplex\n",
> + ? ? ? ? ? ? ? dev->dev.name, dev->dev.id, speed, duplex ? "full" : "half");
> + ? ? ? return 0;
> +
> +err_out:
> + ? ? ? printf("%s%d: failed to read MII data\n", dev->dev.name, dev->dev.id);
> + ? ? ? return -EIO;
> +}
> +
> +static inline void debug_pkt(struct eth_device *dev, const char *func,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?u8 *data, int len)
> +{
> +#if DEBUG_PKT_BYTES
> + ? ? ? int i;
> +
> + ? ? ? fprintf(stderr, "%s%d: %s(%4i) ", dev->dev.name, dev->dev.id, func, len);
> + ? ? ? for (i = 0; i < len; i++) {
> + ? ? ? ? ? ? ? if (i >= DEBUG_PKT_BYTES)
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%02X",
> + ? ? ? ? ? ? ? ? ? ? ? ((i == 6) || (i == 12) || (i >= 14)) ? " " : "",
> + ? ? ? ? ? ? ? ? ? ? ? data[i]);
> + ? ? ? }
> + ? ? ? fprintf(stderr, "\n");
> +#endif
> +}
> +
> +
> +static inline void debug_desc(struct desc *desc)
> +{
> +#if DEBUG_DESC
> + ? ? ? fprintf(stderr, "%07X: %X %3X %3X %07X %2X < %2X %4X %X"
> + ? ? ? ? ? ? ? " %X %X %02X%02X%02X%02X%02X%02X < %02X%02X%02X%02X%02X%02X\n",
> + ? ? ? ? ? ? ? (u32)desc, (u32)desc->next, desc->buf_len, desc->pkt_len,
> + ? ? ? ? ? ? ? (u32)desc->data, desc->dest_id, desc->src_id, desc->flags,
> + ? ? ? ? ? ? ? desc->qos, desc->padlen, desc->vlan_tci,
> + ? ? ? ? ? ? ? desc->dst_mac[0], desc->dst_mac[1], desc->dst_mac[2],
> + ? ? ? ? ? ? ? desc->dst_mac[3], desc->dst_mac[4], desc->dst_mac[5],
> + ? ? ? ? ? ? ? desc->src_mac[0], desc->src_mac[1], desc->src_mac[2],
> + ? ? ? ? ? ? ? desc->src_mac[3], desc->src_mac[4], desc->src_mac[5]);
> +#endif
> +}
> +
> +static inline int queue_get_desc(unsigned int queue, struct port *port,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int is_tx)
> +{
> + ? ? ? u32 addr, n;
> + ? ? ? struct desc *tab;
> +
> + ? ? ? if (!(addr = qmgr_get_entry(queue)))
> + ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? addr &= ~0x1F; /* mask out non-address bits */
> + ? ? ? tab = is_tx ? port->tx_desc_tab : port->rx_desc_tab;
> + ? ? ? n = (addr - (u32)tab) / sizeof(struct desc);
> + ? ? ? BUG_ON(n >= (is_tx ? TX_DESCS : RX_DESCS));
> + ? ? ? debug_desc((struct desc*)addr);
> + ? ? ? BUG_ON(tab[n].next);
> + ? ? ? return n;
> +}
> +
> +static inline void queue_put_desc(unsigned int queue, struct desc *desc)
> +{
> + ? ? ? debug_desc(desc);
> + ? ? ? BUG_ON(((u32)desc) & 0x1F);
> + ? ? ? qmgr_put_entry(queue, (u32)desc);
> + ? ? ? /* Don't check for queue overflow here, we've allocated sufficient
> + ? ? ? ? ?length and queues >= 32 don't support this check anyway. */
> +}
> +
> +
> +static int ixp4xx_eth_poll(struct eth_device *dev)
> +{
> + ? ? ? struct port *port = dev->priv;
> + ? ? ? struct desc *desc;
> + ? ? ? u8 *buff;
> + ? ? ? int n, len;
> +
> +#if DEBUG_RX
> + ? ? ? fprintf(stderr, "%s%d: eth_poll\n", dev->dev.name, dev->dev.id);
> +#endif
> +
> + ? ? ? if ((n = queue_get_desc(RX_QUEUE(port), port, 0)) < 0) {
> +#if DEBUG_RX
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: eth_poll = no packet received\n", dev->dev.name, dev->dev.id);
> +#endif
> + ? ? ? ? ? ? ? return 0;
> + ? ? ? }
> +
> + ? ? ? barrier();
> + ? ? ? desc = &port->rx_desc_tab[n];
> + ? ? ? buff = rx_buff(port, n);
> + ? ? ? len = desc->pkt_len;
> + ? ? ? /* process received frame */
> + ? ? ? memcpy((void *)NetRxPackets[0], buff, len);
> + ? ? ? debug_pkt(dev, "RX", desc->data, len);
> +
> + ? ? ? /* put the new buffer on RX-free queue */
> + ? ? ? desc->buf_len = MAX_MRU;
> + ? ? ? desc->pkt_len = 0;
> + ? ? ? queue_put_desc(RXFREE_QUEUE(port), desc);
> +
> + ? ? ? net_receive(NetRxPackets[0], len);
> +
> +#if DEBUG_RX
> + ? ? ? fprintf(stderr, "%s%d: eth_poll end\n", dev->dev.name, dev->dev.id);
> +#endif
> + ? ? ? return 0;
> +}
> +
> +
> +static int ixp4xx_eth_xmit(struct eth_device *dev, void *data, int len)
> +{
> + ? ? ? struct port *port = dev->priv;
> + ? ? ? int n;
> + ? ? ? struct desc *desc;
> +
> +#if DEBUG_TX
> + ? ? ? fprintf(stderr, "%s%d: eth_xmit\n", dev->dev.name, dev->dev.id);
> +#endif
> +
> + ? ? ? if (unlikely(len > 1500))
> + ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? debug_pkt(dev, "TX", data, len);
> +
> + ? ? ? if ((n = queue_get_desc(TXDONE_QUEUE, port, 1)) < 0)
> + ? ? ? ? ? ? ? return -1; /* no free buffers */
> + ? ? ? desc = &port->tx_desc_tab[n];
> + ? ? ? desc->data = tx_buff(port, n);
> + ? ? ? desc->buf_len = desc->pkt_len = len;
> + ? ? ? memcpy(desc->data, data, len);
> +
> + ? ? ? /* NPE firmware pads short frames with zeros internally */
> + ? ? ? // wmb();
> + ? ? ? barrier();
> + ? ? ? queue_put_desc(TX_QUEUE(port), desc);
> +
> +#if DEBUG_TX
> + ? ? ? fprintf(stderr, "%s%d: eth_xmit end\n", dev->dev.name, dev->dev.id);
> +#endif
> + ? ? ? return 0;
> +}
> +
> +static void request_queues(struct port *port, struct eth_device *dev)
> +{
> + ? ? ? qmgr_request_queue(RXFREE_QUEUE(port), RX_DESCS, 0, 0, "%s:RX-free", dev->dev.name);
> + ? ? ? qmgr_request_queue(RX_QUEUE(port), RX_DESCS, 0, 0, "%s:RX", dev->dev.name);
> + ? ? ? qmgr_request_queue(TX_QUEUE(port), TX_DESCS, 0, 0, "%s:TX", dev->dev.name);
> +
> + ? ? ? /* Common TX-done queue handles buffers sent out by the NPEs */
> + ? ? ? qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?"%s:TX-done", dev->dev.name);
> +}
> +
> +static void release_queues(struct port *port)
> +{
> + ? ? ? qmgr_release_queue(RXFREE_QUEUE(port));
> + ? ? ? qmgr_release_queue(RX_QUEUE(port));
> + ? ? ? qmgr_release_queue(TX_QUEUE(port));
> + ? ? ? qmgr_release_queue(TXDONE_QUEUE);
> +}
> +
> +static void init_queues(struct port *port)
> +{
> + ? ? ? int i;
> +
> + ? ? ? memset(port->tx_desc_tab, 0, sizeof(port->tx_desc_tab)); /* descs */
> + ? ? ? memset(port->rx_desc_tab, 0, sizeof(port->rx_desc_tab));
> +
> + ? ? ? /* Setup RX buffers */
> + ? ? ? for (i = 0; i < RX_DESCS; i++) {
> + ? ? ? ? ? ? ? struct desc *desc = &port->rx_desc_tab[i];
> + ? ? ? ? ? ? ? desc->buf_len = MAX_MRU;
> + ? ? ? ? ? ? ? desc->data = rx_buff(port, i);
> + ? ? ? }
> +}
> +
> +static int ixp4xx_eth_open(struct eth_device *dev)
> +{
> + ? ? ? struct port *port = dev->priv;
> + ? ? ? struct npe *npe = port->npe;
> + ? ? ? struct msg msg;
> + ? ? ? int i, err;
> +
> +#if DEBUG_OPEN
> + ? ? ? fprintf(stderr, "%s%d: opening %p\n", dev->dev.name, dev->dev.id, dev);
> +#endif
> +
> + ? ? ? if (!npe_running(npe)) {
> + ? ? ? ? ? ? ? err = npe_load_firmware(npe);
> + ? ? ? ? ? ? ? if (err)
> + ? ? ? ? ? ? ? ? ? ? ? return err;
> +
> + ? ? ? ? ? ? ? if (npe_recv_message(npe, &msg, "ETH_GET_STATUS")) {
> + ? ? ? ? ? ? ? ? ? ? ? fprintf(stderr, "%s%d: %s not responding\n", dev->dev.name, dev->dev.id, npe->name);
> + ? ? ? ? ? ? ? ? ? ? ? return -EIO;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? memcpy(port->firmware, msg.params + 2, 4);
> + ? ? ? }
> +
> + ? ? ? if (ixp4xx_adjust_link(dev))
> + ? ? ? ? ? ? ? return -ENOLINK;
> +
> + ? ? ? port->buff_tab = xmalloc((RX_DESCS + TX_DESCS) * MAX_MRU);
> +
> + ? ? ? memset(&msg, 0, sizeof(msg));
> + ? ? ? msg.cmd = NPE_VLAN_SETRXQOSENTRY;
> + ? ? ? msg.eth_id = LOGICAL_ID(port);
> + ? ? ? msg.params[3] = RX_QUEUE(port) | 0x80;
> + ? ? ? msg.params[4] = RX_QUEUE(port) >> 4; /* MSB of offset */
> + ? ? ? msg.params[5] = RX_QUEUE(port) << 4; /* LSB of offset */
> + ? ? ? for (i = 0; i < 8; i++) {
> + ? ? ? ? ? ? ? msg.params[1] = i;
> + ? ? ? ? ? ? ? if (npe_send_recv_message(port->npe, &msg, "ETH_SET_RXQ")) {
> + ? ? ? ? ? ? ? ? ? ? ? err = -EIO;
> + ? ? ? ? ? ? ? ? ? ? ? goto out;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? msg.cmd = NPE_EDB_SETPORTADDRESS;
> + ? ? ? msg.eth_id = PHYSICAL_ID(port);
> + ? ? ? memcpy(msg.params, port->pinfo->hwaddr, ETH_ALEN);
> + ? ? ? if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAC")) {
> + ? ? ? ? ? ? ? err = -EIO;
> + ? ? ? ? ? ? ? goto out;
> + ? ? ? }
> +
> + ? ? ? memset(&msg, 0, sizeof(msg));
> + ? ? ? msg.cmd = NPE_FW_SETFIREWALLMODE;
> + ? ? ? msg.eth_id = LOGICAL_ID(port);
> + ? ? ? if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE")) {
> + ? ? ? ? ? ? ? err = -EIO;
> + ? ? ? ? ? ? ? goto out;
> + ? ? ? }
> +
> + ? ? ? request_queues(port, dev);
> + ? ? ? init_queues(port);
> +
> + ? ? ? for (i = 0; i < ETH_ALEN; i++)
> + ? ? ? ? ? ? ? __raw_writel(port->pinfo->hwaddr[i], &port->regs->hw_addr[i]);
> + ? ? ? __raw_writel(0x08, &port->regs->random_seed);
> + ? ? ? __raw_writel(0x12, &port->regs->partial_empty_threshold);
> + ? ? ? __raw_writel(0x30, &port->regs->partial_full_threshold);
> + ? ? ? __raw_writel(0x08, &port->regs->tx_start_bytes);
> + ? ? ? __raw_writel(0x15, &port->regs->tx_deferral);
> + ? ? ? __raw_writel(0x08, &port->regs->tx_2part_deferral[0]);
> + ? ? ? __raw_writel(0x07, &port->regs->tx_2part_deferral[1]);
> + ? ? ? __raw_writel(0x80, &port->regs->slot_time);
> + ? ? ? __raw_writel(0x01, &port->regs->int_clock_threshold);
> +
> + ? ? ? /* Populate queues with buffers, no failure after this point */
> + ? ? ? for (i = 0; i < TX_DESCS; i++)
> + ? ? ? ? ? ? ? queue_put_desc(TXDONE_QUEUE, &port->tx_desc_tab[i]);
> +
> + ? ? ? for (i = 0; i < RX_DESCS; i++)
> + ? ? ? ? ? ? ? queue_put_desc(RXFREE_QUEUE(port), &port->rx_desc_tab[i]);
> +
> + ? ? ? __raw_writel(TX_CNTRL1_RETRIES, &port->regs->tx_control[1]);
> + ? ? ? __raw_writel(DEFAULT_TX_CNTRL0, &port->regs->tx_control[0]);
> + ? ? ? __raw_writel(0, &port->regs->rx_control[1]);
> + ? ? ? __raw_writel(DEFAULT_RX_CNTRL0, &port->regs->rx_control[0]);
> +
> +#if 0
> + ? ? ? qmgr_set_irq(RX_QUEUE(port), QUEUE_IRQ_SRC_NOT_EMPTY,
> + ? ? ? ? ? ? ? ? ? ?eth_rx_irq, dev);
> + ? ? ? qmgr_set_irq(TXDONE_QUEUE, QUEUE_IRQ_SRC_NOT_EMPTY,
> + ? ? ? ? ? ? ? ? ? ?eth_txdone_irq, NULL);
> + ? ? ? qmgr_enable_irq(TXDONE_QUEUE);
> +#endif
> + ? ? ? memset(&msg, 0, sizeof(msg));
> +#if DEBUG_OPEN
> + ? ? ? fprintf(stderr, "%s%d opened\n", dev->dev.name, dev->dev.id);
> +#endif
> + ? ? ? return 0;
> +out:
> + ? ? ? free(port->buff_tab);
> + ? ? ? port->buff_tab = NULL;
> +#if DEBUG_OPEN
> + ? ? ? fprintf(stderr, "%s%d open failed (%i)\n", dev->dev.name, dev->dev.id, err);
> +#endif
> + ? ? ? return err;
> +}
> +
> +static void ixp4xx_eth_close(struct eth_device *dev)
> +{
> + ? ? ? struct port *port = dev->priv;
> + ? ? ? struct msg msg;
> + ? ? ? int buffs = RX_DESCS; /* allocated RX buffers */
> + ? ? ? int i;
> +
> +#if DEBUG_CLOSE
> + ? ? ? fprintf(stderr, "%s%d: closing\n", dev->dev.name, dev->dev.id);
> +#endif
> +#if 0
> + ? ? ? qmgr_disable_irq(RX_QUEUE(port));
> +#endif
> +
> + ? ? ? if (!port->buff_tab)
> + ? ? ? ? ? ? ? return; /* already closed */
> +
> + ? ? ? while (queue_get_desc(RXFREE_QUEUE(port), port, 0) >= 0)
> + ? ? ? ? ? ? ? buffs--;
> +
> + ? ? ? memset(&msg, 0, sizeof(msg));
> + ? ? ? msg.cmd = NPE_SETLOOPBACK_MODE;
> + ? ? ? msg.eth_id = LOGICAL_ID(port);
> + ? ? ? msg.params[1] = 1;
> + ? ? ? if (npe_send_recv_message(port->npe, &msg, "ETH_ENABLE_LOOPBACK"))
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: unable to enable loopback\n", dev->dev.name, dev->dev.id);
> +
> +#if DEBUG_CLOSE
> + ? ? ? fprintf(stderr, "%s%d: draining RX queue\n", dev->dev.name, dev->dev.id);
> +#endif
> + ? ? ? i = 0;
> + ? ? ? do { /* drain RX buffers */
> + ? ? ? ? ? ? ? while (queue_get_desc(RX_QUEUE(port), port, 0) >= 0)
> + ? ? ? ? ? ? ? ? ? ? ? buffs--;
> + ? ? ? ? ? ? ? if (!buffs)
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? if (qmgr_stat_full(TXDONE_QUEUE) && !(i % 10)) {
> + ? ? ? ? ? ? ? ? ? ? ? /* we have to inject some packet */
> + ? ? ? ? ? ? ? ? ? ? ? struct desc *desc;
> + ? ? ? ? ? ? ? ? ? ? ? int n = queue_get_desc(TXDONE_QUEUE, port, 1);
> + ? ? ? ? ? ? ? ? ? ? ? BUG_ON(n < 0);
> + ? ? ? ? ? ? ? ? ? ? ? desc = &port->tx_desc_tab[n];
> + ? ? ? ? ? ? ? ? ? ? ? desc->buf_len = desc->pkt_len = 1;
> + ? ? ? ? ? ? ? ? ? ? ? //wmb();
> + ? ? ? ? ? ? ? ? ? ? ? barrier();
> + ? ? ? ? ? ? ? ? ? ? ? queue_put_desc(TX_QUEUE(port), desc);
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? } while (++i < MAX_CLOSE_WAIT);
> +
> + ? ? ? if (buffs)
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: unable to drain RX queue, %i buffer(s) left in NPE\n",
> + ? ? ? ? ? ? ? ? ? ? ? dev->dev.name, dev->dev.id, buffs);
> +#if DEBUG_CLOSE
> + ? ? ? if (!buffs)
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: draining RX queue took %i cycles\n", dev->dev.name, dev->dev.id, i);
> +#endif
> +
> + ? ? ? buffs = TX_DESCS;
> + ? ? ? while (queue_get_desc(TX_QUEUE(port), port, 1) >= 0)
> + ? ? ? ? ? ? ? buffs--; /* cancel TX */
> +
> + ? ? ? i = 0;
> + ? ? ? do {
> + ? ? ? ? ? ? ? while (queue_get_desc(TXDONE_QUEUE, port, 1) >= 0)
> + ? ? ? ? ? ? ? ? ? ? ? buffs--;
> + ? ? ? ? ? ? ? if (!buffs)
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? } while (++i < MAX_CLOSE_WAIT);
> +
> + ? ? ? if (buffs)
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: unable to drain TX queue, %i buffer(s) left in NPE\n",
> + ? ? ? ? ? ? ? ? ? ? ? dev->dev.name, dev->dev.id, buffs);
> +#if DEBUG_CLOSE
> + ? ? ? if (!buffs)
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: draining TX queues took %i cycles\n", dev->dev.name, dev->dev.id, i);
> +#endif
> +
> + ? ? ? msg.params[1] = 0;
> + ? ? ? if (npe_send_recv_message(port->npe, &msg, "ETH_DISABLE_LOOPBACK"))
> + ? ? ? ? ? ? ? fprintf(stderr, "%s%d: unable to disable loopback\n", dev->dev.name, dev->dev.id);
> +
> +#if 0
> + ? ? ? qmgr_disable_irq(TXDONE_QUEUE);
> +#endif
> + ? ? ? release_queues(port);
> + ? ? ? free(port->buff_tab);
> + ? ? ? port->buff_tab = NULL;
> +#if DEBUG_CLOSE
> + ? ? ? fprintf(stderr, "%s%d: closed\n", dev->dev.name, dev->dev.id);
> +#endif
> +}
> +
> +static int ixp4xx_eth_get_hwaddr(struct eth_device *eth, unsigned char *addr)
> +{
> + ? ? ? struct port *port = eth->priv;
> + ? ? ? memcpy(addr, port->pinfo->hwaddr, 6);
> + ? ? ? return 0;
> +}
> +
> +static int ixp4xx_eth_set_hwaddr(struct eth_device *eth, unsigned char *addr)
> +{
> + ? ? ? struct port *port = eth->priv;
> + ? ? ? memcpy(port->pinfo->hwaddr, addr, 6);
> + ? ? ? return 0;
> +}
> +
> +static int ixp4xx_eth_init(struct eth_device *eth)
> +{
> + ? ? ? struct port *port = eth->priv;
> +
> + ? ? ? __raw_writel(DEFAULT_CORE_CNTRL | CORE_RESET,
> + ? ? ? ? ? ? ? ? ? ?&port->regs->core_control);
> + ? ? ? udelay(50);
> + ? ? ? __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
> + ? ? ? udelay(50);
> +
> + ? ? ? miidev_restart_aneg(&port->miidev);
> + ? ? ? return 0;
> +}
> +
> +static int ixp4xx_eth_probe(struct device_d *dev)
> +{
> + ? ? ? struct npe *npe;
> + ? ? ? struct port *port;
> + ? ? ? struct eth_plat_info *pinfo = dev->platform_data;
> +
> + ? ? ? if (!pinfo) {
> + ? ? ? ? ? ? ? fprintf(stderr, "ixp4xx_eth: no platform information\n");
> + ? ? ? ? ? ? ? return -ENODEV;
> + ? ? ? }
> +
> + ? ? ? if (!(npe = npe_request(pinfo->npe))) {
> + ? ? ? ? ? ? ? fprintf(stderr, "ixp4xx_eth: unable to acquire NPE\n");
> + ? ? ? ? ? ? ? return -ENODEV;
> + ? ? ? }
> +
> + ? ? ? port = memalign(0x20, sizeof(*port));
> + ? ? ? memset(port, 0, sizeof(*port));
> +
> + ? ? ? port->regs = pinfo->regs;
> + ? ? ? port->npe = npe;
> + ? ? ? port->pinfo = pinfo;
> + ? ? ? port->eth.dev.id = -1;
> + ? ? ? port->eth.priv = port;
> + ? ? ? port->eth.init = ixp4xx_eth_init;
> + ? ? ? port->eth.open = ixp4xx_eth_open;
> + ? ? ? port->eth.halt = ixp4xx_eth_close;
> + ? ? ? port->eth.send = ixp4xx_eth_xmit;
> + ? ? ? port->eth.recv = ixp4xx_eth_poll;
> + ? ? ? port->eth.get_ethaddr = ixp4xx_eth_get_hwaddr;
> + ? ? ? port->eth.set_ethaddr = ixp4xx_eth_set_hwaddr;
> +
> + ? ? ? port->miidev.dev.id = -1;
> + ? ? ? port->miidev.read = ixp4xx_mdio_read;
> + ? ? ? port->miidev.write = ixp4xx_mdio_write;
> + ? ? ? port->miidev.address = pinfo->phy;
> + ? ? ? port->miidev.edev = &port->eth;
> + ? ? ? mii_register(&port->miidev);
> + ? ? ? eth_register(&port->eth);
> + ? ? ? return 0;
> +}
> +
> +static struct driver_d ixp4xx_eth_driver = {
> + ? ? ? .name ?= "ixp4xx_eth",
> + ? ? ? .probe = ixp4xx_eth_probe,
> +};
> +
> +static int __init ixp4xx_eth_module_init(void)
> +{
> + ? ? ? if (cpu_is_ixp43x()) {
> + ? ? ? ? ? ? ? /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
> + ? ? ? ? ? ? ? if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
> + ? ? ? ? ? ? ? ? ? ? ? return -ENOSYS;
> + ? ? ? ? ? ? ? mdio_regs = (struct eth_regs *)IXP4XX_EthC_BASE;
> + ? ? ? } else {
> + ? ? ? ? ? ? ? /* All MII PHY accesses use NPE-B Ethernet registers */
> + ? ? ? ? ? ? ? if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
> + ? ? ? ? ? ? ? ? ? ? ? return -ENOSYS;
> + ? ? ? ? ? ? ? mdio_regs = (struct eth_regs *)IXP4XX_EthB_BASE;
> + ? ? ? }
> +
> + ? ? ? __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
> +
> + ? ? ? register_driver(&ixp4xx_eth_driver);
> + ? ? ? return 0;
> +}
> +
> +device_initcall(ixp4xx_eth_module_init);
> diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
> index 290619f..0f25ceb 100644
> --- a/drivers/serial/serial_ns16550.c
> +++ b/drivers/serial/serial_ns16550.c
> @@ -102,7 +102,11 @@ static void ns16550_serial_init_port(struct console_device *cdev)
> ? ? ? ?baud_divisor = ns16550_calc_divisor(cdev, CONFIG_BAUDRATE);
>
> ? ? ? ?/* initializing the device for the first time */
> +#ifdef CONFIG_ARCH_IXP4XX
> + ? ? ? plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
> +#else
> ? ? ? ?plat->reg_write(0x00, base, ier);
> +#endif
> ?#ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
> ? ? ? ?plat->reg_write(0x07, base, mdr1); ? ? ?/* Disable */
> ?#endif
> @@ -181,7 +185,11 @@ static int ns16550_setbaudrate(struct console_device *cdev, int baud_rate)
> ? ? ? ? ? ?cdev->dev->platform_data;
> ? ? ? ?unsigned long base = cdev->dev->map_base;
> ? ? ? ?unsigned int baud_divisor = ns16550_calc_divisor(cdev, baud_rate);
> +#ifdef CONFIG_ARCH_IXP4XX
> + ? ? ? plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
> +#else
> ? ? ? ?plat->reg_write(0x00, base, ier);
> +#endif
> ? ? ? ?plat->reg_write(LCR_BKSE, base, lcr);
> ? ? ? ?plat->reg_write(baud_divisor & 0xff, base, dll);
> ? ? ? ?plat->reg_write((baud_divisor >> 8) & 0xff, base, dlm);
> diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
> index eb2fd10..ba20a6f 100644
> --- a/drivers/serial/serial_ns16550.h
> +++ b/drivers/serial/serial_ns16550.h
> @@ -50,6 +50,8 @@
> ?#define dll ? ? ? ? ? ?rbr
> ?#define dlm ? ? ? ? ? ?ier
>
> +#define IER_UUE ? ? ? ? ? ? ? ?0x40 ? ?/* UART Unit Enable (XScale) */
> +
> ?#define FCR_FIFO_EN ? ? 0x01 ? /* Fifo enable */
> ?#define FCR_RXSR ? ? ? ?0x02 ? /* Receiver soft reset */
> ?#define FCR_TXSR ? ? ? ?0x04 ? /* Transmitter soft reset */
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From s.hauer at pengutronix.de  Tue Dec 21 04:25:43 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Dec 2010 10:25:43 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <AANLkTi=ptG8Ubx-caJ1Nnv7mxEZtKK5UAtWiPjEGj=H5@mail.gmail.com>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<AANLkTi=ptG8Ubx-caJ1Nnv7mxEZtKK5UAtWiPjEGj=H5@mail.gmail.com>
Message-ID: <20101221092543.GY6017@pengutronix.de>

On Tue, Dec 21, 2010 at 08:42:41AM +0100, Belisko Marek wrote:
> Hi,
> 
> On Tue, Dec 21, 2010 at 12:06 AM, Krzysztof Halasa <khc at pm.waw.pl> wrote:
> > Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 8cb86cb..56b5a0d 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -39,6 +39,13 @@ config ARCH_IMX
> > ? ? ? ?bool "Freescale iMX-based"
> > ? ? ? ?select GENERIC_GPIO
> >
> > +config ARCH_IXP4XX
> > + ? ? ? bool "Intel IXP4xx-based"
> > + ? ? ? select CPU_32v5
> > + ? ? ? select ARCH_SUPPORTS_BIG_ENDIAN
> > + ? ? ? select CPU_BIG_ENDIAN
> > + ? ? ? select ARCH_HAS_LOWLEVEL_INIT
> > +
> Should go to different Kconfig. This is ARM related and you have
> intel cpu which is possibly x86.  Also in other patches you stick to ARM
> but your CPU doesn't have ARM core.

The ixp4xx actually is an ARM processor.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Tue Dec 21 04:30:11 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 10:30:11 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <AANLkTi=ptG8Ubx-caJ1Nnv7mxEZtKK5UAtWiPjEGj=H5@mail.gmail.com>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<AANLkTi=ptG8Ubx-caJ1Nnv7mxEZtKK5UAtWiPjEGj=H5@mail.gmail.com>
Message-ID: <201012211030.11134.jbe@pengutronix.de>

Belisko Marek wrote:
> On Tue, Dec 21, 2010 at 12:06 AM, Krzysztof Halasa <khc at pm.waw.pl> wrote:
> > Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 8cb86cb..56b5a0d 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -39,6 +39,13 @@ config ARCH_IMX
> > ? ? ? ?bool "Freescale iMX-based"
> > ? ? ? ?select GENERIC_GPIO
> >
> > +config ARCH_IXP4XX
> > + ? ? ? bool "Intel IXP4xx-based"
> > + ? ? ? select CPU_32v5
> > + ? ? ? select ARCH_SUPPORTS_BIG_ENDIAN
> > + ? ? ? select CPU_BIG_ENDIAN
> > + ? ? ? select ARCH_HAS_LOWLEVEL_INIT
> > +
>
> Should go to different Kconfig. This is ARM related and you have
> intel cpu which is possibly x86.  Also in other patches you stick to ARM
> but your CPU doesn't have ARM core.

Hmm, IPX4xx is ARM (AFAIK).

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Tue Dec 21 04:34:23 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Dec 2010 10:34:23 +0100
Subject: [PATCH 1] Delete unused file common/dlmalloc.src.
In-Reply-To: <m31v5cdq4z.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m31v5cdq4z.fsf@intrepid.localdomain>
Message-ID: <20101221093423.GA6017@pengutronix.de>

On Mon, Dec 20, 2010 at 11:40:44PM +0100, Krzysztof Halasa wrote:
> Delete unused file common/dlmalloc.src.
> Or is there any reason to have it here?

The reason probably is to keep the original code the implementation is
derived from around. I agree that we can remove it though, we have our
history in git and even this file can be restored from the history.

Sascha

> 
> Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
> 
> diff --git a/common/dlmalloc.src b/common/dlmalloc.src
> deleted file mode 100644
> index 32a38bc..0000000
> --- a/common/dlmalloc.src
> +++ /dev/null
> @@ -1,3265 +0,0 @@
> -/* ---------- To make a malloc.h, start cutting here ------------ */
> -
> -/*
> -  A version of malloc/free/realloc written by Doug Lea and released to the
> -  public domain.  Send questions/comments/complaints/performance data
> -  to dl at cs.oswego.edu
> -
> -* VERSION 2.6.6  Sun Mar  5 19:10:03 2000  Doug Lea  (dl at gee)
> -
> -   Note: There may be an updated version of this malloc obtainable at
> -	   ftp://g.oswego.edu/pub/misc/malloc.c
> -	 Check before installing!
> -
> -* Why use this malloc?
> -
> -  This is not the fastest, most space-conserving, most portable, or
> -  most tunable malloc ever written. However it is among the fastest
> -  while also being among the most space-conserving, portable and tunable.
> -  Consistent balance across these factors results in a good general-purpose
> -  allocator. For a high-level description, see
> -     http://g.oswego.edu/dl/html/malloc.html
> -
> -* Synopsis of public routines
> -
> -  (Much fuller descriptions are contained in the program documentation below.)
> -
> -  malloc(size_t n);
> -     Return a pointer to a newly allocated chunk of at least n bytes, or null
> -     if no space is available.
> -  free(Void_t* p);
> -     Release the chunk of memory pointed to by p, or no effect if p is null.
> -  realloc(Void_t* p, size_t n);
> -     Return a pointer to a chunk of size n that contains the same data
> -     as does chunk p up to the minimum of (n, p's size) bytes, or null
> -     if no space is available. The returned pointer may or may not be
> -     the same as p. If p is null, equivalent to malloc.  Unless the
> -     #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
> -     size argument of zero (re)allocates a minimum-sized chunk.
> -  memalign(size_t alignment, size_t n);
> -     Return a pointer to a newly allocated chunk of n bytes, aligned
> -     in accord with the alignment argument, which must be a power of
> -     two.
> -  valloc(size_t n);
> -     Equivalent to memalign(pagesize, n), where pagesize is the page
> -     size of the system (or as near to this as can be figured out from
> -     all the includes/defines below.)
> -  pvalloc(size_t n);
> -     Equivalent to valloc(minimum-page-that-holds(n)), that is,
> -     round up n to nearest pagesize.
> -  calloc(size_t unit, size_t quantity);
> -     Returns a pointer to quantity * unit bytes, with all locations
> -     set to zero.
> -  cfree(Void_t* p);
> -     Equivalent to free(p).
> -  malloc_trim(size_t pad);
> -     Release all but pad bytes of freed top-most memory back
> -     to the system. Return 1 if successful, else 0.
> -  malloc_usable_size(Void_t* p);
> -     Report the number usable allocated bytes associated with allocated
> -     chunk p. This may or may not report more bytes than were requested,
> -     due to alignment and minimum size constraints.
> -  malloc_stats();
> -     Prints brief summary statistics on stderr.
> -  mallinfo()
> -     Returns (by copy) a struct containing various summary statistics.
> -  mallopt(int parameter_number, int parameter_value)
> -     Changes one of the tunable parameters described below. Returns
> -     1 if successful in changing the parameter, else 0.
> -
> -* Vital statistics:
> -
> -  Alignment:                            8-byte
> -       8 byte alignment is currently hardwired into the design.  This
> -       seems to suffice for all current machines and C compilers.
> -
> -  Assumed pointer representation:       4 or 8 bytes
> -       Code for 8-byte pointers is untested by me but has worked
> -       reliably by Wolfram Gloger, who contributed most of the
> -       changes supporting this.
> -
> -  Assumed size_t  representation:       4 or 8 bytes
> -       Note that size_t is allowed to be 4 bytes even if pointers are 8.
> -
> -  Minimum overhead per allocated chunk: 4 or 8 bytes
> -       Each malloced chunk has a hidden overhead of 4 bytes holding size
> -       and status information.
> -
> -  Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
> -			  8-byte ptrs:  24/32 bytes (including, 4/8 overhead)
> -
> -       When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
> -       ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
> -       needed; 4 (8) for a trailing size field
> -       and 8 (16) bytes for free list pointers. Thus, the minimum
> -       allocatable size is 16/24/32 bytes.
> -
> -       Even a request for zero bytes (i.e., malloc(0)) returns a
> -       pointer to something of the minimum allocatable size.
> -
> -  Maximum allocated size: 4-byte size_t: 2^31 -  8 bytes
> -			  8-byte size_t: 2^63 - 16 bytes
> -
> -       It is assumed that (possibly signed) size_t bit values suffice to
> -       represent chunk sizes. `Possibly signed' is due to the fact
> -       that `size_t' may be defined on a system as either a signed or
> -       an unsigned type. To be conservative, values that would appear
> -       as negative numbers are avoided.
> -       Requests for sizes with a negative sign bit when the request
> -       size is treaded as a long will return null.
> -
> -  Maximum overhead wastage per allocated chunk: normally 15 bytes
> -
> -       Alignnment demands, plus the minimum allocatable size restriction
> -       make the normal worst-case wastage 15 bytes (i.e., up to 15
> -       more bytes will be allocated than were requested in malloc), with
> -       two exceptions:
> -	 1. Because requests for zero bytes allocate non-zero space,
> -	    the worst case wastage for a request of zero bytes is 24 bytes.
> -	 2. For requests >= mmap_threshold that are serviced via
> -	    mmap(), the worst case wastage is 8 bytes plus the remainder
> -	    from a system page (the minimal mmap unit); typically 4096 bytes.
> -
> -* Limitations
> -
> -    Here are some features that are NOT currently supported
> -
> -    * No user-definable hooks for callbacks and the like.
> -    * No automated mechanism for fully checking that all accesses
> -      to malloced memory stay within their bounds.
> -    * No support for compaction.
> -
> -* Synopsis of compile-time options:
> -
> -    People have reported using previous versions of this malloc on all
> -    versions of Unix, sometimes by tweaking some of the defines
> -    below. It has been tested most extensively on Solaris and
> -    Linux. It is also reported to work on WIN32 platforms.
> -    People have also reported adapting this malloc for use in
> -    stand-alone embedded systems.
> -
> -    The implementation is in straight, hand-tuned ANSI C.  Among other
> -    consequences, it uses a lot of macros.  Because of this, to be at
> -    all usable, this code should be compiled using an optimizing compiler
> -    (for example gcc -O2) that can simplify expressions and control
> -    paths.
> -
> -  __STD_C                  (default: derived from C compiler defines)
> -     Nonzero if using ANSI-standard C compiler, a C++ compiler, or
> -     a C compiler sufficiently close to ANSI to get away with it.
> -  DEBUG                    (default: NOT defined)
> -     Define to enable debugging. Adds fairly extensive assertion-based
> -     checking to help track down memory errors, but noticeably slows down
> -     execution.
> -  REALLOC_ZERO_BYTES_FREES (default: NOT defined)
> -     Define this if you think that realloc(p, 0) should be equivalent
> -     to free(p). Otherwise, since malloc returns a unique pointer for
> -     malloc(0), so does realloc(p, 0).
> -  HAVE_MEMCPY               (default: defined)
> -     Define if you are not otherwise using ANSI STD C, but still
> -     have memcpy and memset in your C library and want to use them.
> -     Otherwise, simple internal versions are supplied.
> -  USE_MEMCPY               (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
> -     Define as 1 if you want the C library versions of memset and
> -     memcpy called in realloc and calloc (otherwise macro versions are used).
> -     At least on some platforms, the simple macro versions usually
> -     outperform libc versions.
> -  HAVE_MMAP                 (default: defined as 1)
> -     Define to non-zero to optionally make malloc() use mmap() to
> -     allocate very large blocks.
> -  HAVE_MREMAP                 (default: defined as 0 unless Linux libc set)
> -     Define to non-zero to optionally make realloc() use mremap() to
> -     reallocate very large blocks.
> -  malloc_getpagesize        (default: derived from system #includes)
> -     Either a constant or routine call returning the system page size.
> -  HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
> -     Optionally define if you are on a system with a /usr/include/malloc.h
> -     that declares struct mallinfo. It is not at all necessary to
> -     define this even if you do, but will ensure consistency.
> -  INTERNAL_SIZE_T           (default: size_t)
> -     Define to a 32-bit type (probably `unsigned int') if you are on a
> -     64-bit machine, yet do not want or need to allow malloc requests of
> -     greater than 2^31 to be handled. This saves space, especially for
> -     very small chunks.
> -  INTERNAL_LINUX_C_LIB      (default: NOT defined)
> -     Defined only when compiled as part of Linux libc.
> -     Also note that there is some odd internal name-mangling via defines
> -     (for example, internally, `malloc' is named `mALLOc') needed
> -     when compiling in this case. These look funny but don't otherwise
> -     affect anything.
> -  WIN32                     (default: undefined)
> -     Define this on MS win (95, nt) platforms to compile in sbrk emulation.
> -  LACKS_UNISTD_H            (default: undefined if not WIN32)
> -     Define this if your system does not have a <unistd.h>.
> -  LACKS_SYS_PARAM_H         (default: undefined if not WIN32)
> -     Define this if your system does not have a <sys/param.h>.
> -  MORECORE                  (default: sbrk)
> -     The name of the routine to call to obtain more memory from the system.
> -  MORECORE_FAILURE          (default: -1)
> -     The value returned upon failure of MORECORE.
> -  MORECORE_CLEARS           (default 1)
> -     True (1) if the routine mapped to MORECORE zeroes out memory (which
> -     holds for sbrk).
> -  DEFAULT_TRIM_THRESHOLD
> -  DEFAULT_TOP_PAD
> -  DEFAULT_MMAP_THRESHOLD
> -  DEFAULT_MMAP_MAX
> -     Default values of tunable parameters (described in detail below)
> -     controlling interaction with host system routines (sbrk, mmap, etc).
> -     These values may also be changed dynamically via mallopt(). The
> -     preset defaults are those that give best performance for typical
> -     programs/systems.
> -  USE_DL_PREFIX             (default: undefined)
> -     Prefix all public routines with the string 'dl'.  Useful to
> -     quickly avoid procedure declaration conflicts and linker symbol
> -     conflicts with existing memory allocation routines.
> -
> -
> -*/
> -
> -
> -
> -
> -/* Preliminaries */
> -
> -#ifndef __STD_C
> -#ifdef __STDC__
> -#define __STD_C     1
> -#else
> -#if __cplusplus
> -#define __STD_C     1
> -#else
> -#define __STD_C     0
> -#endif /*__cplusplus*/
> -#endif /*__STDC__*/
> -#endif /*__STD_C*/
> -
> -#ifndef Void_t
> -#if (__STD_C || defined(WIN32))
> -#define Void_t      void
> -#else
> -#define Void_t      char
> -#endif
> -#endif /*Void_t*/
> -
> -#if __STD_C
> -#include <stddef.h>   /* for size_t */
> -#else
> -#include <sys/types.h>
> -#endif
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -#include <stdio.h>    /* needed for malloc_stats */
> -
> -
> -/*
> -  Compile-time options
> -*/
> -
> -
> -/*
> -    Debugging:
> -
> -    Because freed chunks may be overwritten with link fields, this
> -    malloc will often die when freed memory is overwritten by user
> -    programs.  This can be very effective (albeit in an annoying way)
> -    in helping track down dangling pointers.
> -
> -    If you compile with -DDEBUG, a number of assertion checks are
> -    enabled that will catch more memory errors. You probably won't be
> -    able to make much sense of the actual assertion errors, but they
> -    should help you locate incorrectly overwritten memory.  The
> -    checking is fairly extensive, and will slow down execution
> -    noticeably. Calling malloc_stats or mallinfo with DEBUG set will
> -    attempt to check every non-mmapped allocated and free chunk in the
> -    course of computing the summmaries. (By nature, mmapped regions
> -    cannot be checked very much automatically.)
> -
> -    Setting DEBUG may also be helpful if you are trying to modify
> -    this code. The assertions in the check routines spell out in more
> -    detail the assumptions and invariants underlying the algorithms.
> -
> -*/
> -
> -#if DEBUG
> -#include <assert.h>
> -#else
> -#define assert(x) ((void)0)
> -#endif
> -
> -
> -/*
> -  INTERNAL_SIZE_T is the word-size used for internal bookkeeping
> -  of chunk sizes. On a 64-bit machine, you can reduce malloc
> -  overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
> -  at the expense of not being able to handle requests greater than
> -  2^31. This limitation is hardly ever a concern; you are encouraged
> -  to set this. However, the default version is the same as size_t.
> -*/
> -
> -#ifndef INTERNAL_SIZE_T
> -#define INTERNAL_SIZE_T size_t
> -#endif
> -
> -/*
> -  REALLOC_ZERO_BYTES_FREES should be set if a call to
> -  realloc with zero bytes should be the same as a call to free.
> -  Some people think it should. Otherwise, since this malloc
> -  returns a unique pointer for malloc(0), so does realloc(p, 0).
> -*/
> -
> -
> -/*   #define REALLOC_ZERO_BYTES_FREES */
> -
> -
> -/*
> -  WIN32 causes an emulation of sbrk to be compiled in
> -  mmap-based options are not currently supported in WIN32.
> -*/
> -
> -/* #define WIN32 */
> -#ifdef WIN32
> -#define MORECORE wsbrk
> -#define HAVE_MMAP 0
> -
> -#define LACKS_UNISTD_H
> -#define LACKS_SYS_PARAM_H
> -
> -/*
> -  Include 'windows.h' to get the necessary declarations for the
> -  Microsoft Visual C++ data structures and routines used in the 'sbrk'
> -  emulation.
> -
> -  Define WIN32_LEAN_AND_MEAN so that only the essential Microsoft
> -  Visual C++ header files are included.
> -*/
> -#define WIN32_LEAN_AND_MEAN
> -#include <windows.h>
> -#endif
> -
> -
> -/*
> -  HAVE_MEMCPY should be defined if you are not otherwise using
> -  ANSI STD C, but still have memcpy and memset in your C library
> -  and want to use them in calloc and realloc. Otherwise simple
> -  macro versions are defined here.
> -
> -  USE_MEMCPY should be defined as 1 if you actually want to
> -  have memset and memcpy called. People report that the macro
> -  versions are often enough faster than libc versions on many
> -  systems that it is better to use them.
> -
> -*/
> -
> -#define HAVE_MEMCPY
> -
> -#ifndef USE_MEMCPY
> -#ifdef HAVE_MEMCPY
> -#define USE_MEMCPY 1
> -#else
> -#define USE_MEMCPY 0
> -#endif
> -#endif
> -
> -#if (__STD_C || defined(HAVE_MEMCPY))
> -
> -#if __STD_C
> -void* memset(void*, int, size_t);
> -void* memcpy(void*, const void*, size_t);
> -#else
> -#ifdef WIN32
> -/* On Win32 platforms, 'memset()' and 'memcpy()' are already declared in */
> -/* 'windows.h' */
> -#else
> -Void_t* memset();
> -Void_t* memcpy();
> -#endif
> -#endif
> -#endif
> -
> -#if USE_MEMCPY
> -
> -/* The following macros are only invoked with (2n+1)-multiples of
> -   INTERNAL_SIZE_T units, with a positive integer n. This is exploited
> -   for fast inline execution when n is small. */
> -
> -#define MALLOC_ZERO(charp, nbytes)                                            \
> -do {                                                                          \
> -  INTERNAL_SIZE_T mzsz = (nbytes);                                            \
> -  if(mzsz <= 9*sizeof(mzsz)) {                                                \
> -    INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp);                         \
> -    if(mzsz >= 5*sizeof(mzsz)) {     *mz++ = 0;                               \
> -				     *mz++ = 0;                               \
> -      if(mzsz >= 7*sizeof(mzsz)) {   *mz++ = 0;                               \
> -				     *mz++ = 0;                               \
> -	if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0;                               \
> -				     *mz++ = 0; }}}                           \
> -				     *mz++ = 0;                               \
> -				     *mz++ = 0;                               \
> -				     *mz   = 0;                               \
> -  } else memset((charp), 0, mzsz);                                            \
> -} while(0)
> -
> -#define MALLOC_COPY(dest,src,nbytes)                                          \
> -do {                                                                          \
> -  INTERNAL_SIZE_T mcsz = (nbytes);                                            \
> -  if(mcsz <= 9*sizeof(mcsz)) {                                                \
> -    INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src);                        \
> -    INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest);                       \
> -    if(mcsz >= 5*sizeof(mcsz)) {     *mcdst++ = *mcsrc++;                     \
> -				     *mcdst++ = *mcsrc++;                     \
> -      if(mcsz >= 7*sizeof(mcsz)) {   *mcdst++ = *mcsrc++;                     \
> -				     *mcdst++ = *mcsrc++;                     \
> -	if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++;                     \
> -				     *mcdst++ = *mcsrc++; }}}                 \
> -				     *mcdst++ = *mcsrc++;                     \
> -				     *mcdst++ = *mcsrc++;                     \
> -				     *mcdst   = *mcsrc  ;                     \
> -  } else memcpy(dest, src, mcsz);                                             \
> -} while(0)
> -
> -#else /* !USE_MEMCPY */
> -
> -/* Use Duff's device for good zeroing/copying performance. */
> -
> -#define MALLOC_ZERO(charp, nbytes)                                            \
> -do {                                                                          \
> -  INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp);                           \
> -  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
> -  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
> -  switch (mctmp) {                                                            \
> -    case 0: for(;;) { *mzp++ = 0;                                             \
> -    case 7:           *mzp++ = 0;                                             \
> -    case 6:           *mzp++ = 0;                                             \
> -    case 5:           *mzp++ = 0;                                             \
> -    case 4:           *mzp++ = 0;                                             \
> -    case 3:           *mzp++ = 0;                                             \
> -    case 2:           *mzp++ = 0;                                             \
> -    case 1:           *mzp++ = 0; if(mcn <= 0) break; mcn--; }                \
> -  }                                                                           \
> -} while(0)
> -
> -#define MALLOC_COPY(dest,src,nbytes)                                          \
> -do {                                                                          \
> -  INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src;                            \
> -  INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest;                           \
> -  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
> -  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
> -  switch (mctmp) {                                                            \
> -    case 0: for(;;) { *mcdst++ = *mcsrc++;                                    \
> -    case 7:           *mcdst++ = *mcsrc++;                                    \
> -    case 6:           *mcdst++ = *mcsrc++;                                    \
> -    case 5:           *mcdst++ = *mcsrc++;                                    \
> -    case 4:           *mcdst++ = *mcsrc++;                                    \
> -    case 3:           *mcdst++ = *mcsrc++;                                    \
> -    case 2:           *mcdst++ = *mcsrc++;                                    \
> -    case 1:           *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; }       \
> -  }                                                                           \
> -} while(0)
> -
> -#endif
> -
> -
> -/*
> -  Define HAVE_MMAP to optionally make malloc() use mmap() to
> -  allocate very large blocks.  These will be returned to the
> -  operating system immediately after a free().
> -*/
> -
> -#ifndef HAVE_MMAP
> -#define HAVE_MMAP 1
> -#endif
> -
> -/*
> -  Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
> -  large blocks.  This is currently only possible on Linux with
> -  kernel versions newer than 1.3.77.
> -*/
> -
> -#ifndef HAVE_MREMAP
> -#ifdef INTERNAL_LINUX_C_LIB
> -#define HAVE_MREMAP 1
> -#else
> -#define HAVE_MREMAP 0
> -#endif
> -#endif
> -
> -#if HAVE_MMAP
> -
> -#include <unistd.h>
> -#include <fcntl.h>
> -#include <sys/mman.h>
> -
> -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
> -#define MAP_ANONYMOUS MAP_ANON
> -#endif
> -
> -#endif /* HAVE_MMAP */
> -
> -/*
> -  Access to system page size. To the extent possible, this malloc
> -  manages memory from the system in page-size units.
> -
> -  The following mechanics for getpagesize were adapted from
> -  bsd/gnu getpagesize.h
> -*/
> -
> -#ifndef LACKS_UNISTD_H
> -#  include <unistd.h>
> -#endif
> -
> -#ifndef malloc_getpagesize
> -#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
> -#    ifndef _SC_PAGE_SIZE
> -#      define _SC_PAGE_SIZE _SC_PAGESIZE
> -#    endif
> -#  endif
> -#  ifdef _SC_PAGE_SIZE
> -#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
> -#  else
> -#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
> -       extern size_t getpagesize();
> -#      define malloc_getpagesize getpagesize()
> -#    else
> -#      ifdef WIN32
> -#        define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */
> -#      else
> -#        ifndef LACKS_SYS_PARAM_H
> -#          include <sys/param.h>
> -#        endif
> -#        ifdef EXEC_PAGESIZE
> -#          define malloc_getpagesize EXEC_PAGESIZE
> -#        else
> -#          ifdef NBPG
> -#            ifndef CLSIZE
> -#              define malloc_getpagesize NBPG
> -#            else
> -#              define malloc_getpagesize (NBPG * CLSIZE)
> -#            endif
> -#          else
> -#            ifdef NBPC
> -#              define malloc_getpagesize NBPC
> -#            else
> -#              ifdef PAGESIZE
> -#                define malloc_getpagesize PAGESIZE
> -#              else
> -#                define malloc_getpagesize (4096) /* just guess */
> -#              endif
> -#            endif
> -#          endif
> -#        endif
> -#      endif
> -#    endif
> -#  endif
> -#endif
> -
> -
> -/*
> -
> -  This version of malloc supports the standard SVID/XPG mallinfo
> -  routine that returns a struct containing the same kind of
> -  information you can get from malloc_stats. It should work on
> -  any SVID/XPG compliant system that has a /usr/include/malloc.h
> -  defining struct mallinfo. (If you'd like to install such a thing
> -  yourself, cut out the preliminary declarations as described above
> -  and below and save them in a malloc.h file. But there's no
> -  compelling reason to bother to do this.)
> -
> -  The main declaration needed is the mallinfo struct that is returned
> -  (by-copy) by mallinfo().  The SVID/XPG malloinfo struct contains a
> -  bunch of fields, most of which are not even meaningful in this
> -  version of malloc. Some of these fields are are instead filled by
> -  mallinfo() with other numbers that might possibly be of interest.
> -
> -  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
> -  /usr/include/malloc.h file that includes a declaration of struct
> -  mallinfo.  If so, it is included; else an SVID2/XPG2 compliant
> -  version is declared below.  These must be precisely the same for
> -  mallinfo() to work.
> -
> -*/
> -
> -/* #define HAVE_USR_INCLUDE_MALLOC_H */
> -
> -#if HAVE_USR_INCLUDE_MALLOC_H
> -#include "/usr/include/malloc.h"
> -#else
> -
> -/* SVID2/XPG mallinfo structure */
> -
> -struct mallinfo {
> -  int arena;    /* total space allocated from system */
> -  int ordblks;  /* number of non-inuse chunks */
> -  int smblks;   /* unused -- always zero */
> -  int hblks;    /* number of mmapped regions */
> -  int hblkhd;   /* total space in mmapped regions */
> -  int usmblks;  /* unused -- always zero */
> -  int fsmblks;  /* unused -- always zero */
> -  int uordblks; /* total allocated space */
> -  int fordblks; /* total non-inuse space */
> -  int keepcost; /* top-most, releasable (via malloc_trim) space */
> -};
> -
> -/* SVID2/XPG mallopt options */
> -
> -#define M_MXFAST  1    /* UNUSED in this malloc */
> -#define M_NLBLKS  2    /* UNUSED in this malloc */
> -#define M_GRAIN   3    /* UNUSED in this malloc */
> -#define M_KEEP    4    /* UNUSED in this malloc */
> -
> -#endif
> -
> -/* mallopt options that actually do something */
> -
> -#define M_TRIM_THRESHOLD    -1
> -#define M_TOP_PAD           -2
> -#define M_MMAP_THRESHOLD    -3
> -#define M_MMAP_MAX          -4
> -
> -
> -#ifndef DEFAULT_TRIM_THRESHOLD
> -#define DEFAULT_TRIM_THRESHOLD (128 * 1024)
> -#endif
> -
> -/*
> -    M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
> -      to keep before releasing via malloc_trim in free().
> -
> -      Automatic trimming is mainly useful in long-lived programs.
> -      Because trimming via sbrk can be slow on some systems, and can
> -      sometimes be wasteful (in cases where programs immediately
> -      afterward allocate more large chunks) the value should be high
> -      enough so that your overall system performance would improve by
> -      releasing.
> -
> -      The trim threshold and the mmap control parameters (see below)
> -      can be traded off with one another. Trimming and mmapping are
> -      two different ways of releasing unused memory back to the
> -      system. Between these two, it is often possible to keep
> -      system-level demands of a long-lived program down to a bare
> -      minimum. For example, in one test suite of sessions measuring
> -      the XF86 X server on Linux, using a trim threshold of 128K and a
> -      mmap threshold of 192K led to near-minimal long term resource
> -      consumption.
> -
> -      If you are using this malloc in a long-lived program, it should
> -      pay to experiment with these values.  As a rough guide, you
> -      might set to a value close to the average size of a process
> -      (program) running on your system.  Releasing this much memory
> -      would allow such a process to run in memory.  Generally, it's
> -      worth it to tune for trimming rather tham memory mapping when a
> -      program undergoes phases where several large chunks are
> -      allocated and released in ways that can reuse each other's
> -      storage, perhaps mixed with phases where there are no such
> -      chunks at all.  And in well-behaved long-lived programs,
> -      controlling release of large blocks via trimming versus mapping
> -      is usually faster.
> -
> -      However, in most programs, these parameters serve mainly as
> -      protection against the system-level effects of carrying around
> -      massive amounts of unneeded memory. Since frequent calls to
> -      sbrk, mmap, and munmap otherwise degrade performance, the default
> -      parameters are set to relatively high values that serve only as
> -      safeguards.
> -
> -      The default trim value is high enough to cause trimming only in
> -      fairly extreme (by current memory consumption standards) cases.
> -      It must be greater than page size to have any useful effect.  To
> -      disable trimming completely, you can set to (unsigned long)(-1);
> -
> -
> -*/
> -
> -
> -#ifndef DEFAULT_TOP_PAD
> -#define DEFAULT_TOP_PAD        (0)
> -#endif
> -
> -/*
> -    M_TOP_PAD is the amount of extra `padding' space to allocate or
> -      retain whenever sbrk is called. It is used in two ways internally:
> -
> -      * When sbrk is called to extend the top of the arena to satisfy
> -	a new malloc request, this much padding is added to the sbrk
> -	request.
> -
> -      * When malloc_trim is called automatically from free(),
> -	it is used as the `pad' argument.
> -
> -      In both cases, the actual amount of padding is rounded
> -      so that the end of the arena is always a system page boundary.
> -
> -      The main reason for using padding is to avoid calling sbrk so
> -      often. Having even a small pad greatly reduces the likelihood
> -      that nearly every malloc request during program start-up (or
> -      after trimming) will invoke sbrk, which needlessly wastes
> -      time.
> -
> -      Automatic rounding-up to page-size units is normally sufficient
> -      to avoid measurable overhead, so the default is 0.  However, in
> -      systems where sbrk is relatively slow, it can pay to increase
> -      this value, at the expense of carrying around more memory than
> -      the program needs.
> -
> -*/
> -
> -
> -#ifndef DEFAULT_MMAP_THRESHOLD
> -#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
> -#endif
> -
> -/*
> -
> -    M_MMAP_THRESHOLD is the request size threshold for using mmap()
> -      to service a request. Requests of at least this size that cannot
> -      be allocated using already-existing space will be serviced via mmap.
> -      (If enough normal freed space already exists it is used instead.)
> -
> -      Using mmap segregates relatively large chunks of memory so that
> -      they can be individually obtained and released from the host
> -      system. A request serviced through mmap is never reused by any
> -      other request (at least not directly; the system may just so
> -      happen to remap successive requests to the same locations).
> -
> -      Segregating space in this way has the benefit that mmapped space
> -      can ALWAYS be individually released back to the system, which
> -      helps keep the system level memory demands of a long-lived
> -      program low. Mapped memory can never become `locked' between
> -      other chunks, as can happen with normally allocated chunks, which
> -      menas that even trimming via malloc_trim would not release them.
> -
> -      However, it has the disadvantages that:
> -
> -	 1. The space cannot be reclaimed, consolidated, and then
> -	    used to service later requests, as happens with normal chunks.
> -	 2. It can lead to more wastage because of mmap page alignment
> -	    requirements
> -	 3. It causes malloc performance to be more dependent on host
> -	    system memory management support routines which may vary in
> -	    implementation quality and may impose arbitrary
> -	    limitations. Generally, servicing a request via normal
> -	    malloc steps is faster than going through a system's mmap.
> -
> -      All together, these considerations should lead you to use mmap
> -      only for relatively large requests.
> -
> -
> -*/
> -
> -
> -#ifndef DEFAULT_MMAP_MAX
> -#if HAVE_MMAP
> -#define DEFAULT_MMAP_MAX       (64)
> -#else
> -#define DEFAULT_MMAP_MAX       (0)
> -#endif
> -#endif
> -
> -/*
> -    M_MMAP_MAX is the maximum number of requests to simultaneously
> -      service using mmap. This parameter exists because:
> -
> -	 1. Some systems have a limited number of internal tables for
> -	    use by mmap.
> -	 2. In most systems, overreliance on mmap can degrade overall
> -	    performance.
> -	 3. If a program allocates many large regions, it is probably
> -	    better off using normal sbrk-based allocation routines that
> -	    can reclaim and reallocate normal heap memory. Using a
> -	    small value allows transition into this mode after the
> -	    first few allocations.
> -
> -      Setting to 0 disables all use of mmap.  If HAVE_MMAP is not set,
> -      the default value is 0, and attempts to set it to non-zero values
> -      in mallopt will fail.
> -*/
> -
> -
> -/*
> -    USE_DL_PREFIX will prefix all public routines with the string 'dl'.
> -      Useful to quickly avoid procedure declaration conflicts and linker
> -      symbol conflicts with existing memory allocation routines.
> -
> -*/
> -
> -/* #define USE_DL_PREFIX */
> -
> -
> -/*
> -
> -  Special defines for linux libc
> -
> -  Except when compiled using these special defines for Linux libc
> -  using weak aliases, this malloc is NOT designed to work in
> -  multithreaded applications.  No semaphores or other concurrency
> -  control are provided to ensure that multiple malloc or free calls
> -  don't run at the same time, which could be disasterous. A single
> -  semaphore could be used across malloc, realloc, and free (which is
> -  essentially the effect of the linux weak alias approach). It would
> -  be hard to obtain finer granularity.
> -
> -*/
> -
> -
> -#ifdef INTERNAL_LINUX_C_LIB
> -
> -#if __STD_C
> -
> -Void_t * __default_morecore_init (ptrdiff_t);
> -Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
> -
> -#else
> -
> -Void_t * __default_morecore_init ();
> -Void_t *(*__morecore)() = __default_morecore_init;
> -
> -#endif
> -
> -#define MORECORE (*__morecore)
> -#define MORECORE_FAILURE 0
> -#define MORECORE_CLEARS 1
> -
> -#else /* INTERNAL_LINUX_C_LIB */
> -
> -#if __STD_C
> -extern Void_t*     sbrk(ptrdiff_t);
> -#else
> -extern Void_t*     sbrk();
> -#endif
> -
> -#ifndef MORECORE
> -#define MORECORE sbrk
> -#endif
> -
> -#ifndef MORECORE_FAILURE
> -#define MORECORE_FAILURE -1
> -#endif
> -
> -#ifndef MORECORE_CLEARS
> -#define MORECORE_CLEARS 1
> -#endif
> -
> -#endif /* INTERNAL_LINUX_C_LIB */
> -
> -#if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
> -
> -#define cALLOc		__libc_calloc
> -#define fREe		__libc_free
> -#define mALLOc		__libc_malloc
> -#define mEMALIGn	__libc_memalign
> -#define rEALLOc		__libc_realloc
> -#define vALLOc		__libc_valloc
> -#define pvALLOc		__libc_pvalloc
> -#define mALLINFo	__libc_mallinfo
> -#define mALLOPt		__libc_mallopt
> -
> -#pragma weak calloc = __libc_calloc
> -#pragma weak free = __libc_free
> -#pragma weak cfree = __libc_free
> -#pragma weak malloc = __libc_malloc
> -#pragma weak memalign = __libc_memalign
> -#pragma weak realloc = __libc_realloc
> -#pragma weak valloc = __libc_valloc
> -#pragma weak pvalloc = __libc_pvalloc
> -#pragma weak mallinfo = __libc_mallinfo
> -#pragma weak mallopt = __libc_mallopt
> -
> -#else
> -
> -#ifdef USE_DL_PREFIX
> -#define cALLOc		dlcalloc
> -#define fREe		dlfree
> -#define mALLOc		dlmalloc
> -#define mEMALIGn	dlmemalign
> -#define rEALLOc		dlrealloc
> -#define vALLOc		dlvalloc
> -#define pvALLOc		dlpvalloc
> -#define mALLINFo	dlmallinfo
> -#define mALLOPt		dlmallopt
> -#else /* USE_DL_PREFIX */
> -#define cALLOc		calloc
> -#define fREe		free
> -#define mALLOc		malloc
> -#define mEMALIGn	memalign
> -#define rEALLOc		realloc
> -#define vALLOc		valloc
> -#define pvALLOc		pvalloc
> -#define mALLINFo	mallinfo
> -#define mALLOPt		mallopt
> -#endif /* USE_DL_PREFIX */
> -
> -#endif
> -
> -/* Public routines */
> -
> -#if __STD_C
> -
> -Void_t* mALLOc(size_t);
> -void    fREe(Void_t*);
> -Void_t* rEALLOc(Void_t*, size_t);
> -Void_t* mEMALIGn(size_t, size_t);
> -Void_t* vALLOc(size_t);
> -Void_t* pvALLOc(size_t);
> -Void_t* cALLOc(size_t, size_t);
> -void    cfree(Void_t*);
> -int     malloc_trim(size_t);
> -size_t  malloc_usable_size(Void_t*);
> -void    malloc_stats();
> -int     mALLOPt(int, int);
> -struct mallinfo mALLINFo(void);
> -#else
> -Void_t* mALLOc();
> -void    fREe();
> -Void_t* rEALLOc();
> -Void_t* mEMALIGn();
> -Void_t* vALLOc();
> -Void_t* pvALLOc();
> -Void_t* cALLOc();
> -void    cfree();
> -int     malloc_trim();
> -size_t  malloc_usable_size();
> -void    malloc_stats();
> -int     mALLOPt();
> -struct mallinfo mALLINFo();
> -#endif
> -
> -
> -#ifdef __cplusplus
> -};  /* end of extern "C" */
> -#endif
> -
> -/* ---------- To make a malloc.h, end cutting here ------------ */
> -
> -
> -/*
> -  Emulation of sbrk for WIN32
> -  All code within the ifdef WIN32 is untested by me.
> -
> -  Thanks to Martin Fong and others for supplying this.
> -*/
> -
> -
> -#ifdef WIN32
> -
> -#define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
> -~(malloc_getpagesize-1))
> -#define AlignPage64K(add) (((add) + (0x10000 - 1)) & ~(0x10000 - 1))
> -
> -/* resrve 64MB to insure large contiguous space */
> -#define RESERVED_SIZE (1024*1024*64)
> -#define NEXT_SIZE (2048*1024)
> -#define TOP_MEMORY ((unsigned long)2*1024*1024*1024)
> -
> -struct GmListElement;
> -typedef struct GmListElement GmListElement;
> -
> -struct GmListElement
> -{
> -	GmListElement* next;
> -	void* base;
> -};
> -
> -static GmListElement* head = 0;
> -static unsigned int gNextAddress = 0;
> -static unsigned int gAddressBase = 0;
> -static unsigned int gAllocatedSize = 0;
> -
> -static
> -GmListElement* makeGmListElement (void* bas)
> -{
> -	GmListElement* this;
> -	this = (GmListElement*)(void*)LocalAlloc (0, sizeof (GmListElement));
> -	assert (this);
> -	if (this)
> -	{
> -		this->base = bas;
> -		this->next = head;
> -		head = this;
> -	}
> -	return this;
> -}
> -
> -void gcleanup ()
> -{
> -	BOOL rval;
> -	assert ( (head == NULL) || (head->base == (void*)gAddressBase));
> -	if (gAddressBase && (gNextAddress - gAddressBase))
> -	{
> -		rval = VirtualFree ((void*)gAddressBase,
> -							gNextAddress - gAddressBase,
> -							MEM_DECOMMIT);
> -	assert (rval);
> -	}
> -	while (head)
> -	{
> -		GmListElement* next = head->next;
> -		rval = VirtualFree (head->base, 0, MEM_RELEASE);
> -		assert (rval);
> -		LocalFree (head);
> -		head = next;
> -	}
> -}
> -
> -static
> -void* findRegion (void* start_address, unsigned long size)
> -{
> -	MEMORY_BASIC_INFORMATION info;
> -	if (size >= TOP_MEMORY) return NULL;
> -
> -	while ((unsigned long)start_address + size < TOP_MEMORY)
> -	{
> -		VirtualQuery (start_address, &info, sizeof (info));
> -		if ((info.State == MEM_FREE) && (info.RegionSize >= size))
> -			return start_address;
> -		else
> -		{
> -			/* Requested region is not available so see if the */
> -			/* next region is available.  Set 'start_address' */
> -			/* to the next region and call 'VirtualQuery()' */
> -			/* again. */
> -
> -			start_address = (char*)info.BaseAddress + info.RegionSize;
> -
> -			/* Make sure we start looking for the next region */
> -			/* on the *next* 64K boundary.  Otherwise, even if */
> -			/* the new region is free according to */
> -			/* 'VirtualQuery()', the subsequent call to */
> -			/* 'VirtualAlloc()' (which follows the call to */
> -			/* this routine in 'wsbrk()') will round *down* */
> -			/* the requested address to a 64K boundary which */
> -			/* we already know is an address in the */
> -			/* unavailable region.  Thus, the subsequent call */
> -			/* to 'VirtualAlloc()' will fail and bring us back */
> -			/* here, causing us to go into an infinite loop. */
> -
> -			start_address =
> -				(void *) AlignPage64K((unsigned long) start_address);
> -		}
> -	}
> -	return NULL;
> -
> -}
> -
> -
> -void* wsbrk (long size)
> -{
> -	void* tmp;
> -	if (size > 0)
> -	{
> -		if (gAddressBase == 0)
> -		{
> -			gAllocatedSize = max (RESERVED_SIZE, AlignPage (size));
> -			gNextAddress = gAddressBase =
> -				(unsigned int)VirtualAlloc (NULL, gAllocatedSize,
> -											MEM_RESERVE, PAGE_NOACCESS);
> -		} else if (AlignPage (gNextAddress + size) > (gAddressBase +
> -gAllocatedSize))
> -		{
> -			long new_size = max (NEXT_SIZE, AlignPage (size));
> -			void* new_address = (void*)(gAddressBase+gAllocatedSize);
> -			do
> -			{
> -				new_address = findRegion (new_address, new_size);
> -
> -				if (new_address == 0)
> -					return (void*)-1;
> -
> -				gAddressBase = gNextAddress =
> -					(unsigned int)VirtualAlloc (new_address, new_size,
> -												MEM_RESERVE, PAGE_NOACCESS);
> -				/* repeat in case of race condition */
> -				/* The region that we found has been snagged */
> -				/* by another thread */
> -			}
> -			while (gAddressBase == 0);
> -
> -			assert (new_address == (void*)gAddressBase);
> -
> -			gAllocatedSize = new_size;
> -
> -			if (!makeGmListElement ((void*)gAddressBase))
> -				return (void*)-1;
> -		}
> -		if ((size + gNextAddress) > AlignPage (gNextAddress))
> -		{
> -			void* res;
> -			res = VirtualAlloc ((void*)AlignPage (gNextAddress),
> -								(size + gNextAddress -
> -								 AlignPage (gNextAddress)),
> -								MEM_COMMIT, PAGE_READWRITE);
> -			if (res == 0)
> -				return (void*)-1;
> -		}
> -		tmp = (void*)gNextAddress;
> -		gNextAddress = (unsigned int)tmp + size;
> -		return tmp;
> -	}
> -	else if (size < 0)
> -	{
> -		unsigned int alignedGoal = AlignPage (gNextAddress + size);
> -		/* Trim by releasing the virtual memory */
> -		if (alignedGoal >= gAddressBase)
> -		{
> -			VirtualFree ((void*)alignedGoal, gNextAddress - alignedGoal,
> -						 MEM_DECOMMIT);
> -			gNextAddress = gNextAddress + size;
> -			return (void*)gNextAddress;
> -		}
> -		else
> -		{
> -			VirtualFree ((void*)gAddressBase, gNextAddress - gAddressBase,
> -						 MEM_DECOMMIT);
> -			gNextAddress = gAddressBase;
> -			return (void*)-1;
> -		}
> -	}
> -	else
> -	{
> -		return (void*)gNextAddress;
> -	}
> -}
> -
> -#endif
> -
> -
> -
> -/*
> -  Type declarations
> -*/
> -
> -
> -struct malloc_chunk
> -{
> -  INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
> -  INTERNAL_SIZE_T size;      /* Size in bytes, including overhead. */
> -  struct malloc_chunk* fd;   /* double links -- used only if free. */
> -  struct malloc_chunk* bk;
> -};
> -
> -typedef struct malloc_chunk* mchunkptr;
> -
> -/*
> -
> -   malloc_chunk details:
> -
> -    (The following includes lightly edited explanations by Colin Plumb.)
> -
> -    Chunks of memory are maintained using a `boundary tag' method as
> -    described in e.g., Knuth or Standish.  (See the paper by Paul
> -    Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
> -    survey of such techniques.)  Sizes of free chunks are stored both
> -    in the front of each chunk and at the end.  This makes
> -    consolidating fragmented chunks into bigger chunks very fast.  The
> -    size fields also hold bits representing whether chunks are free or
> -    in use.
> -
> -    An allocated chunk looks like this:
> -
> -
> -    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Size of previous chunk, if allocated            | |
> -	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Size of chunk, in bytes                         |P|
> -      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             User data starts here...                          .
> -	    .                                                               .
> -	    .             (malloc_usable_space() bytes)                     .
> -	    .                                                               |
> -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Size of chunk                                     |
> -	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -
> -
> -    Where "chunk" is the front of the chunk for the purpose of most of
> -    the malloc code, but "mem" is the pointer that is returned to the
> -    user.  "Nextchunk" is the beginning of the next contiguous chunk.
> -
> -    Chunks always begin on even word boundries, so the mem portion
> -    (which is returned to the user) is also on an even word boundary, and
> -    thus double-word aligned.
> -
> -    Free chunks are stored in circular doubly-linked lists, and look like this:
> -
> -    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Size of previous chunk                            |
> -	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -    `head:' |             Size of chunk, in bytes                         |P|
> -      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Forward pointer to next chunk in list             |
> -	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Back pointer to previous chunk in list            |
> -	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -	    |             Unused space (may be 0 bytes long)                .
> -	    .                                                               .
> -	    .                                                               |
> -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -    `foot:' |             Size of chunk, in bytes                           |
> -	    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> -
> -    The P (PREV_INUSE) bit, stored in the unused low-order bit of the
> -    chunk size (which is always a multiple of two words), is an in-use
> -    bit for the *previous* chunk.  If that bit is *clear*, then the
> -    word before the current chunk size contains the previous chunk
> -    size, and can be used to find the front of the previous chunk.
> -    (The very first chunk allocated always has this bit set,
> -    preventing access to non-existent (or non-owned) memory.)
> -
> -    Note that the `foot' of the current chunk is actually represented
> -    as the prev_size of the NEXT chunk. (This makes it easier to
> -    deal with alignments etc).
> -
> -    The two exceptions to all this are
> -
> -     1. The special chunk `top', which doesn't bother using the
> -	trailing size field since there is no
> -	next contiguous chunk that would have to index off it. (After
> -	initialization, `top' is forced to always exist.  If it would
> -	become less than MINSIZE bytes long, it is replenished via
> -	malloc_extend_top.)
> -
> -     2. Chunks allocated via mmap, which have the second-lowest-order
> -	bit (IS_MMAPPED) set in their size fields.  Because they are
> -	never merged or traversed from any other chunk, they have no
> -	foot size or inuse information.
> -
> -    Available chunks are kept in any of several places (all declared below):
> -
> -    * `av': An array of chunks serving as bin headers for consolidated
> -       chunks. Each bin is doubly linked.  The bins are approximately
> -       proportionally (log) spaced.  There are a lot of these bins
> -       (128). This may look excessive, but works very well in
> -       practice.  All procedures maintain the invariant that no
> -       consolidated chunk physically borders another one. Chunks in
> -       bins are kept in size order, with ties going to the
> -       approximately least recently used chunk.
> -
> -       The chunks in each bin are maintained in decreasing sorted order by
> -       size.  This is irrelevant for the small bins, which all contain
> -       the same-sized chunks, but facilitates best-fit allocation for
> -       larger chunks. (These lists are just sequential. Keeping them in
> -       order almost never requires enough traversal to warrant using
> -       fancier ordered data structures.)  Chunks of the same size are
> -       linked with the most recently freed at the front, and allocations
> -       are taken from the back.  This results in LRU or FIFO allocation
> -       order, which tends to give each chunk an equal opportunity to be
> -       consolidated with adjacent freed chunks, resulting in larger free
> -       chunks and less fragmentation.
> -
> -    * `top': The top-most available chunk (i.e., the one bordering the
> -       end of available memory) is treated specially. It is never
> -       included in any bin, is used only if no other chunk is
> -       available, and is released back to the system if it is very
> -       large (see M_TRIM_THRESHOLD).
> -
> -    * `last_remainder': A bin holding only the remainder of the
> -       most recently split (non-top) chunk. This bin is checked
> -       before other non-fitting chunks, so as to provide better
> -       locality for runs of sequentially allocated chunks.
> -
> -    *  Implicitly, through the host system's memory mapping tables.
> -       If supported, requests greater than a threshold are usually
> -       serviced via calls to mmap, and then later released via munmap.
> -
> -*/
> -
> -
> -
> -
> -
> -/*  sizes, alignments */
> -
> -#define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))
> -#define MALLOC_ALIGNMENT       (SIZE_SZ + SIZE_SZ)
> -#define MALLOC_ALIGN_MASK      (MALLOC_ALIGNMENT - 1)
> -#define MINSIZE                (sizeof(struct malloc_chunk))
> -
> -/* conversion from malloc headers to user pointers, and back */
> -
> -#define chunk2mem(p)   ((Void_t*)((char*)(p) + 2*SIZE_SZ))
> -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
> -
> -/* pad request bytes into a usable size */
> -
> -#define request2size(req) \
> - (((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
> -  (long)(MINSIZE + MALLOC_ALIGN_MASK)) ? MINSIZE : \
> -   (((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
> -
> -/* Check if m has acceptable alignment */
> -
> -#define aligned_OK(m)    (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
> -
> -
> -
> -
> -/*
> -  Physical chunk operations
> -*/
> -
> -
> -/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
> -
> -#define PREV_INUSE 0x1
> -
> -/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
> -
> -#define IS_MMAPPED 0x2
> -
> -/* Bits to mask off when extracting size */
> -
> -#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
> -
> -
> -/* Ptr to next physical malloc_chunk. */
> -
> -#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
> -
> -/* Ptr to previous physical malloc_chunk */
> -
> -#define prev_chunk(p)\
> -   ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
> -
> -
> -/* Treat space at ptr + offset as a chunk */
> -
> -#define chunk_at_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
> -
> -
> -
> -
> -/*
> -  Dealing with use bits
> -*/
> -
> -/* extract p's inuse bit */
> -
> -#define inuse(p)\
> -((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
> -
> -/* extract inuse bit of previous chunk */
> -
> -#define prev_inuse(p)  ((p)->size & PREV_INUSE)
> -
> -/* check for mmap()'ed chunk */
> -
> -#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
> -
> -/* set/clear chunk as in use without otherwise disturbing */
> -
> -#define set_inuse(p)\
> -((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
> -
> -#define clear_inuse(p)\
> -((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
> -
> -/* check/set/clear inuse bits in known places */
> -
> -#define inuse_bit_at_offset(p, s)\
> - (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
> -
> -#define set_inuse_bit_at_offset(p, s)\
> - (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
> -
> -#define clear_inuse_bit_at_offset(p, s)\
> - (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
> -
> -
> -
> -
> -/*
> -  Dealing with size fields
> -*/
> -
> -/* Get size, ignoring use bits */
> -
> -#define chunksize(p)          ((p)->size & ~(SIZE_BITS))
> -
> -/* Set size at head, without disturbing its use bit */
> -
> -#define set_head_size(p, s)   ((p)->size = (((p)->size & PREV_INUSE) | (s)))
> -
> -/* Set size/use ignoring previous bits in header */
> -
> -#define set_head(p, s)        ((p)->size = (s))
> -
> -/* Set size at footer (only when chunk is not in use) */
> -
> -#define set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
> -
> -
> -
> -
> -
> -/*
> -   Bins
> -
> -    The bins, `av_' are an array of pairs of pointers serving as the
> -    heads of (initially empty) doubly-linked lists of chunks, laid out
> -    in a way so that each pair can be treated as if it were in a
> -    malloc_chunk. (This way, the fd/bk offsets for linking bin heads
> -    and chunks are the same).
> -
> -    Bins for sizes < 512 bytes contain chunks of all the same size, spaced
> -    8 bytes apart. Larger bins are approximately logarithmically
> -    spaced. (See the table below.) The `av_' array is never mentioned
> -    directly in the code, but instead via bin access macros.
> -
> -    Bin layout:
> -
> -    64 bins of size       8
> -    32 bins of size      64
> -    16 bins of size     512
> -     8 bins of size    4096
> -     4 bins of size   32768
> -     2 bins of size  262144
> -     1 bin  of size what's left
> -
> -    There is actually a little bit of slop in the numbers in bin_index
> -    for the sake of speed. This makes no difference elsewhere.
> -
> -    The special chunks `top' and `last_remainder' get their own bins,
> -    (this is implemented via yet more trickery with the av_ array),
> -    although `top' is never properly linked to its bin since it is
> -    always handled specially.
> -
> -*/
> -
> -#define NAV             128   /* number of bins */
> -
> -typedef struct malloc_chunk* mbinptr;
> -
> -/* access macros */
> -
> -#define bin_at(i)      ((mbinptr)((char*)&(av_[2*(i) + 2]) - 2*SIZE_SZ))
> -#define next_bin(b)    ((mbinptr)((char*)(b) + 2 * sizeof(mbinptr)))
> -#define prev_bin(b)    ((mbinptr)((char*)(b) - 2 * sizeof(mbinptr)))
> -
> -/*
> -   The first 2 bins are never indexed. The corresponding av_ cells are instead
> -   used for bookkeeping. This is not to save space, but to simplify
> -   indexing, maintain locality, and avoid some initialization tests.
> -*/
> -
> -#define top            (bin_at(0)->fd)   /* The topmost chunk */
> -#define last_remainder (bin_at(1))       /* remainder from last split */
> -
> -
> -/*
> -   Because top initially points to its own bin with initial
> -   zero size, thus forcing extension on the first malloc request,
> -   we avoid having any special code in malloc to check whether
> -   it even exists yet. But we still need to in malloc_extend_top.
> -*/
> -
> -#define initial_top    ((mchunkptr)(bin_at(0)))
> -
> -/* Helper macro to initialize bins */
> -
> -#define IAV(i)  bin_at(i), bin_at(i)
> -
> -static mbinptr av_[NAV * 2 + 2] = {
> - 0, 0,
> - IAV(0),   IAV(1),   IAV(2),   IAV(3),   IAV(4),   IAV(5),   IAV(6),   IAV(7),
> - IAV(8),   IAV(9),   IAV(10),  IAV(11),  IAV(12),  IAV(13),  IAV(14),  IAV(15),
> - IAV(16),  IAV(17),  IAV(18),  IAV(19),  IAV(20),  IAV(21),  IAV(22),  IAV(23),
> - IAV(24),  IAV(25),  IAV(26),  IAV(27),  IAV(28),  IAV(29),  IAV(30),  IAV(31),
> - IAV(32),  IAV(33),  IAV(34),  IAV(35),  IAV(36),  IAV(37),  IAV(38),  IAV(39),
> - IAV(40),  IAV(41),  IAV(42),  IAV(43),  IAV(44),  IAV(45),  IAV(46),  IAV(47),
> - IAV(48),  IAV(49),  IAV(50),  IAV(51),  IAV(52),  IAV(53),  IAV(54),  IAV(55),
> - IAV(56),  IAV(57),  IAV(58),  IAV(59),  IAV(60),  IAV(61),  IAV(62),  IAV(63),
> - IAV(64),  IAV(65),  IAV(66),  IAV(67),  IAV(68),  IAV(69),  IAV(70),  IAV(71),
> - IAV(72),  IAV(73),  IAV(74),  IAV(75),  IAV(76),  IAV(77),  IAV(78),  IAV(79),
> - IAV(80),  IAV(81),  IAV(82),  IAV(83),  IAV(84),  IAV(85),  IAV(86),  IAV(87),
> - IAV(88),  IAV(89),  IAV(90),  IAV(91),  IAV(92),  IAV(93),  IAV(94),  IAV(95),
> - IAV(96),  IAV(97),  IAV(98),  IAV(99),  IAV(100), IAV(101), IAV(102), IAV(103),
> - IAV(104), IAV(105), IAV(106), IAV(107), IAV(108), IAV(109), IAV(110), IAV(111),
> - IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119),
> - IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
> -};
> -
> -
> -
> -/* field-extraction macros */
> -
> -#define first(b) ((b)->fd)
> -#define last(b)  ((b)->bk)
> -
> -/*
> -  Indexing into bins
> -*/
> -
> -#define bin_index(sz)                                                          \
> -(((((unsigned long)(sz)) >> 9) ==    0) ?       (((unsigned long)(sz)) >>  3): \
> - ((((unsigned long)(sz)) >> 9) <=    4) ?  56 + (((unsigned long)(sz)) >>  6): \
> - ((((unsigned long)(sz)) >> 9) <=   20) ?  91 + (((unsigned long)(sz)) >>  9): \
> - ((((unsigned long)(sz)) >> 9) <=   84) ? 110 + (((unsigned long)(sz)) >> 12): \
> - ((((unsigned long)(sz)) >> 9) <=  340) ? 119 + (((unsigned long)(sz)) >> 15): \
> - ((((unsigned long)(sz)) >> 9) <= 1364) ? 124 + (((unsigned long)(sz)) >> 18): \
> -					  126)
> -/*
> -  bins for chunks < 512 are all spaced 8 bytes apart, and hold
> -  identically sized chunks. This is exploited in malloc.
> -*/
> -
> -#define MAX_SMALLBIN         63
> -#define MAX_SMALLBIN_SIZE   512
> -#define SMALLBIN_WIDTH        8
> -
> -#define smallbin_index(sz)  (((unsigned long)(sz)) >> 3)
> -
> -/*
> -   Requests are `small' if both the corresponding and the next bin are small
> -*/
> -
> -#define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
> -
> -
> -
> -/*
> -    To help compensate for the large number of bins, a one-level index
> -    structure is used for bin-by-bin searching.  `binblocks' is a
> -    one-word bitvector recording whether groups of BINBLOCKWIDTH bins
> -    have any (possibly) non-empty bins, so they can be skipped over
> -    all at once during during traversals. The bits are NOT always
> -    cleared as soon as all bins in a block are empty, but instead only
> -    when all are noticed to be empty during traversal in malloc.
> -*/
> -
> -#define BINBLOCKWIDTH     4   /* bins per block */
> -
> -#define binblocks      (bin_at(0)->size) /* bitvector of nonempty blocks */
> -
> -/* bin<->block macros */
> -
> -#define idx2binblock(ix)    ((unsigned)1 << (ix / BINBLOCKWIDTH))
> -#define mark_binblock(ii)   (binblocks |= idx2binblock(ii))
> -#define clear_binblock(ii)  (binblocks &= ~(idx2binblock(ii)))
> -
> -
> -
> -
> -
> -/*  Other static bookkeeping data */
> -
> -/* variables holding tunable values */
> -
> -static unsigned long trim_threshold   = DEFAULT_TRIM_THRESHOLD;
> -static unsigned long top_pad          = DEFAULT_TOP_PAD;
> -static unsigned int  n_mmaps_max      = DEFAULT_MMAP_MAX;
> -static unsigned long mmap_threshold   = DEFAULT_MMAP_THRESHOLD;
> -
> -/* The first value returned from sbrk */
> -static char* sbrk_base = (char*)(-1);
> -
> -/* The maximum memory obtained from system via sbrk */
> -static unsigned long max_sbrked_mem = 0;
> -
> -/* The maximum via either sbrk or mmap */
> -static unsigned long max_total_mem = 0;
> -
> -/* internal working copy of mallinfo */
> -static struct mallinfo current_mallinfo = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
> -
> -/* The total memory obtained from system via sbrk */
> -#define sbrked_mem  (current_mallinfo.arena)
> -
> -/* Tracking mmaps */
> -
> -static unsigned int n_mmaps = 0;
> -static unsigned int max_n_mmaps = 0;
> -static unsigned long mmapped_mem = 0;
> -static unsigned long max_mmapped_mem = 0;
> -
> -
> -
> -/*
> -  Debugging support
> -*/
> -
> -#if DEBUG
> -
> -
> -/*
> -  These routines make a number of assertions about the states
> -  of data structures that should be true at all times. If any
> -  are not true, it's very likely that a user program has somehow
> -  trashed memory. (It's also possible that there is a coding error
> -  in malloc. In which case, please report it!)
> -*/
> -
> -#if __STD_C
> -static void do_check_chunk(mchunkptr p)
> -#else
> -static void do_check_chunk(p) mchunkptr p;
> -#endif
> -{
> -  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
> -
> -  /* No checkable chunk is mmapped */
> -  assert(!chunk_is_mmapped(p));
> -
> -  /* Check for legal address ... */
> -  assert((char*)p >= sbrk_base);
> -  if (p != top)
> -    assert((char*)p + sz <= (char*)top);
> -  else
> -    assert((char*)p + sz <= sbrk_base + sbrked_mem);
> -
> -}
> -
> -
> -#if __STD_C
> -static void do_check_free_chunk(mchunkptr p)
> -#else
> -static void do_check_free_chunk(p) mchunkptr p;
> -#endif
> -{
> -  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
> -  mchunkptr next = chunk_at_offset(p, sz);
> -
> -  do_check_chunk(p);
> -
> -  /* Check whether it claims to be free ... */
> -  assert(!inuse(p));
> -
> -  /* Unless a special marker, must have OK fields */
> -  if ((long)sz >= (long)MINSIZE)
> -  {
> -    assert((sz & MALLOC_ALIGN_MASK) == 0);
> -    assert(aligned_OK(chunk2mem(p)));
> -    /* ... matching footer field */
> -    assert(next->prev_size == sz);
> -    /* ... and is fully consolidated */
> -    assert(prev_inuse(p));
> -    assert (next == top || inuse(next));
> -
> -    /* ... and has minimally sane links */
> -    assert(p->fd->bk == p);
> -    assert(p->bk->fd == p);
> -  }
> -  else /* markers are always of size SIZE_SZ */
> -    assert(sz == SIZE_SZ);
> -}
> -
> -#if __STD_C
> -static void do_check_inuse_chunk(mchunkptr p)
> -#else
> -static void do_check_inuse_chunk(p) mchunkptr p;
> -#endif
> -{
> -  mchunkptr next = next_chunk(p);
> -  do_check_chunk(p);
> -
> -  /* Check whether it claims to be in use ... */
> -  assert(inuse(p));
> -
> -  /* ... and is surrounded by OK chunks.
> -    Since more things can be checked with free chunks than inuse ones,
> -    if an inuse chunk borders them and debug is on, it's worth doing them.
> -  */
> -  if (!prev_inuse(p))
> -  {
> -    mchunkptr prv = prev_chunk(p);
> -    assert(next_chunk(prv) == p);
> -    do_check_free_chunk(prv);
> -  }
> -  if (next == top)
> -  {
> -    assert(prev_inuse(next));
> -    assert(chunksize(next) >= MINSIZE);
> -  }
> -  else if (!inuse(next))
> -    do_check_free_chunk(next);
> -
> -}
> -
> -#if __STD_C
> -static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
> -#else
> -static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
> -#endif
> -{
> -  INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
> -  long room = sz - s;
> -
> -  do_check_inuse_chunk(p);
> -
> -  /* Legal size ... */
> -  assert((long)sz >= (long)MINSIZE);
> -  assert((sz & MALLOC_ALIGN_MASK) == 0);
> -  assert(room >= 0);
> -  assert(room < (long)MINSIZE);
> -
> -  /* ... and alignment */
> -  assert(aligned_OK(chunk2mem(p)));
> -
> -
> -  /* ... and was allocated at front of an available chunk */
> -  assert(prev_inuse(p));
> -
> -}
> -
> -
> -#define check_free_chunk(P)  do_check_free_chunk(P)
> -#define check_inuse_chunk(P) do_check_inuse_chunk(P)
> -#define check_chunk(P) do_check_chunk(P)
> -#define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N)
> -#else
> -#define check_free_chunk(P)
> -#define check_inuse_chunk(P)
> -#define check_chunk(P)
> -#define check_malloced_chunk(P,N)
> -#endif
> -
> -
> -
> -/*
> -  Macro-based internal utilities
> -*/
> -
> -
> -/*
> -  Linking chunks in bin lists.
> -  Call these only with variables, not arbitrary expressions, as arguments.
> -*/
> -
> -/*
> -  Place chunk p of size s in its bin, in size order,
> -  putting it ahead of others of same size.
> -*/
> -
> -
> -#define frontlink(P, S, IDX, BK, FD)                                          \
> -{                                                                             \
> -  if (S < MAX_SMALLBIN_SIZE)                                                  \
> -  {                                                                           \
> -    IDX = smallbin_index(S);                                                  \
> -    mark_binblock(IDX);                                                       \
> -    BK = bin_at(IDX);                                                         \
> -    FD = BK->fd;                                                              \
> -    P->bk = BK;                                                               \
> -    P->fd = FD;                                                               \
> -    FD->bk = BK->fd = P;                                                      \
> -  }                                                                           \
> -  else                                                                        \
> -  {                                                                           \
> -    IDX = bin_index(S);                                                       \
> -    BK = bin_at(IDX);                                                         \
> -    FD = BK->fd;                                                              \
> -    if (FD == BK) mark_binblock(IDX);                                         \
> -    else                                                                      \
> -    {                                                                         \
> -      while (FD != BK && S < chunksize(FD)) FD = FD->fd;                      \
> -      BK = FD->bk;                                                            \
> -    }                                                                         \
> -    P->bk = BK;                                                               \
> -    P->fd = FD;                                                               \
> -    FD->bk = BK->fd = P;                                                      \
> -  }                                                                           \
> -}
> -
> -
> -/* take a chunk off a list */
> -
> -#define unlink(P, BK, FD)                                                     \
> -{                                                                             \
> -  BK = P->bk;                                                                 \
> -  FD = P->fd;                                                                 \
> -  FD->bk = BK;                                                                \
> -  BK->fd = FD;                                                                \
> -}                                                                             \
> -
> -/* Place p as the last remainder */
> -
> -#define link_last_remainder(P)                                                \
> -{                                                                             \
> -  last_remainder->fd = last_remainder->bk =  P;                               \
> -  P->fd = P->bk = last_remainder;                                             \
> -}
> -
> -/* Clear the last_remainder bin */
> -
> -#define clear_last_remainder \
> -  (last_remainder->fd = last_remainder->bk = last_remainder)
> -
> -
> -
> -
> -
> -/* Routines dealing with mmap(). */
> -
> -#if HAVE_MMAP
> -
> -#if __STD_C
> -static mchunkptr mmap_chunk(size_t size)
> -#else
> -static mchunkptr mmap_chunk(size) size_t size;
> -#endif
> -{
> -  size_t page_mask = malloc_getpagesize - 1;
> -  mchunkptr p;
> -
> -#ifndef MAP_ANONYMOUS
> -  static int fd = -1;
> -#endif
> -
> -  if(n_mmaps >= n_mmaps_max) return 0; /* too many regions */
> -
> -  /* For mmapped chunks, the overhead is one SIZE_SZ unit larger, because
> -   * there is no following chunk whose prev_size field could be used.
> -   */
> -  size = (size + SIZE_SZ + page_mask) & ~page_mask;
> -
> -#ifdef MAP_ANONYMOUS
> -  p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE,
> -		      MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
> -#else /* !MAP_ANONYMOUS */
> -  if (fd < 0)
> -  {
> -    fd = open("/dev/zero", O_RDWR);
> -    if(fd < 0) return 0;
> -  }
> -  p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
> -#endif
> -
> -  if(p == (mchunkptr)-1) return 0;
> -
> -  n_mmaps++;
> -  if (n_mmaps > max_n_mmaps) max_n_mmaps = n_mmaps;
> -
> -  /* We demand that eight bytes into a page must be 8-byte aligned. */
> -  assert(aligned_OK(chunk2mem(p)));
> -
> -  /* The offset to the start of the mmapped region is stored
> -   * in the prev_size field of the chunk; normally it is zero,
> -   * but that can be changed in memalign().
> -   */
> -  p->prev_size = 0;
> -  set_head(p, size|IS_MMAPPED);
> -
> -  mmapped_mem += size;
> -  if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
> -    max_mmapped_mem = mmapped_mem;
> -  if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
> -    max_total_mem = mmapped_mem + sbrked_mem;
> -  return p;
> -}
> -
> -#if __STD_C
> -static void munmap_chunk(mchunkptr p)
> -#else
> -static void munmap_chunk(p) mchunkptr p;
> -#endif
> -{
> -  INTERNAL_SIZE_T size = chunksize(p);
> -  int ret;
> -
> -  assert (chunk_is_mmapped(p));
> -  assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
> -  assert((n_mmaps > 0));
> -  assert(((p->prev_size + size) & (malloc_getpagesize-1)) == 0);
> -
> -  n_mmaps--;
> -  mmapped_mem -= (size + p->prev_size);
> -
> -  ret = munmap((char *)p - p->prev_size, size + p->prev_size);
> -
> -  /* munmap returns non-zero on failure */
> -  assert(ret == 0);
> -}
> -
> -#if HAVE_MREMAP
> -
> -#if __STD_C
> -static mchunkptr mremap_chunk(mchunkptr p, size_t new_size)
> -#else
> -static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
> -#endif
> -{
> -  size_t page_mask = malloc_getpagesize - 1;
> -  INTERNAL_SIZE_T offset = p->prev_size;
> -  INTERNAL_SIZE_T size = chunksize(p);
> -  char *cp;
> -
> -  assert (chunk_is_mmapped(p));
> -  assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
> -  assert((n_mmaps > 0));
> -  assert(((size + offset) & (malloc_getpagesize-1)) == 0);
> -
> -  /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */
> -  new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask;
> -
> -  cp = (char *)mremap((char *)p - offset, size + offset, new_size, 1);
> -
> -  if (cp == (char *)-1) return 0;
> -
> -  p = (mchunkptr)(cp + offset);
> -
> -  assert(aligned_OK(chunk2mem(p)));
> -
> -  assert((p->prev_size == offset));
> -  set_head(p, (new_size - offset)|IS_MMAPPED);
> -
> -  mmapped_mem -= size + offset;
> -  mmapped_mem += new_size;
> -  if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
> -    max_mmapped_mem = mmapped_mem;
> -  if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
> -    max_total_mem = mmapped_mem + sbrked_mem;
> -  return p;
> -}
> -
> -#endif /* HAVE_MREMAP */
> -
> -#endif /* HAVE_MMAP */
> -
> -
> -
> -
> -/*
> -  Extend the top-most chunk by obtaining memory from system.
> -  Main interface to sbrk (but see also malloc_trim).
> -*/
> -
> -#if __STD_C
> -static void malloc_extend_top(INTERNAL_SIZE_T nb)
> -#else
> -static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
> -#endif
> -{
> -  char*     brk;                  /* return value from sbrk */
> -  INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
> -  INTERNAL_SIZE_T correction;     /* bytes for 2nd sbrk call */
> -  char*     new_brk;              /* return of 2nd sbrk call */
> -  INTERNAL_SIZE_T top_size;       /* new size of top chunk */
> -
> -  mchunkptr old_top     = top;  /* Record state of old top */
> -  INTERNAL_SIZE_T old_top_size = chunksize(old_top);
> -  char*     old_end      = (char*)(chunk_at_offset(old_top, old_top_size));
> -
> -  /* Pad request with top_pad plus minimal overhead */
> -
> -  INTERNAL_SIZE_T    sbrk_size     = nb + top_pad + MINSIZE;
> -  unsigned long pagesz    = malloc_getpagesize;
> -
> -  /* If not the first time through, round to preserve page boundary */
> -  /* Otherwise, we need to correct to a page size below anyway. */
> -  /* (We also correct below if an intervening foreign sbrk call.) */
> -
> -  if (sbrk_base != (char*)(-1))
> -    sbrk_size = (sbrk_size + (pagesz - 1)) & ~(pagesz - 1);
> -
> -  brk = (char*)(MORECORE (sbrk_size));
> -
> -  /* Fail if sbrk failed or if a foreign sbrk call killed our space */
> -  if (brk == (char*)(MORECORE_FAILURE) ||
> -      (brk < old_end && old_top != initial_top))
> -    return;
> -
> -  sbrked_mem += sbrk_size;
> -
> -  if (brk == old_end) /* can just add bytes to current top */
> -  {
> -    top_size = sbrk_size + old_top_size;
> -    set_head(top, top_size | PREV_INUSE);
> -  }
> -  else
> -  {
> -    if (sbrk_base == (char*)(-1))  /* First time through. Record base */
> -      sbrk_base = brk;
> -    else  /* Someone else called sbrk().  Count those bytes as sbrked_mem. */
> -      sbrked_mem += brk - (char*)old_end;
> -
> -    /* Guarantee alignment of first new chunk made from this space */
> -    front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;
> -    if (front_misalign > 0)
> -    {
> -      correction = (MALLOC_ALIGNMENT) - front_misalign;
> -      brk += correction;
> -    }
> -    else
> -      correction = 0;
> -
> -    /* Guarantee the next brk will be at a page boundary */
> -
> -    correction += ((((unsigned long)(brk + sbrk_size))+(pagesz-1)) &
> -		   ~(pagesz - 1)) - ((unsigned long)(brk + sbrk_size));
> -
> -    /* Allocate correction */
> -    new_brk = (char*)(MORECORE (correction));
> -    if (new_brk == (char*)(MORECORE_FAILURE)) return;
> -
> -    sbrked_mem += correction;
> -
> -    top = (mchunkptr)brk;
> -    top_size = new_brk - brk + correction;
> -    set_head(top, top_size | PREV_INUSE);
> -
> -    if (old_top != initial_top)
> -    {
> -
> -      /* There must have been an intervening foreign sbrk call. */
> -      /* A double fencepost is necessary to prevent consolidation */
> -
> -      /* If not enough space to do this, then user did something very wrong */
> -      if (old_top_size < MINSIZE)
> -      {
> -	set_head(top, PREV_INUSE); /* will force null return from malloc */
> -	return;
> -      }
> -
> -      /* Also keep size a multiple of MALLOC_ALIGNMENT */
> -      old_top_size = (old_top_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
> -      set_head_size(old_top, old_top_size);
> -      chunk_at_offset(old_top, old_top_size          )->size =
> -	SIZE_SZ|PREV_INUSE;
> -      chunk_at_offset(old_top, old_top_size + SIZE_SZ)->size =
> -	SIZE_SZ|PREV_INUSE;
> -      /* If possible, release the rest. */
> -      if (old_top_size >= MINSIZE)
> -	fREe(chunk2mem(old_top));
> -    }
> -  }
> -
> -  if ((unsigned long)sbrked_mem > (unsigned long)max_sbrked_mem)
> -    max_sbrked_mem = sbrked_mem;
> -  if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
> -    max_total_mem = mmapped_mem + sbrked_mem;
> -
> -  /* We always land on a page boundary */
> -  assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
> -}
> -
> -
> -
> -
> -/* Main public routines */
> -
> -
> -/*
> -  Malloc Algorthim:
> -
> -    The requested size is first converted into a usable form, `nb'.
> -    This currently means to add 4 bytes overhead plus possibly more to
> -    obtain 8-byte alignment and/or to obtain a size of at least
> -    MINSIZE (currently 16 bytes), the smallest allocatable size.
> -    (All fits are considered `exact' if they are within MINSIZE bytes.)
> -
> -    From there, the first successful of the following steps is taken:
> -
> -      1. The bin corresponding to the request size is scanned, and if
> -	 a chunk of exactly the right size is found, it is taken.
> -
> -      2. The most recently remaindered chunk is used if it is big
> -	 enough.  This is a form of (roving) first fit, used only in
> -	 the absence of exact fits. Runs of consecutive requests use
> -	 the remainder of the chunk used for the previous such request
> -	 whenever possible. This limited use of a first-fit style
> -	 allocation strategy tends to give contiguous chunks
> -	 coextensive lifetimes, which improves locality and can reduce
> -	 fragmentation in the long run.
> -
> -      3. Other bins are scanned in increasing size order, using a
> -	 chunk big enough to fulfill the request, and splitting off
> -	 any remainder.  This search is strictly by best-fit; i.e.,
> -	 the smallest (with ties going to approximately the least
> -	 recently used) chunk that fits is selected.
> -
> -      4. If large enough, the chunk bordering the end of memory
> -	 (`top') is split off. (This use of `top' is in accord with
> -	 the best-fit search rule.  In effect, `top' is treated as
> -	 larger (and thus less well fitting) than any other available
> -	 chunk since it can be extended to be as large as necessary
> -	 (up to system limitations).
> -
> -      5. If the request size meets the mmap threshold and the
> -	 system supports mmap, and there are few enough currently
> -	 allocated mmapped regions, and a call to mmap succeeds,
> -	 the request is allocated via direct memory mapping.
> -
> -      6. Otherwise, the top of memory is extended by
> -	 obtaining more space from the system (normally using sbrk,
> -	 but definable to anything else via the MORECORE macro).
> -	 Memory is gathered from the system (in system page-sized
> -	 units) in a way that allows chunks obtained across different
> -	 sbrk calls to be consolidated, but does not require
> -	 contiguous memory. Thus, it should be safe to intersperse
> -	 mallocs with other sbrk calls.
> -
> -
> -      All allocations are made from the the `lowest' part of any found
> -      chunk. (The implementation invariant is that prev_inuse is
> -      always true of any allocated chunk; i.e., that each allocated
> -      chunk borders either a previously allocated and still in-use chunk,
> -      or the base of its memory arena.)
> -
> -*/
> -
> -#if __STD_C
> -Void_t* mALLOc(size_t bytes)
> -#else
> -Void_t* mALLOc(bytes) size_t bytes;
> -#endif
> -{
> -  mchunkptr victim;                  /* inspected/selected chunk */
> -  INTERNAL_SIZE_T victim_size;       /* its size */
> -  int       idx;                     /* index for bin traversal */
> -  mbinptr   bin;                     /* associated bin */
> -  mchunkptr remainder;               /* remainder from a split */
> -  long      remainder_size;          /* its size */
> -  int       remainder_index;         /* its bin index */
> -  unsigned long block;               /* block traverser bit */
> -  int       startidx;                /* first bin of a traversed block */
> -  mchunkptr fwd;                     /* misc temp for linking */
> -  mchunkptr bck;                     /* misc temp for linking */
> -  mbinptr q;                         /* misc temp */
> -
> -  INTERNAL_SIZE_T nb;
> -
> -  if ((long)bytes < 0) return 0;
> -
> -  nb = request2size(bytes);  /* padded request size; */
> -
> -  /* Check for exact match in a bin */
> -
> -  if (is_small_request(nb))  /* Faster version for small requests */
> -  {
> -    idx = smallbin_index(nb);
> -
> -    /* No traversal or size check necessary for small bins.  */
> -
> -    q = bin_at(idx);
> -    victim = last(q);
> -
> -    /* Also scan the next one, since it would have a remainder < MINSIZE */
> -    if (victim == q)
> -    {
> -      q = next_bin(q);
> -      victim = last(q);
> -    }
> -    if (victim != q)
> -    {
> -      victim_size = chunksize(victim);
> -      unlink(victim, bck, fwd);
> -      set_inuse_bit_at_offset(victim, victim_size);
> -      check_malloced_chunk(victim, nb);
> -      return chunk2mem(victim);
> -    }
> -
> -    idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */
> -
> -  }
> -  else
> -  {
> -    idx = bin_index(nb);
> -    bin = bin_at(idx);
> -
> -    for (victim = last(bin); victim != bin; victim = victim->bk)
> -    {
> -      victim_size = chunksize(victim);
> -      remainder_size = victim_size - nb;
> -
> -      if (remainder_size >= (long)MINSIZE) /* too big */
> -      {
> -	--idx; /* adjust to rescan below after checking last remainder */
> -	break;
> -      }
> -
> -      else if (remainder_size >= 0) /* exact fit */
> -      {
> -	unlink(victim, bck, fwd);
> -	set_inuse_bit_at_offset(victim, victim_size);
> -	check_malloced_chunk(victim, nb);
> -	return chunk2mem(victim);
> -      }
> -    }
> -
> -    ++idx;
> -
> -  }
> -
> -  /* Try to use the last split-off remainder */
> -
> -  if ( (victim = last_remainder->fd) != last_remainder)
> -  {
> -    victim_size = chunksize(victim);
> -    remainder_size = victim_size - nb;
> -
> -    if (remainder_size >= (long)MINSIZE) /* re-split */
> -    {
> -      remainder = chunk_at_offset(victim, nb);
> -      set_head(victim, nb | PREV_INUSE);
> -      link_last_remainder(remainder);
> -      set_head(remainder, remainder_size | PREV_INUSE);
> -      set_foot(remainder, remainder_size);
> -      check_malloced_chunk(victim, nb);
> -      return chunk2mem(victim);
> -    }
> -
> -    clear_last_remainder;
> -
> -    if (remainder_size >= 0)  /* exhaust */
> -    {
> -      set_inuse_bit_at_offset(victim, victim_size);
> -      check_malloced_chunk(victim, nb);
> -      return chunk2mem(victim);
> -    }
> -
> -    /* Else place in bin */
> -
> -    frontlink(victim, victim_size, remainder_index, bck, fwd);
> -  }
> -
> -  /*
> -     If there are any possibly nonempty big-enough blocks,
> -     search for best fitting chunk by scanning bins in blockwidth units.
> -  */
> -
> -  if ( (block = idx2binblock(idx)) <= binblocks)
> -  {
> -
> -    /* Get to the first marked block */
> -
> -    if ( (block & binblocks) == 0)
> -    {
> -      /* force to an even block boundary */
> -      idx = (idx & ~(BINBLOCKWIDTH - 1)) + BINBLOCKWIDTH;
> -      block <<= 1;
> -      while ((block & binblocks) == 0)
> -      {
> -	idx += BINBLOCKWIDTH;
> -	block <<= 1;
> -      }
> -    }
> -
> -    /* For each possibly nonempty block ... */
> -    for (;;)
> -    {
> -      startidx = idx;          /* (track incomplete blocks) */
> -      q = bin = bin_at(idx);
> -
> -      /* For each bin in this block ... */
> -      do
> -      {
> -	/* Find and use first big enough chunk ... */
> -
> -	for (victim = last(bin); victim != bin; victim = victim->bk)
> -	{
> -	  victim_size = chunksize(victim);
> -	  remainder_size = victim_size - nb;
> -
> -	  if (remainder_size >= (long)MINSIZE) /* split */
> -	  {
> -	    remainder = chunk_at_offset(victim, nb);
> -	    set_head(victim, nb | PREV_INUSE);
> -	    unlink(victim, bck, fwd);
> -	    link_last_remainder(remainder);
> -	    set_head(remainder, remainder_size | PREV_INUSE);
> -	    set_foot(remainder, remainder_size);
> -	    check_malloced_chunk(victim, nb);
> -	    return chunk2mem(victim);
> -	  }
> -
> -	  else if (remainder_size >= 0)  /* take */
> -	  {
> -	    set_inuse_bit_at_offset(victim, victim_size);
> -	    unlink(victim, bck, fwd);
> -	    check_malloced_chunk(victim, nb);
> -	    return chunk2mem(victim);
> -	  }
> -
> -	}
> -
> -       bin = next_bin(bin);
> -
> -      } while ((++idx & (BINBLOCKWIDTH - 1)) != 0);
> -
> -      /* Clear out the block bit. */
> -
> -      do   /* Possibly backtrack to try to clear a partial block */
> -      {
> -	if ((startidx & (BINBLOCKWIDTH - 1)) == 0)
> -	{
> -	  binblocks &= ~block;
> -	  break;
> -	}
> -	--startidx;
> -       q = prev_bin(q);
> -      } while (first(q) == q);
> -
> -      /* Get to the next possibly nonempty block */
> -
> -      if ( (block <<= 1) <= binblocks && (block != 0) )
> -      {
> -	while ((block & binblocks) == 0)
> -	{
> -	  idx += BINBLOCKWIDTH;
> -	  block <<= 1;
> -	}
> -      }
> -      else
> -	break;
> -    }
> -  }
> -
> -
> -  /* Try to use top chunk */
> -
> -  /* Require that there be a remainder, ensuring top always exists  */
> -  if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
> -  {
> -
> -#if HAVE_MMAP
> -    /* If big and would otherwise need to extend, try to use mmap instead */
> -    if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
> -	(victim = mmap_chunk(nb)) != 0)
> -      return chunk2mem(victim);
> -#endif
> -
> -    /* Try to extend */
> -    malloc_extend_top(nb);
> -    if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
> -      return 0; /* propagate failure */
> -  }
> -
> -  victim = top;
> -  set_head(victim, nb | PREV_INUSE);
> -  top = chunk_at_offset(victim, nb);
> -  set_head(top, remainder_size | PREV_INUSE);
> -  check_malloced_chunk(victim, nb);
> -  return chunk2mem(victim);
> -
> -}
> -
> -
> -
> -
> -/*
> -
> -  free() algorithm :
> -
> -    cases:
> -
> -       1. free(0) has no effect.
> -
> -       2. If the chunk was allocated via mmap, it is release via munmap().
> -
> -       3. If a returned chunk borders the current high end of memory,
> -	  it is consolidated into the top, and if the total unused
> -	  topmost memory exceeds the trim threshold, malloc_trim is
> -	  called.
> -
> -       4. Other chunks are consolidated as they arrive, and
> -	  placed in corresponding bins. (This includes the case of
> -	  consolidating with the current `last_remainder').
> -
> -*/
> -
> -
> -#if __STD_C
> -void fREe(Void_t* mem)
> -#else
> -void fREe(mem) Void_t* mem;
> -#endif
> -{
> -  mchunkptr p;         /* chunk corresponding to mem */
> -  INTERNAL_SIZE_T hd;  /* its head field */
> -  INTERNAL_SIZE_T sz;  /* its size */
> -  int       idx;       /* its bin index */
> -  mchunkptr next;      /* next contiguous chunk */
> -  INTERNAL_SIZE_T nextsz; /* its size */
> -  INTERNAL_SIZE_T prevsz; /* size of previous contiguous chunk */
> -  mchunkptr bck;       /* misc temp for linking */
> -  mchunkptr fwd;       /* misc temp for linking */
> -  int       islr;      /* track whether merging with last_remainder */
> -
> -  if (mem == 0)                              /* free(0) has no effect */
> -    return;
> -
> -  p = mem2chunk(mem);
> -  hd = p->size;
> -
> -#if HAVE_MMAP
> -  if (hd & IS_MMAPPED)                       /* release mmapped memory. */
> -  {
> -    munmap_chunk(p);
> -    return;
> -  }
> -#endif
> -
> -  check_inuse_chunk(p);
> -
> -  sz = hd & ~PREV_INUSE;
> -  next = chunk_at_offset(p, sz);
> -  nextsz = chunksize(next);
> -
> -  if (next == top)                            /* merge with top */
> -  {
> -    sz += nextsz;
> -
> -    if (!(hd & PREV_INUSE))                    /* consolidate backward */
> -    {
> -      prevsz = p->prev_size;
> -      p = chunk_at_offset(p, -((long) prevsz));
> -      sz += prevsz;
> -      unlink(p, bck, fwd);
> -    }
> -
> -    set_head(p, sz | PREV_INUSE);
> -    top = p;
> -    if ((unsigned long)(sz) >= (unsigned long)trim_threshold)
> -      malloc_trim(top_pad);
> -    return;
> -  }
> -
> -  set_head(next, nextsz);                    /* clear inuse bit */
> -
> -  islr = 0;
> -
> -  if (!(hd & PREV_INUSE))                    /* consolidate backward */
> -  {
> -    prevsz = p->prev_size;
> -    p = chunk_at_offset(p, -((long) prevsz));
> -    sz += prevsz;
> -
> -    if (p->fd == last_remainder)             /* keep as last_remainder */
> -      islr = 1;
> -    else
> -      unlink(p, bck, fwd);
> -  }
> -
> -  if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
> -  {
> -    sz += nextsz;
> -
> -    if (!islr && next->fd == last_remainder)  /* re-insert last_remainder */
> -    {
> -      islr = 1;
> -      link_last_remainder(p);
> -    }
> -    else
> -      unlink(next, bck, fwd);
> -  }
> -
> -
> -  set_head(p, sz | PREV_INUSE);
> -  set_foot(p, sz);
> -  if (!islr)
> -    frontlink(p, sz, idx, bck, fwd);
> -}
> -
> -
> -
> -
> -
> -/*
> -
> -  Realloc algorithm:
> -
> -    Chunks that were obtained via mmap cannot be extended or shrunk
> -    unless HAVE_MREMAP is defined, in which case mremap is used.
> -    Otherwise, if their reallocation is for additional space, they are
> -    copied.  If for less, they are just left alone.
> -
> -    Otherwise, if the reallocation is for additional space, and the
> -    chunk can be extended, it is, else a malloc-copy-free sequence is
> -    taken.  There are several different ways that a chunk could be
> -    extended. All are tried:
> -
> -       * Extending forward into following adjacent free chunk.
> -       * Shifting backwards, joining preceding adjacent space
> -       * Both shifting backwards and extending forward.
> -       * Extending into newly sbrked space
> -
> -    Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with a
> -    size argument of zero (re)allocates a minimum-sized chunk.
> -
> -    If the reallocation is for less space, and the new request is for
> -    a `small' (<512 bytes) size, then the newly unused space is lopped
> -    off and freed.
> -
> -    The old unix realloc convention of allowing the last-free'd chunk
> -    to be used as an argument to realloc is no longer supported.
> -    I don't know of any programs still relying on this feature,
> -    and allowing it would also allow too many other incorrect
> -    usages of realloc to be sensible.
> -
> -
> -*/
> -
> -
> -#if __STD_C
> -Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
> -#else
> -Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
> -#endif
> -{
> -  INTERNAL_SIZE_T    nb;      /* padded request size */
> -
> -  mchunkptr oldp;             /* chunk corresponding to oldmem */
> -  INTERNAL_SIZE_T    oldsize; /* its size */
> -
> -  mchunkptr newp;             /* chunk to return */
> -  INTERNAL_SIZE_T    newsize; /* its size */
> -  Void_t*   newmem;           /* corresponding user mem */
> -
> -  mchunkptr next;             /* next contiguous chunk after oldp */
> -  INTERNAL_SIZE_T  nextsize;  /* its size */
> -
> -  mchunkptr prev;             /* previous contiguous chunk before oldp */
> -  INTERNAL_SIZE_T  prevsize;  /* its size */
> -
> -  mchunkptr remainder;        /* holds split off extra space from newp */
> -  INTERNAL_SIZE_T  remainder_size;   /* its size */
> -
> -  mchunkptr bck;              /* misc temp for linking */
> -  mchunkptr fwd;              /* misc temp for linking */
> -
> -#ifdef REALLOC_ZERO_BYTES_FREES
> -  if (bytes == 0) { fREe(oldmem); return 0; }
> -#endif
> -
> -  if ((long)bytes < 0) return 0;
> -
> -  /* realloc of null is supposed to be same as malloc */
> -  if (oldmem == 0) return mALLOc(bytes);
> -
> -  newp    = oldp    = mem2chunk(oldmem);
> -  newsize = oldsize = chunksize(oldp);
> -
> -
> -  nb = request2size(bytes);
> -
> -#if HAVE_MMAP
> -  if (chunk_is_mmapped(oldp))
> -  {
> -#if HAVE_MREMAP
> -    newp = mremap_chunk(oldp, nb);
> -    if(newp) return chunk2mem(newp);
> -#endif
> -    /* Note the extra SIZE_SZ overhead. */
> -    if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
> -    /* Must alloc, copy, free. */
> -    newmem = mALLOc(bytes);
> -    if (newmem == 0) return 0; /* propagate failure */
> -    MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
> -    munmap_chunk(oldp);
> -    return newmem;
> -  }
> -#endif
> -
> -  check_inuse_chunk(oldp);
> -
> -  if ((long)(oldsize) < (long)(nb))
> -  {
> -
> -    /* Try expanding forward */
> -
> -    next = chunk_at_offset(oldp, oldsize);
> -    if (next == top || !inuse(next))
> -    {
> -      nextsize = chunksize(next);
> -
> -      /* Forward into top only if a remainder */
> -      if (next == top)
> -      {
> -	if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE))
> -	{
> -	  newsize += nextsize;
> -	  top = chunk_at_offset(oldp, nb);
> -	  set_head(top, (newsize - nb) | PREV_INUSE);
> -	  set_head_size(oldp, nb);
> -	  return chunk2mem(oldp);
> -	}
> -      }
> -
> -      /* Forward into next chunk */
> -      else if (((long)(nextsize + newsize) >= (long)(nb)))
> -      {
> -	unlink(next, bck, fwd);
> -	newsize  += nextsize;
> -	goto split;
> -      }
> -    }
> -    else
> -    {
> -      next = 0;
> -      nextsize = 0;
> -    }
> -
> -    /* Try shifting backwards. */
> -
> -    if (!prev_inuse(oldp))
> -    {
> -      prev = prev_chunk(oldp);
> -      prevsize = chunksize(prev);
> -
> -      /* try forward + backward first to save a later consolidation */
> -
> -      if (next != 0)
> -      {
> -	/* into top */
> -	if (next == top)
> -	{
> -	  if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE))
> -	  {
> -	    unlink(prev, bck, fwd);
> -	    newp = prev;
> -	    newsize += prevsize + nextsize;
> -	    newmem = chunk2mem(newp);
> -	    MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
> -	    top = chunk_at_offset(newp, nb);
> -	    set_head(top, (newsize - nb) | PREV_INUSE);
> -	    set_head_size(newp, nb);
> -	    return newmem;
> -	  }
> -	}
> -
> -	/* into next chunk */
> -	else if (((long)(nextsize + prevsize + newsize) >= (long)(nb)))
> -	{
> -	  unlink(next, bck, fwd);
> -	  unlink(prev, bck, fwd);
> -	  newp = prev;
> -	  newsize += nextsize + prevsize;
> -	  newmem = chunk2mem(newp);
> -	  MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
> -	  goto split;
> -	}
> -      }
> -
> -      /* backward only */
> -      if (prev != 0 && (long)(prevsize + newsize) >= (long)nb)
> -      {
> -	unlink(prev, bck, fwd);
> -	newp = prev;
> -	newsize += prevsize;
> -	newmem = chunk2mem(newp);
> -	MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
> -	goto split;
> -      }
> -    }
> -
> -    /* Must allocate */
> -
> -    newmem = mALLOc (bytes);
> -
> -    if (newmem == 0)  /* propagate failure */
> -      return 0;
> -
> -    /* Avoid copy if newp is next chunk after oldp. */
> -    /* (This can only happen when new chunk is sbrk'ed.) */
> -
> -    if ( (newp = mem2chunk(newmem)) == next_chunk(oldp))
> -    {
> -      newsize += chunksize(newp);
> -      newp = oldp;
> -      goto split;
> -    }
> -
> -    /* Otherwise copy, free, and exit */
> -    MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
> -    fREe(oldmem);
> -    return newmem;
> -  }
> -
> -
> - split:  /* split off extra room in old or expanded chunk */
> -
> -  if (newsize - nb >= MINSIZE) /* split off remainder */
> -  {
> -    remainder = chunk_at_offset(newp, nb);
> -    remainder_size = newsize - nb;
> -    set_head_size(newp, nb);
> -    set_head(remainder, remainder_size | PREV_INUSE);
> -    set_inuse_bit_at_offset(remainder, remainder_size);
> -    fREe(chunk2mem(remainder)); /* let free() deal with it */
> -  }
> -  else
> -  {
> -    set_head_size(newp, newsize);
> -    set_inuse_bit_at_offset(newp, newsize);
> -  }
> -
> -  check_inuse_chunk(newp);
> -  return chunk2mem(newp);
> -}
> -
> -
> -
> -
> -/*
> -
> -  memalign algorithm:
> -
> -    memalign requests more than enough space from malloc, finds a spot
> -    within that chunk that meets the alignment request, and then
> -    possibly frees the leading and trailing space.
> -
> -    The alignment argument must be a power of two. This property is not
> -    checked by memalign, so misuse may result in random runtime errors.
> -
> -    8-byte alignment is guaranteed by normal malloc calls, so don't
> -    bother calling memalign with an argument of 8 or less.
> -
> -    Overreliance on memalign is a sure way to fragment space.
> -
> -*/
> -
> -
> -#if __STD_C
> -Void_t* mEMALIGn(size_t alignment, size_t bytes)
> -#else
> -Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
> -#endif
> -{
> -  INTERNAL_SIZE_T    nb;      /* padded  request size */
> -  char*     m;                /* memory returned by malloc call */
> -  mchunkptr p;                /* corresponding chunk */
> -  char*     brk;              /* alignment point within p */
> -  mchunkptr newp;             /* chunk to return */
> -  INTERNAL_SIZE_T  newsize;   /* its size */
> -  INTERNAL_SIZE_T  leadsize;  /* leading space befor alignment point */
> -  mchunkptr remainder;        /* spare room at end to split off */
> -  long      remainder_size;   /* its size */
> -
> -  if ((long)bytes < 0) return 0;
> -
> -  /* If need less alignment than we give anyway, just relay to malloc */
> -
> -  if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
> -
> -  /* Otherwise, ensure that it is at least a minimum chunk size */
> -
> -  if (alignment <  MINSIZE) alignment = MINSIZE;
> -
> -  /* Call malloc with worst case padding to hit alignment. */
> -
> -  nb = request2size(bytes);
> -  m  = (char*)(mALLOc(nb + alignment + MINSIZE));
> -
> -  if (m == 0) return 0; /* propagate failure */
> -
> -  p = mem2chunk(m);
> -
> -  if ((((unsigned long)(m)) % alignment) == 0) /* aligned */
> -  {
> -#if HAVE_MMAP
> -    if(chunk_is_mmapped(p))
> -      return chunk2mem(p); /* nothing more to do */
> -#endif
> -  }
> -  else /* misaligned */
> -  {
> -    /*
> -      Find an aligned spot inside chunk.
> -      Since we need to give back leading space in a chunk of at
> -      least MINSIZE, if the first calculation places us at
> -      a spot with less than MINSIZE leader, we can move to the
> -      next aligned spot -- we've allocated enough total room so that
> -      this is always possible.
> -    */
> -
> -    brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) & -((signed) alignment));
> -    if ((long)(brk - (char*)(p)) < MINSIZE) brk = brk + alignment;
> -
> -    newp = (mchunkptr)brk;
> -    leadsize = brk - (char*)(p);
> -    newsize = chunksize(p) - leadsize;
> -
> -#if HAVE_MMAP
> -    if(chunk_is_mmapped(p))
> -    {
> -      newp->prev_size = p->prev_size + leadsize;
> -      set_head(newp, newsize|IS_MMAPPED);
> -      return chunk2mem(newp);
> -    }
> -#endif
> -
> -    /* give back leader, use the rest */
> -
> -    set_head(newp, newsize | PREV_INUSE);
> -    set_inuse_bit_at_offset(newp, newsize);
> -    set_head_size(p, leadsize);
> -    fREe(chunk2mem(p));
> -    p = newp;
> -
> -    assert (newsize >= nb && (((unsigned long)(chunk2mem(p))) % alignment) == 0);
> -  }
> -
> -  /* Also give back spare room at the end */
> -
> -  remainder_size = chunksize(p) - nb;
> -
> -  if (remainder_size >= (long)MINSIZE)
> -  {
> -    remainder = chunk_at_offset(p, nb);
> -    set_head(remainder, remainder_size | PREV_INUSE);
> -    set_head_size(p, nb);
> -    fREe(chunk2mem(remainder));
> -  }
> -
> -  check_inuse_chunk(p);
> -  return chunk2mem(p);
> -
> -}
> -
> -
> -
> -
> -/*
> -    valloc just invokes memalign with alignment argument equal
> -    to the page size of the system (or as near to this as can
> -    be figured out from all the includes/defines above.)
> -*/
> -
> -#if __STD_C
> -Void_t* vALLOc(size_t bytes)
> -#else
> -Void_t* vALLOc(bytes) size_t bytes;
> -#endif
> -{
> -  return mEMALIGn (malloc_getpagesize, bytes);
> -}
> -
> -/*
> -  pvalloc just invokes valloc for the nearest pagesize
> -  that will accommodate request
> -*/
> -
> -
> -#if __STD_C
> -Void_t* pvALLOc(size_t bytes)
> -#else
> -Void_t* pvALLOc(bytes) size_t bytes;
> -#endif
> -{
> -  size_t pagesize = malloc_getpagesize;
> -  return mEMALIGn (pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
> -}
> -
> -/*
> -
> -  calloc calls malloc, then zeroes out the allocated chunk.
> -
> -*/
> -
> -#if __STD_C
> -Void_t* cALLOc(size_t n, size_t elem_size)
> -#else
> -Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
> -#endif
> -{
> -  mchunkptr p;
> -  INTERNAL_SIZE_T csz;
> -
> -  INTERNAL_SIZE_T sz = n * elem_size;
> -
> -
> -  /* check if expand_top called, in which case don't need to clear */
> -#if MORECORE_CLEARS
> -  mchunkptr oldtop = top;
> -  INTERNAL_SIZE_T oldtopsize = chunksize(top);
> -#endif
> -  Void_t* mem = mALLOc (sz);
> -
> -  if ((long)n < 0) return 0;
> -
> -  if (mem == 0)
> -    return 0;
> -  else
> -  {
> -    p = mem2chunk(mem);
> -
> -    /* Two optional cases in which clearing not necessary */
> -
> -
> -#if HAVE_MMAP
> -    if (chunk_is_mmapped(p)) return mem;
> -#endif
> -
> -    csz = chunksize(p);
> -
> -#if MORECORE_CLEARS
> -    if (p == oldtop && csz > oldtopsize)
> -    {
> -      /* clear only the bytes from non-freshly-sbrked memory */
> -      csz = oldtopsize;
> -    }
> -#endif
> -
> -    MALLOC_ZERO(mem, csz - SIZE_SZ);
> -    return mem;
> -  }
> -}
> -
> -/*
> -
> -  cfree just calls free. It is needed/defined on some systems
> -  that pair it with calloc, presumably for odd historical reasons.
> -
> -*/
> -
> -#if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
> -#if __STD_C
> -void cfree(Void_t *mem)
> -#else
> -void cfree(mem) Void_t *mem;
> -#endif
> -{
> -  fREe(mem);
> -}
> -#endif
> -
> -
> -
> -/*
> -
> -    Malloc_trim gives memory back to the system (via negative
> -    arguments to sbrk) if there is unused memory at the `high' end of
> -    the malloc pool. You can call this after freeing large blocks of
> -    memory to potentially reduce the system-level memory requirements
> -    of a program. However, it cannot guarantee to reduce memory. Under
> -    some allocation patterns, some large free blocks of memory will be
> -    locked between two used chunks, so they cannot be given back to
> -    the system.
> -
> -    The `pad' argument to malloc_trim represents the amount of free
> -    trailing space to leave untrimmed. If this argument is zero,
> -    only the minimum amount of memory to maintain internal data
> -    structures will be left (one page or less). Non-zero arguments
> -    can be supplied to maintain enough trailing space to service
> -    future expected allocations without having to re-obtain memory
> -    from the system.
> -
> -    Malloc_trim returns 1 if it actually released any memory, else 0.
> -
> -*/
> -
> -#if __STD_C
> -int malloc_trim(size_t pad)
> -#else
> -int malloc_trim(pad) size_t pad;
> -#endif
> -{
> -  long  top_size;        /* Amount of top-most memory */
> -  long  extra;           /* Amount to release */
> -  char* current_brk;     /* address returned by pre-check sbrk call */
> -  char* new_brk;         /* address returned by negative sbrk call */
> -
> -  unsigned long pagesz = malloc_getpagesize;
> -
> -  top_size = chunksize(top);
> -  extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
> -
> -  if (extra < (long)pagesz)  /* Not enough memory to release */
> -    return 0;
> -
> -  else
> -  {
> -    /* Test to make sure no one else called sbrk */
> -    current_brk = (char*)(MORECORE (0));
> -    if (current_brk != (char*)(top) + top_size)
> -      return 0;     /* Apparently we don't own memory; must fail */
> -
> -    else
> -    {
> -      new_brk = (char*)(MORECORE (-extra));
> -
> -      if (new_brk == (char*)(MORECORE_FAILURE)) /* sbrk failed? */
> -      {
> -	/* Try to figure out what we have */
> -	current_brk = (char*)(MORECORE (0));
> -	top_size = current_brk - (char*)top;
> -	if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */
> -	{
> -	  sbrked_mem = current_brk - sbrk_base;
> -	  set_head(top, top_size | PREV_INUSE);
> -	}
> -	check_chunk(top);
> -	return 0;
> -      }
> -
> -      else
> -      {
> -	/* Success. Adjust top accordingly. */
> -	set_head(top, (top_size - extra) | PREV_INUSE);
> -	sbrked_mem -= extra;
> -	check_chunk(top);
> -	return 1;
> -      }
> -    }
> -  }
> -}
> -
> -
> -
> -/*
> -  malloc_usable_size:
> -
> -    This routine tells you how many bytes you can actually use in an
> -    allocated chunk, which may be more than you requested (although
> -    often not). You can use this many bytes without worrying about
> -    overwriting other allocated objects. Not a particularly great
> -    programming practice, but still sometimes useful.
> -
> -*/
> -
> -#if __STD_C
> -size_t malloc_usable_size(Void_t* mem)
> -#else
> -size_t malloc_usable_size(mem) Void_t* mem;
> -#endif
> -{
> -  mchunkptr p;
> -  if (mem == 0)
> -    return 0;
> -  else
> -  {
> -    p = mem2chunk(mem);
> -    if(!chunk_is_mmapped(p))
> -    {
> -      if (!inuse(p)) return 0;
> -      check_inuse_chunk(p);
> -      return chunksize(p) - SIZE_SZ;
> -    }
> -    return chunksize(p) - 2*SIZE_SZ;
> -  }
> -}
> -
> -
> -
> -
> -/* Utility to update current_mallinfo for malloc_stats and mallinfo() */
> -
> -static void malloc_update_mallinfo()
> -{
> -  int i;
> -  mbinptr b;
> -  mchunkptr p;
> -#if DEBUG
> -  mchunkptr q;
> -#endif
> -
> -  INTERNAL_SIZE_T avail = chunksize(top);
> -  int   navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0;
> -
> -  for (i = 1; i < NAV; ++i)
> -  {
> -    b = bin_at(i);
> -    for (p = last(b); p != b; p = p->bk)
> -    {
> -#if DEBUG
> -      check_free_chunk(p);
> -      for (q = next_chunk(p);
> -	   q < top && inuse(q) && (long)(chunksize(q)) >= (long)MINSIZE;
> -	   q = next_chunk(q))
> -	check_inuse_chunk(q);
> -#endif
> -      avail += chunksize(p);
> -      navail++;
> -    }
> -  }
> -
> -  current_mallinfo.ordblks = navail;
> -  current_mallinfo.uordblks = sbrked_mem - avail;
> -  current_mallinfo.fordblks = avail;
> -  current_mallinfo.hblks = n_mmaps;
> -  current_mallinfo.hblkhd = mmapped_mem;
> -  current_mallinfo.keepcost = chunksize(top);
> -
> -}
> -
> -
> -
> -/*
> -
> -  malloc_stats:
> -
> -    Prints on stderr the amount of space obtain from the system (both
> -    via sbrk and mmap), the maximum amount (which may be more than
> -    current if malloc_trim and/or munmap got called), the maximum
> -    number of simultaneous mmap regions used, and the current number
> -    of bytes allocated via malloc (or realloc, etc) but not yet
> -    freed. (Note that this is the number of bytes allocated, not the
> -    number requested. It will be larger than the number requested
> -    because of alignment and bookkeeping overhead.)
> -
> -*/
> -
> -void malloc_stats()
> -{
> -  malloc_update_mallinfo();
> -  fprintf(stderr, "max system bytes = %10u\n",
> -	  (unsigned int)(max_total_mem));
> -  fprintf(stderr, "system bytes     = %10u\n",
> -	  (unsigned int)(sbrked_mem + mmapped_mem));
> -  fprintf(stderr, "in use bytes     = %10u\n",
> -	  (unsigned int)(current_mallinfo.uordblks + mmapped_mem));
> -#if HAVE_MMAP
> -  fprintf(stderr, "max mmap regions = %10u\n",
> -	  (unsigned int)max_n_mmaps);
> -#endif
> -}
> -
> -/*
> -  mallinfo returns a copy of updated current mallinfo.
> -*/
> -
> -struct mallinfo mALLINFo()
> -{
> -  malloc_update_mallinfo();
> -  return current_mallinfo;
> -}
> -
> -
> -
> -
> -/*
> -  mallopt:
> -
> -    mallopt is the general SVID/XPG interface to tunable parameters.
> -    The format is to provide a (parameter-number, parameter-value) pair.
> -    mallopt then sets the corresponding parameter to the argument
> -    value if it can (i.e., so long as the value is meaningful),
> -    and returns 1 if successful else 0.
> -
> -    See descriptions of tunable parameters above.
> -
> -*/
> -
> -#if __STD_C
> -int mALLOPt(int param_number, int value)
> -#else
> -int mALLOPt(param_number, value) int param_number; int value;
> -#endif
> -{
> -  switch(param_number)
> -  {
> -    case M_TRIM_THRESHOLD:
> -      trim_threshold = value; return 1;
> -    case M_TOP_PAD:
> -      top_pad = value; return 1;
> -    case M_MMAP_THRESHOLD:
> -      mmap_threshold = value; return 1;
> -    case M_MMAP_MAX:
> -#if HAVE_MMAP
> -      n_mmaps_max = value; return 1;
> -#else
> -      if (value != 0) return 0; else  n_mmaps_max = value; return 1;
> -#endif
> -
> -    default:
> -      return 0;
> -  }
> -}
> -
> -/*
> -
> -History:
> -
> -    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
> -      * return null for negative arguments
> -      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
> -	 * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
> -	  (e.g. WIN32 platforms)
> -	 * Cleanup up header file inclusion for WIN32 platforms
> -	 * Cleanup code to avoid Microsoft Visual C++ compiler complaints
> -	 * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
> -	   memory allocation routines
> -	 * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
> -	 * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
> -	   usage of 'assert' in non-WIN32 code
> -	 * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
> -	   avoid infinite loop
> -      * Always call 'fREe()' rather than 'free()'
> -
> -    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
> -      * Fixed ordering problem with boundary-stamping
> -
> -    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
> -      * Added pvalloc, as recommended by H.J. Liu
> -      * Added 64bit pointer support mainly from Wolfram Gloger
> -      * Added anonymously donated WIN32 sbrk emulation
> -      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
> -      * malloc_extend_top: fix mask error that caused wastage after
> -	foreign sbrks
> -      * Add linux mremap support code from HJ Liu
> -
> -    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
> -      * Integrated most documentation with the code.
> -      * Add support for mmap, with help from
> -	Wolfram Gloger (Gloger at lrz.uni-muenchen.de).
> -      * Use last_remainder in more cases.
> -      * Pack bins using idea from  colin at nyx10.cs.du.edu
> -      * Use ordered bins instead of best-fit threshhold
> -      * Eliminate block-local decls to simplify tracing and debugging.
> -      * Support another case of realloc via move into top
> -      * Fix error occuring when initial sbrk_base not word-aligned.
> -      * Rely on page size for units instead of SBRK_UNIT to
> -	avoid surprises about sbrk alignment conventions.
> -      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
> -	(raymond at es.ele.tue.nl) for the suggestion.
> -      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
> -      * More precautions for cases where other routines call sbrk,
> -	courtesy of Wolfram Gloger (Gloger at lrz.uni-muenchen.de).
> -      * Added macros etc., allowing use in linux libc from
> -	H.J. Lu (hjl at gnu.ai.mit.edu)
> -      * Inverted this history list
> -
> -    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
> -      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
> -      * Removed all preallocation code since under current scheme
> -	the work required to undo bad preallocations exceeds
> -	the work saved in good cases for most test programs.
> -      * No longer use return list or unconsolidated bins since
> -	no scheme using them consistently outperforms those that don't
> -	given above changes.
> -      * Use best fit for very large chunks to prevent some worst-cases.
> -      * Added some support for debugging
> -
> -    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
> -      * Removed footers when chunks are in use. Thanks to
> -	Paul Wilson (wilson at cs.texas.edu) for the suggestion.
> -
> -    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
> -      * Added malloc_trim, with help from Wolfram Gloger
> -	(wmglo at Dent.MED.Uni-Muenchen.DE).
> -
> -    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
> -
> -    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
> -      * realloc: try to expand in both directions
> -      * malloc: swap order of clean-bin strategy;
> -      * realloc: only conditionally expand backwards
> -      * Try not to scavenge used bins
> -      * Use bin counts as a guide to preallocation
> -      * Occasionally bin return list chunks in first scan
> -      * Add a few optimizations from colin at nyx10.cs.du.edu
> -
> -    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
> -      * faster bin computation & slightly different binning
> -      * merged all consolidations to one part of malloc proper
> -	 (eliminating old malloc_find_space & malloc_clean_bin)
> -      * Scan 2 returns chunks (not just 1)
> -      * Propagate failure in realloc if malloc returns 0
> -      * Add stuff to allow compilation on non-ANSI compilers
> -	  from kpv at research.att.com
> -
> -    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
> -      * removed potential for odd address access in prev_chunk
> -      * removed dependency on getpagesize.h
> -      * misc cosmetics and a bit more internal documentation
> -      * anticosmetics: mangled names in macros to evade debugger strangeness
> -      * tested on sparc, hp-700, dec-mips, rs6000
> -	  with gcc & native cc (hp, dec only) allowing
> -	  Detlefs & Zorn comparison study (in SIGPLAN Notices.)
> -
> -    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
> -      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
> -	 structure of old version,  but most details differ.)
> -
> -*/
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jbe at pengutronix.de  Tue Dec 21 06:25:17 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:17 +0100
Subject: [PATCH 5/9] ARM STM/i.MX: Just fix the docs
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-6-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index 85e9684..8a34e4c 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -77,7 +77,7 @@ static unsigned calc_output_reg(unsigned no)
 }
 
 /**
- * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
+ * @param[in] m One pin define per call from iomux-mx23.h/iomux-mx28.h
  */
 void imx_gpio_mode(uint32_t m)
 {
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:14 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:14 +0100
Subject: [PATCH 2/9] ARM STM/i.MX: Fix register offset calculation for GPIO
	input pins
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-3-git-send-email-jbe@pengutronix.de>

Fix the forgotten register calculation for GPIO input pins.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index 2c68ebf..2c34d01 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -129,6 +129,8 @@ void imx_gpio_mode(unsigned m)
 			writel(0x1 << (gpio_pin % 32),
 				IMX_IOMUXC_BASE + reg_offset + BIT_SET);
 		} else {
+			/* then the direction */
+			reg_offset = calc_output_enable_reg(gpio_pin);
 			writel(0x1 << (gpio_pin % 32),
 				IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
 		}
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:19 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:19 +0100
Subject: [PATCH 7/9] ARM STM/i.MX: Avoid very long lines
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-8-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index b9fa565..c59f0ac 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -124,14 +124,16 @@ void imx_gpio_mode(uint32_t m)
 
 	if (PE_PRESENT(m)) {
 		reg_offset = calc_pullup_reg(gpio_pin);
-		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
+		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset +
+				(GET_PULLUP(m) == 1 ? 4 : 8));
 	}
 
 	if (GET_FUNC(m) == IS_GPIO) {
 		if (GET_GPIODIR(m) == 1) {
 			/* first set the output value */
 			reg_offset = calc_output_reg(gpio_pin);
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE +
+				reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
 			/* then the direction */
 			reg_offset = calc_output_enable_reg(gpio_pin);
 			writel(0x1 << (gpio_pin % 32),
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:12 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:12 +0100
Subject: [PATCH] Add gpio command support to STM/i.MX arch
Message-ID: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>

In order to complete graphics handling on STM/i.MX architecture, the platforms
need GPIO command support (for example to enable the display and backlight).

The following changes since commit af05a9dd223f0a77133e37893354680c2f857a54:

  xyzModem.c: fix 'dummy' is used uninitialized in this function warning (2010-12-21 10:23:41 +0100)

are available in the git repository at:
  http://git.pengutronix.de/git/jbe/for_barebox_next/ next_stm_gpio_v3

Juergen Beisert (9):
      Fix a typo in the GPIO doc
      ARM STM/i.MX: Fix register offset calculation for GPIO input pins
      ARM STM/i.MX: Remove variable size restrictions in iomux managing routines
      ARM STM/i.MX: Setting the iomux needs at least 32 bit.
      ARM STM/i.MX: Just fix the docs
      ARM STM/i.MX: Add support for the gpio commands
      ARM STM/i.MX: Avoid very long lines
      ARM STM/i.MX: Replace cryptic numbers
      ARM Chumby: Add list of available GPIOs and their meaning

 arch/arm/Kconfig                               |    1 +
 arch/arm/boards/chumby_falconwing/falconwing.c |   85 ++++++++++++++++++++++++
 arch/arm/configs/chumbyone_defconfig           |    1 +
 arch/arm/configs/tx28stk5_defconfig            |    1 +
 arch/arm/mach-stm/include/mach/gpio.h          |    8 ++-
 arch/arm/mach-stm/iomux-imx.c                  |   85 +++++++++++++++++++++---
 commands/gpio.c                                |    2 +-
 7 files changed, 171 insertions(+), 12 deletions(-)


From jbe at pengutronix.de  Tue Dec 21 06:25:13 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:13 +0100
Subject: [PATCH 1/9] Fix a typo in the GPIO doc
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-2-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 commands/gpio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/commands/gpio.c b/commands/gpio.c
index 0cf19fe..073c9d3 100644
--- a/commands/gpio.c
+++ b/commands/gpio.c
@@ -148,7 +148,7 @@ between @b barebox releases.
 - gpio_no: Architecture dependend GPIO number
 - initial_value: Output value
 
-<p> To avoid glitches on the pad the routines will first sett up the
+<p> To avoid glitches on the pad the routines will first set up the
 pad's value and afterwards switch the pad to output (if the silicon is
 able to do so). If the pad is already configured in non-GPIO mode (if
 available), this command may silently fail. </p>
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:20 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:20 +0100
Subject: [PATCH 8/9] ARM STM/i.MX: Replace cryptic numbers
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-9-git-send-email-jbe@pengutronix.de>

Try to make the source more understandable.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index c59f0ac..bf6165f 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -125,7 +125,7 @@ void imx_gpio_mode(uint32_t m)
 	if (PE_PRESENT(m)) {
 		reg_offset = calc_pullup_reg(gpio_pin);
 		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset +
-				(GET_PULLUP(m) == 1 ? 4 : 8));
+				(GET_PULLUP(m) == 1 ? BIT_SET : BIT_CLR));
 	}
 
 	if (GET_FUNC(m) == IS_GPIO) {
@@ -133,7 +133,7 @@ void imx_gpio_mode(uint32_t m)
 			/* first set the output value */
 			reg_offset = calc_output_reg(gpio_pin);
 			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE +
-				reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+				reg_offset + (GET_GPIOVAL(m) == 1 ? BIT_SET : BIT_CLR));
 			/* then the direction */
 			reg_offset = calc_output_enable_reg(gpio_pin);
 			writel(0x1 << (gpio_pin % 32),
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:16 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:16 +0100
Subject: [PATCH 4/9] ARM STM/i.MX: Setting the iomux needs at least 32 bit.
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-5-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/include/mach/gpio.h |    4 +++-
 arch/arm/mach-stm/iomux-imx.c         |    2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
index 5615b67..97566a2 100644
--- a/arch/arm/mach-stm/include/mach/gpio.h
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -20,6 +20,8 @@
 #ifndef __ASM_MACH_GPIO_H
 #define __ASM_MACH_GPIO_H
 
+#include <types.h>
+
 #if defined CONFIG_ARCH_IMX23
 # include <mach/iomux-imx23.h>
 #endif
@@ -27,6 +29,6 @@
 # include <mach/iomux-imx28.h>
 #endif
 
-void imx_gpio_mode(unsigned);
+void imx_gpio_mode(uint32_t);
 
 #endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index 2ebe058..85e9684 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -79,7 +79,7 @@ static unsigned calc_output_reg(unsigned no)
 /**
  * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
  */
-void imx_gpio_mode(unsigned m)
+void imx_gpio_mode(uint32_t m)
 {
 	uint32_t reg;
 	unsigned gpio_pin, reg_offset;
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:15 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:15 +0100
Subject: [PATCH 3/9] ARM STM/i.MX: Remove variable size restrictions in iomux
	managing routines
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-4-git-send-email-jbe@pengutronix.de>

There is no really need for restricted variable types for the parameters.
Replace them by standard C types with the same behaviour.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index 2c34d01..2ebe058 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -46,31 +46,31 @@
 #define MAX_GPIO_NO 159
 #endif
 
-static uint32_t calc_mux_reg(uint32_t no)
+static unsigned calc_mux_reg(unsigned no)
 {
 	/* each register controls 16 pads */
 	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
 }
 
-static uint32_t calc_strength_reg(uint32_t no)
+static unsigned calc_strength_reg(unsigned no)
 {
 	/* each register controls 8 pads */
 	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
 }
 
-static uint32_t calc_pullup_reg(uint32_t no)
+static unsigned calc_pullup_reg(unsigned no)
 {
 	/* each register controls 32 pads */
 	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
 }
 
-static uint32_t calc_output_enable_reg(uint32_t no)
+static unsigned calc_output_enable_reg(unsigned no)
 {
 	/* each register controls 32 pads */
 	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
 }
 
-static uint32_t calc_output_reg(uint32_t no)
+static unsigned calc_output_reg(unsigned no)
 {
 	/* each register controls 32 pads */
 	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
@@ -81,7 +81,8 @@ static uint32_t calc_output_reg(uint32_t no)
  */
 void imx_gpio_mode(unsigned m)
 {
-	uint32_t reg_offset, gpio_pin, reg;
+	uint32_t reg;
+	unsigned gpio_pin, reg_offset;
 
 	gpio_pin = GET_GPIO_NO(m);
 
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:21 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:21 +0100
Subject: [PATCH 9/9] ARM Chumby: Add list of available GPIOs and their meaning
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-10-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/boards/chumby_falconwing/falconwing.c |   85 ++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index f5ed133..76ff906 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -390,4 +390,89 @@ make ARCH=arm CROSS_COMPILE=armv5compiler
   partition or you can do it in the classic way: mkfs on it, mount it and copy
   all required data and programs into it.
 
+ at section gpio_falconwing Available GPIOs
+
+The Falconwing uses some GPIOs to control various features. With the regular
+GPIO commands these features can be controlled at @a barebox's runtime.
+
+<table width="100%" border="1" cellspacing="1" cellpadding="3">
+	<tr>
+		<td>No</td>
+		<td>Direction</td>
+		<td>Function</td>
+		<td>Reset</td>
+		<td>Set</td>
+	</tr>
+	<tr>
+		<td>8</td>
+		<td>Output</td>
+		<td>Switch Audio Amplifier</td>
+		<td>Off</td>
+		<td>On</td>
+	</tr>
+	<tr>
+		<td>11</td>
+		<td>Input</td>
+		<td>Head Phone Detection</td>
+		<td>TBD</td>
+		<td>TBD</td>
+	</tr>
+	<tr>
+		<td>14</td>
+		<td>Input</td>
+		<td>Unused (J113)</td>
+		<td>User</td>
+		<td>User</td>
+	</tr>
+	<tr>
+		<td>15</td>
+		<td>Input</td>
+		<td>Unused (J114)</td>
+		<td>User</td>
+		<td>User</td>
+	</tr>
+	<tr>
+		<td>26</td>
+		<td>Output</td>
+		<td>USB Power</td>
+		<td>TBD</td>
+		<td>TBD</td>
+	</tr>
+	<tr>
+		<td>27</td>
+		<td>Input</td>
+		<td>Display Connected</td>
+		<td>Display<br>Attached</td>
+		<td>Display<br>Disconnected</td>
+	</tr>
+	<tr>
+		<td>29</td>
+		<td>Output</td>
+		<td>USB HUB Reset</td>
+		<td>TBD</td>
+		<td>TBD</td>
+	</tr>
+	<tr>
+		<td>50</td>
+		<td>Output</td>
+		<td>Display Reset</td>
+		<td>Display<br>Reset</td>
+		<td>Display<br>Running</td>
+	</tr>
+	<tr>
+		<td>60</td>
+		<td>Output</td>
+		<td>Display Backlight</td>
+		<td>Backlight<br>Off</td>
+		<td>Backlight<br>On (100 %)</td>
+	</tr>
+	<tr>
+		<td>62</td>
+		<td>Input</td>
+		<td>Bend</td>
+		<td>Not pressed</td>
+		<td>Pressed</td>
+	</tr>
+</table>
+
 */
-- 
1.7.2.3



From jbe at pengutronix.de  Tue Dec 21 06:25:18 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Tue, 21 Dec 2010 12:25:18 +0100
Subject: [PATCH 6/9] ARM STM/i.MX: Add support for the gpio commands
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1292930721-31734-7-git-send-email-jbe@pengutronix.de>

Just an architecture improvement.

Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
---
 arch/arm/Kconfig                      |    1 +
 arch/arm/configs/chumbyone_defconfig  |    1 +
 arch/arm/configs/tx28stk5_defconfig   |    1 +
 arch/arm/mach-stm/include/mach/gpio.h |    4 ++
 arch/arm/mach-stm/iomux-imx.c         |   60 +++++++++++++++++++++++++++++++++
 5 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c09d21b..f1536a5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -41,6 +41,7 @@ config ARCH_IMX
 
 config ARCH_STM
 	bool "SigmaTel/FSL iMX-based"
+	select GENERIC_GPIO
 
 config ARCH_NETX
 	bool "Hilscher NetX based"
diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
index 6e6623a..45804a8 100644
--- a/arch/arm/configs/chumbyone_defconfig
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -24,6 +24,7 @@ CONFIG_CMD_RESET=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_PARTITION=y
 CONFIG_CMD_BMP=y
+CONFIG_CMD_GPIO=y
 # CONFIG_SPI is not set
 CONFIG_VIDEO=y
 CONFIG_DRIVER_VIDEO_STM=y
diff --git a/arch/arm/configs/tx28stk5_defconfig b/arch/arm/configs/tx28stk5_defconfig
index d6b81c6..0851d5e 100644
--- a/arch/arm/configs/tx28stk5_defconfig
+++ b/arch/arm/configs/tx28stk5_defconfig
@@ -32,6 +32,7 @@ CONFIG_CMD_GO=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_PARTITION=y
 CONFIG_CMD_BMP=y
+CONFIG_CMD_GPIO=y
 CONFIG_NET=y
 CONFIG_NET_DHCP=y
 CONFIG_NET_TFTP=y
diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
index 97566a2..c419926 100644
--- a/arch/arm/mach-stm/include/mach/gpio.h
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -30,5 +30,9 @@
 #endif
 
 void imx_gpio_mode(uint32_t);
+void gpio_set_value(unsigned, int);
+int gpio_direction_input(unsigned);
+int gpio_direction_output(unsigned, int);
+int gpio_get_value(unsigned);
 
 #endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
index 8a34e4c..b9fa565 100644
--- a/arch/arm/mach-stm/iomux-imx.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -20,6 +20,7 @@
 #include <common.h>
 #include <init.h>
 #include <gpio.h>
+#include <errno.h>
 #include <asm/io.h>
 #include <mach/imx-regs.h>
 
@@ -76,6 +77,12 @@ static unsigned calc_output_reg(unsigned no)
 	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
 }
 
+static unsigned calc_input_reg(unsigned no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DIN0;
+}
+
 /**
  * @param[in] m One pin define per call from iomux-mx23.h/iomux-mx28.h
  */
@@ -137,3 +144,56 @@ void imx_gpio_mode(uint32_t m)
 		}
 	}
 }
+
+int gpio_direction_input(unsigned gpio)
+{
+	unsigned reg_offset;
+
+	if (gpio > MAX_GPIO_NO)
+		return -EINVAL;
+
+	reg_offset = calc_output_enable_reg(gpio);
+	writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
+
+	return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int val)
+{
+	unsigned reg_offset;
+
+	if (gpio > MAX_GPIO_NO)
+		return -EINVAL;
+
+	/* first set the output value... */
+	reg_offset = calc_output_reg(gpio);
+	writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE +
+		reg_offset + (val != 0 ? BIT_SET : BIT_CLR));
+	/* ...then the direction */
+	reg_offset = calc_output_enable_reg(gpio);
+	writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + reg_offset + BIT_SET);
+
+	return 0;
+}
+
+void gpio_set_value(unsigned gpio, int val)
+{
+	unsigned reg_offset;
+
+	reg_offset = calc_output_reg(gpio);
+	writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE +
+				reg_offset + (val != 0 ? BIT_SET : BIT_CLR));
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	uint32_t reg;
+	unsigned reg_offset;
+
+	reg_offset = calc_input_reg(gpio);
+	reg = readl(IMX_IOMUXC_BASE + reg_offset);
+	if (reg & (0x1 << (gpio % 32)))
+		return 1;
+
+	return 0;
+}
-- 
1.7.2.3



From khc at pm.waw.pl  Tue Dec 21 19:48:36 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 01:48:36 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <20101221083540.GV6017@pengutronix.de> (Sascha Hauer's message of
	"Tue, 21 Dec 2010 09:35:40 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<20101221083540.GV6017@pengutronix.de>
Message-ID: <m3wrn2d44b.fsf@intrepid.localdomain>

Sascha Hauer <s.hauer at pengutronix.de> writes:

> These partitions are not on eraseblock boundaries, so I assume you use
> some script to combine barebox and firmware into a single image. Can we
> integrate this into the make system or at least add some instructions
> how to generate this image?

I patch them in flash with JTAG/OpenOCD, guess that's not what most
people will do. Added some instructions, it should be pretty clear now
(the NPE microcode files aren't going to change, Intel seems to have
finalized the IXP42x support at version 2.4).

>> +#ifdef CONFIG_USE_IRQ
>> +
>> +static void (*irq_handlers[HALF_QUEUES])(void *pdev);
>> +static void *irq_pdevs[HALF_QUEUES];
>> +
>> +#undef fls
>> +static inline int fls(int x)
>> +{
>> +	int ret;
>> +	asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc");
>> +	ret = 32 - ret;
>> +	return ret;
>> +}
>
> fls is defined in a similar way in arch/arm/include/asm/bitops.h:
>
> #define fls(x) \
> 	(__builtin_constant_p(x) ? constant_fls(x) : \
> 	({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }))
>
> Or am I missing something?

Looks like u-boot (v.1) doesn't have it, I was thinking of using u-boot
instead at first. Removed (I don't use CONFIG_USE_IRQ anyway).


WRT endianness switching, I added a couple of #ifdefs. It seems
gcc-4.4.x with EABI can optimize the unused "swap" parameter out, even
without actually inlining the function.
-- 
Krzysztof Halasa


From khc at pm.waw.pl  Tue Dec 21 19:51:03 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 01:51:03 +0100
Subject: [PATCH 5a] Fix error handling with malloc,
	memalign etc. Introduce xmemalign().
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
Message-ID: <m3sjxqd408.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 08a57ce..df664f6 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -95,13 +95,7 @@ void setup_dma_coherent(unsigned long offset)
 
 void *dma_alloc_coherent(size_t size)
 {
-	void *mem;
-
-	mem = memalign(4096, size);
-	if (mem)
-		return mem + dma_coherent_offset;
-
-	return NULL;
+	return xmemalign(4096, size) + dma_coherent_offset;
 }
 
 unsigned long virt_to_phys(void *virt)
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index fdd23b5..7789cc9 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -28,7 +28,7 @@ void *phys_to_virt(unsigned long phys);
 #else
 static inline void *dma_alloc_coherent(size_t size)
 {
-	return malloc(size);
+	return xmalloc(size);
 }
 
 static inline void dma_free_coherent(void *mem)
diff --git a/commands/edit.c b/commands/edit.c
index ca40d59..3519b09 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -184,10 +184,8 @@ static struct line *line_realloc(int len, struct line *line)
 {
 	int size = 32;
 
-	if (!line) {
+	if (!line)
 		line = xzalloc(sizeof(struct line));
-		line->data = malloc(32);
-	}
 
 	while (size < len)
 		size <<= 1;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 717fea5..9d52beb 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -116,9 +116,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
 {
 	struct clk_lookup_alloc *cla;
 
-	cla = kzalloc(sizeof(*cla), GFP_KERNEL);
-	if (!cla)
-		return NULL;
+	cla = xzalloc(sizeof(*cla), GFP_KERNEL);
 
 	cla->cl.clk = clk;
 	if (con_id) {
@@ -150,8 +148,6 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
 
 	l = clkdev_alloc(r, alias, alias_dev_name);
 	clk_put(r);
-	if (!l)
-		return -ENODEV;
 	clkdev_add(l);
 	return 0;
 }
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 04a1e4c..c196185 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1333,10 +1333,7 @@ static struct driver_d mci_driver = {
 
 static int mci_init(void)
 {
-	sector_buf = memalign(32, 512);
-	if (!sector_buf)
-		return -ENOMEM;
-
+	sector_buf = xmemalign(32, 512);
 	return register_driver(&mci_driver);
 }
 
diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c
index 4563ff3..d5e26a1 100644
--- a/drivers/net/at91_ether.c
+++ b/drivers/net/at91_ether.c
@@ -263,7 +263,7 @@ static int at91rm9200_eth_init (struct device_d *dev)
 	struct eth_device *edev;
 	int i;
 
-	edev = malloc(sizeof(struct eth_device));
+	edev = xmalloc(sizeof(struct eth_device));
 	dev->priv = edev;
 
 	edev->open = at91rm9200_eth_open;
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index 8120877..187c0fb 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -440,14 +440,14 @@ static int cs8900_probe(struct device_d *dev)
 
 	debug("cs8900_init()\n");
 
-	priv = (struct cs8900_priv *)malloc(sizeof(*priv));
+	priv = (struct cs8900_priv *)xmalloc(sizeof(*priv));
 	priv->regs = (u16 *)dev->map_base;
 	if (cs8900_check_id(priv)) {
 		free(priv);
 		return -1;
 	}
 
-	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
 	dev->type_data = edev;
 	edev->priv = priv;
 
diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c
index 8b2cb4d..7528316 100644
--- a/drivers/net/fec_mpc5200.c
+++ b/drivers/net/fec_mpc5200.c
@@ -661,9 +661,9 @@ int mpc5xxx_fec_probe(struct device_d *dev)
         struct eth_device *edev;
 	mpc5xxx_fec_priv *fec;
 
-        edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+        edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
         dev->type_data = edev;
-	fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
+	fec = (mpc5xxx_fec_priv *)xmalloc(sizeof(*fec));
         edev->priv = fec;
 	edev->open = mpc5xxx_fec_open,
 	edev->init = mpc5xxx_fec_init,
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 522a9f1..a30a9c8 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -79,7 +79,7 @@ int tap_probe(struct device_d *dev)
 	struct tap_priv *priv;
 	int ret = 0;
 
-	priv = malloc(sizeof(struct tap_priv));
+	priv = xmalloc(sizeof(struct tap_priv));
 	priv->name = "barebox";
 
 	priv->fd = tap_alloc(priv->name);
@@ -88,7 +88,7 @@ int tap_probe(struct device_d *dev)
 		goto out;
 	}
 
-	edev = malloc(sizeof(struct eth_device));
+	edev = xmalloc(sizeof(struct eth_device));
 	dev->type_data = edev;
 	edev->priv = priv;
 
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index efe8785..faf965a 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -305,7 +305,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 #endif
 
 	/* first only malloc space for the first sector */
-	info->start = malloc(sizeof(ulong));
+	info->start = xmalloc(sizeof(ulong));
 
 	info->start[0] = base;
 	info->protect = 0;
@@ -394,8 +394,8 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 			cur_offset += erase_region_size * erase_region_count;
 
 			/* increase the space malloced for the sector start addresses */
-			info->start = realloc(info->start, sizeof(ulong) * (erase_region_count + sect_cnt));
-			info->protect = realloc(info->protect, sizeof(uchar) * (erase_region_count + sect_cnt));
+			info->start = xrealloc(info->start, sizeof(ulong) * (erase_region_count + sect_cnt));
+			info->protect = xrealloc(info->protect, sizeof(uchar) * (erase_region_count + sect_cnt));
 
 			for (j = 0; j < erase_region_count; j++) {
 				info->start[sect_cnt] = sector;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index bc9b0de..442dbc4 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -157,8 +157,7 @@ static int pl011_probe(struct device_d *dev)
 	struct amba_uart_port *uart;
 	struct console_device *cdev;
 
-	uart = malloc(sizeof(struct amba_uart_port));
-
+	uart = xmalloc(sizeof(struct amba_uart_port));
 	uart->clk = clk_get(dev, NULL);
 
 	if (IS_ERR(uart->clk))
diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c
index b99ec4d..1098952 100644
--- a/drivers/serial/atmel.c
+++ b/drivers/serial/atmel.c
@@ -398,8 +398,7 @@ static int atmel_serial_probe(struct device_d *dev)
 	struct atmel_uart_port *uart;
 	struct console_device *cdev;
 
-	uart = malloc(sizeof(struct atmel_uart_port));
-
+	uart = xmalloc(sizeof(struct atmel_uart_port));
 	cdev = &uart->uart;
 	dev->type_data = cdev;
 	cdev->dev = dev;
diff --git a/drivers/serial/serial_blackfin.c b/drivers/serial/serial_blackfin.c
index 2101b7e..59b2fbb 100644
--- a/drivers/serial/serial_blackfin.c
+++ b/drivers/serial/serial_blackfin.c
@@ -115,7 +115,7 @@ static int blackfin_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index a7562f9..984d7f2 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -319,7 +319,7 @@ static int imx_serial_probe(struct device_d *dev)
 	struct imx_serial_priv *priv;
 	uint32_t val;
 
-	priv = malloc(sizeof(*priv));
+	priv = xmalloc(sizeof(*priv));
 	cdev = &priv->cdev;
 
 	priv->regs = (void __force __iomem *)dev->map_base;
diff --git a/drivers/serial/serial_netx.c b/drivers/serial/serial_netx.c
index 7c09519..9d4b29e 100644
--- a/drivers/serial/serial_netx.c
+++ b/drivers/serial/serial_netx.c
@@ -140,7 +140,7 @@ static int netx_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c
index 1a6366f..7923ebb 100644
--- a/drivers/serial/serial_pl010.c
+++ b/drivers/serial/serial_pl010.c
@@ -141,7 +141,7 @@ static int pl010_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index d7eac8f..0a17967 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -121,8 +121,7 @@ static int s3c24x0_serial_probe(struct device_d *dev)
 {
 	struct console_device *cdev;
 
-	cdev = malloc(sizeof(struct console_device));
-
+	cdev = xmalloc(sizeof(struct console_device));
 	dev->type_data = cdev;
 	cdev->dev = dev;
 	cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 978fdd1..fd70e62 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -903,9 +903,6 @@ static int __init composite_bind(struct usb_gadget *gadget)
 	int				status = -ENOMEM;
 
 	cdev = xzalloc(sizeof *cdev);
-	if (!cdev)
-		return status;
-
 	cdev->gadget = gadget;
 	set_gadget_data(gadget, cdev);
 	INIT_LIST_HEAD(&cdev->configs);
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 48fd0b5..20a5064 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -1016,8 +1016,6 @@ fsl_alloc_request(struct usb_ep *_ep)
 	struct fsl_req *req;
 
 	req = xzalloc(sizeof *req);
-	if (!req)
-		return NULL;
 
 	INIT_LIST_HEAD(&req->queue);
 
@@ -2095,7 +2093,7 @@ static int struct_udc_setup(struct fsl_udc *udc,
 	udc->status_req = container_of(fsl_alloc_request(NULL),
 			struct fsl_req, req);
 	/* allocate a small amount of memory to get valid address */
-	udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
+	udc->status_req->req.buf = xmalloc(8);
 	udc->resume_state = USB_STATE_NOTATTACHED;
 	udc->usb_state = USB_STATE_POWERED;
 	udc->ep0_dir = 0;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index cb65b19..d3baed7 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -205,11 +205,7 @@ gs_alloc_req(struct usb_ep *ep, unsigned len)
 
 	if (req != NULL) {
 		req->length = len;
-		req->buf = memalign(32, len);
-		if (req->buf == NULL) {
-			usb_ep_free_request(ep, req);
-			return NULL;
-		}
+		req->buf = xmemalign(32, len);
 	}
 
 	return req;
diff --git a/include/net.h b/include/net.h
index 2d28fee..33d8a32 100644
--- a/include/net.h
+++ b/include/net.h
@@ -392,7 +392,7 @@ struct net_connection {
 
 static inline char *net_alloc_packet(void)
 {
-	return memalign(32, PKTSIZE);
+	return xmemalign(32, PKTSIZE);
 }
 
 struct net_connection *net_udp_new(IPaddr_t dest, uint16_t dport,
diff --git a/include/xfuncs.h b/include/xfuncs.h
index 222ea41..261aaa5 100644
--- a/include/xfuncs.h
+++ b/include/xfuncs.h
@@ -7,5 +7,6 @@ void *xmalloc(size_t size);
 void *xrealloc(void *ptr, size_t size);
 void *xzalloc(size_t size);
 char *xstrdup(const char *s);
+void* xmemalign(size_t alignment, size_t bytes);
 
 #endif /* __XFUNCS_H */
diff --git a/lib/xfuncs.c b/lib/xfuncs.c
index 01a64cf..71394ff 100644
--- a/lib/xfuncs.c
+++ b/lib/xfuncs.c
@@ -70,3 +70,11 @@ char *xstrdup(const char *s)
 }
 EXPORT_SYMBOL(xstrdup);
 
+void* xmemalign(size_t alignment, size_t bytes)
+{
+	void *p = memalign(alignment, bytes);
+	if (!p)
+		panic("ERROR: out of memory\n");
+	return p;
+}
+EXPORT_SYMBOL(xmemalign);
diff --git a/net/net.c b/net/net.c
index 9b4ab89..7495357 100644
--- a/net/net.c
+++ b/net/net.c
@@ -365,7 +365,7 @@ static struct net_connection *net_new(IPaddr_t dest, rx_handler_f *handler)
 		return ERR_PTR(-ENETDOWN);
 
 	con = xzalloc(sizeof(*con));
-	con->packet = memalign(32, PKTSIZE);
+	con->packet = xmemalign(32, PKTSIZE);
 	memset(con->packet, 0, PKTSIZE);
 
 	con->et = (struct ethernet *)con->packet;
@@ -658,7 +658,7 @@ static int net_init(void)
 	int i;
 
 	for (i = 0; i < PKTBUFSRX; i++)
-		NetRxPackets[i] =  memalign(32, PKTSIZE);
+		NetRxPackets[i] =  xmemalign(32, PKTSIZE);
 
 	return 0;
 }
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 0d4f5e7..9f6535d 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -122,8 +122,11 @@ int symfilecnt = 0;
 
 void add_new_symbol(struct symfile *sym, char * symname)
 {
-	sym->symbollist =
-          realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	sym->symbollist = realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
+	if (!sym->symbollist) {
+		fprintf(stderr, "docproc: out of memory\n");
+		exit(1);
+	}
 	sym->symbollist[sym->symbolcnt++].name = strdup(symname);
 }
 
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4075c35..08b75b6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1317,7 +1317,7 @@ void buf_write(struct buffer *buf, const char *s, int len)
 {
 	if (buf->size - buf->pos < len) {
 		buf->size += len + SZ;
-		buf->p = realloc(buf->p, buf->size);
+		buf->p = NOFAIL(realloc(buf->p, buf->size));
 	}
 	strncpy(buf->p + buf->pos, s, len);
 	buf->pos += len;


From khc at pm.waw.pl  Tue Dec 21 19:53:29 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 01:53:29 +0100
Subject: [PATCH 6a] ARM: support big/little endian switching in "bootz".
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
Message-ID: <m3r5dad3w6.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 3572a1f..73ee115 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -73,6 +73,15 @@ config CPU_BIG_ENDIAN
 	  port must properly enable any big-endian related features
 	  of your chipset/board/processor.
 
+config BOOTZ_ENDIANNESS_SWITCH
+	bool "Support switching of Linux kernel endianness"
+	help
+	  Say Y here if you need to switch CPU endianness before running
+	  Linux kernel, e.g. if you want big-endian Barebox to run
+	  little-endian Linux.
+
+	  Currently implemented only in "bootz" command.
+
 config ARCH_HAS_L2X0
 	bool
 
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index f826da6..6462013 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -41,6 +41,7 @@
 #include <asm/setup.h>
 #include <asm/barebox-arm.h>
 #include <asm/armlinux.h>
+#include <asm/system.h>
 
 static struct tag *params;
 static int armlinux_architecture = 0;
@@ -85,9 +86,10 @@ static void setup_memory_tags(void)
 	}
 }
 
-static void setup_commandline_tag(const char *commandline)
+static void setup_commandline_tag(const char *commandline, int swap)
 {
 	const char *p;
+	size_t words;
 
 	if (!commandline)
 		return;
@@ -102,12 +104,20 @@ static void setup_commandline_tag(const char *commandline)
 	if (*p == '\0')
 		return;
 
+	words = (strlen(p) + 1 /* NUL */ + 3 /* round up */) >> 2;
 	params->hdr.tag = ATAG_CMDLINE;
-	params->hdr.size =
-	    (sizeof (struct tag_header) + strlen(p) + 1 + 4) >> 2;
+	params->hdr.size = (sizeof(struct tag_header) >> 2) + words;
 
 	strcpy(params->u.cmdline.cmdline, p);
 
+#ifdef CONFIG_BOOTZ_ENDIANNESS_SWITCH
+	if (swap) {
+		u32 *cmd = (u32 *)params->u.cmdline.cmdline;
+		while (words--)
+			cmd[words] = swab32(cmd[words]);
+	}
+#endif
+
 	params = tag_next(params);
 }
 
@@ -156,13 +166,13 @@ static void setup_end_tag (void)
 	params->hdr.size = 0;
 }
 
-static void setup_tags(struct image_data *data)
+static void setup_tags(struct image_data *data, int swap)
 {
 	const char *commandline = getenv("bootargs");
 
 	setup_start_tag();
 	setup_memory_tags();
-	setup_commandline_tag(commandline);
+	setup_commandline_tag(commandline, swap);
 
 	if (data && data->initrd)
 		setup_initrd_tag (&data->initrd->header);
@@ -231,7 +241,7 @@ static int do_bootm_linux(struct image_data *data)
 	debug("## Transferring control to Linux (at address 0x%p) ...\n",
 	       theKernel);
 
-	setup_tags(data);
+	setup_tags(data, 0);
 
 	if (relocate_image(data->os, (void *)image_get_load(os_header)))
 		return -1;
@@ -290,18 +300,21 @@ late_initcall(armlinux_register_image_handler);
 
 #ifdef CONFIG_CMD_BOOTZ
 struct zimage_header {
-	u32	unsused[9];
+	u32	unused[9];
 	u32	magic;
 	u32	start;
 	u32	end;
 };
 
+#define ZIMAGE_MAGIC 0x016F2818
+
 static int do_bootz(struct command *cmdtp, int argc, char *argv[])
 {
 	void (*theKernel)(int zero, int arch, void *params);
-	int fd, ret;
+	int fd, ret, swap = 0;
 	struct zimage_header header;
 	void *zimage;
+	u32 end;
 
 	if (argc != 2) {
 		barebox_cmd_usage(cmdtp);
@@ -320,27 +333,53 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
 		goto err_out;
 	}
 
-	if (header.magic != 0x016f2818) {
+	switch (header.magic) {
+#ifdef CONFIG_BOOTZ_ENDIANNESS_SWITCH
+	case swab32(ZIMAGE_MAGIC):
+		swap = 1;
+		/* fall through */
+#endif
+	case ZIMAGE_MAGIC:
+		break;
+	default:
 		printf("invalid magic 0x%08x\n", header.magic);
 		goto err_out;
 	}
 
-	zimage = xmalloc(header.end);
+	end = header.end;
+
+	if (swap)
+		end = swab32(end);
+
+	zimage = xmalloc(end);
 	memcpy(zimage, &header, sizeof(header));
 
-	ret = read(fd, zimage + sizeof(header), header.end - sizeof(header));
-	if (ret < header.end - sizeof(header)) {
+	ret = read(fd, zimage + sizeof(header), end - sizeof(header));
+	if (ret < end - sizeof(header)) {
 		printf("could not read %s\n", argv[1]);
 		goto err_out1;
 	}
 
+	if (swap) {
+		void *ptr;
+		for (ptr = zimage; ptr < zimage + end; ptr += 4)
+			*(u32 *)ptr = swab32(*(u32 *)ptr);
+	}
+
 	theKernel = zimage;
 
-	printf("loaded zImage from %s with size %d\n", argv[1], header.end);
+	printf("loaded zImage from %s with size %d\n", argv[1], end);
 
-	setup_tags(NULL);
+	setup_tags(NULL, swap);
 
 	shutdown_barebox();
+	if (swap) {
+		u32 reg;
+		__asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));
+		reg ^= CR_B; /* swap big-endian flag */
+		__asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
+	}
+
 	theKernel(0, armlinux_architecture, armlinux_bootparams);
 
 	return 0;
@@ -382,7 +421,7 @@ static int do_bootu(struct command *cmdtp, int argc, char *argv[])
 	if (!theKernel)
 		theKernel = (void *)simple_strtoul(argv[1], NULL, 0);
 
-	setup_tags(NULL);
+	setup_tags(NULL, 0);
 
 	shutdown_barebox();
 	theKernel(0, armlinux_architecture, armlinux_bootparams);


From khc at pm.waw.pl  Tue Dec 21 19:55:23 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 01:55:23 +0100
Subject: [PATCH 10a] ARM: Add support for IXP4xx CPU and for Goramo Multilink
	router platform.
In-Reply-To: <m362uodqms.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Mon, 20 Dec 2010 23:30:03 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
Message-ID: <m3pqsud3t0.fsf@intrepid.localdomain>

Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>

diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index 8087f01..8d8701f 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -20,6 +20,7 @@ ARM type:
 @li @subpage board_babage
 @li @subpage chumbyone
 @li @subpage scb9328
+ at li @subpage multilink
 @li @subpage netx
 @li @subpage dev_omap_arch
 @li @subpage a9m2440
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c09d21b..2b33a07 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -39,6 +39,13 @@ config ARCH_IMX
 	bool "Freescale iMX-based"
 	select GENERIC_GPIO
 
+config ARCH_IXP4XX
+	bool "Intel IXP4xx-based"
+	select CPU_32v5
+	select ARCH_SUPPORTS_BIG_ENDIAN
+	select CPU_BIG_ENDIAN
+	select ARCH_HAS_LOWLEVEL_INIT
+
 config ARCH_STM
 	bool "SigmaTel/FSL iMX-based"
 
@@ -70,6 +77,7 @@ source arch/arm/cpu/Kconfig
 source arch/arm/mach-at91/Kconfig
 source arch/arm/mach-ep93xx/Kconfig
 source arch/arm/mach-imx/Kconfig
+source arch/arm/mach-ixp4xx/Kconfig
 source arch/arm/mach-stm/Kconfig
 source arch/arm/mach-netx/Kconfig
 source arch/arm/mach-nomadik/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c90960e..4cc0c0c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -41,6 +41,7 @@ CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
 machine-$(CONFIG_ARCH_AT91)		:= at91
 machine-$(CONFIG_ARCH_EP93XX)		:= ep93xx
 machine-$(CONFIG_ARCH_IMX)		:= imx
+machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_STM)		:= stm
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NETX)		:= netx
@@ -74,6 +75,7 @@ board-$(CONFIG_MACH_FREESCALE_MX35_3STACK)	:= freescale-mx35-3-stack
 board-$(CONFIG_MACH_IMX21ADS)			:= imx21ads
 board-$(CONFIG_MACH_IMX27ADS)			:= imx27ads
 board-$(CONFIG_MACH_MMCCPU)			:= mmccpu
+board-$(CONFIG_MACH_MULTILINK)			:= multilink
 board-$(CONFIG_MACH_MX1ADS)			:= mx1ads
 board-$(CONFIG_MACH_NOMADIK_8815NHK)		:= nhk8815
 board-$(CONFIG_MACH_NXDB500)			:= netx
diff --git a/arch/arm/boards/multilink/Makefile b/arch/arm/boards/multilink/Makefile
new file mode 100644
index 0000000..d5a8bbc
--- /dev/null
+++ b/arch/arm/boards/multilink/Makefile
@@ -0,0 +1 @@
+obj-y += lowlevel_init.o multilink.o
diff --git a/arch/arm/boards/multilink/config.h b/arch/arm/boards/multilink/config.h
new file mode 100644
index 0000000..e69de29
diff --git a/arch/arm/boards/multilink/lowlevel_init.S b/arch/arm/boards/multilink/lowlevel_init.S
new file mode 100644
index 0000000..970ef72
--- /dev/null
+++ b/arch/arm/boards/multilink/lowlevel_init.S
@@ -0,0 +1,64 @@
+#include <mach/ixp4xx-regs.h>
+
+	.section ".text_bare_init", "ax"
+	.balign 0x40
+	.space 0x40 /* configuration block at 0x40 */
+
+	.macro DELAY_FOR cycles, reg0
+	ldr \reg0, =\cycles
+	subs \reg0, \reg0, #1
+	subne pc, pc, #0xc
+	.endm
+
+#define CFG_SDRAM_SIZE    0x50 /* u32 */
+#define CFG_SDRAM_CONF    0x54 /* u32 */
+#define CFG_SDRAM_MODE    0x58 /* u32 */
+#define CFG_SDRAM_REFRESH 0x5C /* u32 */
+
+.globl board_init_lowlevel
+board_init_lowlevel:
+	mov r8, #IXP4XX_EXP_BASE(0)
+	ldr r1, [r8, #CFG_SDRAM_CONF]
+	ldr r2, =IXP4XX_SDRAM_CONFIG
+	str r1, [r2]
+
+	/* disable refresh cycles */
+	mov r1, #0
+	add r2, r2, #4 /* r2 = IXP4XX_SDRAM_REFRESH */
+	str r1, [r2]
+
+	/* send NOP command */
+	mov r1, #3
+	add r3, r2, #4 /* r3 = IXP4XX_SDRAM_IR */
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	/* set SDRAM internal refresh */
+	ldr r1, [r8, #CFG_SDRAM_REFRESH]
+	str r1, [r2]
+	DELAY_FOR 0x4000, r0
+
+	/* send precharge-all command to close all open banks */
+	mov r1, #2
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	/* provide 8 auto-refresh cycles */
+	mov r1, #4
+	mov r4, #8
+1:	str r1, [r3]
+	DELAY_FOR 0x100, r0
+	subs r4, r4, #1
+	bne 1b
+
+	/* set mode register in SDRAM */
+	ldr r1, [r8, #CFG_SDRAM_MODE]
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	/* send normal operation command */
+	mov r1, #6
+	str r1, [r3]
+	DELAY_FOR 0x4000, r0
+
+	mov pc, lr
diff --git a/arch/arm/boards/multilink/multilink.c b/arch/arm/boards/multilink/multilink.c
new file mode 100644
index 0000000..f2fb8f4
--- /dev/null
+++ b/arch/arm/boards/multilink/multilink.c
@@ -0,0 +1,144 @@
+//#define DEBUG
+#include <common.h>
+#include <errno.h>
+#include <init.h>
+#include <linux/types.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/ixp4xx-regs.h>
+#include <mach/platform.h>
+
+/* offsets from start of flash ROM = 0x50000000 */
+#define CFG_ETH0_ADDRESS     0x40 /* 6 bytes */
+#define CFG_ETH1_ADDRESS     0x46 /* 6 bytes */
+#define CFG_REV              0x4C /* u32 */
+#define CFG_SDRAM_SIZE       0x50 /* u32 */
+#define CFG_SDRAM_CONF       0x54 /* u32 */
+#define CFG_SDRAM_MODE       0x58 /* u32 */
+#define CFG_SDRAM_REFRESH    0x5C /* u32 */
+
+#define CFG_HW_BITS          0x60 /* u32 */
+#define  CFG_HW_USB_PORTS    0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
+#define  CFG_HW_HAS_PCI_SLOT 0x00000008
+#define  CFG_HW_HAS_ETH0     0x00000010
+#define  CFG_HW_HAS_ETH1     0x00000020
+#define  CFG_HW_HAS_HSS0     0x00000040
+#define  CFG_HW_HAS_HSS1     0x00000080
+#define  CFG_HW_HAS_UART0    0x00000100
+#define  CFG_HW_HAS_UART1    0x00000200
+#define  CFG_HW_HAS_EEPROM   0x00000400
+
+#define ETH_ALEN             6
+
+#define BAREBOX_START        0x00000
+#define BAREBOX_LENGTH       0x34000
+#define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
+#define NPE_A_LENGTH         0x05000
+#define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
+#define NPE_B_LENGTH         0x03000
+#define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
+#define NPE_C_LENGTH         0x04000
+#define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
+#define NPE_ENV0_LENGTH      0x20000
+
+static struct device_d cfi_dev = {
+	.name     = "cfi_flash",
+	.map_base = IXP4XX_EXP_BASE(0),
+	.size     = 16 * 1024 * 1024,
+};
+
+static struct eth_plat_info eth_pinfo[2] = {
+	{
+		.regs     = IXP4XX_EthB_BASE,
+		.npe      = 1,
+		.phy      = 0,
+		.rxq      = 20,
+		.txreadyq = 29,
+	}, {
+		.regs     = IXP4XX_EthC_BASE,
+		.npe      = 2,
+		.phy      = 1,
+		.rxq      = 21,
+		.txreadyq = 30,
+	}
+};
+
+static struct device_d eth_dev[2] = {
+	{
+		.name           = "ixp4xx_eth",
+		.platform_data  = &eth_pinfo[0],
+	}, {
+		.id             = 1,
+		.name           = "ixp4xx_eth",
+		.platform_data  = &eth_pinfo[1],
+	}
+};
+
+static struct memory_platform_data ram_pdata = {
+	.name           = "ram0",
+	.flags          = DEVFS_RDWR,
+};
+
+struct device_d sdram_dev = {
+	.id             = -1,
+	.name           = "mem",
+	.map_base       = 0x00000000,
+	.size           = 32 * 1024 * 1024,
+	.platform_data  = &ram_pdata,
+};
+
+static inline u8 __init flash_readb(u32 addr)
+{
+	return __raw_readb(IXP4XX_EXP_BASE(0) + addr);
+}
+
+static int __init gml_devices_init(void)
+{
+	u32 hw_bits;
+	int i;
+
+	IXP4XX_EXP_CS0 = IXP4XX_EXP_EN | IXP4XX_EXP_INTEL |
+		IXP4XX_EXP_BITS(24) | IXP4XX_EXP_WR_EN | IXP4XX_EXP_BYTE_RD16;
+	i = register_device(&cfi_dev);
+	if (i)
+		goto out;
+
+	devfs_add_partition("nor0", BAREBOX_START, BAREBOX_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "barebox");
+	devfs_add_partition("nor0", NPE_A_START, NPE_A_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-A");
+	devfs_add_partition("nor0", NPE_B_START, NPE_B_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-B");
+	devfs_add_partition("nor0", NPE_C_START, NPE_C_LENGTH,
+			    DEVFS_PARTITION_FIXED | DEVFS_PARTITION_READONLY, "NPE-C");
+	devfs_add_partition("nor0", NPE_ENV0_START, NPE_ENV0_LENGTH,
+			    DEVFS_PARTITION_FIXED, "env0");
+
+	hw_bits = __raw_readl(IXP4XX_EXP_BASE(0) + CFG_HW_BITS);
+
+	if (hw_bits & CFG_HW_HAS_ETH0) {
+		for (i = 0; i < ETH_ALEN; i++)
+			eth_pinfo[0].hwaddr[i] = flash_readb(CFG_ETH0_ADDRESS + i);
+		register_device(&eth_dev[0]);
+	}
+
+	if (hw_bits & CFG_HW_HAS_ETH1) {
+		for (i = 0; i < ETH_ALEN; i++)
+			eth_pinfo[1].hwaddr[i] = flash_readb(CFG_ETH1_ADDRESS + i);
+		register_device(&eth_dev[1]);
+	}
+
+	sdram_dev.size = __raw_readl(IXP4XX_EXP_BASE(0) + CFG_SDRAM_SIZE);
+	i = register_device(&sdram_dev);
+	if (i)
+		goto out;
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void *)(0x00000100));
+	armlinux_set_architecture(MACH_TYPE_GORAMO_MLR);
+
+out:
+	return i;
+}
+device_initcall(gml_devices_init);
diff --git a/arch/arm/boards/multilink/multilink.dox b/arch/arm/boards/multilink/multilink.dox
new file mode 100644
index 0000000..eada1e1
--- /dev/null
+++ b/arch/arm/boards/multilink/multilink.dox
@@ -0,0 +1,36 @@
+/** @page multilink Goramo MultiLink
+
+These boards are based on Intel IXP42x CPU.
+
+Variants:
+
+MicroRouter module: IXP421 or IXP425 266 MHz CPU, 32 MiB SDRAM,
+   1 or 2 Fast Ethernet ports, 2 sync serial ports, 1 RS-232 (console) port.
+
+MultiLink v.1: IXP425 266 or 533 MHz CPU, 64 - 256 MiB SDRAM,
+   2 Fast Ethernet ports, 2 sync serial ports, 1 - 2 RS-232 ports,
+   a mini-PCI slot, 2 optional USB host connectors.
+
+MultiLink v.2: IXP425 266 or 533 MHz CPU, 64 - 256 MiB SDRAM,
+   2 Fast Ethernet ports, 2 sync serial ports, 1 - 2 RS-232 ports,
+   2 additional optional Fast or Gigabit Ethernet ports, a mini-PCI slot,
+   4 optional USB host connectors, optional Real-Time Clock,
+   optional IDE connector.
+
+16 MiB Intel StrataFlash memory is partitioned as follows:
+
+0x00000-0x34000 : Barebox image
+0x34000-0x39000 : NPE-A microcode
+0x39000-0x3c000 : NPE-B microcode
+0x3c000-0x40000 : NPE-C microcode
+0x40000-0x60000 : env0
+
+There is a factory configuration region within Barebox image at locations
+0x40 - 0x7F. Details are in file multilink.c
+
+Barebox image and NPE microcode files are combined in first two blocks
+of flash memory. NPE-A microcode is not used by Barebox (but may be used
+by Linux HSS driver). NPE-B microcode is needed for eth0 and NPE-C for
+eth1. Barebox needs version 2.4 of regular non-VLAN-aware microcode files
+(with or without crypto support).
+*/
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
new file mode 100644
index 0000000..f5e4b41
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -0,0 +1,26 @@
+if ARCH_IXP4XX
+
+choice
+	prompt "IXP4xx Board Type"
+
+config MACH_MULTILINK
+	bool "Goramo MultiLink"
+	select MACH_HAS_LOWLEVEL_INIT
+endchoice
+
+config BOARDINFO
+	default "Goramo MultiLink" if MACH_MULTILINK
+
+config IXP4XX_QMGR
+	tristate "IXP4xx Queue Manager support"
+	help
+	  This driver supports IXP4xx built-in hardware queue manager
+	  and is required by the Ethernet driver.
+
+config IXP4XX_NPE
+	tristate "IXP4xx Network Processor Engine support"
+	help
+	  This driver supports IXP4xx built-in network coprocessors
+	  and is required by the Ethernet driver.
+
+endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
new file mode 100644
index 0000000..aa38991
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -0,0 +1,3 @@
+obj-y += lowlevel_init.o generic.o
+obj-$(CONFIG_IXP4XX_QMGR) += qmgr.o
+obj-$(CONFIG_IXP4XX_NPE) += npe.o
diff --git a/arch/arm/mach-ixp4xx/generic.c b/arch/arm/mach-ixp4xx/generic.c
new file mode 100644
index 0000000..02394a4
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/generic.c
@@ -0,0 +1,120 @@
+#include <common.h>
+#include <init.h>
+#include <ns16550.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+
+#define OSTS_FREQUENCY 66666000
+
+void reset_cpu(ulong addr)
+{
+	/* Use on-chip reset capability */
+	/* This may not work on IXP425 rev. A0 */
+
+	IXP4XX_OSWK = IXP4XX_WDT_KEY;
+	IXP4XX_OSWT = 0; /* request immediate reset */
+	IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
+	while (1)
+		;
+}
+
+#include <clock.h>
+
+/**
+ * @brief Provide a simple clock read
+ *
+ * Nothing is simpler.. read direct from clock and provide it
+ * to the caller.
+ *
+ * @return clock counter
+ */
+static uint64_t ixp4xx_clocksource_read(void)
+{
+	return IXP4XX_OSTS;
+}
+
+static struct clocksource cs = {
+	.read = ixp4xx_clocksource_read,
+	.mask = 0xffffffff,
+	.shift = 10,
+};
+
+/**
+ * @brief Initialize the Clock
+ *
+ * We use the Time-Stamp Timer
+ *
+ * @return result of @ref init_clock
+ */
+static int ixp4xx_clocksource_init(void)
+{
+	cs.mult = clocksource_hz2mult(OSTS_FREQUENCY, cs.shift);
+
+	return init_clock(&cs);
+}
+
+/* Run me at boot time */
+core_initcall(ixp4xx_clocksource_init);
+
+
+#ifdef CONFIG_DRIVER_SERIAL_NS16550
+
+/**
+ * @brief UART port register read function for IXP4XX
+ *
+ * @param base base address of UART
+ * @param reg_idx register index
+ *
+ * @return character read from register
+ */
+unsigned int ixp4xx_uart_read(unsigned long base, unsigned char reg_idx)
+{
+	return readb(4 * reg_idx + 3 /* big-endian */ + (uint8_t *)base);
+}
+EXPORT_SYMBOL(ixp4xx_uart_read);
+
+/**
+ * @brief UART port register write function for IXP4XX
+ *
+ * @param val value to write
+ * @param base base address of UART
+ * @param reg_idx register index
+ *
+ * @return void
+ */
+void ixp4xx_uart_write(unsigned int val, unsigned long base, unsigned char reg_idx)
+{
+	writeb(val, 4 * reg_idx + 3 /* big-endian */ + (uint8_t *)base);
+}
+EXPORT_SYMBOL(ixp4xx_uart_write);
+
+
+static struct NS16550_plat serial_plat = {
+	.clock = 14745600,
+	.f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
+	.reg_read = ixp4xx_uart_read,
+	.reg_write = ixp4xx_uart_write,
+};
+
+static struct device_d ixp4xx_serial_device = {
+	.name = "serial_ns16550",
+	.map_base = (u32)IXP4XX_UART1_BASE,
+	.size = 1024,
+	.platform_data = (void *)&serial_plat,
+};
+
+/**
+ * @brief UART serial port initialization
+ *
+ * @return result of device registration
+ */
+static int ixp4xx_console_init(void)
+{
+	/* Register the serial port */
+	return register_device(&ixp4xx_serial_device);
+}
+
+console_initcall(ixp4xx_console_init);
+
+#endif /* CONFIG_DRIVER_SERIAL_NS16550 */
diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
new file mode 100644
index 0000000..3de021e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/cpu.h
+ *
+ * IXP4XX cpu type detection
+ *
+ * Copyright (C) 2007 MontaVista Software, 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+#include <linux/types.h>
+
+/* Processor id value in CP15 Register 0 */
+#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
+#define IXP42X_PROCESSOR_ID_MASK  0xffffffc0
+
+#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
+#define IXP43X_PROCESSOR_ID_MASK  0xfffffff0
+
+#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
+#define IXP46X_PROCESSOR_ID_MASK  0xfffffff0
+
+#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
+				IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
+			 IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
+			 IXP43X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
+			 IXP46X_PROCESSOR_ID_VALUE)
+
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant.  Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline u32 __attribute_const__ read_cpuid_id(void)
+{
+	u32 val;
+	asm("mrc p15, 0, %0, c0, c0, 0" : "=r" (val) : : "cc");
+
+	return val;
+}
+
+static inline u32 ixp4xx_read_feature_bits(void)
+{
+	u32 val = ~IXP4XX_EXP_CFG2;
+
+	if (cpu_is_ixp42x_rev_a0())
+		return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
+					       IXP4XX_FEATURE_AES);
+	if (cpu_is_ixp42x())
+		return val & IXP42X_FEATURE_MASK;
+	if (cpu_is_ixp43x())
+		return val & IXP43X_FEATURE_MASK;
+	return val & IXP46X_FEATURE_MASK;
+}
+
+static inline void ixp4xx_write_feature_bits(u32 value)
+{
+	IXP4XX_EXP_CFG2 = ~value;
+}
+
+#endif  /* _ASM_ARCH_CPU_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
new file mode 100644
index 0000000..da4dc8a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -0,0 +1,365 @@
+/*
+ * Register definitions for IXP4xx chipset.
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, 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.
+ *
+ */
+
+#ifndef _ASM_ARM_IXP4XX_H_
+#define _ASM_ARM_IXP4XX_H_
+
+#ifdef __ASSEMBLER__
+#define IXP4XX_REG(reg)  (reg)
+#else
+#define IXP4XX_REG(reg)  (*(volatile u32 *)(reg))
+#define IXP4XX_BASE(reg) ((u32*)(reg))
+#endif
+
+/* Expansion Bus region */
+
+/* Queue Manager */
+#define IXP4XX_QMGR_BASE              (0x60000000)
+#define IXP4XX_QMGR_REGION_SIZE       (0x00004000)
+
+
+/* PCI Config registers */
+#define IXP4XX_PCI_CFG_BASE           (0xC0000000)
+#define IXP4XX_PCI_CFG_REGION_SIZE    (0x00001000)
+
+/* Peripheral space */
+#define IXP4XX_PERIPHERAL_BASE        (0xC8000000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
+
+/*
+ * Debug UART
+ *
+ * This is basically a remap of UART1 into a region that is section
+ * aligned so that it can be used with the low-level debug code.
+ */
+#define IXP4XX_DEBUG_UART_BASE        (0xC8000000)
+#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
+
+/* Expansion Bus Controller registers. */
+#define IXP4XX_EXP_CS0       IXP4XX_REG(0xC4000000)
+#define IXP4XX_EXP_CS1       IXP4XX_REG(0xC4000004)
+#define IXP4XX_EXP_CS2       IXP4XX_REG(0xC4000008)
+#define IXP4XX_EXP_CS3       IXP4XX_REG(0xC400000C)
+#define IXP4XX_EXP_CS4       IXP4XX_REG(0xC4000010)
+#define IXP4XX_EXP_CS5       IXP4XX_REG(0xC4000014)
+#define IXP4XX_EXP_CS6       IXP4XX_REG(0xC4000018)
+#define IXP4XX_EXP_CS7       IXP4XX_REG(0xC400001C)
+
+#define IXP4XX_EXP_BASE(n)  (0x50000000 + (n) * 1000000)
+
+#define IXP4XX_EXP_EN        0x80000000
+#define IXP4XX_EXP_T1(n)    (0x10000000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T2(n)    (0x04000000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T3(n)    (0x00400000 * (n)) /* valid: 0 - 15 */
+#define IXP4XX_EXP_T4(n)    (0x00100000 * (n)) /* valid: 0 - 3 */
+#define IXP4XX_EXP_T5(n)    (0x00010000 * (n)) /* valid: 0 - 15 */
+#define IXP4XX_EXP_INTEL     0x00000000
+#define IXP4XX_EXP_MOTO      0x00004000
+#define IXP4XX_EXP_HPI       0x00008000
+#define IXP4XX_EXP_BITS(n)  (0x00000400 * ((n) - 9)) /* valid: 9 - 24 */
+#define IXP4XX_EXP_BYTE_RD16 0x00000040
+#define IXP4XX_EXP_HRDY_POL  0x00000020
+#define IXP4XX_EXP_MUX_EN    0x00000010
+#define IXP4XX_EXP_SPLT_EN   0x00000008
+#define IXP4XX_EXP_WR_EN     0x00000002
+#define IXP4XX_EXP_BYTE_EN   0x00000001
+
+#define IXP4XX_EXP_CFG0      IXP4XX_REG(0xC4000020)
+#define IXP4XX_EXP_CFG1      IXP4XX_REG(0xC4000024)
+#define IXP4XX_EXP_CFG2      IXP4XX_REG(0xC4000028)
+#define IXP4XX_EXP_CFG3      IXP4XX_REG(0xC400002C)
+
+
+/* Peripheral Space Register Region Base Addresses */
+#define IXP4XX_UART1_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x0000)
+#define IXP4XX_UART2_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x1000)
+#define IXP4XX_PMU_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x2000)
+#define IXP4XX_INTC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x3000)
+#define IXP4XX_GPIO_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x4000)
+#define IXP4XX_NPEA_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x6000)
+#define IXP4XX_NPEB_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x7000)
+#define IXP4XX_NPEC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x8000)
+#define IXP4XX_EthB_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x9000)
+#define IXP4XX_EthC_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xA000)
+#define IXP4XX_USB_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xB000)
+/* IXP46x only */
+#define IXP4XX_EthA_BASE     IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xC000)
+#define IXP4XX_EthB1_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xD000)
+#define IXP4XX_EthB2_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xE000)
+#define IXP4XX_EthB3_BASE    IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0xF000)
+#define IXP4XX_TIMESYNC_BASE IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x10000)
+#define IXP4XX_I2C_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x11000)
+#define IXP4XX_SSP_BASE      IXP4XX_BASE(IXP4XX_PERIPHERAL_BASE + 0x12000)
+
+/*
+  Constants to make it easy to access Interrupt Controller registers
+ */
+#define IXP4XX_ICPR_OFFSET   0x00 /* Interrupt Status */
+#define IXP4XX_ICMR_OFFSET   0x04 /* Interrupt Enable */
+#define IXP4XX_ICLR_OFFSET   0x08 /* Interrupt IRQ/FIQ Select */
+#define IXP4XX_ICIP_OFFSET   0x0C /* IRQ Status */
+#define IXP4XX_ICFP_OFFSET   0x10 /* FIQ Status */
+#define IXP4XX_ICHR_OFFSET   0x14 /* Interrupt Priority */
+#define IXP4XX_ICIH_OFFSET   0x18 /* IRQ Highest Pri Int */
+#define IXP4XX_ICFH_OFFSET   0x1C /* FIQ Highest Pri Int */
+
+/* IXP465-only */
+#define IXP4XX_ICPR2_OFFSET  0x20 /* Interrupt Status 2 */
+#define IXP4XX_ICMR2_OFFSET  0x24 /* Interrupt Enable 2 */
+#define IXP4XX_ICLR2_OFFSET  0x28 /* Interrupt IRQ/FIQ Select 2 */
+#define IXP4XX_ICIP2_OFFSET  0x2C /* IRQ Status */
+#define IXP4XX_ICFP2_OFFSET  0x30 /* FIQ Status */
+#define IXP4XX_ICEEN_OFFSET  0x34 /* Error High Pri Enable */
+
+
+/* Interrupt Controller Register Definitions. */
+#define IXP4XX_INTC_REG(x)   ((volatile u32 *)(IXP4XX_INTC_BASE + (x)))
+
+#define IXP4XX_ICPR          IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
+#define IXP4XX_ICMR          IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
+#define IXP4XX_ICLR          IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
+#define IXP4XX_ICIP          IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
+#define IXP4XX_ICFP          IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
+#define IXP4XX_ICHR          IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
+#define IXP4XX_ICIH          IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET)
+#define IXP4XX_ICFH          IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
+#define IXP4XX_ICPR2         IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
+#define IXP4XX_ICMR2         IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
+#define IXP4XX_ICLR2         IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
+#define IXP4XX_ICIP2         IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
+#define IXP4XX_ICFP2         IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
+#define IXP4XX_ICEEN         IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
+
+/* Constants to make it easy to access GPIO registers */
+#define IXP4XX_GPIO_GPOUTR_OFFSET   0x00
+#define IXP4XX_GPIO_GPOER_OFFSET    0x04
+#define IXP4XX_GPIO_GPINR_OFFSET    0x08
+#define IXP4XX_GPIO_GPISR_OFFSET    0x0C
+#define IXP4XX_GPIO_GPIT1R_OFFSET   0x10
+#define IXP4XX_GPIO_GPIT2R_OFFSET   0x14
+#define IXP4XX_GPIO_GPCLKR_OFFSET   0x18
+#define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C
+
+/* GPIO Register Definitions - perform only 32-bit reads/writes */
+#define IXP4XX_GPIO_REG(x)   ((volatile u32 *)(IXP4XX_GPIO_BASE + (x)))
+
+#define IXP4XX_GPIO_GPOUTR   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
+#define IXP4XX_GPIO_GPOER    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
+#define IXP4XX_GPIO_GPINR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
+#define IXP4XX_GPIO_GPISR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
+#define IXP4XX_GPIO_GPIT1R   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
+#define IXP4XX_GPIO_GPIT2R   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
+#define IXP4XX_GPIO_GPCLKR   IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
+#define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
+
+/* GPIO register bit definitions */
+
+/* Interrupt styles */
+#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH  0x0
+#define IXP4XX_GPIO_STYLE_ACTIVE_LOW   0x1
+#define IXP4XX_GPIO_STYLE_RISING_EDGE  0x2
+#define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3
+#define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4
+
+/* Mask used to clear interrupt styles */
+#define IXP4XX_GPIO_STYLE_CLEAR        0x7
+#define IXP4XX_GPIO_STYLE_SIZE         3
+
+/* Operating System Timer Register Definitions. */
+#define IXP4XX_OSTS          IXP4XX_REG(0xC8005000) /* Continious TimeStamp */
+#define IXP4XX_OST1          IXP4XX_REG(0xC8005004) /* Timer 1 Timestamp */
+#define IXP4XX_OSRT1         IXP4XX_REG(0xC8005008) /* Timer 1 Reload */
+#define IXP4XX_OST2          IXP4XX_REG(0xC800500C) /* Timer 2 Timestamp */
+#define IXP4XX_OSRT2         IXP4XX_REG(0xC8005010) /* Timer 2 Reload */
+#define IXP4XX_OSWT          IXP4XX_REG(0xC8005014) /* Watchdog Timer */
+#define IXP4XX_OSWE          IXP4XX_REG(0xC8005018) /* Watchdog Enable */
+#define IXP4XX_OSWK          IXP4XX_REG(0xC800501C) /* Watchdog Key */
+#define IXP4XX_OSST          IXP4XX_REG(0xC8005020) /* Timer Status */
+
+/* Timer register values and bit definitions */
+#define IXP4XX_OST_ENABLE            0x00000001
+#define IXP4XX_OST_ONE_SHOT          0x00000002
+/* Low order bits of reload value ignored */
+#define IXP4XX_OST_RELOAD_MASK       0x00000003
+#define IXP4XX_OST_DISABLED          0x00000000
+#define IXP4XX_OSST_TIMER_1_PEND     0x00000001
+#define IXP4XX_OSST_TIMER_2_PEND     0x00000002
+#define IXP4XX_OSST_TIMER_TS_PEND    0x00000004
+#define IXP4XX_OSST_TIMER_WDOG_PEND  0x00000008
+#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
+
+#define IXP4XX_WDT_KEY               0x0000482E
+
+#define IXP4XX_WDT_RESET_ENABLE      0x00000001
+#define IXP4XX_WDT_IRQ_ENABLE        0x00000002
+#define IXP4XX_WDT_COUNT_ENABLE      0x00000004
+
+
+/* Constants to make it easy to access PCI Control/Status registers */
+#define PCI_NP_AD_OFFSET           0x00
+#define PCI_NP_CBE_OFFSET          0x04
+#define PCI_NP_WDATA_OFFSET        0x08
+#define PCI_NP_RDATA_OFFSET        0x0c
+#define PCI_CRP_AD_CBE_OFFSET      0x10
+#define PCI_CRP_WDATA_OFFSET       0x14
+#define PCI_CRP_RDATA_OFFSET       0x18
+#define PCI_CSR_OFFSET             0x1c
+#define PCI_ISR_OFFSET             0x20
+#define PCI_INTEN_OFFSET           0x24
+#define PCI_DMACTRL_OFFSET         0x28
+#define PCI_AHBMEMBASE_OFFSET      0x2c
+#define PCI_AHBIOBASE_OFFSET       0x30
+#define PCI_PCIMEMBASE_OFFSET      0x34
+#define PCI_AHBDOORBELL_OFFSET     0x38
+#define PCI_PCIDOORBELL_OFFSET     0x3C
+#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
+#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
+#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
+#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
+#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
+#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
+
+/* PCI Control/Status Registers */
+#define IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE + (x)))
+
+#define PCI_NP_AD            IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
+#define PCI_NP_CBE           IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
+#define PCI_NP_WDATA         IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
+#define PCI_NP_RDATA         IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
+#define PCI_CRP_AD_CBE       IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
+#define PCI_CRP_WDATA        IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
+#define PCI_CRP_RDATA        IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
+#define PCI_CSR              IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
+#define PCI_ISR              IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
+#define PCI_INTEN            IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
+#define PCI_DMACTRL          IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
+#define PCI_AHBMEMBASE       IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
+#define PCI_AHBIOBASE        IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
+#define PCI_PCIMEMBASE       IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
+#define PCI_AHBDOORBELL      IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
+#define PCI_PCIDOORBELL      IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
+#define PCI_ATPDMA0_AHBADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
+#define PCI_ATPDMA0_PCIADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
+#define PCI_ATPDMA0_LENADDR  IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
+#define PCI_ATPDMA1_AHBADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
+#define PCI_ATPDMA1_PCIADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
+#define PCI_ATPDMA1_LENADDR  IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
+
+/* PCI register values and bit definitions */
+
+/* CSR bit definitions */
+#define PCI_CSR_HOST         0x00000001
+#define PCI_CSR_ARBEN        0x00000002
+#define PCI_CSR_ADS          0x00000004
+#define PCI_CSR_PDS          0x00000008
+#define PCI_CSR_ABE          0x00000010
+#define PCI_CSR_DBT          0x00000020
+#define PCI_CSR_ASE          0x00000100
+#define PCI_CSR_IC           0x00008000
+
+/* ISR (Interrupt status) Register bit definitions */
+#define PCI_ISR_PSE          0x00000001
+#define PCI_ISR_PFE          0x00000002
+#define PCI_ISR_PPE          0x00000004
+#define PCI_ISR_AHBE         0x00000008
+#define PCI_ISR_APDC         0x00000010
+#define PCI_ISR_PADC         0x00000020
+#define PCI_ISR_ADB          0x00000040
+#define PCI_ISR_PDB          0x00000080
+
+/* INTEN (Interrupt Enable) Register bit definitions */
+#define PCI_INTEN_PSE        0x00000001
+#define PCI_INTEN_PFE        0x00000002
+#define PCI_INTEN_PPE        0x00000004
+#define PCI_INTEN_AHBE       0x00000008
+#define PCI_INTEN_APDC       0x00000010
+#define PCI_INTEN_PADC       0x00000020
+#define PCI_INTEN_ADB        0x00000040
+#define PCI_INTEN_PDB        0x00000080
+
+/* Shift value for byte enable on NP cmd/byte enable register */
+#define IXP4XX_PCI_NP_CBE_BESL 4
+
+/* PCI commands supported by NP access unit */
+#define NP_CMD_IOREAD        0x2
+#define NP_CMD_IOWRITE       0x3
+#define NP_CMD_CONFIGREAD    0xA
+#define NP_CMD_CONFIGWRITE   0xB
+#define NP_CMD_MEMREAD       0x6
+#define NP_CMD_MEMWRITE      0x7
+
+/* Constants for CRP access into local config space */
+#define CRP_AD_CBE_BESL      20
+#define CRP_AD_CBE_WRITE     0x00010000
+
+/* USB Device Controller */
+# define IXP4XX_USB_REG(x)   (*((volatile u32 *)(x)))
+
+/* SDRAM Controller registers. */
+#define IXP4XX_SDRAM_CONFIG  IXP4XX_REG(0xCC000000)
+#define IXP4XX_SDRAM_REFRESH IXP4XX_REG(0xCC000004)
+#define IXP4XX_SDRAM_IR      IXP4XX_REG(0xCC000008)
+
+/* "fuse" bits of IXP_EXP_CFG2 */
+/* All IXP4xx CPUs */
+#define IXP4XX_FEATURE_RCOMP            (1 << 0)
+#define IXP4XX_FEATURE_USB_DEVICE       (1 << 1)
+#define IXP4XX_FEATURE_HASH             (1 << 2)
+#define IXP4XX_FEATURE_AES              (1 << 3)
+#define IXP4XX_FEATURE_DES              (1 << 4)
+#define IXP4XX_FEATURE_HDLC             (1 << 5)
+#define IXP4XX_FEATURE_AAL              (1 << 6)
+#define IXP4XX_FEATURE_HSS              (1 << 7)
+#define IXP4XX_FEATURE_UTOPIA           (1 << 8)
+#define IXP4XX_FEATURE_NPEB_ETH0        (1 << 9)
+#define IXP4XX_FEATURE_NPEC_ETH         (1 << 10)
+#define IXP4XX_FEATURE_RESET_NPEA       (1 << 11)
+#define IXP4XX_FEATURE_RESET_NPEB       (1 << 12)
+#define IXP4XX_FEATURE_RESET_NPEC       (1 << 13)
+#define IXP4XX_FEATURE_PCI              (1 << 14)
+#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
+#define IXP4XX_FEATURE_XSCALE_MAX_FREQ  (3 << 22)
+#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP            | \
+			     IXP4XX_FEATURE_USB_DEVICE       | \
+			     IXP4XX_FEATURE_HASH             | \
+			     IXP4XX_FEATURE_AES              | \
+			     IXP4XX_FEATURE_DES              | \
+			     IXP4XX_FEATURE_HDLC             | \
+			     IXP4XX_FEATURE_AAL              | \
+			     IXP4XX_FEATURE_HSS              | \
+			     IXP4XX_FEATURE_UTOPIA           | \
+			     IXP4XX_FEATURE_NPEB_ETH0        | \
+			     IXP4XX_FEATURE_NPEC_ETH         | \
+			     IXP4XX_FEATURE_RESET_NPEA       | \
+			     IXP4XX_FEATURE_RESET_NPEB       | \
+			     IXP4XX_FEATURE_RESET_NPEC       | \
+			     IXP4XX_FEATURE_PCI              | \
+			     IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
+			     IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
+/* IXP43x/46x CPUs */
+#define IXP4XX_FEATURE_ECC_TIMESYNC     (1 << 15)
+#define IXP4XX_FEATURE_USB_HOST         (1 << 18)
+#define IXP4XX_FEATURE_NPEA_ETH         (1 << 19)
+#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK             | \
+			     IXP4XX_FEATURE_ECC_TIMESYNC     | \
+			     IXP4XX_FEATURE_USB_HOST         | \
+			     IXP4XX_FEATURE_NPEA_ETH)
+
+/* IXP46x CPU (including IXP455) only */
+#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3  (1 << 20)
+#define IXP4XX_FEATURE_RSA              (1 << 21)
+#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK             | \
+			     IXP4XX_FEATURE_NPEB_ETH_1_TO_3  | \
+			     IXP4XX_FEATURE_RSA)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/npe.h b/arch/arm/mach-ixp4xx/include/mach/npe.h
new file mode 100644
index 0000000..18bd01b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/npe.h
@@ -0,0 +1,30 @@
+#ifndef __IXP4XX_NPE_H
+#define __IXP4XX_NPE_H
+
+#include <common.h>
+
+#define NPE_NAME_LENGTH 5
+
+struct npe_regs {
+	u32 exec_addr, exec_data, exec_status_cmd, exec_count;
+	u32 action_points[4];
+	u32 watchpoint_fifo, watch_count;
+	u32 profile_count;
+	u32 messaging_status, messaging_control;
+	u32 mailbox_status, /*messaging_*/ in_out_fifo;
+};
+
+struct npe {
+	struct npe_regs *regs;
+	int id, valid;
+	const char name[NPE_NAME_LENGTH + 1];
+};
+
+int npe_running(struct npe *npe);
+int npe_send_message(struct npe *npe, const void *msg, const char *what);
+int npe_recv_message(struct npe *npe, void *msg, const char *what);
+int npe_send_recv_message(struct npe *npe, void *msg, const char *what);
+int npe_load_firmware(struct npe *npe);
+struct npe *npe_request(int id);
+
+#endif /* __IXP4XX_NPE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
new file mode 100644
index 0000000..1df4aa4
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -0,0 +1,15 @@
+#include <asm/types.h>
+
+#define IXP4XX_ETH_NPEA 0x00
+#define IXP4XX_ETH_NPEB 0x10
+#define IXP4XX_ETH_NPEC 0x20
+
+/* Information about built-in Ethernet MAC interfaces */
+struct eth_plat_info {
+	void *regs;
+	u8 npe;
+	u8 phy; /* MII PHY ID, 0 - 31 */
+	u8 rxq; /* configurable, currently 0 - 31 only */
+	u8 txreadyq;
+	u8 hwaddr[6];
+};
diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
new file mode 100644
index 0000000..4e9b8d4
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef IXP4XX_QMGR_H
+#define IXP4XX_QMGR_H
+
+#include <common.h>
+#include <mach/ixp4xx-regs.h>
+#include <asm/io.h>
+
+#define DEBUG_QMGR       0
+
+#define HALF_QUEUES     32
+#define QUEUES          64
+#define MAX_QUEUE_LENGTH 4 /* in dwords */
+
+#define QUEUE_STAT1_EMPTY               1 /* queue status bits */
+#define QUEUE_STAT1_NEARLY_EMPTY        2
+#define QUEUE_STAT1_NEARLY_FULL         4
+#define QUEUE_STAT1_FULL                8
+#define QUEUE_STAT2_UNDERFLOW           1
+#define QUEUE_STAT2_OVERFLOW            2
+
+#define QUEUE_WATERMARK_0_ENTRIES       0
+#define QUEUE_WATERMARK_1_ENTRY         1
+#define QUEUE_WATERMARK_2_ENTRIES       2
+#define QUEUE_WATERMARK_4_ENTRIES       3
+#define QUEUE_WATERMARK_8_ENTRIES       4
+#define QUEUE_WATERMARK_16_ENTRIES      5
+#define QUEUE_WATERMARK_32_ENTRIES      6
+#define QUEUE_WATERMARK_64_ENTRIES      7
+
+/* queue interrupt request conditions */
+#define QUEUE_IRQ_SRC_EMPTY             0
+#define QUEUE_IRQ_SRC_NEARLY_EMPTY      1
+#define QUEUE_IRQ_SRC_NEARLY_FULL       2
+#define QUEUE_IRQ_SRC_FULL              3
+#define QUEUE_IRQ_SRC_NOT_EMPTY         4
+#define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY  5
+#define QUEUE_IRQ_SRC_NOT_NEARLY_FULL   6
+#define QUEUE_IRQ_SRC_NOT_FULL          7
+
+struct qmgr_regs {
+	u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */
+	u32 stat1[4];         /* 0x400 - 0x40F */
+	u32 stat2[2];         /* 0x410 - 0x417 */
+	u32 statne_h;         /* 0x418 - queue nearly empty */
+	u32 statf_h;          /* 0x41C - queue full */
+	u32 irqsrc[4];        /* 0x420 - 0x42F IRC source */
+	u32 irqen[2];         /* 0x430 - 0x437 IRQ enabled */
+	u32 irqstat[2];       /* 0x438 - 0x43F - IRQ access only */
+	u32 reserved[1776];
+	u32 sram[2048];       /* 0x2000 - 0x3FFF - config and buffer */
+};
+
+static const struct qmgr_regs *qmgr_regs = (struct qmgr_regs *)IXP4XX_QMGR_BASE;
+
+void qmgr_set_irq(unsigned int queue, int src,
+		  void (*handler)(void *pdev), void *pdev);
+void qmgr_enable_irq(unsigned int queue);
+void qmgr_disable_irq(unsigned int queue);
+
+/* request_ and release_queue() must be called from non-IRQ context */
+
+#if DEBUG_QMGR
+extern char qmgr_queue_descs[HALF_QUEUES][32];
+
+void qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			unsigned int nearly_empty_watermark,
+			unsigned int nearly_full_watermark,
+			const char *desc_format, const char* name);
+#else
+void __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			  unsigned int nearly_empty_watermark,
+			  unsigned int nearly_full_watermark);
+#define qmgr_request_queue(queue, len, nearly_empty_watermark,       \
+			   nearly_full_watermark, desc_format, name) \
+	__qmgr_request_queue(queue, len, nearly_empty_watermark,     \
+			     nearly_full_watermark)
+#endif
+
+void qmgr_release_queue(unsigned int queue);
+
+
+static inline void qmgr_put_entry(unsigned int queue, u32 val)
+{
+#if DEBUG_QMGR
+	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+	fprintf(stderr, "Queue %s(%i) put %X\n",
+		qmgr_queue_descs[queue], queue, val);
+#endif
+	__raw_writel(val, &qmgr_regs->acc[queue][0]);
+}
+
+static inline u32 qmgr_get_entry(unsigned int queue)
+{
+	u32 val;
+	val = __raw_readl(&qmgr_regs->acc[queue][0]);
+#if DEBUG_QMGR
+	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+	fprintf(stderr, "Queue %s(%i) get %X\n",
+		qmgr_queue_descs[queue], queue, val);
+#endif
+	return val;
+}
+
+static inline int __qmgr_get_stat1(unsigned int queue)
+{
+	return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
+		>> ((queue & 7) << 2)) & 0xF;
+}
+
+/**
+ * qmgr_stat_empty() - checks if a hardware queue is empty
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is empty.
+ */
+static inline int qmgr_stat_empty(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
+}
+
+/**
+ * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is below low watermark.
+ */
+static inline int qmgr_stat_below_low_watermark(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
+}
+
+/**
+ * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is above high watermark
+ */
+static inline int qmgr_stat_above_high_watermark(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
+}
+
+/**
+ * qmgr_stat_full() - checks if a hardware queue is full
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is full.
+ */
+static inline int qmgr_stat_full(unsigned int queue)
+{
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
+}
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/lowlevel_init.S b/arch/arm/mach-ixp4xx/lowlevel_init.S
new file mode 100644
index 0000000..a4e93ef
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/lowlevel_init.S
@@ -0,0 +1,17 @@
+#include <mach/ixp4xx-regs.h>
+
+	.section ".text_bare_init", "ax"
+
+	.globl arch_init_lowlevel
+arch_init_lowlevel:
+	ldr r0, cfg
+	ldr r1, [r0]
+	and r1, r1, #~0x80000000 /* unmap EXP bus from 0x0 */
+	str r1, [r0]
+
+	/* return to ROM */
+	orr lr, #0x50000000
+	mov pc, lr
+
+cfg:
+	.word IXP4XX_EXP_CFG0
diff --git a/arch/arm/mach-ixp4xx/npe.c b/arch/arm/mach-ixp4xx/npe.c
new file mode 100644
index 0000000..a8ddd5a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/npe.c
@@ -0,0 +1,668 @@
+/*
+ * Intel IXP4xx Network Processor Engine driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fs.h>
+#include <init.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <mach/ixp4xx-regs.h>
+#include <mach/cpu.h>
+#include <mach/npe.h>
+
+#define DEBUG_MSG                      0
+#define DEBUG_FW                       0
+
+#define NPE_COUNT                      3
+#define MAX_RETRIES                    1000  /* microseconds */
+#define NPE_42X_DATA_SIZE              0x800 /* in dwords */
+#define NPE_46X_DATA_SIZE              0x1000
+#define NPE_A_42X_INSTR_SIZE           0x1000
+#define NPE_B_AND_C_42X_INSTR_SIZE     0x800
+#define NPE_46X_INSTR_SIZE             0x1000
+#define REGS_SIZE                      0x1000
+
+#define NPE_PHYS_REG                   32
+
+#define FW_MAGIC                       0xFEEDF00D
+#define FW_BLOCK_TYPE_INSTR            0x0
+#define FW_BLOCK_TYPE_DATA             0x1
+#define FW_BLOCK_TYPE_EOF              0xF
+
+/* NPE exec status (read) and command (write) */
+#define CMD_NPE_STEP                   0x01
+#define CMD_NPE_START                  0x02
+#define CMD_NPE_STOP                   0x03
+#define CMD_NPE_CLR_PIPE               0x04
+#define CMD_CLR_PROFILE_CNT            0x0C
+#define CMD_RD_INS_MEM                 0x10 /* instruction memory */
+#define CMD_WR_INS_MEM                 0x11
+#define CMD_RD_DATA_MEM                0x12 /* data memory */
+#define CMD_WR_DATA_MEM                0x13
+#define CMD_RD_ECS_REG                 0x14 /* exec access register */
+#define CMD_WR_ECS_REG                 0x15
+
+#define STAT_RUN                       0x80000000
+#define STAT_STOP                      0x40000000
+#define STAT_CLEAR                     0x20000000
+#define STAT_ECS_K                     0x00800000 /* pipeline clean */
+
+#define NPE_STEVT                      0x1B
+#define NPE_STARTPC                    0x1C
+#define NPE_REGMAP                     0x1E
+#define NPE_CINDEX                     0x1F
+
+#define INSTR_WR_REG_SHORT             0x0000C000
+#define INSTR_WR_REG_BYTE              0x00004000
+#define INSTR_RD_FIFO                  0x0F888220
+#define INSTR_RESET_MBOX               0x0FAC8210
+
+#define ECS_BG_CTXT_REG_0              0x00 /* Background Executing Context */
+#define ECS_BG_CTXT_REG_1              0x01 /* Stack level */
+#define ECS_BG_CTXT_REG_2              0x02
+#define ECS_PRI_1_CTXT_REG_0           0x04 /* Priority 1 Executing Context */
+#define ECS_PRI_1_CTXT_REG_1           0x05 /* Stack level */
+#define ECS_PRI_1_CTXT_REG_2           0x06
+#define ECS_PRI_2_CTXT_REG_0           0x08 /* Priority 2 Executing Context */
+#define ECS_PRI_2_CTXT_REG_1           0x09 /* Stack level */
+#define ECS_PRI_2_CTXT_REG_2           0x0A
+#define ECS_DBG_CTXT_REG_0             0x0C /* Debug Executing Context */
+#define ECS_DBG_CTXT_REG_1             0x0D /* Stack level */
+#define ECS_DBG_CTXT_REG_2             0x0E
+#define ECS_INSTRUCT_REG               0x11 /* NPE Instruction Register */
+
+#define ECS_REG_0_ACTIVE               0x80000000 /* all levels */
+#define ECS_REG_0_NEXTPC_MASK          0x1FFF0000 /* BG/PRI1/PRI2 levels */
+#define ECS_REG_0_LDUR_BITS            8
+#define ECS_REG_0_LDUR_MASK            0x00000700 /* all levels */
+#define ECS_REG_1_CCTXT_BITS           16
+#define ECS_REG_1_CCTXT_MASK           0x000F0000 /* all levels */
+#define ECS_REG_1_SELCTXT_BITS         0
+#define ECS_REG_1_SELCTXT_MASK         0x0000000F /* all levels */
+#define ECS_DBG_REG_2_IF               0x00100000 /* debug level */
+#define ECS_DBG_REG_2_IE               0x00080000 /* debug level */
+
+/* NPE watchpoint_fifo register bit */
+#define WFIFO_VALID                    0x80000000
+
+/* NPE messaging_status register bit definitions */
+#define MSGSTAT_OFNE  0x00010000 /* OutFifoNotEmpty */
+#define MSGSTAT_IFNF  0x00020000 /* InFifoNotFull */
+#define MSGSTAT_OFNF  0x00040000 /* OutFifoNotFull */
+#define MSGSTAT_IFNE  0x00080000 /* InFifoNotEmpty */
+#define MSGSTAT_MBINT 0x00100000 /* Mailbox interrupt */
+#define MSGSTAT_IFINT 0x00200000 /* InFifo interrupt */
+#define MSGSTAT_OFINT 0x00400000 /* OutFifo interrupt */
+#define MSGSTAT_WFINT 0x00800000 /* WatchFifo interrupt */
+
+/* NPE messaging_control register bit definitions */
+#define MSGCTL_OUT_FIFO       0x00010000 /* enable output FIFO */
+#define MSGCTL_IN_FIFO        0x00020000 /* enable input FIFO */
+#define MSGCTL_OUT_FIFO_WRITE 0x01000000 /* enable FIFO + WRITE */
+#define MSGCTL_IN_FIFO_WRITE  0x02000000
+
+/* NPE mailbox_status value for reset */
+#define RESET_MBOX_STAT          0x0000F0F0
+
+#define print_npe(npe, fmt, ...) fprintf(stderr, "%s: " fmt, npe->name, ## __VA_ARGS__)
+
+#if DEBUG_MSG
+#define debug_msg(npe, fmt, ...) print_npe(npe, fmt, ## __VA_ARGS__)
+#else
+#define debug_msg(npe, fmt, ...)
+#endif
+
+static struct {
+	u32 reg, val;
+} ecs_reset[] = {
+	{ECS_BG_CTXT_REG_0,    0xA0000000},
+	{ECS_BG_CTXT_REG_1,    0x01000000},
+	{ECS_BG_CTXT_REG_2,    0x00008000},
+	{ECS_PRI_1_CTXT_REG_0, 0x20000080},
+	{ECS_PRI_1_CTXT_REG_1, 0x01000000},
+	{ECS_PRI_1_CTXT_REG_2, 0x00008000},
+	{ECS_PRI_2_CTXT_REG_0, 0x20000080},
+	{ECS_PRI_2_CTXT_REG_1, 0x01000000},
+	{ECS_PRI_2_CTXT_REG_2, 0x00008000},
+	{ECS_DBG_CTXT_REG_0,   0x20000000},
+	{ECS_DBG_CTXT_REG_1,   0x00000000},
+	{ECS_DBG_CTXT_REG_2,   0x001E0000},
+	{ECS_INSTRUCT_REG,     0x1003C00F},
+};
+
+static struct npe npe_tab[NPE_COUNT] = {
+	{
+		.regs = (struct npe_regs *)IXP4XX_NPEA_BASE,
+		.id = 0,
+		.name = "NPE-A",
+	}, {
+		.regs = (struct npe_regs *)IXP4XX_NPEB_BASE,
+		.id = 1,
+		.name = "NPE-B",
+	}, {
+		.regs = (struct npe_regs *)IXP4XX_NPEC_BASE,
+		.id = 2,
+		.name = "NPE-C",
+	}
+};
+
+int npe_running(struct npe *npe)
+{
+	return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
+}
+
+static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
+{
+	__raw_writel(data, &npe->regs->exec_data);
+	__raw_writel(addr, &npe->regs->exec_addr);
+	__raw_writel(cmd, &npe->regs->exec_status_cmd);
+}
+
+static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
+{
+	__raw_writel(addr, &npe->regs->exec_addr);
+	__raw_writel(cmd, &npe->regs->exec_status_cmd);
+	/* Iintroduce extra read cycles after issuing read command to NPE
+	   so that we read the register after the NPE has updated it.
+	   This is to overcome race condition between XScale and NPE */
+	__raw_readl(&npe->regs->exec_data);
+	__raw_readl(&npe->regs->exec_data);
+	return __raw_readl(&npe->regs->exec_data);
+}
+
+static void npe_clear_active(struct npe *npe, u32 reg)
+{
+	u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
+	npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
+}
+
+static void npe_start(struct npe *npe)
+{
+	/* ensure only Background Context Stack Level is active */
+	npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
+	npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
+	npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
+
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+	__raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
+}
+
+static void npe_stop(struct npe *npe)
+{
+	__raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
+}
+
+static int npe_debug_instr(struct npe *npe, u32 instr, u32 ctx, u32 ldur)
+{
+	u32 wc;
+	int i;
+
+	/* set the Active bit, and the LDUR, in the debug level */
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
+		      ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
+
+	/* set CCTXT at ECS DEBUG L3 to specify in which context to execute
+	   the instruction, and set SELCTXT at ECS DEBUG Level to specify
+	   which context store to access.
+	   Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
+	*/
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
+		      (ctx << ECS_REG_1_CCTXT_BITS) |
+		      (ctx << ECS_REG_1_SELCTXT_BITS));
+
+	/* clear the pipeline */
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+
+	/* load NPE instruction into the instruction register */
+	npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
+
+	/* we need this value later to wait for completion of NPE execution
+	   step */
+	wc = __raw_readl(&npe->regs->watch_count);
+
+	/* issue a Step One command via the Execution Control register */
+	__raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
+
+	/* Watch Count register increments when NPE completes an instruction */
+	for (i = 0; i < MAX_RETRIES; i++) {
+		if (wc != __raw_readl(&npe->regs->watch_count))
+			return 0;
+		udelay(1);
+	}
+
+	print_npe(npe, "reset: npe_debug_instr(): timeout\n");
+	return -ETIMEDOUT;
+}
+
+static int npe_logical_reg_write8(struct npe *npe, u32 addr, u8 val, u32 ctx)
+{
+	/* here we build the NPE assembler instruction: mov8 d0, #0 */
+	u32 instr = INSTR_WR_REG_BYTE | /* OpCode */
+		addr << 9 |             /* base Operand */
+		(val & 0x1F) << 4 |     /* lower 5 bits to immediate data */
+		(val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
+	return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
+}
+
+static int npe_logical_reg_write16(struct npe *npe, u32 addr, u16 val, u32 ctx)
+{
+	/* here we build the NPE assembler instruction: mov16 d0, #0 */
+	u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
+		addr << 9 |             /* base Operand */
+		(val & 0x1F) << 4 |     /* lower 5 bits to immediate data */
+		(val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
+	return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
+}
+
+static int npe_logical_reg_write32(struct npe *npe, u32 addr, u32 val, u32 ctx)
+{
+	/* write in 16 bit steps first the high and then the low value */
+	if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
+		return -ETIMEDOUT;
+	return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
+}
+
+static int npe_reset(struct npe *npe)
+{
+	u32 val, ctl, exec_count, ctx_reg2;
+	int i;
+
+	ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
+		0x3F3FFFFF;
+
+	/* disable parity interrupt */
+	__raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
+
+	/* pre exec - debug instruction */
+	/* turn off the halt bit by clearing Execution Count register. */
+	exec_count = __raw_readl(&npe->regs->exec_count);
+	__raw_writel(0, &npe->regs->exec_count);
+	/* ensure that IF and IE are on (temporarily), so that we don't end up
+	   stepping forever */
+	ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
+		      ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
+
+	/* clear the FIFOs */
+	while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
+		;
+	while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
+		/* read from the outFIFO until empty */
+		print_npe(npe, "npe_reset: read FIFO = 0x%X\n",
+			  __raw_readl(&npe->regs->in_out_fifo));
+
+	while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
+		/* step execution of the NPE intruction to read inFIFO using
+		   the Debug Executing Context stack */
+		if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
+			return -ETIMEDOUT;
+
+	/* reset the mailbox reg from the XScale side */
+	__raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
+	/* from NPE side */
+	if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
+		return -ETIMEDOUT;
+
+	/* Reset the physical registers in the NPE register file */
+	for (val = 0; val < NPE_PHYS_REG; val++) {
+		if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
+			return -ETIMEDOUT;
+		/* address is either 0 or 4 */
+		if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
+			return -ETIMEDOUT;
+	}
+
+	/* Reset the context store = each context's Context Store registers */
+
+	/* Context 0 has no STARTPC. Instead, this value is used to set NextPC
+	   for Background ECS, to set where NPE starts executing code */
+	val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
+	val &= ~ECS_REG_0_NEXTPC_MASK;
+	val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
+	npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
+
+	for (i = 0; i < 16; i++) {
+		if (i) { /* Context 0 has no STEVT nor STARTPC */
+			/* STEVT = off, 0x80 */
+			if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
+				return -ETIMEDOUT;
+			if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
+				return -ETIMEDOUT;
+		}
+		/* REGMAP = d0->p0, d8->p2, d16->p4 */
+		if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
+			return -ETIMEDOUT;
+		if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
+			return -ETIMEDOUT;
+	}
+
+	/* post exec */
+	/* clear active bit in debug level */
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
+	/* clear the pipeline */
+	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+	/* restore previous values */
+	__raw_writel(exec_count, &npe->regs->exec_count);
+	npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
+
+	/* write reset values to Execution Context Stack registers */
+	for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
+		npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
+			      ecs_reset[val].val);
+
+	/* clear the profile counter */
+	__raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
+
+	__raw_writel(0, &npe->regs->exec_count);
+	__raw_writel(0, &npe->regs->action_points[0]);
+	__raw_writel(0, &npe->regs->action_points[1]);
+	__raw_writel(0, &npe->regs->action_points[2]);
+	__raw_writel(0, &npe->regs->action_points[3]);
+	__raw_writel(0, &npe->regs->watch_count);
+
+	val = ixp4xx_read_feature_bits();
+	/* reset the NPE */
+	ixp4xx_write_feature_bits(val &
+				  ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
+	/* deassert reset */
+	ixp4xx_write_feature_bits(val |
+				  (IXP4XX_FEATURE_RESET_NPEA << npe->id));
+	for (i = 0; i < MAX_RETRIES; i++) {
+		if (ixp4xx_read_feature_bits() &
+		    (IXP4XX_FEATURE_RESET_NPEA << npe->id))
+			break; /* NPE is back alive */
+		udelay(1);
+	}
+	if (i == MAX_RETRIES)
+		return -ETIMEDOUT;
+
+	npe_stop(npe);
+
+	/* restore NPE configuration bus Control Register - parity settings */
+	__raw_writel(ctl, &npe->regs->messaging_control);
+	return 0;
+}
+
+
+int npe_send_message(struct npe *npe, const void *msg, const char *what)
+{
+	const u32 *send = msg;
+	int cycles = 0;
+
+	debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
+		  what, send[0], send[1]);
+
+	if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
+		debug_msg(npe, "NPE input FIFO not empty\n");
+		return -EIO;
+	}
+
+	__raw_writel(send[0], &npe->regs->in_out_fifo);
+
+	if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
+		debug_msg(npe, "NPE input FIFO full\n");
+		return -EIO;
+	}
+
+	__raw_writel(send[1], &npe->regs->in_out_fifo);
+
+	while ((cycles < MAX_RETRIES) &&
+	       (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
+		udelay(1);
+		cycles++;
+	}
+
+	if (cycles == MAX_RETRIES) {
+		debug_msg(npe, "Timeout sending message\n");
+		return -ETIMEDOUT;
+	}
+
+#if DEBUG_MSG > 1
+	debug_msg(npe, "Sending a message took %i cycles\n", cycles);
+#endif
+	return 0;
+}
+
+int npe_recv_message(struct npe *npe, void *msg, const char *what)
+{
+	u32 *recv = msg;
+	int cycles = 0, cnt = 0;
+
+	debug_msg(npe, "Trying to receive message %s\n", what);
+
+	while (cycles < MAX_RETRIES) {
+		if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
+			recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
+			if (cnt == 2)
+				break;
+		} else {
+			udelay(1);
+			cycles++;
+		}
+	}
+
+	switch(cnt) {
+	case 1:
+		debug_msg(npe, "Received [%08X]\n", recv[0]);
+		break;
+	case 2:
+		debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
+		break;
+	}
+
+	if (cycles == MAX_RETRIES) {
+		debug_msg(npe, "Timeout waiting for message\n");
+		return -ETIMEDOUT;
+	}
+
+#if DEBUG_MSG > 1
+	debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
+#endif
+	return 0;
+}
+
+int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
+{
+	int result;
+	u32 *send = msg, recv[2];
+
+	if ((result = npe_send_message(npe, msg, what)) != 0)
+		return result;
+	if ((result = npe_recv_message(npe, recv, what)) != 0)
+		return result;
+
+	if ((recv[0] != send[0]) || (recv[1] != send[1])) {
+		debug_msg(npe, "Message %s: unexpected message received\n",
+			  what);
+		return -EIO;
+	}
+	return 0;
+}
+
+
+int npe_load_firmware(struct npe *npe)
+{
+	struct dl_block {
+		u32 type;
+		u32 offset;
+	} *blk;
+
+	struct dl_image {
+		u32 magic;
+		u32 id;
+		u32 size;
+		union {
+			u32 data[0];
+			struct dl_block blocks[0];
+		};
+	} *image;
+
+	struct dl_codeblock {
+		u32 npe_addr;
+		u32 size;
+		u32 data[0];
+	} *cb;
+
+	int i, j, err, data_size, instr_size, blocks, table_end;
+	u32 cmd;
+	char name[5 /* "/dev/" */ + NPE_NAME_LENGTH + 1 /* NUL */];
+	size_t image_size;
+
+	sprintf(name, "/dev/%s", npe->name);
+	if (!(image = read_file(name, &image_size))) {
+		print_npe(npe, "bad or missing microcode file %s", name);
+		return -EIO;
+	}
+
+	err = -EINVAL;
+	if (image_size < sizeof(struct dl_image)) {
+		print_npe(npe, "incomplete microcode file %s\n", name);
+		goto err;
+	}
+
+#if DEBUG_FW
+	print_npe(npe, "microcode: %08X %08X %08X (0x%X bytes)\n",
+		  image->magic, image->id, image->size, image->size * 4);
+#endif
+
+	if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
+		image->id = swab32(image->id);
+		image->size = swab32(image->size);
+	} else if (image->magic != FW_MAGIC) {
+		print_npe(npe, "bad microcode file %s magic: 0x%X\n", name, image->magic);
+		goto err;
+	}
+	if ((image->size * 4 + sizeof(struct dl_image)) > image_size) {
+		print_npe(npe, "incomplete microcode file %s\n", name);
+		goto err;
+	}
+	if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
+		print_npe(npe, "NPE ID mismatch in microcode file %s\n", name);
+		goto err;
+	}
+	if (image->magic == swab32(FW_MAGIC))
+		for (i = 0; i < image->size; i++)
+			image->data[i] = swab32(image->data[i]);
+
+	if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
+		print_npe(npe, "IXP43x/IXP46x microcode ignored on IXP42x\n");
+		goto err;
+	}
+
+	if (npe_running(npe)) {
+		print_npe(npe, "unable to load microcode file %s, NPE is already running\n", name);
+		err = -EBUSY;
+		goto err;
+	}
+
+	if (cpu_is_ixp42x()) {
+		if (!npe->id)
+			instr_size = NPE_A_42X_INSTR_SIZE;
+		else
+			instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
+		data_size = NPE_42X_DATA_SIZE;
+	} else {
+		instr_size = NPE_46X_INSTR_SIZE;
+		data_size = NPE_46X_DATA_SIZE;
+	}
+
+	for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
+	     blocks++)
+		if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
+			break;
+	if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
+		print_npe(npe, "microcode EOF block marker not found\n");
+		goto err;
+	}
+
+#if DEBUG_FW
+	print_npe(npe, "%i microcode blocks found\n", blocks);
+#endif
+
+	table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
+	for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
+		if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
+		    || blk->offset < table_end) {
+			print_npe(npe, "invalid offset 0x%X of "
+				  "microcode block #%i\n", blk->offset, i);
+			goto err;
+		}
+
+		cb = (struct dl_codeblock*)&image->data[blk->offset];
+		if (blk->type == FW_BLOCK_TYPE_INSTR) {
+			if (cb->npe_addr + cb->size > instr_size)
+				goto too_big;
+			cmd = CMD_WR_INS_MEM;
+		} else if (blk->type == FW_BLOCK_TYPE_DATA) {
+			if (cb->npe_addr + cb->size > data_size)
+				goto too_big;
+			cmd = CMD_WR_DATA_MEM;
+		} else {
+			print_npe(npe, "invalid microcode block #%i type 0x%X\n",
+				  i, blk->type);
+			goto err;
+		}
+		if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
+			print_npe(npe, "microcode block #%i doesn't "
+				  "fit in microcode image: type %c, start 0x%X,"
+				  " length 0x%X\n", i,
+				  blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
+				  cb->npe_addr, cb->size);
+			goto err;
+		}
+
+		for (j = 0; j < cb->size; j++)
+			npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
+	}
+
+	npe_start(npe);
+	if (!npe_running(npe))
+		print_npe(npe, "unable to start\n");
+	free(image);
+	return 0;
+
+too_big:
+	print_npe(npe, "microcode block #%i doesn't fit in NPE "
+		  "memory: type %c, start 0x%X, length 0x%X\n", i,
+		  blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
+		  cb->npe_addr, cb->size);
+err:
+	free(image);
+	return err;
+}
+
+
+struct npe *npe_request(int id)
+{
+	if (id < NPE_COUNT)
+		if (npe_tab[id].valid)
+			return &npe_tab[id];
+	return NULL;
+}
+
+static int __init npe_init(void)
+{
+	int i;
+
+	for (i = 0; i < NPE_COUNT; i++) {
+		struct npe *npe = &npe_tab[i];
+		if (!(ixp4xx_read_feature_bits() & (IXP4XX_FEATURE_RESET_NPEA << i)))
+			continue; /* NPE already disabled or not present */
+		if (npe_reset(npe))
+			continue;
+		npe->valid = 1;
+	}
+	return 0;
+}
+
+coredevice_initcall(npe_init);
diff --git a/arch/arm/mach-ixp4xx/qmgr.c b/arch/arm/mach-ixp4xx/qmgr.c
new file mode 100644
index 0000000..81b6522
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/qmgr.c
@@ -0,0 +1,259 @@
+/*
+ * Intel IXP4xx Queue Manager driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#include <init.h>
+#include <errno.h>
+#include <mach/qmgr.h>
+
+static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
+
+#if DEBUG_QMGR
+char qmgr_queue_descs[HALF_QUEUES][32];
+#endif
+
+#ifdef CONFIG_USE_IRQ
+
+static void (*irq_handlers[HALF_QUEUES])(void *pdev);
+static void *irq_pdevs[HALF_QUEUES];
+
+void qmgr_set_irq(unsigned int queue, int src,
+		  void (*handler)(void *pdev), void *pdev)
+{
+	const u32 *reg;
+	int bit;
+	BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL);
+	reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */
+	bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
+	__raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit), reg);
+
+	irq_handlers[queue] = handler;
+	irq_pdevs[queue] = pdev;
+}
+
+
+static void qmgr_irq1_a0(void *data)
+{
+	int i;
+	u32 en_bitmap, src, stat;
+
+	/* ACK - it may clear any bits so don't rely on it */
+	__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]);
+
+	en_bitmap = qmgr_regs->irqen[0];
+	while (en_bitmap) {
+		i = fls(en_bitmap) - 1; /* number of the last "low" queue */
+		en_bitmap &= ~BIT(i);
+		src = qmgr_regs->irqsrc[i >> 3];
+		stat = qmgr_regs->stat1[i >> 3];
+		if (src & 4) /* the IRQ condition is inverted */
+			stat = ~stat;
+		if (stat & BIT(src & 3))
+			irq_handlers[i](irq_pdevs[i]);
+	}
+}
+
+
+static void qmgr_irq1(void *data)
+{
+	int i;
+	u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[0]);
+
+	if (!req_bitmap)
+		return;
+	__raw_writel(req_bitmap, &qmgr_regs->irqstat[0]); /* ACK */
+
+	while (req_bitmap) {
+		i = fls(req_bitmap) - 1; /* number of the last queue */
+		req_bitmap &= ~BIT(i);
+		irq_handlers[i](irq_pdevs[i]);
+	}
+}
+
+
+void qmgr_enable_irq(unsigned int queue)
+{
+	u32 mask = 1 << queue;
+
+	__raw_writel(__raw_readl(&qmgr_regs->irqen[0]) | mask,
+		     &qmgr_regs->irqen[0]);
+}
+
+void qmgr_disable_irq(unsigned int queue)
+{
+	u32 mask = 1 << queue;
+
+	__raw_writel(__raw_readl(&qmgr_regs->irqen[0]) & ~mask,
+		     &qmgr_regs->irqen[0]);
+	__raw_writel(mask, &qmgr_regs->irqstat[0]); /* clear */
+}
+
+#endif /* CONFIG_USE_IRQ */
+
+static inline void shift_mask(u32 *mask)
+{
+	mask[3] = mask[3] << 1 | mask[2] >> 31;
+	mask[2] = mask[2] << 1 | mask[1] >> 31;
+	mask[1] = mask[1] << 1 | mask[0] >> 31;
+	mask[0] <<= 1;
+}
+
+#if DEBUG_QMGR
+void qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			unsigned int nearly_empty_watermark,
+			unsigned int nearly_full_watermark,
+			const char *desc_format, const char* name)
+#else
+void __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+			  unsigned int nearly_empty_watermark,
+			  unsigned int nearly_full_watermark)
+#endif
+{
+	u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
+
+	BUG_ON(queue >= HALF_QUEUES);
+	BUG_ON((nearly_empty_watermark | nearly_full_watermark) & ~7);
+
+	switch (len) {
+	case  16:
+		cfg = 0 << 24;
+		mask[0] = 0x1;
+		break;
+	case  32:
+		cfg = 1 << 24;
+		mask[0] = 0x3;
+		break;
+	case  64:
+		cfg = 2 << 24;
+		mask[0] = 0xF;
+		break;
+	case 128:
+		cfg = 3 << 24;
+		mask[0] = 0xFF;
+		break;
+	default:
+		BUG();
+	}
+
+	cfg |= nearly_empty_watermark << 26;
+	cfg |= nearly_full_watermark << 29;
+	len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */
+	mask[1] = mask[2] = mask[3] = 0;
+
+	BUG_ON(__raw_readl(&qmgr_regs->sram[queue]));
+
+	while (1) {
+		if (!(used_sram_bitmap[0] & mask[0]) &&
+		    !(used_sram_bitmap[1] & mask[1]) &&
+		    !(used_sram_bitmap[2] & mask[2]) &&
+		    !(used_sram_bitmap[3] & mask[3]))
+			break; /* found free space */
+
+		addr++;
+		shift_mask(mask);
+		if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
+			fprintf(stderr, "qmgr: no free SRAM space for"
+				" queue %i\n", queue);
+			BUG();
+		}
+	}
+
+	used_sram_bitmap[0] |= mask[0];
+	used_sram_bitmap[1] |= mask[1];
+	used_sram_bitmap[2] |= mask[2];
+	used_sram_bitmap[3] |= mask[3];
+	__raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
+#if DEBUG_QMGR
+	/* no snprintf() */
+	sprintf(qmgr_queue_descs[queue], desc_format, name);
+	fprintf(stderr, "qmgr: requested queue %s(%i) addr = 0x%02X\n",
+		qmgr_queue_descs[queue], queue, addr);
+#endif
+}
+
+void qmgr_release_queue(unsigned int queue)
+{
+	u32 cfg, addr, mask[4];
+
+	BUG_ON(queue >= HALF_QUEUES); /* not in valid range */
+
+	cfg = __raw_readl(&qmgr_regs->sram[queue]);
+	addr = (cfg >> 14) & 0xFF;
+
+	BUG_ON(!addr); /* not requested */
+
+	switch ((cfg >> 24) & 3) {
+	case 0: mask[0] = 0x1; break;
+	case 1: mask[0] = 0x3; break;
+	case 2: mask[0] = 0xF; break;
+	case 3: mask[0] = 0xFF; break;
+	}
+
+	mask[1] = mask[2] = mask[3] = 0;
+
+	while (addr--)
+		shift_mask(mask);
+
+#if DEBUG_QMGR
+	fprintf(stderr, "qmgr: releasing queue %s(%i)\n",
+		qmgr_queue_descs[queue], queue);
+	qmgr_queue_descs[queue][0] = '\x0';
+#endif
+	__raw_writel(0, &qmgr_regs->sram[queue]);
+
+	used_sram_bitmap[0] &= ~mask[0];
+	used_sram_bitmap[1] &= ~mask[1];
+	used_sram_bitmap[2] &= ~mask[2];
+	used_sram_bitmap[3] &= ~mask[3];
+#ifdef CONFIG_USE_IRQ
+	irq_handlers[queue] = NULL; /* catch IRQ bugs */
+#endif
+
+	while ((addr = qmgr_get_entry(queue)))
+		fprintf(stderr, "qmgr: released queue %i not empty: 0x%08X\n",
+			queue, addr);
+}
+
+static int __init qmgr_init(void)
+{
+	int i;
+#ifdef CONFIG_USE_IRQ
+	interrupt_handler_t *handler;
+#endif
+
+	/* reset qmgr registers */
+	for (i = 0; i < 4; i++) {
+		__raw_writel(0x33333333, &qmgr_regs->stat1[i]);
+		__raw_writel(0, &qmgr_regs->irqsrc[i]);
+	}
+	for (i = 0; i < 2; i++) {
+		__raw_writel(0, &qmgr_regs->stat2[i]);
+		__raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
+		__raw_writel(0, &qmgr_regs->irqen[i]);
+	}
+
+	__raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h);
+	__raw_writel(0, &qmgr_regs->statf_h);
+
+	for (i = 0; i < QUEUES; i++)
+		__raw_writel(0, &qmgr_regs->sram[i]);
+
+#ifdef CONFIG_USE_IRQ
+	if (cpu_is_ixp42x_rev_a0())
+		handler = qmgr_irq1_a0;
+	else
+		handler = qmgr_irq1;
+
+	irq_install_handler(IXP425_QM1_IRQ, handler, NULL);
+#endif
+	used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
+	return 0;
+}
+
+coredevice_initcall(qmgr_init);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 69f3352..df6e42c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -77,6 +77,14 @@ config DRIVER_NET_MACB
 	depends on HAS_MACB
 	select MIIDEV
 
+config DRIVER_NET_IXP4XX_ETH
+	tristate "Intel IXP4xx Ethernet support"
+	depends on ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
+	select MIIDEV
+	help
+	  Say Y here if you want to use built-in Ethernet ports
+	  on IXP4xx processor.
+
 config DRIVER_NET_TAP
 	bool "tap Ethernet driver"
 	depends on LINUX
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 96d3d32..97cb44b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_DRIVER_NET_MACB)		+= macb.o
 obj-$(CONFIG_DRIVER_NET_TAP)		+= tap.o
 obj-$(CONFIG_MIIDEV)			+= miidev.o
 obj-$(CONFIG_NET_USB)			+= usb/
+obj-$(CONFIG_DRIVER_NET_IXP4XX_ETH)	+= ixp4xx_eth.o
diff --git a/drivers/net/ixp4xx_eth.c b/drivers/net/ixp4xx_eth.c
new file mode 100644
index 0000000..71e6d92
--- /dev/null
+++ b/drivers/net/ixp4xx_eth.c
@@ -0,0 +1,763 @@
+/*
+ * Intel IXP4xx Ethernet driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc at pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * Ethernet port config (0x00 is not present on IXP42X):
+ *
+ * logical port		0x00		0x10		0x20
+ * NPE			0 (NPE-A)	1 (NPE-B)	2 (NPE-C)
+ * physical port	2		0		1
+ * RX queue (variable)	20		21		22
+ * TX queue		23		24		25
+ * RX-free queue	26		27		28
+ * TX-done queue is always 31, per-port RX queue is configurable
+ *
+ *
+ * Queue entries:
+ * bits 0 -> 1  - NPE ID (RX and TX-done)
+ * bits 0 -> 2  - priority (TX, per 802.1D)
+ * bits 3 -> 4  - port ID (user-set?)
+ * bits 5 -> 31 - physical descriptor address
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <miidev.h>
+#include <net.h>
+#include <errno.h>
+#include <mach/ixp4xx-regs.h>
+#include <mach/platform.h>
+#include <mach/cpu.h>
+#include <mach/npe.h>
+#include <mach/qmgr.h>
+
+#define DEBUG_DESC		0
+#define DEBUG_RX		0
+#define DEBUG_TX		0
+#define DEBUG_PKT_BYTES		0
+#define DEBUG_MDIO		0
+#define DEBUG_OPEN		0
+#define DEBUG_CLOSE		0
+
+#define RX_DESCS		16 /* also length of all RX queues */
+#define TX_DESCS		16 /* also length of all TX queues */
+#define TXDONE_QUEUE_LEN	16 /* dwords */
+
+#define MAX_MRU			1536 /* 0x600 */
+#define RX_BUFF_SIZE		MAX_MRU
+
+#define MAX_MDIO_RETRIES	100 /* microseconds, typically 30 cycles */
+#define MAX_CLOSE_WAIT		1000 /* microseconds, typically 2-3 cycles */
+#define ETH_ALEN		6
+
+#define PHYSICAL_ID(port)	(((port)->npe->id + 2) % 3)
+#define LOGICAL_ID(port)	((port)->npe->id << 4)
+#define RX_QUEUE(port)		((port)->npe->id + 20) /* can be changed */
+#define TX_QUEUE(port)		((port)->npe->id + 23)
+#define RXFREE_QUEUE(port)	((port)->npe->id + 26)
+#define TXDONE_QUEUE		31
+
+/* TX Control Registers */
+#define TX_CNTRL0_TX_EN		0x01
+#define TX_CNTRL0_HALFDUPLEX	0x02
+#define TX_CNTRL0_RETRY		0x04
+#define TX_CNTRL0_PAD_EN	0x08
+#define TX_CNTRL0_APPEND_FCS	0x10
+#define TX_CNTRL0_2DEFER	0x20
+#define TX_CNTRL0_RMII		0x40 /* reduced MII */
+#define TX_CNTRL1_RETRIES	0x0F /* 4 bits */
+
+/* RX Control Registers */
+#define RX_CNTRL0_RX_EN		0x01
+#define RX_CNTRL0_PADSTRIP_EN	0x02
+#define RX_CNTRL0_SEND_FCS	0x04
+#define RX_CNTRL0_PAUSE_EN	0x08
+#define RX_CNTRL0_LOOP_EN	0x10
+#define RX_CNTRL0_ADDR_FLTR_EN	0x20
+#define RX_CNTRL0_RX_RUNT_EN	0x40
+#define RX_CNTRL0_BCAST_DIS	0x80
+#define RX_CNTRL1_DEFER_EN	0x01
+
+/* Core Control Register */
+#define CORE_RESET		0x01
+#define CORE_RX_FIFO_FLUSH	0x02
+#define CORE_TX_FIFO_FLUSH	0x04
+#define CORE_SEND_JAM		0x08
+#define CORE_MDC_EN		0x10 /* MDIO using NPE-B ETH-0 only */
+
+#define DEFAULT_TX_CNTRL0	(TX_CNTRL0_TX_EN | TX_CNTRL0_RETRY |       \
+				 TX_CNTRL0_PAD_EN | TX_CNTRL0_APPEND_FCS | \
+				 TX_CNTRL0_2DEFER)
+#define DEFAULT_RX_CNTRL0	RX_CNTRL0_RX_EN
+#define DEFAULT_CORE_CNTRL	CORE_MDC_EN
+
+
+/* NPE message codes */
+#define NPE_GETSTATUS			 0x00
+#define NPE_EDB_SETPORTADDRESS		 0x01
+#define NPE_EDB_GETMACADDRESSDATABASE	 0x02
+#define NPE_EDB_SETMACADDRESSSDATABASE	 0x03
+#define NPE_GETSTATS			 0x04
+#define NPE_RESETSTATS			 0x05
+#define NPE_SETMAXFRAMELENGTHS		 0x06
+#define NPE_VLAN_SETRXTAGMODE		 0x07
+#define NPE_VLAN_SETDEFAULTRXVID	 0x08
+#define NPE_VLAN_SETPORTVLANTABLEENTRY	 0x09
+#define NPE_VLAN_SETPORTVLANTABLERANGE	 0x0A
+#define NPE_VLAN_SETRXQOSENTRY		 0x0B
+#define NPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C
+#define NPE_STP_SETBLOCKINGSTATE	 0x0D
+#define NPE_FW_SETFIREWALLMODE		 0x0E
+#define NPE_PC_SETFRAMECONTROLDURATIONID 0x0F
+#define NPE_PC_SETAPMACTABLE		 0x11
+#define NPE_SETLOOPBACK_MODE		 0x12
+#define NPE_PC_SETBSSIDTABLE		 0x13
+#define NPE_ADDRESS_FILTER_CONFIG	 0x14
+#define NPE_APPENDFCSCONFIG		 0x15
+#define NPE_NOTIFY_MAC_RECOVERY_DONE	 0x16
+#define NPE_MAC_RECOVERY_START		 0x17
+
+struct eth_regs {
+	u32 tx_control[2], __res1[2];		 /* 000 */
+	u32 rx_control[2], __res2[2];		 /* 010 */
+	u32 random_seed, __res3[3];		 /* 020 */
+	u32 partial_empty_threshold, __res4;	 /* 030 */
+	u32 partial_full_threshold, __res5;	 /* 038 */
+	u32 tx_start_bytes, __res6[3];		 /* 040 */
+	u32 tx_deferral, rx_deferral, __res7[2]; /* 050 */
+	u32 tx_2part_deferral[2], __res8[2];	 /* 060 */
+	u32 slot_time, __res9[3];		 /* 070 */
+	u32 mdio_command[4];			 /* 080 */
+	u32 mdio_status[4];			 /* 090 */
+	u32 mcast_mask[6], __res10[2];		 /* 0A0 */
+	u32 mcast_addr[6], __res11[2];		 /* 0C0 */
+	u32 int_clock_threshold, __res12[3];	 /* 0E0 */
+	u32 hw_addr[6], __res13[61];		 /* 0F0 */
+	u32 core_control;			 /* 1FC */
+};
+
+/* NPE message structure */
+struct msg {
+	u8 cmd, eth_id, params[6];
+};
+
+/* Ethernet packet descriptor, 32 bytes */
+struct desc {
+	u8 *next;    /* pointer to next buffer, unused */
+
+	u16 buf_len; /* buffer length */
+	u16 pkt_len; /* packet length */
+	u8 *data;    /* pointer to data buffer in RAM */
+	u8 dest_id;
+	u8 src_id;
+	u16 flags;
+	u8 qos;
+	u8 padlen;
+	u16 vlan_tci;
+
+	u8 dst_mac[ETH_ALEN], src_mac[ETH_ALEN];
+};
+
+struct port {
+	struct desc rx_desc_tab[RX_DESCS]; /* alignment: 0x10 */
+	struct desc tx_desc_tab[TX_DESCS];
+	u8 *buff_tab;
+	struct eth_regs *regs;
+	struct npe *npe;
+	u8 firmware[4];
+	struct eth_plat_info *pinfo;
+	struct mii_device miidev;
+	struct eth_device eth;
+};
+
+#define rx_buff(port, n) ((port)->buff_tab + MAX_MRU * (n))
+#define tx_buff(port, n) ((port)->buff_tab + MAX_MRU * (RX_DESCS + (n)))
+
+static struct eth_regs *mdio_regs; /* mdio command and status only */
+
+static int ixp4xx_mdio_cmd(int write, const struct device_d *dev, unsigned char phy_id,
+			   unsigned char location, unsigned short value)
+{
+	int cycles = 0;
+
+	if (__raw_readl(&mdio_regs->mdio_command[3]) & 0x80) {
+		fprintf(stderr, "%s%d: MII not ready to transmit\n", dev->name, dev->id);
+		return -1;
+	}
+
+	if (write) {
+		__raw_writel(value & 0xFF, &mdio_regs->mdio_command[0]);
+		__raw_writel(value >> 8, &mdio_regs->mdio_command[1]);
+	}
+	__raw_writel(((phy_id << 5) | location) & 0xFF,
+		     &mdio_regs->mdio_command[2]);
+	__raw_writel((phy_id >> 3) | (write << 2) | 0x80 /* GO */,
+		     &mdio_regs->mdio_command[3]);
+
+	while ((cycles < MAX_MDIO_RETRIES) &&
+	       (__raw_readl(&mdio_regs->mdio_command[3]) & 0x80)) {
+		udelay(1);
+		cycles++;
+	}
+
+	if (cycles == MAX_MDIO_RETRIES) {
+		fprintf(stderr, "%s%d: MII write failed\n", dev->name, dev->id);
+		return -1;
+	}
+
+#if DEBUG_MDIO
+	fprintf(stderr, "%s%d: mdio_%s() took %i cycles\n", dev->name, dev->id,
+		write ? "write" : "read", cycles);
+#endif
+
+	if (write)
+		return 0;
+
+	if (__raw_readl(&mdio_regs->mdio_status[3]) & 0x80) {
+#if DEBUG_MDIO
+		fprintf(stderr, "%s%d: MII read failed\n", dev->name, dev->id);
+#endif
+		return -1;
+	}
+
+	value = (__raw_readl(&mdio_regs->mdio_status[0]) & 0xFF) |
+		((__raw_readl(&mdio_regs->mdio_status[1]) & 0xFF) << 8);
+#if DEBUG_MDIO
+	fprintf(stderr, "%s%d: MII read [%i] -> 0x%X\n", dev->name, dev->id, location, value);
+#endif
+
+	return value;
+}
+
+static int ixp4xx_mdio_read(struct mii_device *mii, int phy_id, int location)
+{
+	int ret = ixp4xx_mdio_cmd(0, &mii->dev, phy_id, location, 0);
+	return ret;
+}
+
+static int ixp4xx_mdio_write(struct mii_device *mii, int phy_id, int location, int value)
+{
+	int ret = ixp4xx_mdio_cmd(1, &mii->dev, phy_id, location, value);
+#if DEBUG_MDIO
+	fprintf(stderr, "%s%d: MII write [%i] <- 0x%X, err = %i\n",
+		mii->dev.name, mii->dev.id, location, value, ret);
+#endif
+	return ret;
+}
+
+static int ixp4xx_adjust_link(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	int reg, speed, duplex;
+
+	miidev_wait_aneg(&port->miidev);
+
+	reg = mii_read(&port->miidev, port->miidev.address, MII_BMSR);
+	if (reg < 0)
+		goto err_out;
+	if (!(reg & BMSR_LSTATUS)) {
+		printf("%s%d: Link is down", dev->dev.name, dev->dev.id);
+		return -1;
+	}
+
+	reg = mii_read(&port->miidev, port->miidev.address, MII_BMCR);
+	if (reg < 0)
+		goto err_out;
+
+	if (reg & BMCR_ANENABLE) {
+		reg = mii_read(&port->miidev, port->miidev.address, MII_LPA);
+		if (reg < 0)
+			goto err_out;
+		duplex = reg & LPA_DUPLEX;
+		speed = reg & LPA_100 ? 100 : 10;
+	} else {
+		duplex = reg & BMCR_FULLDPLX;
+		speed = reg & BMCR_SPEED100 ? 100 : 10;
+	}
+
+	if (duplex)
+		__raw_writel(DEFAULT_TX_CNTRL0 & ~TX_CNTRL0_HALFDUPLEX,
+			     &port->regs->tx_control[0]);
+	else
+		__raw_writel(DEFAULT_TX_CNTRL0 | TX_CNTRL0_HALFDUPLEX,
+			     &port->regs->tx_control[0]);
+
+	fprintf(stderr, "%s%d: link up, speed %u Mb/s, %s duplex\n",
+		dev->dev.name, dev->dev.id, speed, duplex ? "full" : "half");
+	return 0;
+
+err_out:
+	printf("%s%d: failed to read MII data\n", dev->dev.name, dev->dev.id);
+	return -EIO;
+}
+
+static inline void debug_pkt(struct eth_device *dev, const char *func,
+			     u8 *data, int len)
+{
+#if DEBUG_PKT_BYTES
+	int i;
+
+	fprintf(stderr, "%s%d: %s(%4i) ", dev->dev.name, dev->dev.id, func, len);
+	for (i = 0; i < len; i++) {
+		if (i >= DEBUG_PKT_BYTES)
+			break;
+		fprintf(stderr, "%s%02X",
+			((i == 6) || (i == 12) || (i >= 14)) ? " " : "",
+			data[i]);
+	}
+	fprintf(stderr, "\n");
+#endif
+}
+
+
+static inline void debug_desc(struct desc *desc)
+{
+#if DEBUG_DESC
+	fprintf(stderr, "%07X: %X %3X %3X %07X %2X < %2X %4X %X"
+		" %X %X %02X%02X%02X%02X%02X%02X < %02X%02X%02X%02X%02X%02X\n",
+		(u32)desc, (u32)desc->next, desc->buf_len, desc->pkt_len,
+		(u32)desc->data, desc->dest_id, desc->src_id, desc->flags,
+		desc->qos, desc->padlen, desc->vlan_tci,
+		desc->dst_mac[0], desc->dst_mac[1], desc->dst_mac[2],
+		desc->dst_mac[3], desc->dst_mac[4], desc->dst_mac[5],
+		desc->src_mac[0], desc->src_mac[1], desc->src_mac[2],
+		desc->src_mac[3], desc->src_mac[4], desc->src_mac[5]);
+#endif
+}
+
+static inline int queue_get_desc(unsigned int queue, struct port *port,
+				 int is_tx)
+{
+	u32 addr, n;
+	struct desc *tab;
+
+	if (!(addr = qmgr_get_entry(queue)))
+		return -1;
+
+	addr &= ~0x1F; /* mask out non-address bits */
+	tab = is_tx ? port->tx_desc_tab : port->rx_desc_tab;
+	n = (addr - (u32)tab) / sizeof(struct desc);
+	BUG_ON(n >= (is_tx ? TX_DESCS : RX_DESCS));
+	debug_desc((struct desc*)addr);
+	BUG_ON(tab[n].next);
+	return n;
+}
+
+static inline void queue_put_desc(unsigned int queue, struct desc *desc)
+{
+	debug_desc(desc);
+	BUG_ON(((u32)desc) & 0x1F);
+	qmgr_put_entry(queue, (u32)desc);
+	/* Don't check for queue overflow here, we've allocated sufficient
+	   length and queues >= 32 don't support this check anyway. */
+}
+
+
+static int ixp4xx_eth_poll(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	struct desc *desc;
+	u8 *buff;
+	int n, len;
+
+#if DEBUG_RX
+	fprintf(stderr, "%s%d: eth_poll\n", dev->dev.name, dev->dev.id);
+#endif
+
+	if ((n = queue_get_desc(RX_QUEUE(port), port, 0)) < 0) {
+#if DEBUG_RX
+		fprintf(stderr, "%s%d: eth_poll = no packet received\n", dev->dev.name, dev->dev.id);
+#endif
+		return 0;
+	}
+
+	barrier();
+	desc = &port->rx_desc_tab[n];
+	buff = rx_buff(port, n);
+	len = desc->pkt_len;
+	/* process received frame */
+	memcpy((void *)NetRxPackets[0], buff, len);
+	debug_pkt(dev, "RX", desc->data, len);
+
+	/* put the new buffer on RX-free queue */
+	desc->buf_len = MAX_MRU;
+	desc->pkt_len = 0;
+	queue_put_desc(RXFREE_QUEUE(port), desc);
+
+	net_receive(NetRxPackets[0], len);
+
+#if DEBUG_RX
+	fprintf(stderr, "%s%d: eth_poll end\n", dev->dev.name, dev->dev.id);
+#endif
+	return 0;
+}
+
+
+static int ixp4xx_eth_xmit(struct eth_device *dev, void *data, int len)
+{
+	struct port *port = dev->priv;
+	int n;
+	struct desc *desc;
+
+#if DEBUG_TX
+	fprintf(stderr, "%s%d: eth_xmit\n", dev->dev.name, dev->dev.id);
+#endif
+
+	if (unlikely(len > 1500))
+		return -1;
+
+	debug_pkt(dev, "TX", data, len);
+
+	if ((n = queue_get_desc(TXDONE_QUEUE, port, 1)) < 0)
+		return -1; /* no free buffers */
+	desc = &port->tx_desc_tab[n];
+	desc->data = tx_buff(port, n);
+	desc->buf_len = desc->pkt_len = len;
+	memcpy(desc->data, data, len);
+
+	/* NPE firmware pads short frames with zeros internally */
+	// wmb();
+	barrier();
+	queue_put_desc(TX_QUEUE(port), desc);
+
+#if DEBUG_TX
+	fprintf(stderr, "%s%d: eth_xmit end\n", dev->dev.name, dev->dev.id);
+#endif
+	return 0;
+}
+
+static void request_queues(struct port *port, struct eth_device *dev)
+{
+	qmgr_request_queue(RXFREE_QUEUE(port), RX_DESCS, 0, 0, "%s:RX-free", dev->dev.name);
+	qmgr_request_queue(RX_QUEUE(port), RX_DESCS, 0, 0, "%s:RX", dev->dev.name);
+	qmgr_request_queue(TX_QUEUE(port), TX_DESCS, 0, 0, "%s:TX", dev->dev.name);
+
+	/* Common TX-done queue handles buffers sent out by the NPEs */
+	qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0,
+			   "%s:TX-done", dev->dev.name);
+}
+
+static void release_queues(struct port *port)
+{
+	qmgr_release_queue(RXFREE_QUEUE(port));
+	qmgr_release_queue(RX_QUEUE(port));
+	qmgr_release_queue(TX_QUEUE(port));
+	qmgr_release_queue(TXDONE_QUEUE);
+}
+
+static void init_queues(struct port *port)
+{
+	int i;
+
+	memset(port->tx_desc_tab, 0, sizeof(port->tx_desc_tab)); /* descs */
+	memset(port->rx_desc_tab, 0, sizeof(port->rx_desc_tab));
+
+	/* Setup RX buffers */
+	for (i = 0; i < RX_DESCS; i++) {
+		struct desc *desc = &port->rx_desc_tab[i];
+		desc->buf_len = MAX_MRU;
+		desc->data = rx_buff(port, i);
+	}
+}
+
+static int ixp4xx_eth_open(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	struct npe *npe = port->npe;
+	struct msg msg;
+	int i, err;
+
+#if DEBUG_OPEN
+	fprintf(stderr, "%s%d: opening %p\n", dev->dev.name, dev->dev.id, dev);
+#endif
+
+	if (!npe_running(npe)) {
+		err = npe_load_firmware(npe);
+		if (err)
+			return err;
+
+		if (npe_recv_message(npe, &msg, "ETH_GET_STATUS")) {
+			fprintf(stderr, "%s%d: %s not responding\n", dev->dev.name, dev->dev.id, npe->name);
+			return -EIO;
+		}
+		memcpy(port->firmware, msg.params + 2, 4);
+	}
+
+	if (ixp4xx_adjust_link(dev))
+		return -ENOLINK;
+
+	port->buff_tab = xmalloc((RX_DESCS + TX_DESCS) * MAX_MRU);
+
+	memset(&msg, 0, sizeof(msg));
+	msg.cmd = NPE_VLAN_SETRXQOSENTRY;
+	msg.eth_id = LOGICAL_ID(port);
+	msg.params[3] = RX_QUEUE(port) | 0x80;
+	msg.params[4] = RX_QUEUE(port) >> 4; /* MSB of offset */
+	msg.params[5] = RX_QUEUE(port) << 4; /* LSB of offset */
+	for (i = 0; i < 8; i++) {
+		msg.params[1] = i;
+		if (npe_send_recv_message(port->npe, &msg, "ETH_SET_RXQ")) {
+			err = -EIO;
+			goto out;
+		}
+	}
+
+	msg.cmd = NPE_EDB_SETPORTADDRESS;
+	msg.eth_id = PHYSICAL_ID(port);
+	memcpy(msg.params, port->pinfo->hwaddr, ETH_ALEN);
+	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAC")) {
+		err = -EIO;
+		goto out;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.cmd = NPE_FW_SETFIREWALLMODE;
+	msg.eth_id = LOGICAL_ID(port);
+	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE")) {
+		err = -EIO;
+		goto out;
+	}
+
+	request_queues(port, dev);
+	init_queues(port);
+
+	for (i = 0; i < ETH_ALEN; i++)
+		__raw_writel(port->pinfo->hwaddr[i], &port->regs->hw_addr[i]);
+	__raw_writel(0x08, &port->regs->random_seed);
+	__raw_writel(0x12, &port->regs->partial_empty_threshold);
+	__raw_writel(0x30, &port->regs->partial_full_threshold);
+	__raw_writel(0x08, &port->regs->tx_start_bytes);
+	__raw_writel(0x15, &port->regs->tx_deferral);
+	__raw_writel(0x08, &port->regs->tx_2part_deferral[0]);
+	__raw_writel(0x07, &port->regs->tx_2part_deferral[1]);
+	__raw_writel(0x80, &port->regs->slot_time);
+	__raw_writel(0x01, &port->regs->int_clock_threshold);
+
+	/* Populate queues with buffers, no failure after this point */
+	for (i = 0; i < TX_DESCS; i++)
+		queue_put_desc(TXDONE_QUEUE, &port->tx_desc_tab[i]);
+
+	for (i = 0; i < RX_DESCS; i++)
+		queue_put_desc(RXFREE_QUEUE(port), &port->rx_desc_tab[i]);
+
+	__raw_writel(TX_CNTRL1_RETRIES, &port->regs->tx_control[1]);
+	__raw_writel(DEFAULT_TX_CNTRL0, &port->regs->tx_control[0]);
+	__raw_writel(0, &port->regs->rx_control[1]);
+	__raw_writel(DEFAULT_RX_CNTRL0, &port->regs->rx_control[0]);
+
+#if 0
+	qmgr_set_irq(RX_QUEUE(port), QUEUE_IRQ_SRC_NOT_EMPTY,
+		     eth_rx_irq, dev);
+	qmgr_set_irq(TXDONE_QUEUE, QUEUE_IRQ_SRC_NOT_EMPTY,
+		     eth_txdone_irq, NULL);
+	qmgr_enable_irq(TXDONE_QUEUE);
+#endif
+	memset(&msg, 0, sizeof(msg));
+#if DEBUG_OPEN
+	fprintf(stderr, "%s%d opened\n", dev->dev.name, dev->dev.id);
+#endif
+	return 0;
+out:
+	free(port->buff_tab);
+	port->buff_tab = NULL;
+#if DEBUG_OPEN
+	fprintf(stderr, "%s%d open failed (%i)\n", dev->dev.name, dev->dev.id, err);
+#endif
+	return err;
+}
+
+static void ixp4xx_eth_close(struct eth_device *dev)
+{
+	struct port *port = dev->priv;
+	struct msg msg;
+	int buffs = RX_DESCS; /* allocated RX buffers */
+	int i;
+
+#if DEBUG_CLOSE
+	fprintf(stderr, "%s%d: closing\n", dev->dev.name, dev->dev.id);
+#endif
+#if 0
+	qmgr_disable_irq(RX_QUEUE(port));
+#endif
+
+	if (!port->buff_tab)
+		return; /* already closed */
+
+	while (queue_get_desc(RXFREE_QUEUE(port), port, 0) >= 0)
+		buffs--;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.cmd = NPE_SETLOOPBACK_MODE;
+	msg.eth_id = LOGICAL_ID(port);
+	msg.params[1] = 1;
+	if (npe_send_recv_message(port->npe, &msg, "ETH_ENABLE_LOOPBACK"))
+		fprintf(stderr, "%s%d: unable to enable loopback\n", dev->dev.name, dev->dev.id);
+
+#if DEBUG_CLOSE
+	fprintf(stderr, "%s%d: draining RX queue\n", dev->dev.name, dev->dev.id);
+#endif
+	i = 0;
+	do { /* drain RX buffers */
+		while (queue_get_desc(RX_QUEUE(port), port, 0) >= 0)
+			buffs--;
+		if (!buffs)
+			break;
+		if (qmgr_stat_full(TXDONE_QUEUE) && !(i % 10)) {
+			/* we have to inject some packet */
+			struct desc *desc;
+			int n = queue_get_desc(TXDONE_QUEUE, port, 1);
+			BUG_ON(n < 0);
+			desc = &port->tx_desc_tab[n];
+			desc->buf_len = desc->pkt_len = 1;
+			//wmb();
+			barrier();
+			queue_put_desc(TX_QUEUE(port), desc);
+		}
+		udelay(1);
+	} while (++i < MAX_CLOSE_WAIT);
+
+	if (buffs)
+		fprintf(stderr, "%s%d: unable to drain RX queue, %i buffer(s) left in NPE\n",
+			dev->dev.name, dev->dev.id, buffs);
+#if DEBUG_CLOSE
+	if (!buffs)
+		fprintf(stderr, "%s%d: draining RX queue took %i cycles\n", dev->dev.name, dev->dev.id, i);
+#endif
+
+	buffs = TX_DESCS;
+	while (queue_get_desc(TX_QUEUE(port), port, 1) >= 0)
+		buffs--; /* cancel TX */
+
+	i = 0;
+	do {
+		while (queue_get_desc(TXDONE_QUEUE, port, 1) >= 0)
+			buffs--;
+		if (!buffs)
+			break;
+	} while (++i < MAX_CLOSE_WAIT);
+
+	if (buffs)
+		fprintf(stderr, "%s%d: unable to drain TX queue, %i buffer(s) left in NPE\n",
+			dev->dev.name, dev->dev.id, buffs);
+#if DEBUG_CLOSE
+	if (!buffs)
+		fprintf(stderr, "%s%d: draining TX queues took %i cycles\n", dev->dev.name, dev->dev.id, i);
+#endif
+
+	msg.params[1] = 0;
+	if (npe_send_recv_message(port->npe, &msg, "ETH_DISABLE_LOOPBACK"))
+		fprintf(stderr, "%s%d: unable to disable loopback\n", dev->dev.name, dev->dev.id);
+
+#if 0
+	qmgr_disable_irq(TXDONE_QUEUE);
+#endif
+	release_queues(port);
+	free(port->buff_tab);
+	port->buff_tab = NULL;
+#if DEBUG_CLOSE
+	fprintf(stderr, "%s%d: closed\n", dev->dev.name, dev->dev.id);
+#endif
+}
+
+static int ixp4xx_eth_get_hwaddr(struct eth_device *eth, unsigned char *addr)
+{
+	struct port *port = eth->priv;
+	memcpy(addr, port->pinfo->hwaddr, 6);
+	return 0;
+}
+
+static int ixp4xx_eth_set_hwaddr(struct eth_device *eth, unsigned char *addr)
+{
+	struct port *port = eth->priv;
+	memcpy(port->pinfo->hwaddr, addr, 6);
+	return 0;
+}
+
+static int ixp4xx_eth_init(struct eth_device *eth)
+{
+	struct port *port = eth->priv;
+
+	__raw_writel(DEFAULT_CORE_CNTRL | CORE_RESET,
+		     &port->regs->core_control);
+	udelay(50);
+	__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
+	udelay(50);
+
+	miidev_restart_aneg(&port->miidev);
+	return 0;
+}
+
+static int ixp4xx_eth_probe(struct device_d *dev)
+{
+	struct npe *npe;
+	struct port *port;
+	struct eth_plat_info *pinfo = dev->platform_data;
+
+	if (!pinfo) {
+		fprintf(stderr, "ixp4xx_eth: no platform information\n");
+		return -ENODEV;
+	}
+
+	if (!(npe = npe_request(pinfo->npe))) {
+		fprintf(stderr, "ixp4xx_eth: unable to acquire NPE\n");
+		return -ENODEV;
+	}
+
+	port = memalign(0x20, sizeof(*port));
+	memset(port, 0, sizeof(*port));
+
+	port->regs = pinfo->regs;
+	port->npe = npe;
+	port->pinfo = pinfo;
+	port->eth.dev.id = -1;
+	port->eth.priv = port;
+	port->eth.init = ixp4xx_eth_init;
+	port->eth.open = ixp4xx_eth_open;
+	port->eth.halt = ixp4xx_eth_close;
+	port->eth.send = ixp4xx_eth_xmit;
+	port->eth.recv = ixp4xx_eth_poll;
+	port->eth.get_ethaddr = ixp4xx_eth_get_hwaddr;
+	port->eth.set_ethaddr = ixp4xx_eth_set_hwaddr;
+
+	port->miidev.dev.id = -1;
+	port->miidev.read = ixp4xx_mdio_read;
+	port->miidev.write = ixp4xx_mdio_write;
+	port->miidev.address = pinfo->phy;
+	port->miidev.edev = &port->eth;
+	mii_register(&port->miidev);
+	eth_register(&port->eth);
+	return 0;
+}
+
+static struct driver_d ixp4xx_eth_driver = {
+	.name  = "ixp4xx_eth",
+	.probe = ixp4xx_eth_probe,
+};
+
+static int __init ixp4xx_eth_module_init(void)
+{
+	if (cpu_is_ixp43x()) {
+		/* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
+		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
+			return -ENOSYS;
+		mdio_regs = (struct eth_regs *)IXP4XX_EthC_BASE;
+	} else {
+		/* All MII PHY accesses use NPE-B Ethernet registers */
+		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
+			return -ENOSYS;
+		mdio_regs = (struct eth_regs *)IXP4XX_EthB_BASE;
+	}
+
+	__raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+
+	register_driver(&ixp4xx_eth_driver);
+	return 0;
+}
+
+device_initcall(ixp4xx_eth_module_init);
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 290619f..0f25ceb 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -102,7 +102,11 @@ static void ns16550_serial_init_port(struct console_device *cdev)
 	baud_divisor = ns16550_calc_divisor(cdev, CONFIG_BAUDRATE);
 
 	/* initializing the device for the first time */
+#ifdef CONFIG_ARCH_IXP4XX
+	plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
+#else
 	plat->reg_write(0x00, base, ier);
+#endif
 #ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
 	plat->reg_write(0x07, base, mdr1);	/* Disable */
 #endif
@@ -181,7 +185,11 @@ static int ns16550_setbaudrate(struct console_device *cdev, int baud_rate)
 	    cdev->dev->platform_data;
 	unsigned long base = cdev->dev->map_base;
 	unsigned int baud_divisor = ns16550_calc_divisor(cdev, baud_rate);
+#ifdef CONFIG_ARCH_IXP4XX
+	plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
+#else
 	plat->reg_write(0x00, base, ier);
+#endif
 	plat->reg_write(LCR_BKSE, base, lcr);
 	plat->reg_write(baud_divisor & 0xff, base, dll);
 	plat->reg_write((baud_divisor >> 8) & 0xff, base, dlm);
diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
index eb2fd10..ba20a6f 100644
--- a/drivers/serial/serial_ns16550.h
+++ b/drivers/serial/serial_ns16550.h
@@ -50,6 +50,8 @@
 #define dll		rbr
 #define dlm		ier
 
+#define IER_UUE		0x40	/* UART Unit Enable (XScale) */
+
 #define FCR_FIFO_EN     0x01	/* Fifo enable */
 #define FCR_RXSR        0x02	/* Receiver soft reset */
 #define FCR_TXSR        0x04	/* Transmitter soft reset */


From plagnioj at jcrosoft.com  Tue Dec 21 19:57:22 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 22 Dec 2010 01:57:22 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <m3oc8gcae3.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
Message-ID: <20101222005722.GD19266@game.jcrosoft.org>

> +
> +#define BAREBOX_START        0x00000
> +#define BAREBOX_LENGTH       0x34000
> +#define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
> +#define NPE_A_LENGTH         0x05000
> +#define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
> +#define NPE_B_LENGTH         0x03000
> +#define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
> +#define NPE_C_LENGTH         0x04000
> +#define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
> +#define NPE_ENV0_LENGTH      0x20000
why not put the NPE firmware in the env?

btw you have a lots of whitespace please use tab for indent

Best Regards,
J.
> +
> +static struct clocksource cs = {
> +	.read = ixp4xx_clocksource_read,
> +	.mask = 0xffffffff,
please use CLOCKSOURCE_MASK
> +	.shift = 10,
> +};
> diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
> index 290619f..0f25ceb 100644
> --- a/drivers/serial/serial_ns16550.c
> +++ b/drivers/serial/serial_ns16550.c
please do this in a seperate patch
> @@ -102,7 +102,11 @@ static void ns16550_serial_init_port(struct console_device *cdev)
>  	baud_divisor = ns16550_calc_divisor(cdev, CONFIG_BAUDRATE);
>  
>  	/* initializing the device for the first time */
> +#ifdef CONFIG_ARCH_IXP4XX
> +	plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
> +#else
>  	plat->reg_write(0x00, base, ier);
> +#endif
>  #ifdef CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS
>  	plat->reg_write(0x07, base, mdr1);	/* Disable */
>  #endif
> @@ -181,7 +185,11 @@ static int ns16550_setbaudrate(struct console_device *cdev, int baud_rate)
>  	    cdev->dev->platform_data;
>  	unsigned long base = cdev->dev->map_base;
>  	unsigned int baud_divisor = ns16550_calc_divisor(cdev, baud_rate);
> +#ifdef CONFIG_ARCH_IXP4XX
> +	plat->reg_write(IER_UUE, base, ier); /* Enable UART operation */
> +#else
>  	plat->reg_write(0x00, base, ier);
> +#endif
>  	plat->reg_write(LCR_BKSE, base, lcr);
>  	plat->reg_write(baud_divisor & 0xff, base, dll);
>  	plat->reg_write((baud_divisor >> 8) & 0xff, base, dlm);
> diff --git a/drivers/serial/serial_ns16550.h b/drivers/serial/serial_ns16550.h
> index eb2fd10..ba20a6f 100644
> --- a/drivers/serial/serial_ns16550.h
> +++ b/drivers/serial/serial_ns16550.h
> @@ -50,6 +50,8 @@
>  #define dll		rbr
>  #define dlm		ier
>  
> +#define IER_UUE		0x40	/* UART Unit Enable (XScale) */
> +
>  #define FCR_FIFO_EN     0x01	/* Fifo enable */
>  #define FCR_RXSR        0x02	/* Receiver soft reset */
>  #define FCR_TXSR        0x04	/* Transmitter soft reset */
> 
Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Dec 21 19:58:29 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 22 Dec 2010 01:58:29 +0100
Subject: [PATCH 5] Fix error handling with malloc, memalign etc.
	Memalign() can't fail now.
In-Reply-To: <m3vd2ocax2.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3vd2ocax2.fsf@intrepid.localdomain>
Message-ID: <20101222005829.GE19266@game.jcrosoft.org>

  
> diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> index 717fea5..9d52beb 100644
> --- a/drivers/clk/clkdev.c
> +++ b/drivers/clk/clkdev.c
please do not modify it I want to keep it as in the kernel
> @@ -116,9 +116,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
>  {
>  	struct clk_lookup_alloc *cla;
>  
> -	cla = kzalloc(sizeof(*cla), GFP_KERNEL);
> -	if (!cla)
> -		return NULL;
> +	cla = xzalloc(sizeof(*cla), GFP_KERNEL);
>  
>  	cla->cl.clk = clk;
>  	if (con_id) {
> @@ -150,8 +148,6 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
>  
>  	l = clkdev_alloc(r, alias, alias_dev_name);
>  	clk_put(r);
> -	if (!l)
> -		return -ENODEV;
>  	clkdev_add(l);
>  	return 0;
>  }

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Dec 21 20:00:47 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 22 Dec 2010 02:00:47 +0100
Subject: [PATCH 6] ARM: support big/little endian switching in "bootz".
In-Reply-To: <m3tyi8carg.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3tyi8carg.fsf@intrepid.localdomain>
Message-ID: <20101222010047.GF19266@game.jcrosoft.org>

On 23:58 Mon 20 Dec     , Krzysztof Halasa wrote:
> ARM: support big/little endian switching in "bootz".
> Perhaps one should make this conditional? Mostly for big-endian
> Barebox loading little-endian (e.g. armel Debian) Linux.
> 
> Signed-off-by: Krzysztof Ha?asa <khc at pm.waw.pl>
don't we need to update bootm and bootu too?

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Dec 21 20:01:30 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Wed, 22 Dec 2010 02:01:30 +0100
Subject: [PATCH 12] Fix NOR CFI flash driver to work on big endian systems.
In-Reply-To: <m3lj3kca6m.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3lj3kca6m.fsf@intrepid.localdomain>
Message-ID: <20101222010130.GG19266@game.jcrosoft.org>

On 00:10 Tue 21 Dec     , Krzysztof Halasa wrote:
> Fix NOR CFI flash driver to work on big endian systems.
> Basically this transforms the u8/u16/u32/u64 union into
> a single u64 value.
> 
> Not tested on LE platform. Apply with caution.
I'd like to test it a few this week can we wait a few before applying?

Best Regards,
J.


From s.hauer at pengutronix.de  Wed Dec 22 07:46:35 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 22 Dec 2010 13:46:35 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <20101222005722.GD19266@game.jcrosoft.org>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<20101222005722.GD19266@game.jcrosoft.org>
Message-ID: <20101222124635.GC6017@pengutronix.de>

On Wed, Dec 22, 2010 at 01:57:22AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > +
> > +#define BAREBOX_START        0x00000
> > +#define BAREBOX_LENGTH       0x34000
> > +#define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
> > +#define NPE_A_LENGTH         0x05000
> > +#define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
> > +#define NPE_B_LENGTH         0x03000
> > +#define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
> > +#define NPE_C_LENGTH         0x04000
> > +#define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
> > +#define NPE_ENV0_LENGTH      0x20000
> why not put the NPE firmware in the env?

That's a good idea. This way we can tell the users to put the firmware
to arch/arm/boards/.../env/firmware before compilation and avoid
redistribution problems if there are any. Another plus is that the
barebox binary is not larger than it has to be.
The only downside is that the environment gets bigger as it duplicates
the firmware, but even this could be avoided if we add a second (non
environment) filesystem image.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Wed Dec 22 07:48:20 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 22 Dec 2010 13:48:20 +0100
Subject: [PATCH 12] Fix NOR CFI flash driver to work on big endian systems.
In-Reply-To: <20101222010130.GG19266@game.jcrosoft.org>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3lj3kca6m.fsf@intrepid.localdomain>
	<20101222010130.GG19266@game.jcrosoft.org>
Message-ID: <20101222124820.GD6017@pengutronix.de>

On Wed, Dec 22, 2010 at 02:01:30AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 00:10 Tue 21 Dec     , Krzysztof Halasa wrote:
> > Fix NOR CFI flash driver to work on big endian systems.
> > Basically this transforms the u8/u16/u32/u64 union into
> > a single u64 value.
> > 
> > Not tested on LE platform. Apply with caution.
> I'd like to test it a few this week can we wait a few before applying?

I already applied it. I tested it on little endian and it works. Anyway,
if you find regressions we can still update the patch.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From khc at pm.waw.pl  Wed Dec 22 13:55:54 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 19:55:54 +0100
Subject: [PATCH 6] ARM: support big/little endian switching in "bootz".
In-Reply-To: <20101222010047.GF19266@game.jcrosoft.org> (Jean-Christophe
	PLAGNIOL-VILLARD's message of "Wed, 22 Dec 2010 02:00:47 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3tyi8carg.fsf@intrepid.localdomain>
	<20101222010047.GF19266@game.jcrosoft.org>
Message-ID: <m3r5d963id.fsf@intrepid.localdomain>

Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com> writes:

>> ARM: support big/little endian switching in "bootz".

> don't we need to update bootm and bootu too?

Probably. I've never used bootu, so it would be best if someone familiar
with it made the change (or at least tested it). Bootm - I will look at
it sometime (not using it at this time, but I think it's the only
command which can run Linux with external initramfs, I will need
something like that).
-- 
Krzysztof Halasa


From khc at pm.waw.pl  Wed Dec 22 14:00:41 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 20:00:41 +0100
Subject: [PATCH 5] Fix error handling with malloc,
	memalign etc. Memalign() can't fail now.
In-Reply-To: <20101222005829.GE19266@game.jcrosoft.org> (Jean-Christophe
	PLAGNIOL-VILLARD's message of "Wed, 22 Dec 2010 01:58:29 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3vd2ocax2.fsf@intrepid.localdomain>
	<20101222005829.GE19266@game.jcrosoft.org>
Message-ID: <m3mxnx63ae.fsf@intrepid.localdomain>

Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com> writes:

>> --- a/drivers/clk/clkdev.c
>> +++ b/drivers/clk/clkdev.c
> please do not modify it I want to keep it as in the kernel

As you wish.

What's the rationale BTW?
-- 
Krzysztof Halasa


From khc at pm.waw.pl  Wed Dec 22 14:13:06 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 20:13:06 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <20101222005722.GD19266@game.jcrosoft.org> (Jean-Christophe
	PLAGNIOL-VILLARD's message of "Wed, 22 Dec 2010 01:57:22 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<20101222005722.GD19266@game.jcrosoft.org>
Message-ID: <m3fwtp62pp.fsf@intrepid.localdomain>

Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com> writes:

>> +#define BAREBOX_START        0x00000
>> +#define BAREBOX_LENGTH       0x34000
>> +#define NPE_A_START          (BAREBOX_START + BAREBOX_LENGTH)
>> +#define NPE_A_LENGTH         0x05000
>> +#define NPE_B_START          (NPE_A_START + NPE_A_LENGTH)
>> +#define NPE_B_LENGTH         0x03000
>> +#define NPE_C_START          (NPE_B_START + NPE_B_LENGTH)
>> +#define NPE_C_LENGTH         0x04000
>> +#define NPE_ENV0_START       (NPE_C_START + NPE_C_LENGTH)
>> +#define NPE_ENV0_LENGTH      0x20000
>
> btw you have a lots of whitespace please use tab for indent

Well, I try to use tabs for syntactic indentation exclusively.
I admit I haven't checked the patches for this, and some spaces could
have slipped through e.g. copy+paste. Will check.

OTOH I use spaces for visual alignment (as shown above) and I consider
it the right thing. It makes the text display correctly with any tab
length setting. This has been somehow agreed on linux-kernel (though
definitely not unanimously) and I think Barebox tries to duplicate Linux
coding style.

Not that it matters a lot, can change it all to tabs if that's what
Barebox needs.
-- 
Krzysztof Halasa


From khc at pm.waw.pl  Wed Dec 22 14:36:30 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Wed, 22 Dec 2010 20:36:30 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <20101222124635.GC6017@pengutronix.de> (Sascha Hauer's message of
	"Wed, 22 Dec 2010 13:46:35 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<20101222005722.GD19266@game.jcrosoft.org>
	<20101222124635.GC6017@pengutronix.de>
Message-ID: <m3bp4d61mp.fsf@intrepid.localdomain>

Sascha Hauer <s.hauer at pengutronix.de> writes:

>> why not put the NPE firmware in the env?
>
> That's a good idea. This way we can tell the users to put the firmware
> to arch/arm/boards/.../env/firmware before compilation and avoid
> redistribution problems if there are any. Another plus is that the
> barebox binary is not larger than it has to be.
> The only downside is that the environment gets bigger as it duplicates
> the firmware, but even this could be avoided if we add a second (non
> environment) filesystem image.

Actually, there is more. There is plenty of free space in Barebox'
region (2 pages 128 KB each), and the microcode isn't likely to ever
change (unless Intel releases docs/sources, of course).

I don't want it in user-writable area since it could be incidentally
erased. Without the microcode Ethernet interfaces are not functional,
and I'm not sure all users would appreciate it if they had to download
it back with [XY]-modem (or another C-kermit) :-) Even TFTP is sometimes
black magic for some of them.

Obviously, the microcode is optional, and especially NPE-A one isn't at
all used by Barebox (Linux uses it for driving sync serial interfaces).
I don't consider the microcode a part of Barebox, like the
/lib/firmware/* blobs aren't part of Linux.

Also it's simpler to export the microcode to Linux when it's in fixed
well-aligned locations.
-- 
Krzysztof Halasa


From marc at cpdesign.com.au  Wed Dec 22 19:03:31 2010
From: marc at cpdesign.com.au (Marc Reilly)
Date: Thu, 23 Dec 2010 11:03:31 +1100
Subject: Determining barebox version from linux
Message-ID: <201012231103.31335.marc@cpdesign.com.au>

Hi,

I want to be able to determine what version of barebox I have on my NOR flash, 
after booting into linux.

The easiest way I thought of is something like:
cat /dev/mtd0 | grep "barebox 2010"

Another way to do this is to have the version_string (or other version info) 
at a fixed location in the barebox image. This feels like a overly rigid 
solution, and may be a pain to put into the build system.

Does anybody else accomplish this in a better way? (I don't want to pass the 
barebox version as an arg when booting the kernel - I'd rather it be more 
"standalone").

Cheers
Marc


From plagnioj at jcrosoft.com  Wed Dec 22 22:26:31 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu, 23 Dec 2010 04:26:31 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <m3bp4d61mp.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<20101222005722.GD19266@game.jcrosoft.org>
	<20101222124635.GC6017@pengutronix.de>
	<m3bp4d61mp.fsf@intrepid.localdomain>
Message-ID: <20101223032631.GI19266@game.jcrosoft.org>

On 20:36 Wed 22 Dec     , Krzysztof Halasa wrote:
> Sascha Hauer <s.hauer at pengutronix.de> writes:
> 
> >> why not put the NPE firmware in the env?
> >
> > That's a good idea. This way we can tell the users to put the firmware
> > to arch/arm/boards/.../env/firmware before compilation and avoid
> > redistribution problems if there are any. Another plus is that the
> > barebox binary is not larger than it has to be.
> > The only downside is that the environment gets bigger as it duplicates
> > the firmware, but even this could be avoided if we add a second (non
> > environment) filesystem image.
> 
> Actually, there is more. There is plenty of free space in Barebox'
> region (2 pages 128 KB each), and the microcode isn't likely to ever
> change (unless Intel releases docs/sources, of course).
> 
> I don't want it in user-writable area since it could be incidentally
> erased. Without the microcode Ethernet interfaces are not functional,
> and I'm not sure all users would appreciate it if they had to download
> it back with [XY]-modem (or another C-kermit) :-) Even TFTP is sometimes
> black magic for some of them.
> 
> Obviously, the microcode is optional, and especially NPE-A one isn't at
> all used by Barebox (Linux uses it for driving sync serial interfaces).
> I don't consider the microcode a part of Barebox, like the
> /lib/firmware/* blobs aren't part of Linux.
> 
> Also it's simpler to export the microcode to Linux when it's in fixed
> well-aligned locations.
I'm working on a fs support in linux of the barebox env

so linux could get it easly also

but I prefer to be able to change my micro code as some of the people who work
on IXP have acess to it to modify it. So I think its a good option

so as linux it will be better to put it in a fs like /lib/firmware

Best Regards,
J.


From baruch at tkos.co.il  Thu Dec 23 01:18:06 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 23 Dec 2010 08:18:06 +0200
Subject: Determining barebox version from linux
In-Reply-To: <201012231103.31335.marc@cpdesign.com.au>
References: <201012231103.31335.marc@cpdesign.com.au>
Message-ID: <20101223061806.GA12874@jasper.tkos.co.il>

Hi Marc,

On Thu, Dec 23, 2010 at 11:03:31AM +1100, Marc Reilly wrote:
> I want to be able to determine what version of barebox I have on my NOR 
> flash, after booting into linux.

[snip]

> Does anybody else accomplish this in a better way? (I don't want to pass the 
> barebox version as an arg when booting the kernel - I'd rather it be more 
> "standalone").

I set the board revision number, using armlinux_set_revision(), to pass the 
version of the bootloader to the kernel, and then extract it from the 
'Revision' field in /proc/cpuinfo. This solution is ARM specific, though.

baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From plagnioj at jcrosoft.com  Thu Dec 23 02:07:07 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Thu, 23 Dec 2010 08:07:07 +0100
Subject: Determining barebox version from linux
In-Reply-To: <20101223061806.GA12874@jasper.tkos.co.il>
References: <201012231103.31335.marc@cpdesign.com.au>
	<20101223061806.GA12874@jasper.tkos.co.il>
Message-ID: <20101223070707.GK19266@game.jcrosoft.org>

On 08:18 Thu 23 Dec     , Baruch Siach wrote:
> Hi Marc,
> 
> On Thu, Dec 23, 2010 at 11:03:31AM +1100, Marc Reilly wrote:
> > I want to be able to determine what version of barebox I have on my NOR 
> > flash, after booting into linux.
> 
> [snip]
> 
> > Does anybody else accomplish this in a better way? (I don't want to pass the 
> > barebox version as an arg when booting the kernel - I'd rather it be more 
> > "standalone").
> 
> I set the board revision number, using armlinux_set_revision(), to pass the 
> version of the bootloader to the kernel, and then extract it from the 
> 'Revision' field in /proc/cpuinfo. This solution is ARM specific, though.
It will be better to have a std way as you mqy ise the system_rev for other
stuff as example on some at91

I sync we could generate a /etc/version in the env and then export it in linux
via the fs

I think we could do like this

in barebox itself we keep a default read only fs (default env) that we merge
the same way as a unionfs in barebox to avoid duplication and allow non
modifable file with the rw env

and we will do it in linux also

so linux can get the data from barebox and modify it

Best Regards,
J.


From s.hauer at pengutronix.de  Thu Dec 23 05:36:18 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 23 Dec 2010 11:36:18 +0100
Subject: [PATCH 5] Fix error handling with malloc, memalign etc.
	Memalign() can't fail now.
In-Reply-To: <20101222005829.GE19266@game.jcrosoft.org>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3vd2ocax2.fsf@intrepid.localdomain>
	<20101222005829.GE19266@game.jcrosoft.org>
Message-ID: <20101223103618.GF6017@pengutronix.de>

On Wed, Dec 22, 2010 at 01:58:29AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
>   
> > diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
> > index 717fea5..9d52beb 100644
> > --- a/drivers/clk/clkdev.c
> > +++ b/drivers/clk/clkdev.c
> please do not modify it I want to keep it as in the kernel

That's not a good reason to not change it. Keeping it in sync with the kernel
should not be the showstopper for reasonable changes.
I agree that it's sometimes useful to not needlessly change complex
frameworks like UBI or mtd(-nand) to be able to apply later bugfixes or
features from the kernel, but this doesn't match for these trivial
changes in a simple framework.

Sascha

> > @@ -116,9 +116,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
> >  {
> >  	struct clk_lookup_alloc *cla;
> >  
> > -	cla = kzalloc(sizeof(*cla), GFP_KERNEL);
> > -	if (!cla)
> > -		return NULL;
> > +	cla = xzalloc(sizeof(*cla), GFP_KERNEL);
> >  
> >  	cla->cl.clk = clk;
> >  	if (con_id) {
> > @@ -150,8 +148,6 @@ int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
> >  
> >  	l = clkdev_alloc(r, alias, alias_dev_name);
> >  	clk_put(r);
> > -	if (!l)
> > -		return -ENODEV;
> >  	clkdev_add(l);
> >  	return 0;
> >  }
> 
> Best Regards,
> J.
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Thu Dec 23 05:47:08 2010
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 23 Dec 2010 11:47:08 +0100
Subject: [PATCH 6] ARM: support big/little endian switching in "bootz".
In-Reply-To: <m3r5d963id.fsf@intrepid.localdomain>
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3tyi8carg.fsf@intrepid.localdomain>
	<20101222010047.GF19266@game.jcrosoft.org>
	<m3r5d963id.fsf@intrepid.localdomain>
Message-ID: <20101223104708.GG6017@pengutronix.de>

On Wed, Dec 22, 2010 at 07:55:54PM +0100, Krzysztof Halasa wrote:
> Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com> writes:
> 
> >> ARM: support big/little endian switching in "bootz".
> 
> > don't we need to update bootm and bootu too?
> 
> Probably. I've never used bootu, so it would be best if someone familiar
> with it made the change (or at least tested it).

For bootu there will be no simple way to recognize the endianess. The
image started here is a raw binary image without any header information.
We'll probably need a command line switch to switch the endianess
manually.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From khc at pm.waw.pl  Thu Dec 23 06:25:07 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Thu, 23 Dec 2010 12:25:07 +0100
Subject: [PATCH 5] Fix error handling with malloc,
	memalign etc. Memalign() can't fail now.
In-Reply-To: <m3mxnx63ae.fsf@intrepid.localdomain> (Krzysztof Halasa's message
	of "Wed, 22 Dec 2010 20:00:41 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3vd2ocax2.fsf@intrepid.localdomain>
	<20101222005829.GE19266@game.jcrosoft.org>
	<m3mxnx63ae.fsf@intrepid.localdomain>
Message-ID: <m3ei98loj0.fsf@intrepid.localdomain>

Krzysztof Halasa <khc at pm.waw.pl> writes:

> What's the rationale BTW?

Oops sorry, you stated it. Must have been tired.
-- 
Krzysztof Halasa


From gclement00 at gmail.com  Thu Dec 23 06:30:42 2010
From: gclement00 at gmail.com (Gregory CLEMENT)
Date: Thu, 23 Dec 2010 12:30:42 +0100
Subject: [PATCH] Add gpio command support to STM/i.MX arch
In-Reply-To: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
Message-ID: <AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>

2010/12/21 Juergen Beisert <jbe at pengutronix.de>:
> In order to complete graphics handling on STM/i.MX architecture, the platforms
> need GPIO command support (for example to enable the display and backlight).
>
Hi,
I tested this patchset on my board using an imx23. It seems OK.
So if you want you can add a
Tested-by: Gregory CLEMENT <gregory.clement at free-electrons.com>

> The following changes since commit af05a9dd223f0a77133e37893354680c2f857a54:
>
> ?xyzModem.c: fix 'dummy' is used uninitialized in this function warning (2010-12-21 10:23:41 +0100)
>
> are available in the git repository at:
> ?http://git.pengutronix.de/git/jbe/for_barebox_next/ next_stm_gpio_v3
>

I didn't manage to get your git tree:
$ git remote add -f jbe http://git.pengutronix.de/git/jbe/for_barebox_next
Updating jbe
fatal: http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
not found: did you run git update-server-info on the server?
error: Could not fetch jbe

Indeed http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
does not exist.
Maybe I did something wrong or maybe be you have to run git
update-server-info on the server ;)

> Juergen Beisert (9):
> ? ? ?Fix a typo in the GPIO doc
> ? ? ?ARM STM/i.MX: Fix register offset calculation for GPIO input pins
> ? ? ?ARM STM/i.MX: Remove variable size restrictions in iomux managing routines
> ? ? ?ARM STM/i.MX: Setting the iomux needs at least 32 bit.
> ? ? ?ARM STM/i.MX: Just fix the docs
> ? ? ?ARM STM/i.MX: Add support for the gpio commands
> ? ? ?ARM STM/i.MX: Avoid very long lines
> ? ? ?ARM STM/i.MX: Replace cryptic numbers
> ? ? ?ARM Chumby: Add list of available GPIOs and their meaning
>
> ?arch/arm/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
> ?arch/arm/boards/chumby_falconwing/falconwing.c | ? 85 ++++++++++++++++++++++++
> ?arch/arm/configs/chumbyone_defconfig ? ? ? ? ? | ? ?1 +
> ?arch/arm/configs/tx28stk5_defconfig ? ? ? ? ? ?| ? ?1 +
> ?arch/arm/mach-stm/include/mach/gpio.h ? ? ? ? ?| ? ?8 ++-
> ?arch/arm/mach-stm/iomux-imx.c ? ? ? ? ? ? ? ? ?| ? 85 +++++++++++++++++++++---
> ?commands/gpio.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +-
> ?7 files changed, 171 insertions(+), 12 deletions(-)
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>



-- 
Gregory CLEMENT


From khc at pm.waw.pl  Thu Dec 23 06:42:33 2010
From: khc at pm.waw.pl (Krzysztof Halasa)
Date: Thu, 23 Dec 2010 12:42:33 +0100
Subject: [PATCH 10] ARM: Add support for IXP4xx CPU and for Goramo
	Multilink router platform.
In-Reply-To: <20101223032631.GI19266@game.jcrosoft.org> (Jean-Christophe
	PLAGNIOL-VILLARD's message of "Thu, 23 Dec 2010 04:26:31 +0100")
References: <m362uodqms.fsf@intrepid.localdomain>
	<m3oc8gcae3.fsf@intrepid.localdomain>
	<20101222005722.GD19266@game.jcrosoft.org>
	<20101222124635.GC6017@pengutronix.de>
	<m3bp4d61mp.fsf@intrepid.localdomain>
	<20101223032631.GI19266@game.jcrosoft.org>
Message-ID: <m3aajwlnpy.fsf@intrepid.localdomain>

Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com> writes:

> I'm working on a fs support in linux of the barebox env
>
> so linux could get it easly also

If I can put the original copy in RO blocks and use some sort of unionfs
to make it RW, and even better, to export it to Linux easily, then it
may be a way to go for me, too. Meanwhile I have to use what's already
available.

> but I prefer to be able to change my micro code as some of the people who work
> on IXP have acess to it to modify it. So I think its a good option

IOW you (and/or people you know) do have means to change the microcode?
E.g. some documentation, tools (assembler?) or something like that?
Is it something you could make available to me? I'd be interested in
hacking (at least) the NPE-A HSS microcode, though at present, without
any docs, the amount of work needed is prohibitive.

BTW different boards can supply the microcode using different means.
-- 
Krzysztof Halasa


From jbe at pengutronix.de  Thu Dec 23 06:50:07 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Thu, 23 Dec 2010 12:50:07 +0100
Subject: [PATCH] Add gpio command support to STM/i.MX arch
In-Reply-To: <AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
	<AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>
Message-ID: <201012231250.08304.jbe@pengutronix.de>

Gregory CLEMENT wrote:
> [...]
> > are available in the git repository at:
> > ?http://git.pengutronix.de/git/jbe/for_barebox_next/ next_stm_gpio_v3
>
> I didn't manage to get your git tree:
> $ git remote add -f jbe http://git.pengutronix.de/git/jbe/for_barebox_next
> Updating jbe
> fatal: http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
> not found: did you run git update-server-info on the server?
> error: Could not fetch jbe
>
> Indeed http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
> does not exist.
> Maybe I did something wrong or maybe be you have to run git
> update-server-info on the server ;)

Sorry, I'm not a git expert. But this will show the content:

http://git.pengutronix.de/?p=jbe/for_barebox_next;a=summary

Don't know, what's wrong.

@Uwe: ?

jbe
-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From eric at eukrea.com  Thu Dec 23 06:53:11 2010
From: eric at eukrea.com (=?ISO-8859-1?Q?Eric_B=E9nard?=)
Date: Thu, 23 Dec 2010 12:53:11 +0100
Subject: [PATCH] Add gpio command support to STM/i.MX arch
In-Reply-To: <AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
	<AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>
Message-ID: <4D133827.4080204@eukrea.com>

On 23/12/2010 12:30, Gregory CLEMENT wrote:
> I didn't manage to get your git tree:
> $ git remote add -f jbe http://git.pengutronix.de/git/jbe/for_barebox_next
> Updating jbe
> fatal: http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
> not found: did you run git update-server-info on the server?
> error: Could not fetch jbe
>
> Indeed http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
> does not exist.
> Maybe I did something wrong or maybe be you have to run git
> update-server-info on the server ;)
>
try using git protocol instead of http, this works on other tree on the 
pengutronix git server :
git://git.pengutronix.de/git/jbe/for_barebox_next

Eric


From gregory.clement at free-electrons.com  Thu Dec 23 06:58:40 2010
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 23 Dec 2010 12:58:40 +0100
Subject: [PATCH] Add gpio command support to STM/i.MX arch
In-Reply-To: <201012231250.08304.jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
	<AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>
	<201012231250.08304.jbe@pengutronix.de>
Message-ID: <4D133970.7090602@free-electrons.com>

On 12/23/2010 12:50 PM, Juergen Beisert wrote:
> Gregory CLEMENT wrote:
>> [...]
>>> are available in the git repository at:
>>>  http://git.pengutronix.de/git/jbe/for_barebox_next/ next_stm_gpio_v3
>>
>> I didn't manage to get your git tree:
>> $ git remote add -f jbe http://git.pengutronix.de/git/jbe/for_barebox_next
>> Updating jbe
>> fatal: http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
>> not found: did you run git update-server-info on the server?
>> error: Could not fetch jbe
>>
>> Indeed http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
>> does not exist.
>> Maybe I did something wrong or maybe be you have to run git
>> update-server-info on the server ;)
> 
> Sorry, I'm not a git expert. But this will show the content:
> 
> http://git.pengutronix.de/?p=jbe/for_barebox_next;a=summary
> 
> Don't know, what's wrong.
> 
> @Uwe: ?
> 

The problem was that I used http protocol instead of git protocol.
this command finally worked perfectly:
$git remote add -f jbe git://git.pengutronix.de/git/jbe/for_barebox_next

Thanks to Eric B?nard for his advice.


> jbe


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From gregory.clement at free-electrons.com  Thu Dec 23 07:15:51 2010
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 23 Dec 2010 13:15:51 +0100
Subject: Nand support on STM/i.MX (especially iMX23)
Message-ID: <4D133D77.5090908@free-electrons.com>

Hi,

I planned to add NAND support for iMX23 (which should work for iMX28). But this time before starting
writing this driver I would like to know if someone is already working on it.
If it is the case I would like to be involved in this development to bring my help.
If it is not the case, I considered to start from the driver supplied by freescale on thir 2.6.31 kernel.
Is it a good choice? Have you some advice to give me?

Thanks

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From baruch at tkos.co.il  Thu Dec 23 08:07:37 2010
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 23 Dec 2010 15:07:37 +0200
Subject: Nand support on STM/i.MX (especially iMX23)
In-Reply-To: <4D133D77.5090908@free-electrons.com>
References: <4D133D77.5090908@free-electrons.com>
Message-ID: <20101223130737.GE19735@jasper.tkos.co.il>

Hi Gregory,

On Thu, Dec 23, 2010 at 01:15:51PM +0100, Gregory CLEMENT wrote:
> I planned to add NAND support for iMX23 (which should work for iMX28). But 
> this time before starting
> writing this driver I would like to know if someone is already working on it.
> If it is the case I would like to be involved in this development to bring my help.
> If it is not the case, I considered to start from the driver supplied by freescale on thir 2.6.31 kernel.
> Is it a good choice? Have you some advice to give me?

In my opinion it should be easier to start with Freescale's 2.6.35 based 
kernel from branch imx_2.6.35_10.10.01 in 
http://opensource.freescale.com/pub/scm/imx/linux-2.6-imx.git, since it is 
closer to newer kernels.

baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From r.schwebel at pengutronix.de  Thu Dec 23 08:15:54 2010
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Thu, 23 Dec 2010 14:15:54 +0100
Subject: Nand support on STM/i.MX (especially iMX23)
In-Reply-To: <20101223130737.GE19735@jasper.tkos.co.il>
References: <4D133D77.5090908@free-electrons.com>
	<20101223130737.GE19735@jasper.tkos.co.il>
Message-ID: <20101223131554.GU4233@pengutronix.de>

On Thu, Dec 23, 2010 at 03:07:37PM +0200, Baruch Siach wrote:
> On Thu, Dec 23, 2010 at 01:15:51PM +0100, Gregory CLEMENT wrote:
> > I planned to add NAND support for iMX23 (which should work for
> > iMX28). But this time before starting writing this driver I would
> > like to know if someone is already working on it. If it is the case
> > I would like to be involved in this development to bring my help.
> > If it is not the case, I considered to start from the driver
> > supplied by freescale on thir 2.6.31 kernel. Is it a good choice?
> > Have you some advice to give me?
>
> In my opinion it should be easier to start with Freescale's 2.6.35
> based kernel from branch imx_2.6.35_10.10.01 in
> http://opensource.freescale.com/pub/scm/imx/linux-2.6-imx.git, since
> it is closer to newer kernels.

We are working on more mainline support for all kinds of peripherals for
the MX23 and MX28, but until now, nobody has started with NAND yet.

As far as I remember, the FSL code was really, really uggly, so it will
probably need an experienced look at the design. I suppose that there
will be not much activity over the holidays, so if you want to go ahead,
keep the list informed.

rsc
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From u.kleine-koenig at pengutronix.de  Thu Dec 23 09:36:08 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Thu, 23 Dec 2010 15:36:08 +0100
Subject: [PATCH] Add gpio command support to STM/i.MX arch
In-Reply-To: <201012231250.08304.jbe@pengutronix.de>
References: <1292930721-31734-1-git-send-email-jbe@pengutronix.de>
	<AANLkTik0aw9XY6Lqcmwhihwgk0CW86cGEmC+Q3=Kf-mS@mail.gmail.com>
	<201012231250.08304.jbe@pengutronix.de>
Message-ID: <20101223143608.GV14221@pengutronix.de>

On Thu, Dec 23, 2010 at 12:50:07PM +0100, Juergen Beisert wrote:
> Gregory CLEMENT wrote:
> > [...]
> > > are available in the git repository at:
> > > ?http://git.pengutronix.de/git/jbe/for_barebox_next/ next_stm_gpio_v3
> >
> > I didn't manage to get your git tree:
> > $ git remote add -f jbe http://git.pengutronix.de/git/jbe/for_barebox_next
> > Updating jbe
> > fatal: http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
> > not found: did you run git update-server-info on the server?
                           ^^^^^^^^^^^^^^^^^^^^^^
you only need to believe this :-)

> > error: Could not fetch jbe
> >
> > Indeed http://git.pengutronix.de/git/jbe/for_barebox_next/info/refs
> > does not exist.
> > Maybe I did something wrong or maybe be you have to run git
> > update-server-info on the server ;)
> 
> Sorry, I'm not a git expert. But this will show the content:
> 
> http://git.pengutronix.de/?p=jbe/for_barebox_next;a=summary
> 
> Don't know, what's wrong.
> 
> @Uwe: ?
You need to do

	cd /path/to/your/for_barebox_next-repo
	git update-server-info

(to fix this for now and )

	mv hooks/post-update.sample hooks/post-update

(to assert it stays fixed when you push the next time.)

But in general git:// is preferable because it only transfers the needed
objects (in contrast to the complete history when the repository is
perfectly packed even you only miss a single object).

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From franck.jullien at gmail.com  Thu Dec 23 16:42:34 2010
From: franck.jullien at gmail.com (Franck JULLIEN)
Date: Thu, 23 Dec 2010 22:42:34 +0100
Subject: [PATCH] Add a board specific fancy banner
Message-ID: <AANLkTik+7KJrf3H6ZW3i9pA115p2Gn=k=CXYHg5YJwRY@mail.gmail.com>

Hello,

This is the first time I'm using git and submit a patch so if I made a
mistake be cool :)
This is a small patch allowing the user to define a fancy banner for
barebox. I don't know
if you'll use it but it's kind of an experience for me.

I have ported barebox to the altera nios2 processor. I think I'll submit the
corresponding patch
on january. However, I'll need some advices to generate such a big (or lot
of small) patch.

Thanks,
Franck.

-----

from: franck JULLIEN <franck.jullien at gmail.com>
Date: Thu, 23 Dec 2010 22:31:22 +0100
Subject: [PATCH] Add a board specific fancy banner

---
 common/Kconfig   |    6 ++++++
 common/console.c |   10 ++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 617f640..d46c8fc 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -248,6 +248,12 @@ config HUSH_FANCY_PROMPT
   Allow to set PS1 from the command line. PS1 can have several escaped
commands
   like \h for CONFIG_BOARDINFO or \w for the current working directory.

+config BOARD_BANNER
+ bool
+ prompt "allow a board specific fancy banner"
+ help
+  Allow to define a custom board banner (you must define BOARD_BANNER in
your config.h)
+
 config HUSH_GETOPT
  bool
  depends on SHELL_HUSH
diff --git a/common/console.c b/common/console.c
index 82786f2..8a830e3 100644
--- a/common/console.c
+++ b/common/console.c
@@ -46,7 +46,17 @@ EXPORT_SYMBOL(console_list);
 static void display_banner (void)
 {
  printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
+#ifdef CONFIG_BOARD_BANNER
+#ifdef BOARD_BANNER
+ printf(RELOC(BOARD_BANNER));
+#else
+#define VT100_YELLOW "\033[1;33m"
+#define VT100_RESET "\033[1;0m"
+ printf(RELOC("Board: " VT100_YELLOW CONFIG_BOARDINFO VT100_RESET "\n"));
+#endif
+#else
  printf(RELOC("Board: " CONFIG_BOARDINFO "\n"));
+#endif
 }

 static int __early_initdata initialized = 0;
-- 
1.7.0.4
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20101223/e5b12cb8/attachment.html>

From plagnioj at jcrosoft.com  Sat Dec 25 01:38:39 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Sat, 25 Dec 2010 07:38:39 +0100
Subject: [PATCH] Add a board specific fancy banner
In-Reply-To: <AANLkTik+7KJrf3H6ZW3i9pA115p2Gn=k=CXYHg5YJwRY@mail.gmail.com>
References: <AANLkTik+7KJrf3H6ZW3i9pA115p2Gn=k=CXYHg5YJwRY@mail.gmail.com>
Message-ID: <20101225063839.GM19266@game.jcrosoft.org>

On 22:42 Thu 23 Dec     , Franck JULLIEN wrote:
>    Hello,
>    This is the first time I'm using git and submit a patch so if I made a
>    mistake be cool :)
>    This is a small patch allowing the user to define a fancy banner for
>    barebox. I don't know
>    if you'll use it but it's kind of an experience for me.
>    I have ported barebox to the altera nios2 processor. I think I'll submit
>    the corresponding patch
>    on january. However, I'll need some advices to generate such a big (or lot
>    of small) patch.
It will be better to do it via Kconfig and avoid the ifdef

for the nios2 it will be better to spit it in small patch than a big one

Best Regards,
J.


From u.kleine-koenig at pengutronix.de  Sun Dec 26 06:48:41 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Sun, 26 Dec 2010 12:48:41 +0100
Subject: [PATCH] Add a board specific fancy banner
In-Reply-To: <AANLkTik+7KJrf3H6ZW3i9pA115p2Gn=k=CXYHg5YJwRY@mail.gmail.com>
References: <AANLkTik+7KJrf3H6ZW3i9pA115p2Gn=k=CXYHg5YJwRY@mail.gmail.com>
Message-ID: <20101226114841.GH14221@pengutronix.de>

Hello Franck,

On Thu, Dec 23, 2010 at 10:42:34PM +0100, Franck JULLIEN wrote:
> This is the first time I'm using git and submit a patch so if I made a
> mistake be cool :)
:-)

>  common/Kconfig   |    6 ++++++
>  common/console.c |   10 ++++++++++
>  2 files changed, 16 insertions(+), 0 deletions(-)
> 
> diff --git a/common/Kconfig b/common/Kconfig
> index 617f640..d46c8fc 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -248,6 +248,12 @@ config HUSH_FANCY_PROMPT
>    Allow to set PS1 from the command line. PS1 can have several escaped
> commands
>    like \h for CONFIG_BOARDINFO or \w for the current working directory.
> 
> +config BOARD_BANNER
> + bool
> + prompt "allow a board specific fancy banner"
> + help
> +  Allow to define a custom board banner (you must define BOARD_BANNER in
> your config.h)
Your patch is line broken, which makes is unapplicable.  I don't know
which MUA you're using, but you either should use git send-email or take
a look into

	http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches;h=72741ebda12de8fbf786f12531d70ab465eecf42;hb=HEAD#l333

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From franck.jullien at gmail.com  Sun Dec 26 16:40:52 2010
From: franck.jullien at gmail.com (Franck JULLIEN)
Date: Sun, 26 Dec 2010 22:40:52 +0100
Subject: [PATCH] (reformated) Allow board specific fancy banner
Message-ID: <1293399652-2615-1-git-send-email-franck.jullien@gmail.com>

This time I used git to send the email. I think I get it right.
However, I didn't find how to put this file in the thread we were later...
I don't think it is possible since those emails didn't have ID's to use with
the In-Reply-To option (right ?).

---
 common/Kconfig   |    6 ++++++
 common/console.c |   10 ++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 617f640..d46c8fc 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -248,6 +248,12 @@ config HUSH_FANCY_PROMPT
 	  Allow to set PS1 from the command line. PS1 can have several escaped commands
 	  like \h for CONFIG_BOARDINFO or \w for the current working directory.
 
+config BOARD_BANNER
+	bool
+	prompt "allow a board specific fancy banner"
+	help
+	  Allow to define a custom board banner (you must define BOARD_BANNER in your config.h)
+
 config HUSH_GETOPT
 	bool
 	depends on SHELL_HUSH
diff --git a/common/console.c b/common/console.c
index 82786f2..8a830e3 100644
--- a/common/console.c
+++ b/common/console.c
@@ -46,7 +46,17 @@ EXPORT_SYMBOL(console_list);
 static void display_banner (void)
 {
 	printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
+#ifdef CONFIG_BOARD_BANNER
+#ifdef BOARD_BANNER
+	printf(RELOC(BOARD_BANNER));
+#else
+#define VT100_YELLOW	"\033[1;33m"
+#define VT100_RESET	"\033[1;0m"
+	printf(RELOC("Board: " VT100_YELLOW CONFIG_BOARDINFO VT100_RESET "\n"));
+#endif
+#else
 	printf(RELOC("Board: " CONFIG_BOARDINFO "\n"));
+#endif
 }
 
 static int __early_initdata initialized = 0;
-- 
1.7.1



From plagnioj at jcrosoft.com  Mon Dec 27 01:43:05 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Mon, 27 Dec 2010 07:43:05 +0100
Subject: [PATCH] (reformated) Allow board specific fancy banner
In-Reply-To: <1293399652-2615-1-git-send-email-franck.jullien@gmail.com>
References: <1293399652-2615-1-git-send-email-franck.jullien@gmail.com>
Message-ID: <20101227064305.GN19266@game.jcrosoft.org>

On 22:40 Sun 26 Dec     , Franck JULLIEN wrote:
> This time I used git to send the email. I think I get it right.
> However, I didn't find how to put this file in the thread we were later...
> I don't think it is possible since those emails didn't have ID's to use with
> the In-Reply-To option (right ?).
> 
> ---
>  common/Kconfig   |    6 ++++++
>  common/console.c |   10 ++++++++++
>  2 files changed, 16 insertions(+), 0 deletions(-)
> 
> diff --git a/common/Kconfig b/common/Kconfig
> index 617f640..d46c8fc 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -248,6 +248,12 @@ config HUSH_FANCY_PROMPT
>  	  Allow to set PS1 from the command line. PS1 can have several escaped commands
>  	  like \h for CONFIG_BOARDINFO or \w for the current working directory.
>  
> +config BOARD_BANNER
> +	bool
> +	prompt "allow a board specific fancy banner"
> +	help
> +	  Allow to define a custom board banner (you must define BOARD_BANNER in your config.h)
> +
>  config HUSH_GETOPT
>  	bool
>  	depends on SHELL_HUSH
> diff --git a/common/console.c b/common/console.c
> index 82786f2..8a830e3 100644
> --- a/common/console.c
> +++ b/common/console.c
> @@ -46,7 +46,17 @@ EXPORT_SYMBOL(console_list);
>  static void display_banner (void)
>  {
>  	printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
> +#ifdef CONFIG_BOARD_BANNER
> +#ifdef BOARD_BANNER
> +	printf(RELOC(BOARD_BANNER));
> +#else
> +#define VT100_YELLOW	"\033[1;33m"
> +#define VT100_RESET	"\033[1;0m"
> +	printf(RELOC("Board: " VT100_YELLOW CONFIG_BOARDINFO VT100_RESET "\n"));
why not define it in the Kconfig simply?

I'm sorry but I do not see why we can not do it in the defconfig

Best Regards,
J.


From plagnioj at jcrosoft.com  Tue Dec 28 01:33:00 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Tue, 28 Dec 2010 07:33:00 +0100
Subject: [PATCH] (reformated) Allow board specific fancy banner
In-Reply-To: <AANLkTik6kuBviOejiXT_6eU2ZiaagDDMJy2Fsgc_6dk_@mail.gmail.com>
References: <1293399652-2615-1-git-send-email-franck.jullien@gmail.com>
	<20101227064305.GN19266@game.jcrosoft.org>
	<AANLkTik6kuBviOejiXT_6eU2ZiaagDDMJy2Fsgc_6dk_@mail.gmail.com>
Message-ID: <20101228063300.GP19266@game.jcrosoft.org>

>      > diff --git a/common/console.c b/common/console.c
>      > index 82786f2..8a830e3 100644
>      > --- a/common/console.c
>      > +++ b/common/console.c
>      > @@ -46,7 +46,17 @@ EXPORT_SYMBOL(console_list);
>      >  static void display_banner (void)
>      >  {
>      >       printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
>      > +#ifdef CONFIG_BOARD_BANNER
>      > +#ifdef BOARD_BANNER
>      > +     printf(RELOC(BOARD_BANNER));
>      > +#else
>      > +#define VT100_YELLOW "\033[1;33m"
>      > +#define VT100_RESET  "\033[1;0m"
>      > +     printf(RELOC("Board: " VT100_YELLOW CONFIG_BOARDINFO VT100_RESET
>      "\n"));
>      why not define it in the Kconfig simply?
> 
>      I'm sorry but I do not see why we can not do it in the defconfig
> 
>      Best Regards,
>      J.
> 
>    We could do it in the arch/_the_arch_/Kconfig with depends on _your_board_
>    but I don't think that the better/more generic way. Moreover, if we ask
>    for the banner in Kconfig (with a string entry), fancy escape code and/or
>    carriage return will be hard to enter manually.
>    This is for example what I use for my neek board:
>    #define BOARD_BANNER "\e[1;32m\
>    ****************************************\n\
>    *          Altera NEEK board           *\n\
>    ****************************************\
>    \e[0m\n\n"
>    However, if you want I could manage to use the Kconfig way.....
>    Best regards,
so define completely the banner in the config.h
no VT100.... in the console.c as diferrent boards will have different colour

and something like this will be better 

#ifndef CONFIG_BOARD_BANNER
#undef  CONFIG_BOARD_BANNER_TEXT
#define CONFIG_BOARD_BANNER_TEXT "Board: " CONFIG_BOARDINFO "\n"
#endif

printf(RELOC(CONFIG_BOARD_BANNER_TEXT));

please keep CONFIG_xxxx for the macro even in the config.h

Best Regards,
J.


From marek.belisko at gmail.com  Wed Dec 29 05:39:35 2010
From: marek.belisko at gmail.com (Belisko Marek)
Date: Wed, 29 Dec 2010 11:39:35 +0100
Subject: x86 compilation broken in next branch
Message-ID: <AANLkTikS9O0_kNedeaCMRLvn9eH=kCK5ThJkFAAZ6JOs@mail.gmail.com>

Try to play around barebox on x86 will get following error:
ld: barebox section `.initcall.8' will not fit in region `mbr'
ld: section .initcall.8 loaded at [0000000000000400,0000000000000407]
overlaps section .bootstrapping loaded at
[0000000000000400,0000000000000867]
ld: region `mbr' overflowed by 8 bytes
make: *** [barebox] Error 1

thanks,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
icq: 290551086
web: http://open-nandra.com


From jbe at pengutronix.de  Wed Dec 29 06:28:28 2010
From: jbe at pengutronix.de (Juergen Beisert)
Date: Wed, 29 Dec 2010 12:28:28 +0100
Subject: x86 compilation broken in next branch
In-Reply-To: <AANLkTikS9O0_kNedeaCMRLvn9eH=kCK5ThJkFAAZ6JOs@mail.gmail.com>
References: <AANLkTikS9O0_kNedeaCMRLvn9eH=kCK5ThJkFAAZ6JOs@mail.gmail.com>
Message-ID: <201012291228.28623.jbe@pengutronix.de>

Belisko Marek wrote:
> Try to play around barebox on x86 will get following error:
> ld: barebox section `.initcall.8' will not fit in region `mbr'
> ld: section .initcall.8 loaded at [0000000000000400,0000000000000407]
> overlaps section .bootstrapping loaded at
> [0000000000000400,0000000000000867]
> ld: region `mbr' overflowed by 8 bytes
> make: *** [barebox] Error 1

I know. I'm working on a fix.

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |


From u.kleine-koenig at pengutronix.de  Wed Dec 29 06:36:52 2010
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 29 Dec 2010 12:36:52 +0100
Subject: [PATCH] (reformated) Allow board specific fancy banner
In-Reply-To: <1293399652-2615-1-git-send-email-franck.jullien@gmail.com>
References: <1293399652-2615-1-git-send-email-franck.jullien@gmail.com>
Message-ID: <20101229113652.GC14221@pengutronix.de>

On Sun, Dec 26, 2010 at 10:40:52PM +0100, Franck JULLIEN wrote:
> This time I used git to send the email. I think I get it right.
> However, I didn't find how to put this file in the thread we were later...
> I don't think it is possible since those emails didn't have ID's to use with
> the In-Reply-To option (right ?).
--in-reply-to 'AANLkTik+7KJrf3H6ZW3i9pA115p2Gn=k=CXYHg5YJwRY at mail.gmail.com'
would have been the correct option.

And please put such infomal text after the tripple dash below, otherwise
it will end up in the commit log.

> ---
>  common/Kconfig   |    6 ++++++
>  common/console.c |   10 ++++++++++
>  2 files changed, 16 insertions(+), 0 deletions(-)
> 
> diff --git a/common/Kconfig b/common/Kconfig
> index 617f640..d46c8fc 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -248,6 +248,12 @@ config HUSH_FANCY_PROMPT
>  	  Allow to set PS1 from the command line. PS1 can have several escaped commands
>  	  like \h for CONFIG_BOARDINFO or \w for the current working directory.
>  
> +config BOARD_BANNER
> +	bool
> +	prompt "allow a board specific fancy banner"
> +	help
> +	  Allow to define a custom board banner (you must define BOARD_BANNER in your config.h)
The patch below seems to handle a missing BOARD_BANNER just fine, so
maybe s/must/can/.

Best regards
Uwe
> +
>  config HUSH_GETOPT
>  	bool
>  	depends on SHELL_HUSH
> diff --git a/common/console.c b/common/console.c
> index 82786f2..8a830e3 100644
> --- a/common/console.c
> +++ b/common/console.c
> @@ -46,7 +46,17 @@ EXPORT_SYMBOL(console_list);
>  static void display_banner (void)
>  {
>  	printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
> +#ifdef CONFIG_BOARD_BANNER
> +#ifdef BOARD_BANNER
> +	printf(RELOC(BOARD_BANNER));
> +#else
> +#define VT100_YELLOW	"\033[1;33m"
> +#define VT100_RESET	"\033[1;0m"
> +	printf(RELOC("Board: " VT100_YELLOW CONFIG_BOARDINFO VT100_RESET "\n"));
> +#endif
> +#else
>  	printf(RELOC("Board: " CONFIG_BOARDINFO "\n"));
> +#endif
>  }
>  
>  static int __early_initdata initialized = 0;
> -- 
> 1.7.1
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From gclement00 at gmail.com  Wed Dec 29 09:55:15 2010
From: gclement00 at gmail.com (Gregory CLEMENT)
Date: Wed, 29 Dec 2010 15:55:15 +0100
Subject: [PATCH 08/10] ARM STM/i.MX: Add video driver for i.MX23/i.MX28
In-Reply-To: <1292857509-13881-9-git-send-email-jbe@pengutronix.de>
References: <1292857509-13881-1-git-send-email-jbe@pengutronix.de>
	<1292857509-13881-9-git-send-email-jbe@pengutronix.de>
Message-ID: <AANLkTinXmZiA1pVk43fMu1w1mXDBHHpUj-LxJ_YJkn6L@mail.gmail.com>

Hi,
I apply this patch for my project and use it with an imx23 base board.
I have a few comments and I think that I found a bug.
I you are interested I can send you patches related to my comments.

2010/12/20 Juergen Beisert <jbe at pengutronix.de>:
> Signed-off-by: Juergen Beisert <jbe at pengutronix.de>
> ---
> ?arch/arm/mach-stm/include/mach/fb.h ? ? ? ? | ? 43 +++
> ?arch/arm/mach-stm/include/mach/imx23-regs.h | ? ?1 +
> ?drivers/video/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? ?7 +
> ?drivers/video/Makefile ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?drivers/video/stm.c ? ? ? ? ? ? ? ? ? ? ? ? | ?540 +++++++++++++++++++++++++++
> ?5 files changed, 592 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/mach-stm/include/mach/fb.h
> ?create mode 100644 drivers/video/stm.c
>
> diff --git a/arch/arm/mach-stm/include/mach/fb.h b/arch/arm/mach-stm/include/mach/fb.h
> new file mode 100644
> index 0000000..65e3be2
> --- /dev/null
> +++ b/arch/arm/mach-stm/include/mach/fb.h
> @@ -0,0 +1,43 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef __MACH_FB_H
> +# define __MACH_FB_H
> +
> +#include <fb.h>
> +
> +#define STMLCDIF_8BIT 1 ? ? ? ?/** pixel data bus to the display is of 8 bit width */
> +#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
> +#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
> +#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
> +
> +/** LC display uses active high data enable signal */
> +#define FB_SYNC_DE_HIGH_ACT ? ?(1 << 27)
> +/** LC display will latch its data at clock's rising edge */
> +#define FB_SYNC_CLK_INVERT ? ? (1 << 28)
> +/** output RGB digital data inverted */
> +#define FB_SYNC_DATA_INVERT ? ?(1 << 29)
> +/** Stop clock if no data is sent (required for passive displays) */
> +#define FB_SYNC_CLK_IDLE_DIS ? (1 << 30)
> +/** swap RGB to BGR */
> +#define FB_SYNC_SWAP_RGB ? ? ? (1 << 31)
> +
> +struct imx_fb_videomode {
> + ? ? ? struct fb_videomode *mode_list;
> + ? ? ? unsigned mode_cnt;
> +
> + ? ? ? unsigned dotclk_delay; ?/**< refer manual HW_LCDIF_VDCTRL4 register */
> + ? ? ? unsigned ld_intf_width; /**< refer STMLCDIF_* macros */
> +};

Should it be acceptable to add new field in this structure ?
For example for my need I added a data_mode flag which is used to configure
command mode polarity (bit 16 in HW_LCDIF_CTRL register)

> +
> +#endif /* __MACH_FB_H */
> +
> diff --git a/arch/arm/mach-stm/include/mach/imx23-regs.h b/arch/arm/mach-stm/include/mach/imx23-regs.h
> index 89ca453..caac19b 100644
> --- a/arch/arm/mach-stm/include/mach/imx23-regs.h
> +++ b/arch/arm/mach-stm/include/mach/imx23-regs.h
> @@ -36,6 +36,7 @@
> ?#define IMX_CCM_BASE ? ? ? ? ? 0x80040000
> ?#define IMX_I2C1_BASE ? ? ? ? ?0x80058000
> ?#define IMX_SSP1_BASE ? ? ? ? ?0x80010000
> +#define IMX_FB_BASE ? ? ? ? ? ?0x80030000
> ?#define IMX_SSP2_BASE ? ? ? ? ?0x80034000
>
> ?#endif /* __ASM_ARCH_MX23_REGS_H */
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 7a89a3f..c69308e 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -20,4 +20,11 @@ config DRIVER_VIDEO_IMX_IPU
> ? ? ? ? ?Add support for the IPU framebuffer device found on
> ? ? ? ? ?i.MX31 and i.MX35 CPUs.
>
> +config DRIVER_VIDEO_STM
> + ? ? ? bool "i.MX23/28 framebuffer driver"
> + ? ? ? depends on ARCH_STM
> + ? ? ? help
> + ? ? ? ? Say 'Y' here to enable framebuffer and splash screen support for
> + ? ? ? ? i.MX23 and i.MX28 based systems.
> +
> ?endif
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 179f0c4..a217a0b 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -1,4 +1,5 @@
> ?obj-$(CONFIG_VIDEO) += fb.o
>
> +obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o
> ?obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
> ?obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
> diff --git a/drivers/video/stm.c b/drivers/video/stm.c
> new file mode 100644
> index 0000000..f0abe4c
> --- /dev/null
> +++ b/drivers/video/stm.c
> @@ -0,0 +1,540 @@
> +/*
> + * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe at pengutronix.de>
> + *
> + * This is based on code from:
> + * Author: Vitaly Wool <vital at embeddedalley.com>
> + *
> + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
> + *
> + * 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.
> + */
> +#include <common.h>
> +#include <init.h>
> +#include <driver.h>
> +#include <malloc.h>
> +#include <errno.h>
> +#include <xfuncs.h>
> +#include <asm/io.h>
> +#include <mach/imx-regs.h>
> +#include <mach/clock.h>
> +#include <mach/fb.h>
> +
> +#define HW_LCDIF_CTRL 0x00
> +# define CTRL_SFTRST (1 << 31)
> +# define CTRL_CLKGATE (1 << 30)
> +# define CTRL_BYPASS_COUNT (1 << 19)
> +# define CTRL_VSYNC_MODE (1 << 18)
> +# define CTRL_DOTCLK_MODE (1 << 17)
> +# define CTRL_DATA_SELECT (1 << 16)
> +# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
> +# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
> +# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
> +# define CTRL_MASTER (1 << 5)
> +# define CTRL_DF16 (1 << 3)
> +# define CTRL_DF18 (1 << 2)
> +# define CTRL_DF24 (1 << 1)
> +# define CTRL_RUN (1 << 0)
> +
> +#define HW_LCDIF_CTRL1 0x10
> +# define CTRL1_FIFO_CLEAR (1 << 21)
> +# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
> +# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
> +
> +#ifdef CONFIG_ARCH_IMX28
> +# define HW_LCDIF_CTRL2 0x20
> +# define HW_LCDIF_TRANSFER_COUNT 0x30
> +#endif
> +#ifdef CONFIG_ARCH_IMX23
> +# define HW_LCDIF_TRANSFER_COUNT 0x20
> +#endif
> +# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
> +# define SET_HCOUNT(x) ((x) & 0xffff)
> +
> +#ifdef CONFIG_ARCH_IMX28
> +# define HW_LCDIF_CUR_BUF 0x40
> +# define HW_LCDIF_NEXT_BUF 0x50
> +#endif
> +#ifdef CONFIG_ARCH_IMX23
> +# define HW_LCDIF_CUR_BUF 0x30
> +# define HW_LCDIF_NEXT_BUF 0x40
> +#endif
> +
> +#define HW_LCDIF_TIMING 0x60
> +# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
> +# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
> +# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
> +# define SET_DATA_SETUP(x) ((x) & 0xff)
> +
> +#define HW_LCDIF_VDCTRL0 0x70
> +# define VDCTRL0_ENABLE_PRESENT (1 << 28)
> +# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
> +# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
> +# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output at falling, capturing at rising edge */
> +# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
> +# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
> +# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
> +# define VDCTRL0_HALF_LINE (1 << 19)
> +# define VDCTRL0_HALF_LINE_MODE (1 << 18)
> +# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
> +
> +#define HW_LCDIF_VDCTRL1 0x80
> +
> +#define HW_LCDIF_VDCTRL2 0x90
> +#ifdef CONFIG_ARCH_IMX28
> +# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
> +#endif
> +#ifdef CONFIG_ARCH_IMX23
> +# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0xff) << 24)
> +#endif
> +# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
> +
> +#define HW_LCDIF_VDCTRL3 0xa0
> +# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
> +# define VDCTRL3_VSYNC_ONLY (1 << 28)
> +# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
> +# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
> +
> +#define HW_LCDIF_VDCTRL4 0xb0
> +#ifdef CONFIG_ARCH_IMX28
> +# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
> +#endif
> +# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
> +# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
> +
> +#define HW_LCDIF_DVICTRL0 0xc0
> +#define HW_LCDIF_DVICTRL1 0xd0
> +#define HW_LCDIF_DVICTRL2 0xe0
> +#define HW_LCDIF_DVICTRL3 0xf0
> +#define HW_LCDIF_DVICTRL4 0x100
> +
> +#ifdef CONFIG_ARCH_IMX28
> +# define HW_LCDIF_DATA 0x180
> +#endif
> +#ifdef CONFIG_ARCH_IMX23
> +# define HW_LCDIF_DATA 0x1b0
> +#endif
> +
> +#ifdef CONFIG_ARCH_IMX28
> +# define HW_LCDIF_DEBUG0 0x1d0
> +#endif
> +#ifdef CONFIG_ARCH_IMX23
> +# define HW_LCDIF_DEBUG0 0x1f0
> +#endif
> +# define DEBUG_HSYNC (1 < 26)
> +# define DEBUG_VSYNC (1 < 25)
> +
> +#define RED 0
> +#define GREEN 1
> +#define BLUE 2
> +#define TRANSP 3
> +
> +struct imxfb_info {
> + ? ? ? void __iomem *base;
> + ? ? ? unsigned memory_size;
> + ? ? ? struct fb_info info;
> + ? ? ? struct device_d *hw_dev;
> + ? ? ? struct imx_fb_videomode *pdata;
> +};
> +
> +/* the RGB565 true colour mode */
> +static const struct fb_bitfield def_rgb565[] = {
> + ? ? ? [RED] = {
> + ? ? ? ? ? ? ? .offset = 11,
> + ? ? ? ? ? ? ? .length = 5,
> + ? ? ? },
> + ? ? ? [GREEN] = {
> + ? ? ? ? ? ? ? .offset = 5,
> + ? ? ? ? ? ? ? .length = 6,
> + ? ? ? },
> + ? ? ? [BLUE] = {
> + ? ? ? ? ? ? ? .offset = 0,
> + ? ? ? ? ? ? ? .length = 5,
> + ? ? ? },
> + ? ? ? [TRANSP] = { ? ?/* no support for transparency */
> + ? ? ? ? ? ? ? .length = 0,
> + ? ? ? }
> +};
> +
> +/* the RGB666 true colour mode */
> +static const struct fb_bitfield def_rgb666[] = {
> + ? ? ? [RED] = {
> + ? ? ? ? ? ? ? .offset = 16,
> + ? ? ? ? ? ? ? .length = 6,
> + ? ? ? },
> + ? ? ? [GREEN] = {
> + ? ? ? ? ? ? ? .offset = 8,
> + ? ? ? ? ? ? ? .length = 6,
> + ? ? ? },
> + ? ? ? [BLUE] = {
> + ? ? ? ? ? ? ? .offset = 0,
> + ? ? ? ? ? ? ? .length = 6,
> + ? ? ? },
> + ? ? ? [TRANSP] = { ? ?/* no support for transparency */
> + ? ? ? ? ? ? ? .length = 0,
> + ? ? ? }
> +};
> +
> +/* the RGB888 true colour mode */
> +static const struct fb_bitfield def_rgb888[] = {
> + ? ? ? [RED] = {
> + ? ? ? ? ? ? ? .offset = 16,
> + ? ? ? ? ? ? ? .length = 8,
> + ? ? ? },
> + ? ? ? [GREEN] = {
> + ? ? ? ? ? ? ? .offset = 8,
> + ? ? ? ? ? ? ? .length = 8,
> + ? ? ? },
> + ? ? ? [BLUE] = {
> + ? ? ? ? ? ? ? .offset = 0,
> + ? ? ? ? ? ? ? .length = 8,
> + ? ? ? },
> + ? ? ? [TRANSP] = { ? ?/* no support for transparency */
> + ? ? ? ? ? ? ? .length = 0,
> + ? ? ? }
> +};
> +
> +static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
> +{
> + ? ? ? if (bpp == 24)
> + ? ? ? ? ? ? ? bpp = 32;
> + ? ? ? return (ppl * bpp) >> 3;
> +}
> +
> +static int stmfb_memory_mmgt(struct fb_info *fb_info, unsigned size)
> +{
> + ? ? ? struct imxfb_info *fbi = fb_info->priv;
> +
> + ? ? ? if (fbi->memory_size != 0) {
> + ? ? ? ? ? ? ? free(fb_info->screen_base);
> + ? ? ? ? ? ? ? fb_info->screen_base = NULL;
> + ? ? ? ? ? ? ? fbi->memory_size = 0;
> + ? ? ? }
> +
> + ? ? ? if (fbi->memory_size == 0) {
> + ? ? ? ? ? ? ? fb_info->screen_base = xzalloc(size);
> + ? ? ? ? ? ? ? fbi->memory_size = size;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static void stmfb_enable_controller(struct fb_info *fb_info)
> +{
> + ? ? ? struct imxfb_info *fbi = fb_info->priv;
> + ? ? ? uint32_t reg, last_reg;
> + ? ? ? unsigned loop, edges;
> +
> + ? ? ? /*
> + ? ? ? ?* Sometimes some data is still present in the FIFO. This leads into
> + ? ? ? ?* a correct but shifted picture. Clearing the FIFO helps
> + ? ? ? ?*/
> + ? ? ? writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_SET);
> +
> + ? ? ? /* if it was disabled, re-enable the mode again */
> + ? ? ? reg = readl(fbi->base + HW_LCDIF_CTRL);
> + ? ? ? reg |= CTRL_DOTCLK_MODE;
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_CTRL);
> +
> + ? ? ? /* enable the SYNC signals first, then the DMA engine */
> + ? ? ? reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
> + ? ? ? reg |= VDCTRL4_SYNC_SIGNALS_ON;
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
> +
> + ? ? ? /*
> + ? ? ? ?* Give the attached LC display or monitor a chance to sync into
> + ? ? ? ?* our signals.
> + ? ? ? ?* Wait for at least 2 VSYNCs = four VSYNC edges
> + ? ? ? ?*/
> + ? ? ? edges = 4;
> +
> + ? ? ? while (edges != 0) {
> + ? ? ? ? ? ? ? loop = 800;
> + ? ? ? ? ? ? ? last_reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
> + ? ? ? ? ? ? ? do {
> + ? ? ? ? ? ? ? ? ? ? ? reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
> + ? ? ? ? ? ? ? ? ? ? ? if (reg != last_reg)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? last_reg = reg;
> + ? ? ? ? ? ? ? ? ? ? ? loop--;
> + ? ? ? ? ? ? ? } while (loop != 0);
> + ? ? ? ? ? ? ? edges--;
> + ? ? ? }
> +
> + ? ? ? /* stop FIFO reset */
> + ? ? ? writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_CLR);
> + ? ? ? /* start the engine right now */
> + ? ? ? writel(CTRL_RUN, fbi->base + HW_LCDIF_CTRL + BIT_SET);
> +}
> +
> +static void stmfb_disable_controller(struct fb_info *fb_info)
> +{
> + ? ? ? struct imxfb_info *fbi = fb_info->priv;
> + ? ? ? unsigned loop;
> + ? ? ? uint32_t reg;
> +
> + ? ? ? /*
> + ? ? ? ?* Even if we disable the controller here, it will still continue
> + ? ? ? ?* until its FIFOs are running out of data
> + ? ? ? ?*/
> + ? ? ? reg = readl(fbi->base + HW_LCDIF_CTRL);
> + ? ? ? reg &= ~CTRL_DOTCLK_MODE;
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_CTRL);
> +
> + ? ? ? loop = 1000;
> + ? ? ? while (loop) {
> + ? ? ? ? ? ? ? reg = readl(fbi->base + HW_LCDIF_CTRL);
> + ? ? ? ? ? ? ? if (!(reg & CTRL_RUN))
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? loop--;
> + ? ? ? }
> +
> + ? ? ? reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
> + ? ? ? reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
> +}
> +
> +static int stmfb_activate_var(struct fb_info *fb_info)
> +{
> + ? ? ? struct imxfb_info *fbi = fb_info->priv;
> + ? ? ? struct imx_fb_videomode *pdata = fbi->pdata;
> + ? ? ? struct fb_videomode *mode = fb_info->mode;
> + ? ? ? uint32_t reg;
> + ? ? ? int ret;
> + ? ? ? unsigned size;
> +
> + ? ? ? /*
> + ? ? ? ?* we need at least this amount of memory for the framebuffer
> + ? ? ? ?*/
> + ? ? ? size = calc_line_length(mode->xres, fb_info->bits_per_pixel) *
> + ? ? ? ? ? ? ? mode->yres;
> +
> + ? ? ? ret = stmfb_memory_mmgt(fb_info, size);
> + ? ? ? if (ret != 0) {
> + ? ? ? ? ? ? ? dev_err(fbi->hw_dev, "Cannot allocate framebuffer memory\n");
> + ? ? ? ? ? ? ? return ret;
> + ? ? ? }
> +
> + ? ? ? /** @todo ensure HCLK is active at this point of time! */
> +
> + ? ? ? size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock) * 1000);
> + ? ? ? if (size == 0) {
> + ? ? ? ? ? ? ? dev_dbg(fbi->hw_dev, "Unable to set a valid pixel clock\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? /*
> + ? ? ? ?* bring the controller out of reset and
> + ? ? ? ?* configure it into DOTCLOCK mode
> + ? ? ? ?*/
> + ? ? ? reg = CTRL_BYPASS_COUNT | ? ? ? /* always in DOTCLOCK mode */
> + ? ? ? ? ? ? ? CTRL_DOTCLK_MODE;
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_CTRL);
> +
> + ? ? ? /* master mode only */
> + ? ? ? reg |= CTRL_MASTER;
> +
> + ? ? ? /*
> + ? ? ? ?* Configure videomode and interface mode
> + ? ? ? ?*/
> + ? ? ? reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
> + ? ? ? switch (fb_info->bits_per_pixel) {
> + ? ? ? case 8:
> + ? ? ? ? ? ? ? reg |= SET_WORD_LENGTH(1);
> + ? ? ? ? ? ? ? /** @todo refer manual page 2046 for 8 bpp modes */
> + ? ? ? ? ? ? ? dev_dbg(fbi->hw_dev, "8 bpp mode not supported yet\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 16:
> + ? ? ? ? ? ? ? pr_debug("Setting up an RGB565 mode\n");
> + ? ? ? ? ? ? ? reg |= SET_WORD_LENGTH(0);
> + ? ? ? ? ? ? ? reg &= ~CTRL_DF16; /* we assume RGB565 */
> + ? ? ? ? ? ? ? writel(SET_BYTE_PACKAGING(0xf), fbi->base + HW_LCDIF_CTRL1);
> + ? ? ? ? ? ? ? fb_info->red = def_rgb565[RED];
> + ? ? ? ? ? ? ? fb_info->green = def_rgb565[GREEN];
> + ? ? ? ? ? ? ? fb_info->blue = def_rgb565[BLUE];
> + ? ? ? ? ? ? ? fb_info->transp = ?def_rgb565[TRANSP];
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 24:
> + ? ? ? case 32:
> + ? ? ? ? ? ? ? pr_debug("Setting up an RGB888/666 mode\n");
> + ? ? ? ? ? ? ? reg |= SET_WORD_LENGTH(3);
> + ? ? ? ? ? ? ? switch (pdata->ld_intf_width) {
> + ? ? ? ? ? ? ? case STMLCDIF_8BIT:
> + ? ? ? ? ? ? ? ? ? ? ? dev_dbg(fbi->hw_dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "Unsupported LCD bus width mapping\n");
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? case STMLCDIF_16BIT:
> + ? ? ? ? ? ? ? case STMLCDIF_18BIT:
> + ? ? ? ? ? ? ? ? ? ? ? /* 24 bit to 18 bit mapping
> + ? ? ? ? ? ? ? ? ? ? ? ?* which means: ignore the upper 2 bits in
> + ? ? ? ? ? ? ? ? ? ? ? ?* each colour component
> + ? ? ? ? ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? ? ? ? ? reg |= CTRL_DF24;
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->red = def_rgb666[RED];
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->green = def_rgb666[GREEN];
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->blue = def_rgb666[BLUE];
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->transp = ?def_rgb666[TRANSP];
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? case STMLCDIF_24BIT:
> + ? ? ? ? ? ? ? ? ? ? ? /* real 24 bit */
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->red = def_rgb888[RED];
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->green = def_rgb888[GREEN];
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->blue = def_rgb888[BLUE];
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->transp = ?def_rgb888[TRANSP];
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? /* do not use packed pixels = one pixel per word instead */
> + ? ? ? ? ? ? ? writel(SET_BYTE_PACKAGING(0x7), fbi->base + HW_LCDIF_CTRL1);
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? dev_dbg(fbi->hw_dev, "Unhandled colour depth of %u\n",
> + ? ? ? ? ? ? ? ? ? ? ? fb_info->bits_per_pixel);
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_CTRL);
> + ? ? ? pr_debug("Setting up CTRL to %08X\n", reg);
> +
> + ? ? ? writel(SET_VCOUNT(mode->yres) |
> + ? ? ? ? ? ? ? SET_HCOUNT(mode->xres), fbi->base + HW_LCDIF_TRANSFER_COUNT);
> +
> + ? ? ? reg = VDCTRL0_ENABLE_PRESENT | ?/* always in DOTCLOCK mode */
> + ? ? ? ? ? ? ? VDCTRL0_VSYNC_PERIOD_UNIT |
> + ? ? ? ? ? ? ? VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
> + ? ? ? if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
> + ? ? ? ? ? ? ? reg |= VDCTRL0_HSYNC_POL;
> + ? ? ? if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
> + ? ? ? ? ? ? ? reg |= VDCTRL0_VSYNC_POL;
> + ? ? ? if (mode->sync & FB_SYNC_DE_HIGH_ACT)
> + ? ? ? ? ? ? ? reg |= VDCTRL0_ENABLE_POL;
> + ? ? ? if (mode->sync & FB_SYNC_CLK_INVERT)
> + ? ? ? ? ? ? ? reg |= VDCTRL0_DOTCLK_POL;
> +
> + ? ? ? reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
> + ? ? ? writel(reg, fbi->base + HW_LCDIF_VDCTRL0);
> + ? ? ? pr_debug("Setting up VDCTRL0 to %08X\n", reg);
> +
> + ? ? ? /* frame length in lines */
> + ? ? ? writel(mode->upper_margin + mode->vsync_len + mode->lower_margin +
> + ? ? ? ? ? ? ? ? ? ? ? mode->yres,
> + ? ? ? ? ? ? ? fbi->base + HW_LCDIF_VDCTRL1);
> +
> + ? ? ? /* line length in units of clocks or pixels */
> + ? ? ? writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
> + ? ? ? ? ? ? ? SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len +
> + ? ? ? ? ? ? ? ? ? ? ? mode->right_margin + mode->xres),
> + ? ? ? ? ? ? ? fbi->base + HW_LCDIF_VDCTRL2);
> +
> + ? ? ? writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
> + ? ? ? ? ? ? ? SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
> + ? ? ? ? ? ? ? fbi->base + HW_LCDIF_VDCTRL3);
> +
> + ? ? ? writel(
> +#ifdef CONFIG_ARCH_IMX28
> + ? ? ? ? ? ? ? SET_DOTCLK_DLY(pdata->dotclk_delay) |
> +#endif
> + ? ? ? ? ? ? ? SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
> + ? ? ? ? ? ? ? fbi->base + HW_LCDIF_VDCTRL4);
> +
> + ? ? ? writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_CUR_BUF);
> + ? ? ? writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_NEXT_BUF);
> +
> + ? ? ? return 0;
> +}
> +
> +static void stmfb_info(struct device_d *hw_dev)
> +{
> + ? ? ? struct imx_fb_videomode *pdata = hw_dev->platform_data;
> + ? ? ? unsigned u;
> +
> + ? ? ? printf(" Supported video modes:\n");
> + ? ? ? for (u = 0; u < pdata->mode_cnt; u++)
> + ? ? ? ? ? ? ? printf(" ?- '%s': %u x %u\n", pdata->mode_list[u].name,
> + ? ? ? ? ? ? ? ? ? ? ? pdata->mode_list[u].xres, pdata->mode_list[u].yres);
> +}
> +
> +/*
> + * There is only one video hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct fb_ops imxfb_ops = {
> + ? ? ? .fb_activate_var = stmfb_activate_var,
> + ? ? ? .fb_enable = stmfb_enable_controller,
> + ? ? ? .fb_disable = stmfb_disable_controller,
> +};
> +
> +static struct imxfb_info fbi = {
> + ? ? ? .info = {
> + ? ? ? ? ? ? ? .fbops = &imxfb_ops,
> + ? ? ? },
> +};
> +
> +static int stmfb_probe(struct device_d *hw_dev)
> +{
> + ? ? ? struct imx_fb_videomode *pdata = hw_dev->platform_data;
> + ? ? ? int ret;
> +
> + ? ? ? /* just init */
> + ? ? ? fbi.info.priv = &fbi;
> +
> + ? ? ? /* add runtime hardware info */
> + ? ? ? fbi.hw_dev = hw_dev;
> + ? ? ? fbi.base = (void *)hw_dev->map_base;
> + ? ? ? fbi.pdata = pdata;
> +
> + ? ? ? /* add runtime video info */
> + ? ? ? fbi.info.mode_list = pdata->mode_list;
> + ? ? ? fbi.info.num_modes = pdata->mode_cnt;
> + ? ? ? fbi.info.mode = &fbi.info.mode_list[0];
> + ? ? ? fbi.info.xres = fbi.info.mode->xres;
> + ? ? ? fbi.info.yres = fbi.info.mode->yres;
> + ? ? ? fbi.info.bits_per_pixel = 16;
Could we consider to pass .bits_per_pixel through platform _data?
Is there any reason to hardcode this value?


> +
> + ? ? ? ret = register_framebuffer(&fbi.info);

At this point you register the framebuffer but screen_base is not set yet.
So when we want to access framebuffer from mmap we get a pointer to 0x0
instead of getting the pointer to the frambeffer address..
I moved  stmfb_memory_mmgt from  stmfb_activate_var to be able to
display a picture with bmp command. It worked for me because I have only
one screen available, but if you want to keep the capability to change screen on
the fly, then we will need to update map_base in fb driver.


> + ? ? ? if (ret != 0) {
> + ? ? ? ? ? ? ? dev_err(hw_dev, "Failed to register framebuffer\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static struct driver_d stmfb_driver = {
> + ? ? ? .name ? = "stmfb",
> + ? ? ? .probe ?= stmfb_probe,
> + ? ? ? .info ? = stmfb_info,
> +};
> +
> +static int stmfb_init(void)
> +{
> + ? ? ? return register_driver(&stmfb_driver);
> +}
> +
> +device_initcall(stmfb_init);
> +
> +/**
> + * @file
> + * @brief LCDIF driver for i.MX23 and i.MX28
> + *
> + * The LCDIF support four modes of operation
> + * - MPU interface (to drive smart displays) -> not supported yet
> + * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
> + * - Dotclock interface (to drive LC displays with RGB data and sync signals)
> + * - DVI (to drive ITU-R BT656) ?-> not supported yet
> + *
> + * This driver depends on a correct setup of the pins used for this purpose
> + * (platform specific).
> + *
> + * For the developer: Don't forget to set the data bus width to the display
> + * in the imx_fb_videomode structure. You will else end up with ugly colours.
> + * If you fight against jitter you can vary the clock delay. This is a feature
> + * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
> + * the required value in the imx_fb_videomode structure.
> + */
> --
> 1.7.2.3
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From boaz.bd at wellsense-tech.com  Wed Dec 29 15:35:28 2010
From: boaz.bd at wellsense-tech.com (Boaz Ben-David)
Date: Wed, 29 Dec 2010 22:35:28 +0200
Subject: 4096 page NAND boot support on iMX35 PDK board
Message-ID: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>

Hi all,

I just started using barebox on the iMX35 PDK and I have a bit of a problem.
My actual board is based on the PDK but with a slight change: the NAND chip is of newer generation and
has 4k page and 218 oob area.
I need to add support to boot from 4k pages in barebox and I can't seem to find any documentation on how to do that.
Can anyone point me in the right direction as to where to find this in the barebox code?

Thanks,

Boaz.

From eric at eukrea.com  Wed Dec 29 15:48:18 2010
From: eric at eukrea.com (=?ISO-8859-1?Q?Eric_B=E9nard?=)
Date: Wed, 29 Dec 2010 21:48:18 +0100
Subject: 4096 page NAND boot support on iMX35 PDK board
In-Reply-To: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>
References: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>
Message-ID: <4D1B9E92.2010403@eukrea.com>

Hi Boaz,

On 29/12/2010 21:35, Boaz Ben-David wrote:
> I just started using barebox on the iMX35 PDK and I have a bit of a problem.
> My actual board is based on the PDK but with a slight change: the NAND chip is of newer generation and
> has 4k page and 218 oob area.
> I need to add support to boot from 4k pages in barebox and I can't seem to find any documentation on how to do that.
> Can anyone point me in the right direction as to where to find this in the barebox code?
>
check in drivers/mtd/nand/nand_imx.c

Eric


From boaz.bd at wellsense-tech.com  Wed Dec 29 15:51:11 2010
From: boaz.bd at wellsense-tech.com (Boaz Ben-David)
Date: Wed, 29 Dec 2010 22:51:11 +0200
Subject: 4096 page NAND boot support on iMX35 PDK board
In-Reply-To: <4D1B9E92.2010403@eukrea.com>
References: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>,
	<4D1B9E92.2010403@eukrea.com>
Message-ID: <39A4B204C321D34DA3490E3B119D5A6C68BF775746@SBS2008.wellsense.local>

Hi Eric,

Thanks for the quick response, what I would like to know is where is the actual entry point to the code,
i.e. the "main()" function...
I'm asking this because when I try to boot barebox on my board with the different NAND I don't even get a prompt on
the serial line so I figured the image is not read properly.

Thanks,

Boaz.
________________________________________
From: barebox-bounces at lists.infradead.org [barebox-bounces at lists.infradead.org] On Behalf Of Eric B?nard [eric at eukrea.com]
Sent: Wednesday, December 29, 2010 10:48 PM
To: barebox at lists.infradead.org
Subject: Re: 4096 page NAND boot support on iMX35 PDK board

Hi Boaz,

On 29/12/2010 21:35, Boaz Ben-David wrote:
> I just started using barebox on the iMX35 PDK and I have a bit of a problem.
> My actual board is based on the PDK but with a slight change: the NAND chip is of newer generation and
> has 4k page and 218 oob area.
> I need to add support to boot from 4k pages in barebox and I can't seem to find any documentation on how to do that.
> Can anyone point me in the right direction as to where to find this in the barebox code?
>
check in drivers/mtd/nand/nand_imx.c

Eric

_______________________________________________
barebox mailing list
barebox at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


From eric at eukrea.com  Wed Dec 29 15:58:42 2010
From: eric at eukrea.com (=?ISO-8859-1?Q?Eric_B=E9nard?=)
Date: Wed, 29 Dec 2010 21:58:42 +0100
Subject: 4096 page NAND boot support on iMX35 PDK board
In-Reply-To: <39A4B204C321D34DA3490E3B119D5A6C68BF775746@SBS2008.wellsense.local>
References: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>,
	<4D1B9E92.2010403@eukrea.com>
	<39A4B204C321D34DA3490E3B119D5A6C68BF775746@SBS2008.wellsense.local>
Message-ID: <4D1BA102.9030509@eukrea.com>

On 29/12/2010 21:51, Boaz Ben-David wrote:
> Thanks for the quick response, what I would like to know is where is the actual entry point to the code,
> i.e. the "main()" function...
> I'm asking this because when I try to boot barebox on my board with the different NAND I don't even get a prompt on
> the serial line so I figured the image is not read properly.
>
check in this file, the imx_nand_load_image function where only 512 & 2k nand 
are handled.

Are you using internal or external boot ?

Eric


From boaz.bd at wellsense-tech.com  Wed Dec 29 16:05:26 2010
From: boaz.bd at wellsense-tech.com (Boaz Ben-David)
Date: Wed, 29 Dec 2010 23:05:26 +0200
Subject: 4096 page NAND boot support on iMX35 PDK board
In-Reply-To: <4D1BA102.9030509@eukrea.com>
References: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>,
	<4D1B9E92.2010403@eukrea.com>
	<39A4B204C321D34DA3490E3B119D5A6C68BF775746@SBS2008.wellsense.local>,
	<4D1BA102.9030509@eukrea.com>
Message-ID: <39A4B204C321D34DA3490E3B119D5A6C68BF775747@SBS2008.wellsense.local>

external
________________________________________
From: Eric B?nard [eric at eukrea.com]
Sent: Wednesday, December 29, 2010 10:58 PM
To: Boaz Ben-David
Cc: barebox at lists.infradead.org
Subject: Re: 4096 page NAND boot support on iMX35 PDK board

On 29/12/2010 21:51, Boaz Ben-David wrote:
> Thanks for the quick response, what I would like to know is where is the actual entry point to the code,
> i.e. the "main()" function...
> I'm asking this because when I try to boot barebox on my board with the different NAND I don't even get a prompt on
> the serial line so I figured the image is not read properly.
>
check in this file, the imx_nand_load_image function where only 512 & 2k nand
are handled.

Are you using internal or external boot ?

Eric


From eric at eukrea.com  Wed Dec 29 16:10:11 2010
From: eric at eukrea.com (=?ISO-8859-1?Q?Eric_B=E9nard?=)
Date: Wed, 29 Dec 2010 22:10:11 +0100
Subject: 4096 page NAND boot support on iMX35 PDK board
In-Reply-To: <39A4B204C321D34DA3490E3B119D5A6C68BF775747@SBS2008.wellsense.local>
References: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>,
	<4D1B9E92.2010403@eukrea.com>
	<39A4B204C321D34DA3490E3B119D5A6C68BF775746@SBS2008.wellsense.local>,
	<4D1BA102.9030509@eukrea.com>
	<39A4B204C321D34DA3490E3B119D5A6C68BF775747@SBS2008.wellsense.local>
Message-ID: <4D1BA3B3.1020400@eukrea.com>

On 29/12/2010 22:05, Boaz Ben-David wrote:
> external

so you have to update this function to your hardware (ie : to add 4k page 
support in the nand driver).

Eric


From boaz.bd at wellsense-tech.com  Wed Dec 29 16:15:13 2010
From: boaz.bd at wellsense-tech.com (Boaz Ben-David)
Date: Wed, 29 Dec 2010 23:15:13 +0200
Subject: 4096 page NAND boot support on iMX35 PDK board
In-Reply-To: <4D1BA3B3.1020400@eukrea.com>
References: <39A4B204C321D34DA3490E3B119D5A6C68BF775745@SBS2008.wellsense.local>,
	<4D1B9E92.2010403@eukrea.com>
	<39A4B204C321D34DA3490E3B119D5A6C68BF775746@SBS2008.wellsense.local>,
	<4D1BA102.9030509@eukrea.com>
	<39A4B204C321D34DA3490E3B119D5A6C68BF775747@SBS2008.wellsense.local>,
	<4D1BA3B3.1020400@eukrea.com>
Message-ID: <39A4B204C321D34DA3490E3B119D5A6C68BF77574A@SBS2008.wellsense.local>

Ok, thanks a lot for your help I hope it won't be too complicated implementing the support...

Boaz.
________________________________________
From: Eric B?nard [eric at eukrea.com]
Sent: Wednesday, December 29, 2010 11:10 PM
To: Boaz Ben-David
Cc: barebox at lists.infradead.org
Subject: Re: 4096 page NAND boot support on iMX35 PDK board

On 29/12/2010 22:05, Boaz Ben-David wrote:
> external

so you have to update this function to your hardware (ie : to add 4k page
support in the nand driver).

Eric


From franck.jullien at gmail.com  Thu Dec 30 07:49:34 2010
From: franck.jullien at gmail.com (Franck JULLIEN)
Date: Thu, 30 Dec 2010 13:49:34 +0100
Subject: [PATCH] Add an option to set a board specific banner
In-Reply-To: <20101230034811.GS19266@game.jcrosoft.org>
References: <20101230034811.GS19266@game.jcrosoft.org>
Message-ID: <1293713374-3476-1-git-send-email-franck.jullien@gmail.com>

Allow a board specific fancy banner

---

I removed the default fancy banner and do it like Jean-Christophe suggested it.

 common/Kconfig   |    6 ++++++
 common/console.c |    7 ++++++-
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 617f640..d32c1ce 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -248,6 +248,12 @@ config HUSH_FANCY_PROMPT
 	  Allow to set PS1 from the command line. PS1 can have several escaped commands
 	  like \h for CONFIG_BOARDINFO or \w for the current working directory.
 
+config BOARD_BANNER
+	bool
+	prompt "allow a board specific fancy banner"
+	help
+	  Allow to define a custom board banner (you can define CONFIG_BOARD_BANNER_TEXT in your config.h)
+
 config HUSH_GETOPT
 	bool
 	depends on SHELL_HUSH
diff --git a/common/console.c b/common/console.c
index 82786f2..7caef11 100644
--- a/common/console.c
+++ b/common/console.c
@@ -46,7 +46,12 @@ EXPORT_SYMBOL(console_list);
 static void display_banner (void)
 {
 	printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
-	printf(RELOC("Board: " CONFIG_BOARDINFO "\n"));
+
+#ifndef CONFIG_BOARD_BANNER
+#undef  CONFIG_BOARD_BANNER_TEXT
+#define CONFIG_BOARD_BANNER_TEXT "Board: " CONFIG_BOARDINFO "\n"
+#endif
+        printf(RELOC(CONFIG_BOARD_BANNER_TEXT));
 }
 
 static int __early_initdata initialized = 0;
-- 
1.7.1



From premi at ti.com  Thu Dec 30 08:48:28 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:18:28 +0530
Subject: [PATCH 0/6] omap3: Support for silicon revisions
Message-ID: <1293716908-5034-1-git-send-email-premi@ti.com>

This series makes enables auto-detection of silicon revision.
It also adds support for the OMAP3430 ES1.0 silicon as well.

It was tested for multiple boots on the OMAP3EVM (Rev G)
populated with ES3.1 silicon.

Sanjeev Premi (6):
  omap3: Add macros to extract hawkeye and version
  omap3: Detect cpu based on hawkeye
  omap3: Update method to detect si revision
  omap3: Add DPLL tables for silicon rev 1 and 2
  omap3: Define separate functions for DPLL configuration
  omap3: Select DPLL tables based on cpu revision

 arch/arm/mach-omap/include/mach/omap3-clock.h   |    8 +-
 arch/arm/mach-omap/include/mach/omap3-silicon.h |   16 +-
 arch/arm/mach-omap/include/mach/sys_info.h      |   26 +-
 arch/arm/mach-omap/omap3_clock.c                |  319 +++++++++++++++--------
 arch/arm/mach-omap/omap3_clock_core.S           |  200 ++++++++------
 arch/arm/mach-omap/omap3_generic.c              |   60 ++++-
 6 files changed, 399 insertions(+), 230 deletions(-)

-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 08:49:53 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:19:53 +0530
Subject: [PATCH 1/6] omap3: Add macros to extract hawkeye and version
Message-ID: <1293716998-5154-1-git-send-email-premi@ti.com>

This patch adds macros to extract the hawkeye
and version number from IDCODE value.

Updated function get_cpu_rev() to use new macro.

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/include/mach/omap3-silicon.h |   16 ++++++++--------
 arch/arm/mach-omap/omap3_generic.c              |   12 ++++++------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap/include/mach/omap3-silicon.h b/arch/arm/mach-omap/include/mach/omap3-silicon.h
index 62e612b..0e6a45f 100644
--- a/arch/arm/mach-omap/include/mach/omap3-silicon.h
+++ b/arch/arm/mach-omap/include/mach/omap3-silicon.h
@@ -116,17 +116,17 @@
 #define OMAP_TAP_BASE		(OMAP_L4_WKUP_BASE + 0xA000)
 #define IDCODE_REG		(OMAP_TAP_BASE + 0x204)
 
-/************ Generic Chip specific Definitions **********/
-/**
- * CHIP			F number	HAWKEYE (hex)
- * OMAP3430 ES1.0	F771609		B6D6
- * OMAP3430 ES2.0	F771609A	B7AE
- */
+/** Masks to extract information from ID code register */
+#define IDCODE_HAWKEYE_MASK	0x0FFFF000
+#define IDCODE_VERSION_MASK	0xF0000000
+
+ #define get_hawkeye(v)		(((v) & IDCODE_HAWKEYE_MASK) >> 12)
+ #define get_version(v)		(((v) & IDCODE_VERSION_MASK) >> 28)
+
 #define HAWKEYE_ES1		0x0B6D6000
 #define HAWKEYE_ES2		0x0B7AE000
 #define HAWKEYE_ES2_1		0x1B7AE000
-#define HAWKEYE_MASK		0x0FFFF000
-#define VERSION_MASK		0xF0000000
+
 #define DEVICE_MASK		((0x1 << 8)|(0x1 << 9)|(0x1 << 10))
 
 #define OMAP_SDRC_CS0		0x80000000
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index f780794..a079f38 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -82,13 +82,13 @@ u32 get_cpu_type(void)
 u32 get_cpu_rev(void)
 {
 	u32 idcode_val;
+	u32 version;
+
 	idcode_val = readl(IDCODE_REG);
-	if ((idcode_val & (HAWKEYE_MASK | VERSION_MASK)) == HAWKEYE_ES2_1)
-		return CPU_ES2P1;
-	if ((idcode_val & HAWKEYE_MASK) == HAWKEYE_ES2)
-		return CPU_ES2;
-	/* unsupported! */
-	return CPU_ES1;
+
+	version = get_version(idcode_val);
+
+	return version;
 }
 
 /**
-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 08:49:54 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:19:54 +0530
Subject: [PATCH 2/6] omap3: Detect cpu based on hawkeye
In-Reply-To: <1293716998-5154-1-git-send-email-premi@ti.com>
References: <1293716998-5154-1-git-send-email-premi@ti.com>
Message-ID: <1293716998-5154-2-git-send-email-premi@ti.com>

This patch sets the cpu type based on the hawkeye value
read from the IDCODE register. So far, cpu type was
hardcoded.

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/include/mach/sys_info.h |    5 +++++
 arch/arm/mach-omap/omap3_generic.c         |   14 +++++++++++++-
 2 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap/include/mach/sys_info.h b/arch/arm/mach-omap/include/mach/sys_info.h
index 4396720..f9df51c 100644
--- a/arch/arm/mach-omap/include/mach/sys_info.h
+++ b/arch/arm/mach-omap/include/mach/sys_info.h
@@ -81,6 +81,11 @@
 #define HS_DEVICE               0x2
 #define GP_DEVICE               0x3
 
+/**
+ * Hawkeye definitions to identify silicon families
+ */
+#define OMAP_HAWKEYE_34XX	0xB7AE
+
 /** These are implemented by the System specific code in omapX-generic.c */
 u32 get_cpu_type(void);
 u32 get_cpu_rev(void);
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index a079f38..cd9aceb 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -70,7 +70,19 @@ EXPORT_SYMBOL(reset_cpu);
  */
 u32 get_cpu_type(void)
 {
-	/* FIXME: need to get register defines for 3430 */
+	u32 idcode_val;
+	u16 hawkeye;
+
+	idcode_val = readl(IDCODE_REG);
+
+	hawkeye = get_hawkeye(idcode_val);
+
+	if (hawkeye == OMAP_HAWKEYE_34XX)
+		return CPU_3430;
+
+	/*
+	 * Fallback to OMAP3430 as default.
+	 */
 	return CPU_3430;
 }
 
-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 08:49:55 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:19:55 +0530
Subject: [PATCH 3/6] omap3: Update method to detect si revision
In-Reply-To: <1293716998-5154-1-git-send-email-premi@ti.com>
References: <1293716998-5154-1-git-send-email-premi@ti.com>
Message-ID: <1293716998-5154-3-git-send-email-premi@ti.com>

This patch ensures that all silicon revisions
are detected. (Current implementation cannot
detect ES1.0).

In the process, the 'seemingly' hardcoded macros
identifying cpu revision (e.g. CPU_ES1P1) have
been updated to include the CPU name as well.
(The mapping of IDCODE value to silicon revision
may not be same across different OMAP families).

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/include/mach/sys_info.h |   21 ++++++---------
 arch/arm/mach-omap/omap3_generic.c         |   38 +++++++++++++++++++++++++---
 2 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap/include/mach/sys_info.h b/arch/arm/mach-omap/include/mach/sys_info.h
index f9df51c..8b8d332 100644
--- a/arch/arm/mach-omap/include/mach/sys_info.h
+++ b/arch/arm/mach-omap/include/mach/sys_info.h
@@ -51,20 +51,15 @@
 #define CPU_1610	0x1610
 
 /**
- * CPU revision
+ * Define CPU revisions
  */
-#define CPU_ES1		1
-#define CPU_ES1P1	2
-#define CPU_ES1P2	3
-#define CPU_ES2		4
-#define CPU_ES2P1	5
-#define CPU_ES2P2	6
-#define CPU_ES3		7
-#define CPU_ES3P1	8
-#define CPU_ES3P2	9
-#define CPU_ES4		10
-#define CPU_ES4P1	11
-#define CPU_ES4P2	12
+#define	cpu_revision(cpu,rev)	(((cpu) << 16) | (rev))
+
+#define OMAP34XX_ES1		cpu_revision(CPU_3430, 0)
+#define OMAP34XX_ES2		cpu_revision(CPU_3430, 1)
+#define OMAP34XX_ES2_1		cpu_revision(CPU_3430, 2)
+#define OMAP34XX_ES3		cpu_revision(CPU_3430, 3)
+#define OMAP34XX_ES3_1		cpu_revision(CPU_3430, 4)
 
 #define GPMC_MUXED		1
 #define GPMC_NONMUXED		0
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index cd9aceb..e146780 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -87,20 +87,50 @@ u32 get_cpu_type(void)
 }
 
 /**
- * @brief Extract the OMAP ES rev
+ * @brief Extract the OMAP ES revision
  *
- * @return CPU_ES version
+ * Latest known revision is considered default.
+ *
+ * @return silicon version
  */
 u32 get_cpu_rev(void)
 {
 	u32 idcode_val;
-	u32 version;
+	u32 version, retval;
 
 	idcode_val = readl(IDCODE_REG);
 
 	version = get_version(idcode_val);
 
-	return version;
+	/*
+	 * On OMAP3430 ES1.0 the IDCODE register is not exposed on L4.
+	 * Use CPU ID to check for the same.
+	 */
+	__asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(retval));
+	if ((retval & 0xf) == 0x0) {
+		retval = OMAP34XX_ES1;
+	} else {
+		switch (version) {
+		case 0: /* This field was not set in early samples */
+		case 1:
+			retval = OMAP34XX_ES2;
+			break;
+		case 2:
+			retval = OMAP34XX_ES2_1;
+			break;
+		case 3:
+			retval = OMAP34XX_ES3;
+			break;
+		case 4:
+			/*
+			 * Same as default case
+			 */
+		default:
+			retval = OMAP34XX_ES3_1;
+		}
+	}
+
+	return retval;
 }
 
 /**
-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 08:49:56 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:19:56 +0530
Subject: [PATCH 4/6] omap3: Add DPLL tables for silicon rev 1 and 2
In-Reply-To: <1293716998-5154-1-git-send-email-premi@ti.com>
References: <1293716998-5154-1-git-send-email-premi@ti.com>
Message-ID: <1293716998-5154-4-git-send-email-premi@ti.com>

This patch adds DPLL tables for OMAP34xx ES1.0 and ES2.0.

When more than one table is added, the get_xxx_dpll_param()
was updated to use the tables corresponding to ES2.0 to
ensure that current functionality doesn't break.

In addition, the tables have been reformatted for better
readability.

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/omap3_clock_core.S |  144 ++++++++++++++-------------------
 1 files changed, 62 insertions(+), 82 deletions(-)

diff --git a/arch/arm/mach-omap/omap3_clock_core.S b/arch/arm/mach-omap/omap3_clock_core.S
index 872ae5a..207d43a 100644
--- a/arch/arm/mach-omap/omap3_clock_core.S
+++ b/arch/arm/mach-omap/omap3_clock_core.S
@@ -205,106 +205,86 @@ pll_div_val5:
 	/* the literal pools origin */
 	.ltorg
 
-/* DPLL(1-4) PARAM TABLES */
-/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal
- * OPP (1.2V). The fields are defined according to dpll_param
- * struct(omap3_clock.c). MAX index is as per omap3_clock.h
+/* MPU DPLL Parameter table
+ *
+ * This table defines the DPLL parameter table for the MPU as defined by
+ * "struct dpll_param defined" in "omap3-clock.h"
+ *
+ * The tables are defined for separately each silicon revision.
  */
-
-mpu_dpll_param:
-/* 12MHz */
-/* ES2 */
-.word 0x0FA,0x05,0x07,0x01
-
-/* 13MHz */
-/* ES2 */
-.word 0x1F4,0x0C,0x03,0x01
-
-/* 19.2MHz */
-/* ES2 */
-.word 0x271,0x17,0x03,0x01
-
-/* 26MHz */
-/* ES2 */
-.word 0x0FA,0x0C,0x07,0x01
-
-/* 38.4MHz */
-/* ES2 */
-.word 0x271,0x2F,0x03,0x01
+.globl mpu_dpll_param_es1
+mpu_dpll_param_es1:
+/*    	M	N	FREQSEL	M2	*/
+.word	0x0FE,	0x07,	0x05,	0x01		/* 12   MHz	*/
+.word	0x17D,	0x0C,	0x03,	0x01		/* 13   MHz	*/
+.word	0x179,	0x12,	0x04,	0x01		/* 19.2 MHz	*/
+.word	0x17D,	0x19,	0x03,	0x01		/* 26   MHz	*/
+.word	0x1FA,	0x32,	0x03,	0x01		/* 38.4 MHz	*/
+
+.globl mpu_dpll_param_es2
+mpu_dpll_param_es2:
+/*    	M	N	FREQSEL	M2	*/
+.word	0x0FA,	0x05,	0x07,	0x01		/* 12   MHz	*/
+.word	0x1F4,	0x0C,	0x03,	0x01		/* 13   MHz	*/
+.word	0x271,	0x17,	0x03,	0x01		/* 19.2 MHz	*/
+.word	0x0FA,	0x0C,	0x07,	0x01		/* 26   MHz	*/
+.word	0x271,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
 .globl get_mpu_dpll_param
 get_mpu_dpll_param:
-	adr r0, mpu_dpll_param
+	adr r0, mpu_dpll_param_es2
 	mov pc, lr
 
-iva_dpll_param:
-/* 12MHz */
-/* ES2 */
-.word 0x0B4,0x05,0x07,0x01
-
-/* 13MHz */
-/* ES2 */
-.word 0x168,0x0C,0x03,0x01
-
-/* 19.2MHz */
-/* ES2 */
-.word 0x0E1,0x0B,0x06,0x01
-
-/* 26MHz */
-/* ES2 */
-.word 0x0B4,0x0C,0x07,0x01
-
-/* 38.4MHz */
-/* ES2 */
-.word 0x0E1,0x17,0x06,0x01
+iva_dpll_param_es1:
+/*    	M	N	FREQSEL	M2				*/
+.word	0x07D,	0x05,	0x07,	0x01		/* 12   MHz	*/
+.word	0x0FA,	0x0C,	0x03,	0x01		/* 13   MHz	*/
+.word	0x082,	0x09,	0x07,	0x01		/* 19.2 MHz	*/
+.word	0x07D,	0x0C,	0x07,	0x01		/* 26   MHz	*/
+.word	0x13F,	0x30,	0x03,	0x01		/* 38.4 MHz	*/
+
+iva_dpll_param_es2:
+/*    	M	N	FREQSEL	M2				*/
+.word	0x0B4,	0x05,	0x07,	0x01		/* 12   MHz	*/
+.word	0x168,	0x0C,	0x03,	0x01		/* 13   MHz	*/
+.word	0x0E1,	0x0B,	0x06,	0x01		/* 19.2 MHz	*/
+.word	0x0B4,	0x0C,	0x07,	0x01		/* 26   MHz	*/
+.word	0x0E1,	0x17,	0x06,	0x01		/* 38.4 MHz	*/
 
 .globl get_iva_dpll_param
 get_iva_dpll_param:
-	adr r0, iva_dpll_param
+	adr r0, iva_dpll_param_es2
 	mov pc, lr
 
-core_dpll_param:
-/* 12MHz */
-/* ES2 */
-.word 0x0A6,0x05,0x07,0x01
-
-/* 13MHz */
-/* ES2 */
-.word 0x14C,0x0C,0x03,0x01
-
-/* 19.2MHz */
-/* ES2 */
-.word 0x19F,0x17,0x03,0x01
-
-/* 26MHz */
-/* ES2 */
-.word 0x0A6,0x0C,0x07,0x01
-
-/* 38.4MHz */
-/* ES2 */
-.word 0x19F,0x2F,0x03,0x01
+core_dpll_param_es1:
+/*    	M	N	FREQSEL	M2				*/
+.word	0x19F,	0x0E,	0x03,	0x01		/* 12   MHz	*/
+.word	0x1B2,	0x10,	0x03,	0x01		/* 13   MHz	*/
+.word	0x19F,	0x17,	0x03,	0x01		/* 19.2 MHz	*/
+.word	0x1B2,	0x21,	0x03,	0x01		/* 26   MHz	*/
+.word	0x19F,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
+
+core_dpll_param_es2:
+/*    	M	N	FREQSEL	M2				*/
+.word	0x0A6,	0x05,	0x07,	0x01		/* 12   MHz	*/
+.word	0x14C,	0x0C,	0x03,	0x01		/* 13   MHz	*/
+.word	0x19F,	0x17,	0x03,	0x01		/* 19.2 MHz	*/
+.word	0x0A6,	0x0C,	0x07,	0x01		/* 26   MHz	*/
+.word	0x19F,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
 .globl get_core_dpll_param
 get_core_dpll_param:
-	adr r0, core_dpll_param
+	adr r0, core_dpll_param_es2
 	mov pc, lr
 
 /* PER DPLL values are same for both ES1 and ES2 */
 per_dpll_param:
-/* 12MHz */
-.word 0xD8,0x05,0x07,0x09
-
-/* 13MHz */
-.word 0x1B0,0x0C,0x03,0x09
-
-/* 19.2MHz */
-.word 0xE1,0x09,0x07,0x09
-
-/* 26MHz */
-.word 0xD8,0x0C,0x07,0x09
-
-/* 38.4MHz */
-.word 0xE1,0x13,0x07,0x09
+/*    	M	N	FREQSEL	M2				*/
+.word	0x0D8,	0x05,	0x07,	0x09		/* 12   MHz	*/
+.word	0x1B0,	0x0C,	0x03,	0x09		/* 13   MHz	*/
+.word	0x0E1,	0x09,	0x07,	0x09		/* 19.2 MHz	*/
+.word	0x0D8,	0x0C,	0x07,	0x09		/* 26   MHz	*/
+.word	0x0E1,	0x13,	0x07,	0x09		/* 38.4 MHz	*/
 
 .globl get_per_dpll_param
 get_per_dpll_param:
-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 08:49:58 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:19:58 +0530
Subject: [PATCH 6/6] omap3: Select DPLL tables based on cpu revision
In-Reply-To: <1293716998-5154-1-git-send-email-premi@ti.com>
References: <1293716998-5154-1-git-send-email-premi@ti.com>
Message-ID: <1293716998-5154-6-git-send-email-premi@ti.com>

This patch updates the DPLL functions to return correct
DPLL table based on the cpu revision.

The DPLL table for PER domain is same across all revisions,
but the function signature has been updated to maintain
consistency in the API definition.

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/include/mach/omap3-clock.h |    8 ++--
 arch/arm/mach-omap/omap3_clock.c              |    8 ++--
 arch/arm/mach-omap/omap3_clock_core.S         |   58 ++++++++++++++++++++++---
 3 files changed, 60 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap/include/mach/omap3-clock.h b/arch/arm/mach-omap/include/mach/omap3-clock.h
index b655fe3..1b42500 100644
--- a/arch/arm/mach-omap/include/mach/omap3-clock.h
+++ b/arch/arm/mach-omap/include/mach/omap3-clock.h
@@ -125,10 +125,10 @@ struct dpll_param {
 	unsigned int m2;
 };
 /* External functions see omap3_clock_core.S */
-extern struct dpll_param *get_mpu_dpll_param(void);
-extern struct dpll_param *get_iva_dpll_param(void);
-extern struct dpll_param *get_core_dpll_param(void);
-extern struct dpll_param *get_per_dpll_param(void);
+extern struct dpll_param *get_mpu_dpll_param(u32);
+extern struct dpll_param *get_iva_dpll_param(u32);
+extern struct dpll_param *get_core_dpll_param(u32);
+extern struct dpll_param *get_per_dpll_param(u32);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c
index ff99b2c..dad4ed1 100644
--- a/arch/arm/mach-omap/omap3_clock.c
+++ b/arch/arm/mach-omap/omap3_clock.c
@@ -144,7 +144,7 @@ static void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
  */
 static void init_core_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_core_dpll_param();
+	struct dpll_param *dp = get_core_dpll_param(cpu_rev);
 #ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
 	int p0, p1, p2, p3;
 #endif
@@ -242,7 +242,7 @@ static void init_core_dpll_34x(u32 cpu_rev, u32 clk_sel)
  */
 static void init_per_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_per_dpll_param();
+	struct dpll_param *dp = get_per_dpll_param(cpu_rev);
 
 	dp += clk_sel;
 
@@ -300,7 +300,7 @@ static void init_per_dpll_34x(u32 cpu_rev, u32 clk_sel)
  */
 static void init_mpu_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_mpu_dpll_param();
+	struct dpll_param *dp = get_mpu_dpll_param(cpu_rev);
 
 	dp += clk_sel;
 
@@ -325,7 +325,7 @@ static void init_mpu_dpll_34x(u32 cpu_rev, u32 clk_sel)
  */
 static void init_iva_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_iva_dpll_param();
+	struct dpll_param *dp = get_iva_dpll_param(cpu_rev);
 
 	dp += clk_sel;
 
diff --git a/arch/arm/mach-omap/omap3_clock_core.S b/arch/arm/mach-omap/omap3_clock_core.S
index 207d43a..f28069a 100644
--- a/arch/arm/mach-omap/omap3_clock_core.S
+++ b/arch/arm/mach-omap/omap3_clock_core.S
@@ -230,10 +230,23 @@ mpu_dpll_param_es2:
 .word	0x0FA,	0x0C,	0x07,	0x01		/* 26   MHz	*/
 .word	0x271,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
+/**
+ * @brief Get address of MPU DPLL param table.
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
 .globl get_mpu_dpll_param
 get_mpu_dpll_param:
-	adr r0, mpu_dpll_param_es2
-	mov pc, lr
+	mov	r3, r0
+	lsl	r3, r3, #16		/* Isolate silicon revision */
+	lsr	r3, r3, #16
+	cmp	r3, #0			/* Revision 1 ? */
+	adr	r0, mpu_dpll_param_es1
+	bxeq	lr
+	adr	r0, mpu_dpll_param_es2
+	mov	pc, lr
 
 iva_dpll_param_es1:
 /*    	M	N	FREQSEL	M2				*/
@@ -251,10 +264,23 @@ iva_dpll_param_es2:
 .word	0x0B4,	0x0C,	0x07,	0x01		/* 26   MHz	*/
 .word	0x0E1,	0x17,	0x06,	0x01		/* 38.4 MHz	*/
 
+/**
+ * @brief Get address of IVA DPLL param table.
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
 .globl get_iva_dpll_param
 get_iva_dpll_param:
-	adr r0, iva_dpll_param_es2
-	mov pc, lr
+	mov	r3, r0
+	lsl	r3, r3, #16		/* Isolate silicon revision */
+	lsr	r3, r3, #16
+	cmp	r3, #0			/* Revision 1 ? */
+	adr	r0, iva_dpll_param_es1
+	bxeq	lr
+	adr	r0, iva_dpll_param_es2
+	mov	pc, lr
 
 core_dpll_param_es1:
 /*    	M	N	FREQSEL	M2				*/
@@ -272,10 +298,23 @@ core_dpll_param_es2:
 .word	0x0A6,	0x0C,	0x07,	0x01		/* 26   MHz	*/
 .word	0x19F,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
+/**
+ * @brief Get address of CORE DPLL param table.
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
 .globl get_core_dpll_param
 get_core_dpll_param:
-	adr r0, core_dpll_param_es2
-	mov pc, lr
+	mov	r3, r0
+	lsl	r3, r3, #16		/* Isolate silicon revision */
+	lsr	r3, r3, #16
+	cmp	r3, #0			/* Revision 1 ? */
+	adr	r0, core_dpll_param_es1
+	bxeq	lr
+	adr	r0, core_dpll_param_es2
+	mov	pc, lr
 
 /* PER DPLL values are same for both ES1 and ES2 */
 per_dpll_param:
@@ -286,6 +325,13 @@ per_dpll_param:
 .word	0x0D8,	0x0C,	0x07,	0x09		/* 26   MHz	*/
 .word	0x0E1,	0x13,	0x07,	0x09		/* 38.4 MHz	*/
 
+/**
+ * @brief Get address of PER DPLL param table.
+ *
+ * @param rev Silicon revision (not used).
+ *
+ * @return Address of the param table
+ */
 .globl get_per_dpll_param
 get_per_dpll_param:
 	adr r0, per_dpll_param
-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 08:49:57 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:19:57 +0530
Subject: [PATCH 5/6] omap3: Define separate functions for DPLL configuration
In-Reply-To: <1293716998-5154-1-git-send-email-premi@ti.com>
References: <1293716998-5154-1-git-send-email-premi@ti.com>
Message-ID: <1293716998-5154-5-git-send-email-premi@ti.com>

Content from monolith implementation in prcm_init() has been
moved into separate functions - per clock domain. This makes
code easy to adapt for silicon revisions and families.

Few cosmetic changes may have been done during this movement.

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/omap3_clock.c |  319 +++++++++++++++++++++++++-------------
 1 files changed, 210 insertions(+), 109 deletions(-)

diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c
index 13e8729..ff99b2c 100644
--- a/arch/arm/mach-omap/omap3_clock.c
+++ b/arch/arm/mach-omap/omap3_clock.c
@@ -137,89 +137,87 @@ static void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
 }
 
 /**
- * @brief Inits clocks for PRCM
+ * @brief Initialize CORE DPLL for OMAP34x
  *
- * This is called from SRAM, or Flash (using temp SRAM stack).
- * if CONFIG_OMAP3_COPY_CLOCK_SRAM is defined, @ref go_to_speed
- *
- * @return void
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
  */
-void prcm_init(void)
+static void init_core_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	int xip_safe;
-	u32 osc_clk = 0, sys_clkin_sel = 0;
-	u32 clk_index, sil_index = 0;
-	struct dpll_param *dpll_param_p;
+	struct dpll_param *dp = get_core_dpll_param();
 #ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
 	int p0, p1, p2, p3;
-	f_lock_pll = (void *)(OMAP_SRAM_INTVECT + OMAP_SRAM_INTVECT_COPYSIZE);
 #endif
 
-	xip_safe = running_in_sram();
+	dp += clk_sel;
 
-	/* Gauge the input clock speed and find out the sys_clkin_sel
-	 * value corresponding to the input clock.
-	 */
-	osc_clk = get_osc_clk_speed();
-	get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
-	/* set input crystal speed */
-	sr32(PRM_REG(CLKSEL), 0, 3, sys_clkin_sel);
-
-	/* If the input clock is greater than 19.2M always divide/2 */
-	if (sys_clkin_sel > 2) {
-		/* input clock divider */
-		sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 2);
-		clk_index = sys_clkin_sel / 2;
-	} else {
-		/* input clock divider */
-		sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 1);
-		clk_index = sys_clkin_sel;
-	}
-
-	/* Unlock MPU DPLL (slows things down, and needed later) */
-	sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOW_POWER_BYPASS);
-	wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_MPU), LDELAY);
-
-	/* Getting the base address of Core DPLL param table */
-	dpll_param_p = (struct dpll_param *)get_core_dpll_param();
-	/* Moving it to the right sysclk and ES rev base */
-	dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
-	if (xip_safe) {
-		/* CORE DPLL */
-		/* sr32(CM_REG(CLKSEL2_EMU)) set override to work when asleep */
+	if (running_in_sram()) {
 		sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_FAST_RELOCK_BYPASS);
 		wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_CKGEN), LDELAY);
-		/* For 3430 ES1.0 Errata 1.50, default value directly doesnt
-		   work. write another value and then default value. */
+
+		/*
+		 * OMAP3430 ES1.0 Errata 1.50
+		 * Writing default value doesn't work. First write a different
+		 * value and then write the default value.
+		 */
+
+		/* CM_CLKSEL1_EMU[DIV_DPLL3] */
 		sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2 + 1);
 		sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2);
-		sr32(CM_REG(CLKSEL1_PLL), 27, 2, dpll_param_p->m2);
-		sr32(CM_REG(CLKSEL1_PLL), 16, 11, dpll_param_p->m);
-		sr32(CM_REG(CLKSEL1_PLL), 8, 7, dpll_param_p->n);
+
+		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+		sr32(CM_REG(CLKSEL1_PLL), 27, 2, dp->m2);
+
+		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+		sr32(CM_REG(CLKSEL1_PLL), 16, 11, dp->m);
+
+		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+		sr32(CM_REG(CLKSEL1_PLL), 8, 7, dp->n);
+
+		/* Set source CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
 		sr32(CM_REG(CLKSEL1_PLL), 6, 1, 0);
+
 		sr32(CM_REG(CLKSEL_CORE), 8, 4, CORE_SSI_DIV);
 		sr32(CM_REG(CLKSEL_CORE), 4, 2, CORE_FUSB_DIV);
 		sr32(CM_REG(CLKSEL_CORE), 2, 2, CORE_L4_DIV);
 		sr32(CM_REG(CLKSEL_CORE), 0, 2, CORE_L3_DIV);
 		sr32(CM_REG(CLKSEL_GFX), 0, 3, GFX_DIV);
 		sr32(CM_REG(CLKSEL_WKUP), 1, 2, WKUP_RSM);
-		sr32(CM_REG(CLKEN_PLL), 4, 4, dpll_param_p->fsel);
+
+		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+		sr32(CM_REG(CLKEN_PLL), 4, 4, dp->fsel);
+
+		/* Lock Mode */
 		sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_LOCK);
 		wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_CKGEN), LDELAY);
 	} else if (running_in_flash()) {
 #ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
-		/* if running from flash,
-		 * jump to small relocated code area in SRAM.
+		f_lock_pll = (void *)(OMAP_SRAM_INTVECT +
+					OMAP_SRAM_INTVECT_COPYSIZE);
+
+		/*
+		 * Jump to small relocated code area in SRAM.
 		 */
 		p0 = readl(CM_REG(CLKEN_PLL));
 		sr32((u32) &p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
-		sr32((u32) &p0, 4, 4, dpll_param_p->fsel);
+
+		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+		sr32((u32) &p0, 4, 4, dp->fsel);
 
 		p1 = readl(CM_REG(CLKSEL1_PLL));
-		sr32((u32) &p1, 27, 2, dpll_param_p->m2);
-		sr32((u32) &p1, 16, 11, dpll_param_p->m);
-		sr32((u32) &p1, 8, 7, dpll_param_p->n);
-		sr32((u32) &p1, 6, 1, 0);	/* set source for 96M */
+
+		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+		sr32((u32) &p1, 27, 2, dp->m2);
+
+		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+		sr32((u32) &p1, 16, 11, dp->m);
+
+		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+		sr32((u32) &p1, 8, 7, dp->n);
+
+		/* Set source CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+		sr32((u32) &p1, 6, 1, 0);
+
 		p2 = readl(CM_REG(CLKSEL_CORE));
 		sr32((u32) &p2, 8, 4, CORE_SSI_DIV);
 		sr32((u32) &p2, 4, 2, CORE_FUSB_DIV);
@@ -234,70 +232,173 @@ void prcm_init(void)
 		hang();
 #endif
 	}
+}
+
+/**
+ * @brief Initialize PER DPLL for OMAP34x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_per_dpll_34x(u32 cpu_rev, u32 clk_sel)
+{
+	struct dpll_param *dp = get_per_dpll_param();
+
+	dp += clk_sel;
+
+	/*
+	 * OMAP3430 ES1.0 Errata 1.50
+	 * Writing default value doesn't work. First write a different
+	 * value and then write the default value.
+	 */
 
-	/* PER DPLL */
 	sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_STOP);
 	wait_on_value((0x1 << 1), 0, CM_REG(IDLEST_CKGEN), LDELAY);
 
-	/* Getting the base address to PER  DPLL param table */
-	/* Set N */
-	dpll_param_p = (struct dpll_param *)get_per_dpll_param();
-	/* Moving it to the right sysclk base */
-	dpll_param_p = dpll_param_p + clk_index;
-	/* Errata 1.50 Workaround for 3430 ES1.0 only */
-	/* If using default divisors, write default divisor + 1
-	   and then the actual divisor value */
-	/* Need to change it to silicon and revisino check */
-	if (1) {
-		sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2 + 1);	/* set M6 */
-		sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2);	/* set M6 */
-		sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2 + 1);	/* set M5 */
-		sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2);	/* set M5 */
-		sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2 + 1);	/* set M4 */
-		sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2);	/* set M4 */
-		sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2 + 1);	/* set M3 */
-		sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2);	/* set M3 */
-		/* set M2 */
-		sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2 + 1);
-		sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2);
-	} else {
-		sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2);	/* set M6 */
-		sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2);	/* set M5 */
-		sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2);	/* set M4 */
-		sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2);	/* set M3 */
-		sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2);
-	}
-	sr32(CM_REG(CLKSEL2_PLL), 8, 11, dpll_param_p->m);	/* set m */
-	sr32(CM_REG(CLKSEL2_PLL), 0, 7, dpll_param_p->n);	/* set n */
-	sr32(CM_REG(CLKEN_PLL), 20, 4, dpll_param_p->fsel);	/* FREQSEL */
-	sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_LOCK);	/* lock mode */
+	/* Set M6 */
+	sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2 + 1);
+	sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2);
+
+	/* Set M5 */
+	sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2 + 1);
+	sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2);
+
+	/* Set M4 */
+	sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2 + 1);
+	sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2);
+
+	/* Set M3 */
+	sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2 + 1);
+	sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2);
+
+	/* Set M2 */
+	sr32(CM_REG(CLKSEL3_PLL), 0, 5, dp->m2 + 1);
+	sr32(CM_REG(CLKSEL3_PLL), 0, 5, dp->m2);
+
+	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
+	sr32(CM_REG(CLKSEL2_PLL), 8, 11, dp->m);
+
+	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+	sr32(CM_REG(CLKSEL2_PLL), 0, 7, dp->n);
+
+	/* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
+	sr32(CM_REG(CLKEN_PLL), 20, 4, dp->fsel);
+
+	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+	sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_LOCK);
 	wait_on_value((0x1 << 1), 2, CM_REG(IDLEST_CKGEN), LDELAY);
+}
 
-	/* Getting the base address to MPU DPLL param table */
-	dpll_param_p = (struct dpll_param *)get_mpu_dpll_param();
-	/* Moving it to the right sysclk and ES rev base */
-	dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
-	/* MPU DPLL (unlocked already) */
-	sr32(CM_REG(CLKSEL2_PLL_MPU), 0, 5, dpll_param_p->m2);	/* Set M2 */
-	sr32(CM_REG(CLKSEL1_PLL_MPU), 8, 11, dpll_param_p->m);	/* Set M */
-	sr32(CM_REG(CLKSEL1_PLL_MPU), 0, 7, dpll_param_p->n);	/* Set N */
-	sr32(CM_REG(CLKEN_PLL_MPU), 4, 4, dpll_param_p->fsel);	/* FREQSEL */
-	sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOCK);	/* lock mode */
-	wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_MPU), LDELAY);
+/**
+ * @brief Initialize MPU DPLL for OMAP34x
+ *
+ * The MPU DPLL is already unlocked when control reaches here. This
+ * function doesn't lock the DPLL either - defers to the caller.
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_mpu_dpll_34x(u32 cpu_rev, u32 clk_sel)
+{
+	struct dpll_param *dp = get_mpu_dpll_param();
+
+	dp += clk_sel;
+
+	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+	sr32(CM_REG(CLKSEL2_PLL_MPU), 0, 5, dp->m2);
+
+	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+	sr32(CM_REG(CLKSEL1_PLL_MPU), 8, 11, dp->m);
+
+	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+	sr32(CM_REG(CLKSEL1_PLL_MPU), 0, 7, dp->n);
+
+	/* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
+	sr32(CM_REG(CLKEN_PLL_MPU), 4, 4, dp->fsel);
+}
+
+/**
+ * @brief Initialize IVA DPLL for OMAP34x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_iva_dpll_34x(u32 cpu_rev, u32 clk_sel)
+{
+	struct dpll_param *dp = get_iva_dpll_param();
 
-	/* Getting the base address to IVA DPLL param table */
-	dpll_param_p = (struct dpll_param *)get_iva_dpll_param();
-	/* Moving it to the right sysclk and ES rev base */
-	dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
-	/* IVA DPLL (set to 12*20=240MHz) */
+	dp += clk_sel;
+
+	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
 	sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_STOP);
 	wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_IVA2), LDELAY);
-	sr32(CM_REG(CLKSEL2_PLL_IVA2), 0, 5, dpll_param_p->m2);	/* set M2 */
-	sr32(CM_REG(CLKSEL1_PLL_IVA2), 8, 11, dpll_param_p->m);	/* set M */
-	sr32(CM_REG(CLKSEL1_PLL_IVA2), 0, 7, dpll_param_p->n);	/* set N */
-	sr32(CM_REG(CLKEN_PLL_IVA2), 4, 4, dpll_param_p->fsel);	/* FREQSEL */
-	sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_LOCK);	/* lock mode */
+
+	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+	sr32(CM_REG(CLKSEL2_PLL_IVA2), 0, 5, dp->m2);
+
+	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+	sr32(CM_REG(CLKSEL1_PLL_IVA2), 8, 11, dp->m);
+
+	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+	sr32(CM_REG(CLKSEL1_PLL_IVA2), 0, 7, dp->n);
+
+	/* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
+	sr32(CM_REG(CLKEN_PLL_IVA2), 4, 4, dp->fsel);
+
+	/* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
+	sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_LOCK);
 	wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_IVA2), LDELAY);
+}
+
+/**
+ * @brief Inits clocks for PRCM
+ *
+ * This is called from SRAM, or Flash (using temp SRAM stack).
+ * if CONFIG_OMAP3_COPY_CLOCK_SRAM is defined, @ref go_to_speed
+ *
+ * @return void
+ */
+void prcm_init(void)
+{
+	u32 osc_clk = 0, sys_clkin_sel = 0;
+	u32 cpu_rev = get_cpu_rev();
+	u32 clk_index;
+
+	/* Gauge the input clock speed and find out the sys_clkin_sel
+	 * value corresponding to the input clock.
+	 */
+	osc_clk = get_osc_clk_speed();
+	get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
+	/* set input crystal speed */
+	sr32(PRM_REG(CLKSEL), 0, 3, sys_clkin_sel);
+
+	/* If the input clock is greater than 19.2M always divide/2 */
+	if (sys_clkin_sel > 2) {
+		/* input clock divider */
+		sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 2);
+		clk_index = sys_clkin_sel / 2;
+	} else {
+		/* input clock divider */
+		sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 1);
+		clk_index = sys_clkin_sel;
+	}
+
+	/*
+	 * Unlock the MPU PLL. Run slow while clocks are being configured.
+	 */
+	sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOW_POWER_BYPASS);
+	wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_MPU), LDELAY);
+
+	init_core_dpll_34x(cpu_rev, clk_index);
+	init_per_dpll_34x(cpu_rev, clk_index);
+	init_mpu_dpll_34x(cpu_rev, clk_index);
+	init_iva_dpll_34x(cpu_rev, clk_index);
+
+	/*
+	 * Clock configuration complete. Lock MPU PLL.
+	 */
+	sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOCK);
+	wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_MPU), LDELAY);
 
 	/* Set up GPTimers to sys_clk source only */
 	sr32(CM_REG(CLKSEL_PER), 0, 8, 0xff);
-- 
1.7.2.2



From premi at ti.com  Thu Dec 30 09:09:07 2010
From: premi at ti.com (Sanjeev Premi)
Date: Thu, 30 Dec 2010 19:39:07 +0530
Subject: [PATCH] omap34x: Add suffix to DPLL tables and related function
Message-ID: <1293718147-6248-1-git-send-email-premi@ti.com>

This patch adds suffix 34x to DPLL tables and related functions to
indicate that they are applicable to OMAP34XX only.

The suffix was required to prepare for support of OMAP36XX in the
subsequent patch series.

Signed-off-by: Sanjeev Premi <premi at ti.com>
---
 arch/arm/mach-omap/include/mach/omap3-clock.h |    8 ++--
 arch/arm/mach-omap/omap3_clock.c              |    8 ++--
 arch/arm/mach-omap/omap3_clock_core.S         |   56 ++++++++++++------------
 3 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-omap/include/mach/omap3-clock.h b/arch/arm/mach-omap/include/mach/omap3-clock.h
index 1b42500..6613645 100644
--- a/arch/arm/mach-omap/include/mach/omap3-clock.h
+++ b/arch/arm/mach-omap/include/mach/omap3-clock.h
@@ -125,10 +125,10 @@ struct dpll_param {
 	unsigned int m2;
 };
 /* External functions see omap3_clock_core.S */
-extern struct dpll_param *get_mpu_dpll_param(u32);
-extern struct dpll_param *get_iva_dpll_param(u32);
-extern struct dpll_param *get_core_dpll_param(u32);
-extern struct dpll_param *get_per_dpll_param(u32);
+extern struct dpll_param *get_mpu_dpll_param_34x(u32);
+extern struct dpll_param *get_iva_dpll_param_34x(u32);
+extern struct dpll_param *get_core_dpll_param_34x(u32);
+extern struct dpll_param *get_per_dpll_param_34x(u32);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c
index dad4ed1..c5a32e9 100644
--- a/arch/arm/mach-omap/omap3_clock.c
+++ b/arch/arm/mach-omap/omap3_clock.c
@@ -144,7 +144,7 @@ static void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
  */
 static void init_core_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_core_dpll_param(cpu_rev);
+	struct dpll_param *dp = get_core_dpll_param_34x(cpu_rev);
 #ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
 	int p0, p1, p2, p3;
 #endif
@@ -242,7 +242,7 @@ static void init_core_dpll_34x(u32 cpu_rev, u32 clk_sel)
  */
 static void init_per_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_per_dpll_param(cpu_rev);
+	struct dpll_param *dp = get_per_dpll_param_34x(cpu_rev);
 
 	dp += clk_sel;
 
@@ -300,7 +300,7 @@ static void init_per_dpll_34x(u32 cpu_rev, u32 clk_sel)
  */
 static void init_mpu_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_mpu_dpll_param(cpu_rev);
+	struct dpll_param *dp = get_mpu_dpll_param_34x(cpu_rev);
 
 	dp += clk_sel;
 
@@ -325,7 +325,7 @@ static void init_mpu_dpll_34x(u32 cpu_rev, u32 clk_sel)
  */
 static void init_iva_dpll_34x(u32 cpu_rev, u32 clk_sel)
 {
-	struct dpll_param *dp = get_iva_dpll_param(cpu_rev);
+	struct dpll_param *dp = get_iva_dpll_param_34x(cpu_rev);
 
 	dp += clk_sel;
 
diff --git a/arch/arm/mach-omap/omap3_clock_core.S b/arch/arm/mach-omap/omap3_clock_core.S
index f28069a..5a1f068 100644
--- a/arch/arm/mach-omap/omap3_clock_core.S
+++ b/arch/arm/mach-omap/omap3_clock_core.S
@@ -212,8 +212,8 @@ pll_div_val5:
  *
  * The tables are defined for separately each silicon revision.
  */
-.globl mpu_dpll_param_es1
-mpu_dpll_param_es1:
+.globl mpu_dpll_param_34x_es1
+mpu_dpll_param_34x_es1:
 /*    	M	N	FREQSEL	M2	*/
 .word	0x0FE,	0x07,	0x05,	0x01		/* 12   MHz	*/
 .word	0x17D,	0x0C,	0x03,	0x01		/* 13   MHz	*/
@@ -221,8 +221,8 @@ mpu_dpll_param_es1:
 .word	0x17D,	0x19,	0x03,	0x01		/* 26   MHz	*/
 .word	0x1FA,	0x32,	0x03,	0x01		/* 38.4 MHz	*/
 
-.globl mpu_dpll_param_es2
-mpu_dpll_param_es2:
+.globl mpu_dpll_param_34x_es2
+mpu_dpll_param_34x_es2:
 /*    	M	N	FREQSEL	M2	*/
 .word	0x0FA,	0x05,	0x07,	0x01		/* 12   MHz	*/
 .word	0x1F4,	0x0C,	0x03,	0x01		/* 13   MHz	*/
@@ -231,24 +231,24 @@ mpu_dpll_param_es2:
 .word	0x271,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
 /**
- * @brief Get address of MPU DPLL param table.
+ * @brief Get address of MPU DPLL param table (OMAP34XX).
  *
  * @param rev Silicon revision.
  *
  * @return Address of the param table
  */
-.globl get_mpu_dpll_param
-get_mpu_dpll_param:
+.globl get_mpu_dpll_param_34x
+get_mpu_dpll_param_34x:
 	mov	r3, r0
 	lsl	r3, r3, #16		/* Isolate silicon revision */
 	lsr	r3, r3, #16
 	cmp	r3, #0			/* Revision 1 ? */
-	adr	r0, mpu_dpll_param_es1
+	adr	r0, mpu_dpll_param_34x_es1
 	bxeq	lr
-	adr	r0, mpu_dpll_param_es2
+	adr	r0, mpu_dpll_param_34x_es2
 	mov	pc, lr
 
-iva_dpll_param_es1:
+iva_dpll_param_34x_es1:
 /*    	M	N	FREQSEL	M2				*/
 .word	0x07D,	0x05,	0x07,	0x01		/* 12   MHz	*/
 .word	0x0FA,	0x0C,	0x03,	0x01		/* 13   MHz	*/
@@ -256,7 +256,7 @@ iva_dpll_param_es1:
 .word	0x07D,	0x0C,	0x07,	0x01		/* 26   MHz	*/
 .word	0x13F,	0x30,	0x03,	0x01		/* 38.4 MHz	*/
 
-iva_dpll_param_es2:
+iva_dpll_param_34x_es2:
 /*    	M	N	FREQSEL	M2				*/
 .word	0x0B4,	0x05,	0x07,	0x01		/* 12   MHz	*/
 .word	0x168,	0x0C,	0x03,	0x01		/* 13   MHz	*/
@@ -265,24 +265,24 @@ iva_dpll_param_es2:
 .word	0x0E1,	0x17,	0x06,	0x01		/* 38.4 MHz	*/
 
 /**
- * @brief Get address of IVA DPLL param table.
+ * @brief Get address of IVA DPLL param table (OMAP34XX).
  *
  * @param rev Silicon revision.
  *
  * @return Address of the param table
  */
-.globl get_iva_dpll_param
-get_iva_dpll_param:
+.globl get_iva_dpll_param_34x
+get_iva_dpll_param_34x:
 	mov	r3, r0
 	lsl	r3, r3, #16		/* Isolate silicon revision */
 	lsr	r3, r3, #16
 	cmp	r3, #0			/* Revision 1 ? */
-	adr	r0, iva_dpll_param_es1
+	adr	r0, iva_dpll_param_34x_es1
 	bxeq	lr
-	adr	r0, iva_dpll_param_es2
+	adr	r0, iva_dpll_param_34x_es2
 	mov	pc, lr
 
-core_dpll_param_es1:
+core_dpll_param_34x_es1:
 /*    	M	N	FREQSEL	M2				*/
 .word	0x19F,	0x0E,	0x03,	0x01		/* 12   MHz	*/
 .word	0x1B2,	0x10,	0x03,	0x01		/* 13   MHz	*/
@@ -290,7 +290,7 @@ core_dpll_param_es1:
 .word	0x1B2,	0x21,	0x03,	0x01		/* 26   MHz	*/
 .word	0x19F,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
-core_dpll_param_es2:
+core_dpll_param_34x_es2:
 /*    	M	N	FREQSEL	M2				*/
 .word	0x0A6,	0x05,	0x07,	0x01		/* 12   MHz	*/
 .word	0x14C,	0x0C,	0x03,	0x01		/* 13   MHz	*/
@@ -299,25 +299,25 @@ core_dpll_param_es2:
 .word	0x19F,	0x2F,	0x03,	0x01		/* 38.4 MHz	*/
 
 /**
- * @brief Get address of CORE DPLL param table.
+ * @brief Get address of CORE DPLL param table (OMAP34XX).
  *
  * @param rev Silicon revision.
  *
  * @return Address of the param table
  */
-.globl get_core_dpll_param
-get_core_dpll_param:
+.globl get_core_dpll_param_34x
+get_core_dpll_param_34x:
 	mov	r3, r0
 	lsl	r3, r3, #16		/* Isolate silicon revision */
 	lsr	r3, r3, #16
 	cmp	r3, #0			/* Revision 1 ? */
-	adr	r0, core_dpll_param_es1
+	adr	r0, core_dpll_param_34x_es1
 	bxeq	lr
-	adr	r0, core_dpll_param_es2
+	adr	r0, core_dpll_param_34x_es2
 	mov	pc, lr
 
 /* PER DPLL values are same for both ES1 and ES2 */
-per_dpll_param:
+per_dpll_param_34x:
 /*    	M	N	FREQSEL	M2				*/
 .word	0x0D8,	0x05,	0x07,	0x09		/* 12   MHz	*/
 .word	0x1B0,	0x0C,	0x03,	0x09		/* 13   MHz	*/
@@ -326,13 +326,13 @@ per_dpll_param:
 .word	0x0E1,	0x13,	0x07,	0x09		/* 38.4 MHz	*/
 
 /**
- * @brief Get address of PER DPLL param table.
+ * @brief Get address of PER DPLL param table (OMAP34XX).
  *
  * @param rev Silicon revision (not used).
  *
  * @return Address of the param table
  */
-.globl get_per_dpll_param
-get_per_dpll_param:
-	adr r0, per_dpll_param
+.globl get_per_dpll_param_34x
+get_per_dpll_param_34x:
+	adr r0, per_dpll_param_34x
 	mov pc, lr
-- 
1.7.2.2



From plagnioj at jcrosoft.com  Fri Dec 31 02:24:44 2010
From: plagnioj at jcrosoft.com (Jean-Christophe PLAGNIOL-VILLARD)
Date: Fri, 31 Dec 2010 08:24:44 +0100
Subject: [PATCH] Add an option to set a board specific banner
In-Reply-To: <1293713374-3476-1-git-send-email-franck.jullien@gmail.com>
References: <20101230034811.GS19266@game.jcrosoft.org>
	<1293713374-3476-1-git-send-email-franck.jullien@gmail.com>
Message-ID: <20101231072444.GB2965@game.jcrosoft.org>

On 13:49 Thu 30 Dec     , Franck JULLIEN wrote:
> Allow a board specific fancy banner
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>

Best Regards,
J.


From boaz.bd at wellsense-tech.com  Wed Dec 29 16:11:59 2010
From: boaz.bd at wellsense-tech.com (Boaz Ben-David)
Date: Wed, 29 Dec 2010 23:11:59 +0200
Subject: 4096 page NAND boot support on iMX35 PDK board
Message-ID: <1xhec4ka7so7xglae2hemo2h.1293657114183@email.android.com>

Ok, thanks alot for the help!

Boaz.

Eric B?nard <eric at eukrea.com> wrote:


On 29/12/2010 22:05, Boaz Ben-David wrote:
> external

so you have to update this function to your hardware (ie : to add 4k page
support in the nand driver).

Eric


